Saturday, April 16, 2011

Integrating Oracle UCM 11g RIDC with WebCenter/ADF 11g

I've seen some blog posts about using the Content Server's RIDC API in ADF, but none cover all aspects of using the full power of this API to work with UCM in a programmatic environment.

In order to get things started you need to install the WebCenter extensions for JDeveloper, create a WebCenter Portal project and configure a Content Server connection to point to a running instance of UCM 11g. More details on how to do this are given by Andrejus Baranovskis on his blog here.

Once you have these in place, you can start programming RIDC. I will describe below the most useful operations that can be performed using the API.

Create a RIDC session
String connectionName = DocLibADFConfigUtils.getPrimaryConnectionName();
Repository repository = ADFConnectionsManager.lookupRepository(connectionName);
Credentials creds = new SimpleCredentials("sysadmin", "".toCharArray());
SessionPool sessionPool = new SessionPool(repository, creds);
Session session = sessionPool.getSession();
IdcClient idcClient = (IdcClient) session.getAttribute(oracle.stellent.ridc.IdcClient.class.getName());
IdcContext idcCtx = (IdcContext) session.getAttribute(oracle.stellent.ridc.IdcContext.class.getName());

The IdcClient and IdcContext classes are the base classes for the RIDC API. All further operations will be performed using these two classes.


Retrieve a folder
You can properly retrieve a DataBinder object for a folder using the RIDC API, as shown below.
The input variable folderPath must contain the full path to the folder.
DataBinder binder = idcClient.createBinder();
binder.putLocal("IdcService", "COLLECTION_INFO");
binder.putLocal("hasCollectionPath", "true");
binder.putLocal("dCollectionPath", folderPath);

DataBinder folder = idcClient.sendRequest(adminUserCtx, binder).getResponseAsBinder();


Create a folder
You can properly create a folder by using the RIDC API, as shown below.
The input variables are self-explaining: folderName, securityGroup, parentFolderID (DataBinder object), user and account.
DataBinder dbinder = idcClient.createBinder();
dbinder.putLocal("IdcService", "COLLECTION_ADD");
dbinder.putLocal("dCollectionName", folderName);
dbinder.putLocal("dCollectionOwner", idcCtx.getUser());
dbinder.putLocal("dSecurityGroup", securityGroup);
dbinder.putLocal("hasParentCollectionID", "true");
dbinder.putLocal("dParentCollectionID", parentFolderID);
dbinder.putLocal("ignoreMaxFolderLimit", "

dbinder.putLocal("dCollectionCreator", user);
dbinder.putLocal("dCollectionModifier", user);
dbinder.putLocal("dDocAccount", account);

Delete a folder

You can properly delete a folder by using the RIDC API, as shown below.
The input variable is the DataBinder object of the folder: folderToDelete
DataBinder binder = idcClient.createBinder();
binder.putLocal("IdcService", "COLLECTION_DELETE");
binder.putLocal("hasCollectionGUID", "true");
binder.putLocal("dCollectionGUID", folderToDelete.getLocal("dCollectionGUID"));
binder.putLocal("deleteImmediate", "true");
binder.putLocal("force", "true");
idcClient.sendRequest(idcContext, binder).getResponseAsBinder();

Uploading a file
The RIDC API doesn't provide functions to upload files. In order to achieve this, you need to use the JCR API.
The input variables are the file name, the InputStream of the file you want to upload and the destination folder path: fileName, inputStream and folderPath
Node parentNode = session.getRootNode(folderPath);
boolean overWrite = true;
Node fileNode = null;
Node contentNode = null;

if (overWrite) {
   fileNode = parentNode.getNode(fileName);
   contentNode = fileNode.getNode(Names.JCR_CONTENT.toString(session));
}
else {
   fileNode = parentNode.addNode(fileName, Names.NT_FILE.toString(session));
   contentNode = fileNode.addNode(Names.JCR_CONTENT.toString(session));
}
contentNode.setProperty(Names.JCR_DATA.toString(session), inputStream);
parentNode.save();

Getting file contents
This operation must also be performed through JCR API. Using the above example, get a Node for the file and query for the Names.JCR_DATA property to get the file content.

Setting permissions for a user or group
You can assign accounts and roles to a user and corresponding permissions for each. Input variables are: principalName (name of the user or group), accountName (name of the account to add), accountPerms (permissions for the account as integer), roleName (name of the role to add), rolePerms (permissions for the role as integer).
List fields = new ArrayList(3);
fields.add(new DataResultSet.Field("dUserName"));
fields.add(new DataResultSet.Field("dApplication"));
fields.add(new DataResultSet.Field("AttributeInfo"));
DataResultSet resultSet = new DataResultSetImpl();
resultSet.setFields(fields);



List accountRow = new ArrayList(3);
accountRow.add(principal.getName());
accountRow.add(appName);
accountRow.add("account," + accountName + "," + accountPerms);
resultSet.addRow(accountRow);



List roleRow = new ArrayList(3);
roleRow.add(principal.getName());
roleRow.add(appName);
roleRow.add("role," + roleName + "," + permsToSet);
resultSet.addRow(roleRow);

 
DataBinder binder = idcClient.createBinder();
if(principal is a user)
  binder.putLocal("IdcService", "ADD_EXTENDED_USER_ATTRIBUTES");
else // principal is a group
  binder.putLocal("IdcService", "SET_EXTENDED_ATTRIBUTE_MAPPINGS");


binder.putLocal("dName", principalName);
binder.addResultSet("ExtUserAttribInfo", resultSet);

idcClient.sendRequest(adminUserCtx, binder);
 Having the examples above, you can harvest the full power of UCM services. Just find the service you want to use (check the Oracle Fusion Middleware Services Reference Guide for Oracle Universal Content Management) and then invoke the services as shown in the examples above with their appropriate parameters described in the guide.

Enjoy!

7 comments:

  1. Thax, nice and quick info blog !

    ReplyDelete
  2. Hii Andrejus, This is durgesh..
    Actually i have just started using ridc and i am trying to execute some common functions like deleting a document through follwing code :-
    public void deleteDoc() throws IdcClientException ,IOException {

    System.out.println("In the deleteDoc method.. ");
    IdcClient client =getConnection();
    DataBinder binder = client.createBinder ();
    binder.putLocal ("IdcService", "DELETE_DOC");
    binder.putLocal ("dID", "COOPER_4444001205");
    binder.putLocal ("dDocName", "COOPER_4444001205");
    IdcContext userContext = new IdcContext(username);
    client.sendRequest (userContext, binder);
    System.out.println("After deleteDoc method.. ");

    }
    For that we have to use dID, which is the generated content ID,
    can you please tell me from where to get this dID..!!!
    The program is not throwing any error or exception..
    but it is also not deleting the document.

    ReplyDelete
    Replies
    1. Hello,

      dID is a unique numeric id which is per document per version. dID can never contain alphanumerics as in your sample.
      One of the ways to get it is by using the service DOC_INFO_BY_NAME.
      After that you can delete the document.
      Alternative is to create a custom delete service comparable to for example CHECKOUT_BY_NAME, where the servie itself calculates the dID.

      Delete
  3. it's Good!!

    yes, we unable to get the ID...
    Blog ID, Forum ID, Announcement ID...

    ReplyDelete
  4. Hi Flavius,

    I am using RIDC to upload existing content into UCM.

    I have found this blog entry very helpful -- thanks very much for providing that!

    I plan to load the content via batch loader.

    Since the content I will be loading is in a large directory tree, and I will need to provide the value of dCollectionID for content I load with the batch loader, I am first creating the folder hierarchy in UCM.

    I have 2 questions I am hoping you can help with:

    1) when I create a new folder, using COLLECTION_ADD, the only
    DataResultSet I seem to get back is "UserAttribInfo"

    I was expecting to get back some DataResultSet such as "PATH"
    which would provide the dCollectionID (which I would use to
    create any sub-folders of this new folder).

    Do have any thoughts on how best to get the dCollectionID of
    the folder created using COLLECTION_ADD?

    2) I am having a difficult time finding comprehensive reference
    for calling the various services, e.g.
    a) which parameters to supply (using setLocal())
    b) which result sets are returned
    c) the expected contents of any given result set

    I regularly consult such docs as the one you reference in
    your blog entry above:
    "Oracle Fusion Middleware Services Reference Guide for
    Oracle Universal Content Management"
    http://docs.oracle.com/cd/E14571_01/doc.1111/e11011/toc.htm
    but this does not have complete information.

    For example, section 8.2.41 "COLLECTION_INFO" does not indicate
    which result sets are returned, although I see (using
    DataBinder.getResultSetNames()), these result sets:
    DocFormats, UserAttribInfo, PATH, DocTypes, metadata

    Do you have any suggestions as to the best way to go about
    understanding such specifics of each service, in particular
    when invoking them via RIDC calls?

    Thanks very much for any help on this!

    Paul

    ReplyDelete
  5. Hi,

    Very useful post. If possible please share code for workflow approval using RIDC client in UCM 11g.

    Regards,
    Shashi Ranjan

    ReplyDelete
  6. Hi Flavius

    Is there a way to show these uploaded files into an activity stream?

    ReplyDelete