Search UCM (Stellent) With Groovy

July 9, 2009 Jason Stortz Comments off

In a previous article we talked about using Groovy to execute the PING_SERVER service of our SOA enabled Content Server. Interesting, but fairly useless you might say. Let's see how we can conduct a search using Groovy and then access specific metadata from those search results.

You may want to keep the RIDC JavaDoc link handy as you explore Groovy Integration further.

First, the script, and then some discussion.

The Script

// Import needed classes from Remote Intradoc Jarimport oracle.stellent.ridc.IdcClientManagerimport oracle.stellent.ridc.IdcContext
 
// Create the client for request/response, connect directly to serverclient = (new IdcClientManager()).createClient("idc://localhost:4444")
 
// Create a user/security contextuserContext = new IdcContext("sysadmin", "idc")
 
// Setup the request, search for two pieces of contentreq = client.createBinder()req.putLocal("IdcService", "GET_SEARCH_RESULTS")req.putLocal("QueryText", "")req.putLocal("ResultCount", "2")
 
// Get the responseresp = client.sendRequest(userContext, req).getResponseAsBinder()
 
// Dump out the local data of the responseprintln "LocalData:" resp.getLocalData().keySet().each{ println " $it = ${resp.getLocalData().get(it)}"}
 
// Dump out the names of the resultsets in the responseprintln "\nResultSets:"resp.getResultSetNames().each{ println " $it"}
 
// Dump out dDocTitle for each piece of content in the responseprintln "\nTitles:"rsSearchResults = resp.getResultSet("SearchResults")rsSearchResults.getRows().each{ println " ${it.get('dDocTitle')}"}
 
// Wrap it up!println "\nDone"
 

Closures

The above script makes extensive use of a language feature in Groovy known as a closure. Closures are not specific to Groovy and they are certainly not a new concept. They are found in many other programming languages. One such language you may be very familiar with is JavaScript!

In this particular case we are using the "each" closure function. Here is an excerpt from the sample script:

println "LocalData:"resp.getLocalData().keySet().each{ println " $it = ${resp.getLocalData().get(it)}"}
 

See that "each" statement in the second line? The word each followed by curly brackets forges the wrapping closure and the code inside is what becomes executed when the closure is invoked. In this case, our closure is invoked for each key in the Key Set of the Local Data collection. Within the closure you can use the "it" variable (as in iterator) to access each key.

If you have something against the name "it" for the variable you can alter the variable name. As an example, let's change the syntax so the variable will be named "key", try this:

println "LocalData:"resp.getLocalData().keySet().each{ key -> println " $key = ${resp.getLocalData().get(key)}"} 
 

This is also very helpful when using a closure within a closure. An example? Sure. What if you wanted to loop the resultsets and print the value for each column for each row of each resultset? You're code might use nested closures and look something like this:

resp.getResultSetNames().each{ println "\nResult Set '$it':" resp.getResultSet(it).getRows().each { row ->  resp.getResultSet(it).getFields().each {  field ->  println "\t${field.getName()} = ${row.get(field.getName())}" } } print("\t----------------")}
 

Additional Sample Scripts

Here are two additional Groovy Scripts you can download and try out:

Search & Target Title, and Search & List Result Sets

Categories: OracleUCM Tags:

Get Groovy With UCM (Stellent)

June 11, 2009 Jason Stortz Comments off

Yet another way to work with UCM? You bet! But this one is super Groovy (sorry, I had to do that). Check out how to setup Groovy and the Remote Intradoc Client to integrate with the Oracle Fusion Enterprise Content Management platform. You know you want to!

I really like the Remote Intradoc Client (RIDC). RIDC allows me to control UCM (Stellent) from a Java based application (Console, JSP, Servlet, etc.). What was that? Sounds similar to Content Integration Suite (CIS) you say? Yes, so far it does. RIDC is a thinner, light weight framework for those already familiar with UCM services. RIDC has very few of those "helper methods" that would guide you through the intelli-sense embedded in your IDE. However, for those familiar with services or willing to research them RIDC will offer tremendous capacity with little effort.

You can get RIDC as part of the CIS download from here. Within the CIS download is a folder containing the jar files and documentation needed to get up to speed on RIDC. This is not a deep dive on RIDC itself, but more of a sampling of how I use it to integrate/control UCM. Bex Huff has a similar article using Jython with RIDC. There is always more than one way to skin a cat.

I make use of RIDC via Groovy. Side Note: Groovy is built in with ADF 11g and Oracle uptake on Groovy will go even deeper in the future.

Important Groovy Links

  • Download – As of this writing the latest version of Groovy was 1.6.3.
  • Documentation – (Tons of examples!)
  • Getting Started – Discusses configuration of the JDK and variables like JAVA_HOME

Pure Groovy Examples

Sample #1 – Hello World

println "Hello, World!"

Sample #2 – JSON Like Syntax Possibilities

scores = [ "Brett":100, "Pete":"Did not finish" ]
println scores["Pete"]
println scores.Pete

Groovy UCM Sample

How about we start with a very simple example? We will use Groovy to Ping the Content Server. Start by opening the Groovy Console application. From there I need to use the "Script" menu to add a reference to the RIDC JAR file. At this point the environment is pretty well ready to go and we can start writing code in the console to be executed. To execute the code you can use CTRL-R, and to clear the output window you can use CTRL-W.

Using RIDC is easiest when we are familiar with the services calls, the parameters to send the calls, and what to expect in the response from the calls. If you set your profile to Top Menus so you can see the URL you will be able to look at the variables passed around to service calls as you surf through content server. You could also use a tool like Fiddler or another HTTP proxy/sniffer to spy on the parameters being swapped with content server by your browser.

Use the "Script" menu to add JARs.

Use script menu to add jars

Add the RIDC JAR specifically.

Add the RIDC JAR

As an example, when I execute this url:

http://localhost/idc/idcplg?IdcService=PING_SERVER&IsJava=1

I get back a response like this one below, which I can then use RIDC/Groovy to access the response data.

<?hda version="10.1.3.4.1 (090528)" jcharset=UTF8 encoding=utf-8?>
@Properties LocalData
dUser=sysadmin
blFieldTypes=StatusMessage message
refreshSubMonikers=
StatusMessage=You are logged in as 'sysadmin'.
blDateFormat=M/d/yy {h:mm[:ss] {aa}[zzz]}!mAM,PM!tAmerica/Chicago
XmlEncodingMode=Full
changedSubjects=
refreshSubjects=
refreshMonikers=
changedMonikers=
IdcService=PING_SERVER
IsJava=1
@end

Armed with this request/response knowledge, we can create a Groovy script using RIDC like this:

// Import needed classes from Remote Intradoc Client Jar
import oracle.stellent.ridc.IdcClientManager
import oracle.stellent.ridc.IdcContext

// Create the client for request/response
client = (new IdcClientManager()).createClient("idc://localhost:4444")

// Create a user/security context, don't need a as we're connecting
// directly to ucm and we're a trusted ip
userContext = new IdcContext("sysadmin")

// Setup the request
req = client.createBinder()
req.putLocal("IdcService", "PING_SERVER")

// Get the response
resp = client.sendRequest(userContext, req).getResponseAsBinder()

// Use the response, should say "Response: you are logged in as 'sysadmin'"
println "Response: ${resp.getLocal("StatusMessage")}"

// Wrap it up!
println "Done"

Here's what this looks like run in Groovy Console:

PING_SERVER run in Groovy

You may need to add your ip address to the IP Address Filter of content server for this script to run (as it is written). You can also use a user name and password with RIDC. This is covered in the documentation.

Download the Sample PingServer.groovy Script.

Categories: OracleUCM Tags:

Hide Primary File In Site Studio Contributor

June 10, 2009 Jason Stortz Comments off

When users create new datafiles through Site Studio Contributor the Primary File (primaryFile) field can be the source of some questions or confusion. This field is usually pre-populated with ?default.xml?. Sometimes users will ask what this field is and/or why they see it. One of the easiest ways to deal with this issue or answer this problem is to hide that field! Add the following field to the server's config.cfg and restart. It looks like this setting may have been added in the may releases, so this may or may not work for you depending on your version and when this new feature was added.

SSHidePrimaryFileInContributor=true

Categories: OracleWCM

Link To a Specific PDF Page

June 9, 2009 Jason Stortz Comments off

Sometimes I need to send someone to the documentation. Now and then it will be easier to tell them, "Hey, check out page 10 of the iDocScript guide!" This can easily accomplished by tagging #page= onto the end of the PDF URL.

As an example, check out page 30 of the "Using Components" PDF:

http://download.oracle.com/docs/cd/E10316_01/cs/cs_doc_10/documentation/developer/using_components_10en.pdf#page=30

Send users directly to a certain page makes the process much easier for them.

Categories: OracleUCM

Saying I Don't Know

June 2, 2009 Jason Stortz Comments off

How do you say "I don't know"? More often than I would like I am presented with an opportunity to tell a client or potential client how little I know about topic XYZ. In consulting, each opportunity presents itself as new twists to an old problem or some completely new animal that catches you totally off guard.

If you have had success in your past endeavors you usually have an answer or a process that quickly derives an answer in your back pocket. For those days when you get blind-sided, just how do you say you are clueless without coming off as inept?

  1. Discuss something you have done that is similar
  2. Demonstrate some degree of familiarity with the problem space (though perhaps not a solution)
  3. Admit you simply do not know

I have found that trying to know everything is generally a recipe for disaster. It comes back to bite you in the end. I will usually opt for total transparency whenever possible and point out where I may be lacking in hopes of fostering a trust relationship with the client. This in turn sometimes leads them to grant a little latitude or even an allotment of time to learn something new.

Since I am always looking for new ways to not look totally moronic, how do you say "I don't know" gracefully?

Categories: Mindlessness

Manually Disable Component

June 1, 2009 Jason Stortz Comments off

It is very easy to disable a Stellent component manually. Sometimes when you install a new component you may find something is wrong and the server does not restart. Other times you might be developing the component yourself and the server again fails to restart. On a variety of occasions you will not even be able to fire up Component Wizard. This process also comes in handy when content server is installed on a remote machine and you do not have access to be able to pull up component wizard.

That is where this trick comes in. Find this file: /config/components.hda

Remove the name and location entries for the component causing the issue. I suggest storing those strings somewhere else, perhaps another text file?

Now attempt to restart your content server and all should be right with the world once again.

Categories: OracleUCM

Hide Standard Profile Menus

May 29, 2009 Jason Stortz Comments off

Content Profiles allow administrators to craft custom check-in and search screens. They can perform all sorts of default metadata tips and tricks and generally craft targeted, context centric pages that help users properly apply metadata to their content.

On occasion I have been asked about how to hide the Standard Check-In and Search menus once Content Profiles have been enabled. This post explains how to construct a component to accomplish this task. You can also download this Sample Component to Hide Standard Profile Menus.

When you install this component it will prompt you for four (4) preference variables. These variables (2 for each menu) indicate if the functionality is currently enabled and what iDocScript should be executed to determine if the menu item should show or not. The default settings hide the menu from anyone without the admin role.

Categories: OracleUCM Tags:

Force Security Group Choice (Stellent)

May 28, 2009 Jason Stortz Comments off

Similar to the article on forcing users to select a Content Type (dDocType) there is a setting that forces the selection of a security group.

ForceSecurityGroupChoice=true

This setting adds a new blank list item for Security Group and sets this new blank list item as the default selection thereby requiring the user to select a Security Group.

Place this setting in <install_dir>/config/config.cfg

Or, put this setting in place in the General Configuration section of the Admin Server.

Categories: OracleUCM

Force Doc Type Selection (Stellent)

May 22, 2009 Jason Stortz Comments off

By default, when the check-in page loads up the Content Type select list automatically sets itself to the first item in the list. Sometimes this can cause problems if users do not pay attention, get lazy, etc. On occasion it will be desirable to force the selection of a Content Type (dDocType). Through the admin server go to general configuration and add this setting:

ForceDocTypeChoice=1

Restart content server and you should be all set. Now when you visit a check-in page they Content Type will not be preset and users will be forced to make a selection from the list.

Categories: OracleUCM

Adding Fields to Quick Search

April 23, 2009 Jason Stortz Comments off

The Quick Search box in Oracle Fusion ECM (Stellent) will search Content ID, Title and the full text of content by default. To change the fields this functionality uses you will need to add two configuration variables: QuickSearchFields & QuickSearchOperators.

For example, say you wanted to make the quick search use the default fields AND the comments field. Through the Admin Server then General Configuration add the following (then restart and try it out):

QuickSearchFields=dDocName|dDocTitle|dDocFullText|xComments
QuickSearchOperators=hasAsSubstring,hasAsSubstring,fullText,hasAsSubstring

Possible values for Quick Search Operators:

equals
hasAsSubstring
beginsWith
endsWith
hasAsWord
fullText
dateGreater
dateGE
dateEquals
dateLE
dateLess
numberGreater
numberGE
numberEquals
numberLE
numberLess
zoneHasAsWord
zoneHasAsWordPrefix

Categories: OracleUCM