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

 
 
Picture
Evolution doesn’t always apply to Darwin and his studies of the Galapagos Islands; it can refer to the improvement of anything over time.  Cars have evolved from the Model T to sports cars and SUVs. The internet is no different.  Not only has the internet evolved but so have its users and applications.  

One of the most important internet applications is the “Search Engine” ie. Google, Ask Jeeves, Yahoo, Bing. They are essential to navigating the internet and one could even make the argument that they are essentially the operating system of the internet. 

Search Engines have been evolving at an alarming rate for years.  In 2010, Google launched 516 improvements to their Search Engine. Examples of visual improvements include: “Auto Complete” “Google Spelling Correction” “Knowledge Graph” “Dictionary results” and “Products Listings on SERPs”. An example of an improvement that we don’t see is an algorithm change. 

Since its beginnings, Google has placed value on keywords. The internet and its users have evolved, so has Google. Searchers today are much more advanced and know how to “search”.  Why? Search words have become search queries.  We know longer blindly enter keywords, we ask questions that let Google know what we want and what our intention is regarding the information we are seeking.  

Below is an example that demonstrates the difference of searching with keywords vs. a key query.  

Want:    Athletic Shoes 
Intent:    Buy
Where:    Online
Keywords - athletic shoes 
When we searched using keywords, Google delivers results relevant to what we searched for - "athletic shoes" - but far less than relevant results for what we are actually looking to do. 

We are actually looking to buy athletic shoes online -therefore the results of local shoe store locations and organic results of non E-Commerce sites are not relevant
Key query - red basketball shoes for sale online
When we searched with a key query instead, we were delivered much more relevant results.  

Instead of seeing a map for local stores, we actually see product listings of shoes on the search engine.  
You may be thinking this is great for the consumer but what does this mean for SEO Managers and Webmasters? It's very simple, since people are using questions to search Google you must optimize with answers! This requires only a few minor changes in most common SEO strategies, but here are two simple steps to follow. 

How to Adapt


1.       Identify questions visitors are going to ask Google to find information on your website. Use Google Analytics and Webmaster Tools to identify what people are already searching for when they find you. 

2.       Add the questions you identified in step 1 to your site and answer them on your site. By doing so you will increase your relevant content and increase your SEO effectiveness. 

**Note: If you want people to find you for something specific, ask yourself how would you search Google to find information, and optimize for that query. 
 
 
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");
     }
}
 

Redstone Content Solutions