Oracle WebCenter Content (abbreviated WCC and formerly referred to as UCM or Stellent) exposes nearly everything it can do as a service.  WCC is very SOA friendly.  We can take advantage of this fact and use something like curl or wget to execute services in WCC from the command line.

While curl and wget are often thought of as Linux/UNIX/OSX commands we should point out that there are versions that can be installed for Windows as well.  The official description of curl:
Curl is a command line tool for transferring data with URL syntax, supporting DICT, FILE, FTP, FTPS, Gopher, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMTP, SMTPS, Telnet and TFTP. curl supports SSL certificates, HTTP POST, HTTP PUT, FTP uploading, HTTP form based upload, proxies, cookies, user+password authentication (Basic, Digest, NTLM, Negotiate, Kerberos…), file transfer resume, proxy tunneling, etc.
Curl offers many useful features like proxy support, user authentication, FTP upload, HTTP post, SSL connections, cookies, file transfer resume and more.  We can use curl to script calling services in Oracle WebCenter Content.

First Example - PING_SERVER

Oracle WebCenter Content has a simple service named PING_SERVER that you can execute to see if the Content Server is actually alive, listening and processing.  You can find out more about PING_SERVER by looking in at the Oracle WebCenter Content Services Reference Guide.

To execute the service with curl from the command line there are three basic parts to be typed in:
  1. curl – this is the executable to run
  2. url – username, password, dav cgi url
  3. quoted parameters

With this in mind we will pretend we have a Patch Set 5 instance of Oracle WebCenter Content running on a machine named PS5.  The command to execute PING_SERVER against that machine would look like:

curl http://weblogic:welcome1@ps5/_dav/cs/idcplg -d "IdcService=PING_SERVER&IsJava=1"

Second Example - Workflow Testing

Creating a Workflow in WebCenter Content has a few interesting caveats and testing the Workflow you've developed is very important.  Manually testing the workflow can be a cumbersome process.  A small script that executes a series of curl calls to Content Server can make the testing process a lot smoother.

You can create scripts that test the various paths a piece of content might take through the workflow.  Here is an example of a curl call that will approve a document currently in workflow and advance that document to the next step.  If the document is at the end of the workflow this would cause it to exit workflow and be released for consumption.

curl http://weblogic:welcome1@ps5/_dav/cs/idcplg -d "IdcService=WORKFLOW_APPROVE&dID=1268&IsJava=1"

Curl References

Oracle WebCenter Content References

 
 
What is the sysadmin user for in WebCenter Content 11g?

The primary administrative user ID in WebCenter Content 11g out-of-the-box is the weblogic user. This user and password is created when the WebLogic Domain is created.

So what is that sysadmin user in the User Admin Applet? And what is the sysadmin password?

Out-of-the-box WebCenter Content uses the Oracle WebLogic Server User Store to manage user names and associated passwords. Typically, user management is handled in the Oracle WebLogic Server Administration Console instead of the WebCenter Content User Admin applet. If you create a user only through WebCenter Content User Admin Applet Oracle WebLogic Server does not recognize that user. These kinds of users are called local users.

The sysadmin user can be used to run the stand-alone administration applets. Before you can do that you need to use the User Admin Applet to change the default, randomly encoded password that the sysadmin user is created with.

You might also create local users for integration activities like web service calls or using UXIdcCommand.
 
 
I wanted a keyboard shortcut for an elevated command prompt but just could not seem to find a way to accomplish it with less than three different key combinations. Some suggestions came close by using the new Power User menu in Windows 8, but still required you to execute “Win+X”, then press “A” for Admin, then accept the UAC Prompt. I found a way to get rid of one of these steps.
 
 
Out of the box, Site Studio nodeIds are unique across all websites on a WebCenter Content instance. However, there is a configuration flag to change this. If the WebCenter Content configuration flag SSGenerateUniqueNodeIdsis set to 0 (false), nodeIds will only be unique within each website.

Be careful changing the default value for SSGenerateUniqueNodeIds to be false. It is usually assumed that nodeIds are unique across all websites on a server and many times this is the way the code has been written.
 
 
WebCenter Content Server will deny a check-in when the primary file and the alternate file both have the same file extension. This default behavior is to discourage users from checking the same file in for both the primary and the secondary. Why might they do that? Perhaps they don’t know what the fields really mean?

The primary file should be the original asset. The secondary or alternate file is also called the web viewable file. Examples of proper pairings might include:

  1. Microsoft Word as a primary with an Adobe Acrobat PDF as the alternate
  2. A ZIP file as the primary and a Readme.txt as the alternate
  3. A Photoshop PSD file as the primary and a PNG as the alternate
Sometimes you really need to be able to check in a primary and alternate that have the same file extension. When this is the case you can add this configuration to your config.cfg file:

AllowSamePrimaryAlternateExtensions=true

See the official documentation here:
http://docs.oracle.com/cd/E14571_01/doc.1111/e10726/c06_core_ref010.htm

Other configurations you may find handy:
http://docs.oracle.com/cd/E21043_01/doc.1111/e10726/c04_master_usage004.htm
 
 
It looks like the latest version (version 13) of the popular Firefox browser breaks Site Studio contribution mode. In my tests, region markers stopped displaying on the page and the contribution banner at the top of the page turned completely white (on a 10gR3 WebCenter Content instance with the latest build of Site Studio 11g). On 11gR1 PS5 and SSXA, the region markers and the contribution banner stopped displaying on the page.

Geoffrey Hughes has posted on this WebCenter Content Users Group forum thread the following CSS fix which appears to solve the issue:

.wcm-region-marker { opacity: 1 !important; }

I have an SR open with Oracle and will update this post when I have more information.

Update (06/19/12 11:38 am CST): “Development has found the fix for this Firefox issue. We are currently waiting on the fix [to be] implemented in all the Site Studio build versions (10gR3, 10gR4 and 11g) and release the patches for those builds. We don’t have the date yet, but it should be soon.”

Update 2 (07/09/12 3:59 pm CST): Oracle has partially fixed the issue in internal Site Studio build 11.1.1.6.0_11.0.0.787. I tested this build and it fixed the issue on WebCenter Content 10gR3. However, it did not fix the issue on WebCenter Content 11gR1 PS5 with SSXA. Oracle is not yet specifying a public release date for the patch.
 
 
Remote Intradoc Client (RIDC) filters (only available in RIDC version 11.1.1.4.0+) allow code to be added to a DataBinder before it is sent to WebCenter Content and executed.

There are 3 filter locations:

  1. BeforeServiceRequestFilter - “Called just before service request is processed by IdcClient.sendRequest()”
  2. beforeJaxwsAuthenticateUser* – “Called just before JAX-WS call is made to loginPort.contentServerLogin () in authenticateUser ()”
  3. beforeJaxwsServiceRequest* – “Called just before JAX-WS call is made to loginPort.contentServerRequest () in performServiceRequest ()”
* Only available in RIDC version 11.1.1.5.0+.

The Oracle Javadoc for the above filters can be found here. Before a RIDC filter is available, it needs to be registeredwith the IdcFilterManager. The documentation for RIDC filters provides a fairly good starting point.

RIDC filters can be very helpful in SSXA websites. They provide a way to hook into the core functionality of service calls that could otherwise get quite messy.
 
 
The most common piece of web content is a datafile. Datafiles store various types of information and (usually) are  displayed by Region Templates (typically of type jspx).

When we code our Region Templates, one of the most frequent questions that arises is this:

How can I get a particular metadata field associated with the datafile I am trying to display?

The answer is straight forward:

Make an IdcService call to DOC_INFO and then iterate over the metadata.

This could be easily achieved by using the Site Studio <wcm:metadata> Tag. The only problem here is that if you follow the example from the documentation, then you would have to use a for-each construct to get to your metadata:
<wcm:metadata contentID="${wcmContext.placeholder.dataFile}" var="metadata"/>
<c:forEach var="metadatarow" items="${metadata.resultSets.DOC_INFO.rows}">
<h5>${metadatarow.dDocTitle}</h5>
</c:forEach>
Seems a bit clunky, doesn't it?

Luckily, there is a more convenient way of getting the desired effect without needing extra tags, and honestly, it just makes more sense:
<wcm:metadata contentID="${wcmContext.placeholder.dataFile}" var="metadata"/>
<h5>${metadata.resultSets.DOC_INFO.rows[0].dDocTitle}</h5>
With this approach, you make your Region Templates smaller in size and make your code look logically appealing.

Happy coding.
 
 
Executing a service from a custom ServiceHandler is very easy.

ServiceHandlers always extend the ServiceHandler class. So within a custom ServiceHandler Java class, you have access to the Service object using the variable m_service. From this Service object, you can get a ServiceRequestImplementor object: m_service.getRequestImplementor(). With the ServiceRequestImplementor object, you can execute services with a few different methods (executeSubServiceCode, executeSafeServiceInNewContext, executeServiceEx, executeServiceDirect, executeServiceTopLevelSimple). I typically tend to use the executeServiceTopLevelSimple method.

The executeServiceTopLevelSimple method signature looks like the following:
public void executeServiceTopLevelSimple(DataBinder binder, String serviceName, UserData userData) {}.
Below is a sample method I use to wrap the executeServiceTopLevelSimple method:
/**
* This method executes a service.
* @throws ServiceException
*/
private void executeService(final String DataBinder serviceBinder, final String serviceName) throwsServiceException {
     traceVerbose("Start executeService");
     try {
          trace("Calling service " + serviceName + ": " + serviceBinder.getLocalData().toString());
          // Execute service
          m_service.getRequestImplementor().executeServiceTopLevelSimple(serviceBinder, serviceName, m_service.getUserData());
          trace("Finished calling service");
     } catch (final DataException e) {
          trace("Something went wrong executing service " + serviceName);
          e.printStackTrace(System.out);
          throw new ServiceException("Something went wrong executing service " + serviceName, e);
     } finally {
          traceVerbose("End executeService");
     }
}
 
 
Quite often we need to customize our Content Servers using some specific Java code. Usually we accomplish this by creating a custom component and utilizing Service Handlers or Java Filters (or both). Unfortunately, sometimes it might be hard to decide when you should use one over the other. So, let’s dig deeper into both and understand how they work.

Service Handlers

Service Handlers are a mechanism that allows us to add new services or modify existing services by using  Java.

Multiple Service Handlers could contain the same Java method, but the Content Server would only execute the one that is contained within the Service Handler that has the lowest Search Order. The Search Order is defined during the creation of the configuration table. The configuration table is a table that exposes your custom code to the Content Server.

Service Handlers could be chained/put-in-place to be executed:

  • Instead of new service actions:
    • Create a Service Handler with a lower Search Order.
  • Before existing service actions:
    • Create a Service Handler with a lower Search Order,
    • Make a call to the same method after your custom java code:
… custom java code …
m_service.doCodeEx("<sameMethodName>", this);
  • After existing service actions:
    • Create a Service Handler with a lower Search Order,
    • Make a call to the same method before your custom java code:
m_service.doCodeEx("<sameMethodName>", this);
… custom java code …
Java Filters

Java Filters is an event subscription mechanism through which developers can subscribe to the various events that occur within the Content Server and execute custom Java code.

During the operation of Content Server, there are various events that constantly being fired up. The developer can subscribe to these events and alter the behavior of Content Server. When the desired event would occur the control would be passed to the subscribers of the event and the custom java code could be executed. The Content Server then expects a result of the custom code execution.  The results are pretty straight forward:

  • CONTINUE – informs Content Server that everything went accordingly;
  • FINISHED – informs Content Server to stop running any other filters with the similar name;
  • ABORT – informs Content Server to halt execution of the current process.
When to Use Service Handlers versus Java Filters

Java Filters is the least-intrusive and easiest way to customize the behavior of Content Server with Java, whereas Service Handlers require more thorough understanding of the actions that need to be customized.

Java Filters is the preferred and most commonly used way of customization, but it is limited to the existing set of filters within the Content Server. So, if there is no defined filter to which you can subscribe, then you can create your own custom component that uses Service Handlers to customize the behavior.
 

Redstone Content Solutions