To compile this sample application, you will need to install RIDC library as extension for JDeveloper 11g. Please read instructions available here.
This application allows to add new employee, same time when new employee record is stored in database, it automatically creates new folder in UCM. Folder name is the same as employee ID, this allows to show documents related to selected employee. Adding new employee into the system:
Newly added employee is assigned with ID #232, folder with the same name is created in UCM (achieved programmatically using RIDC API) - WebCenter Document Management ADF task flow renders this folder:
UCM folder is changed dynamically, based on employee table row selection, because startFolderPath parameter points to managed bean method - where folder path is constructed based on current employee row selection:
We can upload new documents using out of the WebCenter functionality:
If someone is trying to remove employee record, we can check first if any documents exist for this employee. If there are documents available in Content Repository - employee removal can be prevented (achieved programmatically, using RIDC API):
Delete associated documents first:
Employee record is removed successfully:
Below I'm listing RIDC API methods from sample application. Connection with UCM is established through socket type, without specifying Content Repository password, Identity Propagation is done automatically through ADF Security Context.
1) Create new UCM folder
DataBinder dataBinder = idcClient.createBinder();
dataBinder.putLocal("IdcService", "COLLECTION_ADD");
dataBinder.putLocal("hasParentCollectionID", "true");
dataBinder.putLocal("dCollectionName", folderName);
dataBinder.putLocal("dParentCollectionID", this.getFolderIdFromPath(idcClient, userContext, PATH));
dataBinder.putLocal("dCollectionOwner", "sysadmin");
ServiceResponse response = idcClient.sendRequest(userContext, dataBinder);
DataBinder serverBinder = response.getResponseAsBinder();
System.out.println(serverBinder.getLocal("dCollectionID"));
dataBinder.putLocal("IdcService", "COLLECTION_ADD");
dataBinder.putLocal("hasParentCollectionID", "true");
dataBinder.putLocal("dCollectionName", folderName);
dataBinder.putLocal("dParentCollectionID", this.getFolderIdFromPath(idcClient, userContext, PATH));
dataBinder.putLocal("dCollectionOwner", "sysadmin");
ServiceResponse response = idcClient.sendRequest(userContext, dataBinder);
DataBinder serverBinder = response.getResponseAsBinder();
System.out.println(serverBinder.getLocal("dCollectionID"));
There is no need to close RIDC connection after request, it is closed automatically when response.getResponseAsBinder() method is invoked. For new folder we must specify parent folder ID, it is internal UCM identificator, it can be retrieved from folder path:
2) UCM folder ID Info
DataBinder dataBinder = idcClient.createBinder();
dataBinder.putLocal("IdcService", "COLLECTION_INFO");
dataBinder.putLocal("hasCollectionPath", "true");
dataBinder.putLocal("dCollectionPath", path);
ServiceResponse response = idcClient.sendRequest(userContext, dataBinder);
DataBinder serverBinder = response.getResponseAsBinder();
DataResultSet resultSet = serverBinder.getResultSet("PATH");
DataObject dataObject = resultSet.getRows().get(resultSet.getRows().size() - 1);
folderId = dataObject.get("dCollectionID");
3) Delete UCM folder
DataBinder dataBinder = idcClient.createBinder();
dataBinder.putLocal("IdcService", "COLLECTION_DELETE");
dataBinder.putLocal("hasCollectionID", "true");
dataBinder.putLocal("dCollectionID", this.getFolderIdFromPath(idcClient, userContext, path));
dataBinder.putLocal("force", "true");
dataBinder.putLocal("deleteImmediate", "true");
ServiceResponse response = idcClient.sendRequest(userContext, dataBinder);
response.getResponseAsBinder();
4) Check if folder contains Files or internal Folders
DataBinder dataBinder = idcClient.createBinder();
dataBinder.putLocal("IdcService", "COLLECTION_GET_COLLECTIONS");
dataBinder.putLocal("hasCollectionID", "true");
dataBinder.putLocal("dCollectionID", this.getFolderIdFromPath(idcClient, userContext, path));
ServiceResponse response = idcClient.sendRequest(userContext, dataBinder);
DataBinder serverBinder = response.getResponseAsBinder();
DataResultSet resultSet = serverBinder.getResultSet("COLLECTIONS");
docCount += resultSet.getRows().size();
dataBinder = idcClient.createBinder();
dataBinder.putLocal("IdcService", "COLLECTION_GET_CONTENTS");
dataBinder.putLocal("hasCollectionPath", "true");
dataBinder.putLocal("dCollectionPath", path);
response = idcClient.sendRequest(userContext, dataBinder);
serverBinder = response.getResponseAsBinder();
resultSet = serverBinder.getResultSet("CONTENTS");
docCount += resultSet.getRows().size();
When I was working with UCM RIDC API, sometimes its very tough to get any info about API method return values. But there is a small trick, you can iterate through response result set names and get names for all return values:
Iterator iter = serverBinder.getResultSetNames().iterator();
while (iter.hasNext()) {
System.out.println(iter.next());
}
35 comments:
I've been using RIDC for a while, its amazing how can you accomplish using this APIs
Like for instance, if this employee has a picture, you can store this picture as a content in his folder, and instead of having iconized picture in Document Library taskflow, you can use dynamic converter to show the actual content of the document selected, same goes for PDF, Word and all extensions supported by Dynamic Converter.
RIDC are really fun to play with, Thanks for this great post, great as always Andrejus
Thanks for great feedback :)
There are 3 kind of interfaces to access UCM
- SAOP Webservices
- Content Integration Suite (CSI)
- Light Weight Remote Intradoc Client(RIDC)
I am happy to see RIDC example , I will love if i can find
something that do the same thing using other two access way.I will try to do it.
This is fantastic stuff to connect to UCM from plain java.
always a great job from andrejus
Thats right, however RIDC seems to be the most popular...
Thanks,
Andrejus
Hi,
thank you for information about ridc. Where do you get information about input parameter to the different services?
For example COLLECTION_GET_CONTENTS. Service reference only list the name.
Arnolf
Hi,
Its special Red Samurai trick :)
Andrejus
Very good article. I also use RIDC in my project and I wonder is ther possible to search specified folder by custom metadata? From other hand I specify metadat as input parameter and the function (idoc script if exists) return me a folder id or a list of ID's.
Do you think is it possible?
I believe this should be possible, you should check in API, operations for find.
Andrejus
I have created a XML document as datafile and I converted into a stream, so how could I use this to upload or create a new web asset for a specific REGIONDEFINATION.
I tried by creating a temp xml file, and uploaded to UCM, but this does not work for multiple request. I want to create a new data file for each request inside a folder.
I am looking for SS_CHECKIN_WEB_ASSET idcservice, but unable to found much on it. I believe this is used to create or check in new data file into UCM, which does not need any primary file.
Regards,
Pranab
Hi Andrejus
I am using a RIDC DataControl to retrieve the QuickSearch results from UCM. I have configured the below user settings for RIDC:
RIDC Socket Type: socket
Server Host Name: localhost
Content Server Listener Port: 4444
Authentication: Identity Propagation
Username/Password: weblogic/weblogi
But even though I am using "weblogic" user credentials and RIDC socket connection, the logs on the UCM shows as a "CIS connection". Also, the user is coming as "anonymous" rather than "weblogic" (used from Connection Repository) Below are the search logs:
searchquery/7 08.09 15:55:41.195 IdcServer-1320 Query by anonymous from CIS
searchquery/6 08.09 15:55:41.198 IdcServer-1320 preparedQueryText: (xCollectionID > `0` xCollectionID < `0`) (test1)
searchquery/6 08.09 15:55:41.199 IdcServer-1320 Setting substr to other operator conv flag: '(xCollectionID > `0` xCollectionID < `0`) (test1)'
searchquery/6 08.09 15:55:41.199 IdcServer-1320 Parsing universal query: '(xCollectionID > `0` xCollectionID < `0`) (test1)'
searchquery/6 08.09 15:55:41.199 IdcServer-1320 Processing callback on query value '0'
searchquery/6 08.09 15:55:41.199 IdcServer-1320 Processing callback on query value '0'
searchquery/6 08.09 15:55:41.200 IdcServer-1320 Converted native query: '( SDATA(xCollectionID > 0) or SDATA(xCollectionID < 0) ) and ( ((DEFINESCORE((test1), RELEVANCE * .1)) ))'
searchquery/6 08.09 15:55:41.200 IdcServer-1320 query(cache): &QueryText=%28xCollectionID+%3e+%600%60+%3cOR%3e+xCollectionID+%3c+%600%60%29+%3cAND%3e+%28%3cqsch%3etest1%3c%2fqsch%3e%29/((((z5075626C6963) WITHIN zdSecurityGroup))) and ((((idcnull) WITHIN dDocAccount)))//ORACLETEXTSEARCH [1,200]
searchquery/6 08.09 15:55:41.200 IdcServer-1320 Execution time is 5.25 ms.
Is there any further configuration I have to in order to mark the connection as RIDC (either in JDev or UCM) ?
Thanks
Khad
Hi,
You should enable ADF Security for your ADF application, so it will not use "anonymous" user, but "authenticated". As I can see from your error log message.
Identity propagation works only with ADF Security enabled.
Regards,
Andrejus
Thanks Andrejus. Do you have any step by step guide/blog for adding ADF security (11g) for the page which is built on DataControl?
Yes, hope this will help: http://andrejusb.blogspot.com/2010/11/things-you-must-know-about-adf-faces.html
Andrejus
Identity propagation happens through the login page. On a successful login, same user credentials are propagated to retrieve the content for the Search.jspx page. I don't think, any additional ADF security configuration need to be added for 11g. I mean, once you configure the Search.jspx page on pages.xml with the required grants Page will be visible once you login to portal from login.jspx.
Yes, if you are using WebCenter. But I don't recommend using pages.xml at all, is full of bugs.
Andrejus
Hi Andrejus
Do you have any example or blog on calling Jive Search using REST Web services ? Any suggestions on this is highly appreciated?
Thanks
Khad
Hi Andrejus,
Could you suggest how we automate document upload process in UCM. We have large volume of scanned PDF files more 34,0000 files per day.
Ramesh
Hi Andrejus,
I am looking for an example to add content under a folder. I have searched documentation and found "COLLECTION_CHECKIN_NEW" service for my purpose. But the documentation doesnot talk about the required parameters to be passed to this service. Can you please share an example.
regards,
Sunil Kumar Dhage
I will, on my todo list ;)
Andrejus
Hi Andrejus,
I have created a folder using "COLLECTION_ADD". I am able to do "COLLECTION_INFO" on the same folder. But while adding content under the same folder and I am getting "Content item '(null)' was not successfully checked in. Unable to open folder".
public void addContent() {
IdcClient idcClient = null;
try {
idcClient = getIdcClient();
IdcContext userContext = new IdcContext(USER);
DataBinder binder = idcClient.createBinder();
binder.putLocal ("IdcService", "COLLECTION_CHECKIN_NEW");
// get the binder
binder.putLocal ("dDocTitle", "Image file");
binder.putLocal ("dDocName", "3.001");
//binder.putLocal ("dDocAuthor", "Developer");
binder.putLocal ("dDocType", "Document");
binder.putLocal ("dSecurityGroup", "Public");
//binder.putLocal ("createPrimaryMetaFile", "true");
//binder.putLocal ("AllowPrimaryMetaFile", "true");
binder.putLocal("hasParentCollectionID", "true");
//binder.putLocal("dParentCollectionID", "739373434448003843");
binder.putLocal("dParentCollectionID", this.getFolderIdFromPath(idcClient, userContext, PATH));
// add a file
binder.addFile ("primaryFile", new TransferFile(new File("D:\\P6WS\\RIDC Test\\src\\com\\oracle\\ridc\\poc\\3.jpg")));
// checkin the file
ServiceResponse response = idcClient.sendRequest(userContext, binder);
DataBinder serverBinder = response.getResponseAsBinder();
String dAction = serverBinder.getLocal("dAction");
System.out.println("the dAction "+dAction);
Map localData = serverBinder.getLocalData();
for( Object key : localData.keySet()) {
System.out.println(" Key "+key +" Value "+localData.get(key));
}
} catch (IOException e) {
System.err.println(" Error due to "+e.getMessage());
//e.printStackTrace();
} catch (IdcClientException e) {
System.err.println(" Error due to "+e.getMessage());
e.printStackTrace();
}
use chekin universal service and provide the metadata xCollection id.Then i belive it sits in the sepcified folder.you dont need this much coding stuff
Hi Andrejus,
tried to run this aplicastion but got this exception
Target URL -- http://127.0.0.1:7101/UCMNewFolder-ViewController-context-root/faces/main
UCM user weblogic was specified as typeShapeUser and does not exist for repository UCMFileStore. Option list for content type security groups may be incomplete (calls will be made as anonymous user).
Submission[id=1, service=oracle.webcenter.content.jcr.login, resource=UCMFileStore] caught exception running task
javax.jcr.RepositoryException: Unable to load content server metadata model using GET_DOC_METADATA_INFO.
at oracle.jcr.impl.ExceptionFactory.repository(ExceptionFactory.java:142)
at oracle.stellent.jcr.IdcConnection.refreshMetadataModel(IdcConnection.java:89)
at oracle.stellent.jcr.IdcPersistenceManagerFactory.createPersistenceManager(IdcPersistenceManagerFactory.java:189)
at oracle.jcr.impl.OracleRepositoryImpl.login(OracleRepositoryImpl.java:444)
at oracle.vcr.jam.LoginTask.call(LoginTask.java:68)
at oracle.vcr.jam.LoginTask.call(LoginTask.java:29)
at oracle.webcenter.concurrent.Submission$2.run(Submission.java:484)
at java.security.AccessController.doPrivileged(Native Method)
at oracle.security.jps.util.JpsSubject.doAsPrivileged(JpsSubject.java:313)
at oracle.webcenter.concurrent.Submission.runAsPrivileged(Submission.java:498)
at oracle.webcenter.concurrent.Submission.run(Submission.java:424)
at oracle.webcenter.concurrent.Submission$SubmissionFutureTask.run(Submission.java:888)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at oracle.webcenter.concurrent.ModifiedThreadPoolExecutor$Worker.runTask(ModifiedThreadPoolExecutor.java:657)
at oracle.webcenter.concurrent.ModifiedThreadPoolExecutor$Worker.run(ModifiedThreadPoolExecutor.java:682)
at java.lang.Thread.run(Thread.java:662)
Caused by: oracle.stellent.ridc.protocol.http.HttpProtocolException: Form validation failed
at oracle.stellent.ridc.protocol.http.auth.FormAuthHandler.throwFormValidateException(FormAuthHandler.java:342)
at oracle.stellent.ridc.protocol.http.auth.FormAuthHandler.handleFormResponse(FormAuthHandler.java:322)
... 16 more
can you help.
Regards,
Raj
I see you are using weblogic user to test, do you have such user in UCM?
Andrejus
Hi, i am new to RIDC thingy and would like to start a project with it. May i know more about the "getFolderIdFromPath" function and what kind of PATH to be expected eg. the folder and actual example?
You can download example from this blog.
Andrejus
Hi
The Oracle® Universal Content Management Services Reference Guide 11g Document is not a complete reference , and i have many problems with this guide .
do you have any better guide?
can you help me (please .........)
bye
Thanks!! you helps me a lot!
Hello, I have a problem with this example.
<[ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'> <> <> <352b2f8e7566887c:-36694a18:13b09a8e815:-8000-00000000000001a8> <1353078105110> <[ServletContext@350520588[app:UCMNewFolder_application1 module:UCMNewFolder-ViewController-context-root path:/UCMNewFolder-ViewController-context-root spec-version:2.5 version:V2.0]] Servlet failed with Exception
java.lang.NullPointerException
at oracle.adf.model.binding.DCIteratorBinding.executeQueryIfNeeded(DCIteratorBinding.java:2160)
at oracle.adf.model.binding.DCBindingContainer.internalRefreshControl(DCBindingContainer.java:3244)
at oracle.adf.model.binding.DCBindingContainer.refresh(DCBindingContainer.java:2874)
at oracle.adf.controller.v2.lifecycle.PageLifecycleImpl.prepareModel(PageLifecycleImpl.java:115)
at oracle.adf.controller.v2.lifecycle.Lifecycle$2.execute(Lifecycle.java:137)
at oracle.adfinternal.controller.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:197)
at oracle.adfinternal.controller.faces.lifecycle.ADFPhaseListener.access$400(ADFPhaseListener.java:23)
at oracle.adfinternal.controller.faces.lifecycle.ADFPhaseListener$PhaseInvokerImpl.startPageLifecycle(ADFPhaseListener.java:238)
at oracle.adfinternal.controller.faces.lifecycle.ADFPhaseListener$1.after(ADFPhaseListener.java:274).......
Can anyone suggest me, please?
Looks like connection to the DB failed, do you have HR schema?
Andrejus
I am tring to Approve/Reject a workflow using RIDC. There seems to be a bug in the API. It allows my to Approve using the superuser (Weblogic). The API throws a valid error while rejecting as weblogic, but it throws a form validation error when I create user context using actual reviewer. Any suggestions?
ORACLE UCM: 11.1.1.5
Hi friends,
How we can integrate BPM and UCM using RIDC API.
I know we need to Connect to UCM server
Fetch the DOC
Close the connection.
So can u provide code using BPEL based Embedded activity.
Regards,
Suman
Hi,
I would suggest to integrate from ADF attached to BPM, don't integrate directly into BPM flow. Basically you would need to build ADF UI Task Form with UCM access.
This is on my TODO list to show how with sample app.
Andrejus
hi Andrejus,
I have the same requirement...
I requirement goes this way..
I need to Connect UCM server of my client machine.
Download the Document and Show it in ADF Screen.
Close the connections.
I've created the Java Class to connect to UCM using RIDC.
Now i need to Download the PDf file and Need to Show it in ADF UI.
Can u plz give sample example on this.. i've to deliver soon.
Regards,
Pavan
Hi andreju,
I am trying to upload a document to UCM
below is the code
IdcClientManager manager = new IdcClientManager();
IdcClient idcClient = manager.createClient(connection);
IdcContext userContext = new IdcContext(username, password);
DataBinder binder = idcClient.createBinder();
binder.putLocal("IdcService", "CHECKIN_UNIVERSAL");
binder.putLocal("dDocTitle", title);
binder.putLocal("dDocName", name);
binder.putLocal("dDocType", type);
binder.putLocal("xCollectionID", Long.toString(folder));
binder.putLocal("dSecurityGroup", "Public");
binder.putLocal("hasParentCollectionID", "true");
binder.addFile("primaryFile", file);
ServiceResponse response = idcClient.sendRequest(userContext, binder);
DataBinder serverBinder = response.getResponseAsBinder();
But i get an exception
oracle.stellent.ridc.protocol.ProtocolException: java.io.IOException: Read error
at oracle.stellent.ridc.protocol.http.IdcHttpProtocol.sendRequest(IdcHttpProtocol.java:345)
at oracle.stellent.ridc.protocol.http.auth.FormAuthHandler.sendAuthenticatedRequest(FormAuthHandler.java:134)
at oracle.stellent.ridc.protocol.http.IdcHttpProtocol.writeRequest(IdcHttpProtocol.java:204)
at oracle.stellent.ridc.IdcClient.sendRequest(IdcClient.java:181)
at view.UCM_API.uploadDocument(UCM_API.java:43)
at view.backing.DocUpload.uploadListener(DocUpload.java:51)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.sun.el.parser.AstValue.invoke(Unknown Source)
at com.sun.el.MethodExpressionImpl.invoke(Unknown Source)
at org.apache.myfaces.trinidad.component.UIXComponentBase.broadcastToMethodExpression(UIXComponentBase.java:1300)
at oracle.adf.view.rich.component.UIXDialog.broadcast(UIXDialog.java:97)
at oracle.adfinternal.view.faces.lifecycle.LifecycleImpl.broadcastEvents(LifecycleImpl.java:1018)
at oracle.adfinternal.view.faces.lifecycle.LifecycleImpl._executePhase(LifecycleImpl.java:386)
at oracle.adfinternal.view.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:194)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:265)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227)
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:300)
at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:26)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
at oracle.webcenter.framework.events.dispatcher.EventDispatcherFilter.doFilter(EventDispatcherFilter.java:44)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
at oracle.adf.model.servlet.ADFBindingFilter.doFilter(ADFBindingFilter.java:205)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
at oracle.adfinternal.view.faces.webapp.rich.RegistrationFilter.doFilter(RegistrationFilter.java:106)
at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl$FilterListChain.doFilter(TrinidadFilterImpl.java:446)
at oracle.adfinternal.view.faces.activedata.AdsFilter.doFilter(AdsFilter.java:60)
at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl$FilterListChain.doFilter(TrinidadFilterImpl.java:446)
at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl._doFilterImpl(TrinidadFilterImpl.java:271)
at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl.doFilter(TrinidadFilterImpl.java:177)
at org.apache.myfaces.trinidad.webapp
Can you please tell me whats the issue in the code.
Hi Andrejus,
I am implemented the same in webcenter portal application.but I am facing some issue while using treebavigation on leftside of the document manager taskflow.Once I used that when I click in employee the document manager is not rendering.illegalStateExpetion.
ppr problem.if i ran your application its running fine.
I am using jdev 11.1.1.7.o and webcenter as 1.1.1.8.0 version.
please suggest me solution.
below type of error i am getting
https://forums.oracle.com/thread/2607074
please give me some solution.
Thanks,
Siva Sankar
Post a Comment