I have always wanted a quick way to build components without firing up ComponentWizard. I'm not talking about the actual construction of the component like adding resources. I'm talking about the assembly of the component zip file. Combing through the intradoc user group and other online forums can yield a little discussion about Apache ANT being used to construct component zip files. However, I did not find an easy reference to an actual ant file for such purpose.
So once we have this ability to create component zips what else can we do with it? Most projects do not consist of a single component. The components are also not completed in a linear fashion. Generally components that are completed will typically have adjustments being made throughout the project. Using a tool like ant we can orchestrate the build of multiple components at once. This orchestration can even include tasks such as placing built components in shared folders or uploading them to an FTP location.
As for using the Component Wizard to lay out the component architecture you might want to add the build file as a component extra. Then the installation of the component at a target location brings the build file along for the ride.
Here's an example build file:
<project name="CompName" default="dist" basedir="."> <property name="build.home" value="${basedir}/classes"/> <property name="src.home" value="${basedir}/src"/> <property name="compile.debug" value="true"/> <property name="compile.deprecation" value="true"/> <property name="component.root" value="component/${ant.project.name}/"/>
<path id="compile.classpath"> <pathelement location="${basedir}/../../shared/classes/server.zip"/> <pathelement location="${basedir}/../../shared/classes/jspserver.jar"/> </path>
<target name="clean"> <delete dir="${build.home}"/> <mkdir dir="${build.home}"/> </target>
<target name="compile" depends="clean"> <javac srcdir="${src.home}" destdir="${build.home}" debug="${compile.debug}" deprecation="${compile.deprecation}"> <classpath refid="compile.classpath"/> </javac> </target>
<target name="dist" depends="compile" description="Package as a Fusion ECM Component"> <delete file="${basedir}/${ant.project.name}.zip"/> <tstamp> <format property="component.timestamp" pattern="yyyy_MM_dd_hh_mm_ss_aa"/> </tstamp>
<zip destfile="${basedir}/${component.timestamp}_${ant.project.name}.zip"> <zipfileset dir="${src.home}" prefix="${component.root}src"/> <zipfileset dir="${build.home}" prefix="${component.root}classes"/> <zipfileset dir="${basedir}/resources" excludes="**/lockwait.dat" prefix="${component.root}resources"/> <zipfileset dir="${basedir}" includes="${ant.project.name}.hda" fullpath="${component.root}${ant.project.name}.hda"/> <zipfileset dir="${basedir}" includes="build.xml" fullpath="${component.root}build.xml"/> <zipfileset dir="${basedir}" includes="readme.txt" fullpath="${component.root}readme.txt"/> <zipfileset dir="${basedir}" includes="manifest.hda" fullpath="manifest.hda"/> </zip> </target> </project>
By adding IsXml=1 to the end of the HCSF URL
There are often a wide variety of reasons why someone may want to keep only the latest n revisions of content in their content server. These reasons range all over from keeping disk usage in check to a form of security/retention management. Whatever your reason the process is pretty straight forward. I am going to show you how to setup archiver to take out all but the latest X revisions. In a later post we can talk about various ways to enact that archive on a scheduled basis.
So, simply put, the secret to this is the Revision Rank (dRevRank) field. A lot of times in the past I've tried looking at dRevLabel, dID, dDocID, but nope, the special field you want is Revision Rank. Use the following steps to set up your archive:
- Log onto your content server as a user with administration rights
- Under "Administration" select "Admin Applets" and then fire up the Archiver applet
- From the "Edit" menu select "Add"
- Give your archive some kind of meaningful name
- Provide a description, perhaps include something about the expected lifetime of this archive?
- Click "OK"
- Select the new archive in the archive list and then click on the "Export Data" tab
- From the Export Query section select "Edit"
- Set the following field defintions
- field to "Revision Rank"
- Set the Operator to "Is Greater Than"
- Set the value to "4"
- Click "Add", add and then "OK"
- Under "Actions" click on "Export"
Great, now lets discuss some of these points. The Revision Rank field is zero based (meaning it starts at zero) and that zero represents the most recent revision of the content in question. The second most recent revision is denoted by a dRevRank of 1, etc. For example, if you wanted to delete everything but the 5 latest revisions you should set dRevRank to 4. If you wanted to only keep the most recent revsion set dRevRank to 0.
Upon selecting "Export" you will be prompted deleting the revisions from content server during the export process. If you place a check mark in the check box the content will be REMOVED from content server. The content will continue to exist in the archive you just exported as long as you don't crack that open and delete it in there as well.
Some of you may have used or even still have an excel spreadsheet which can be used to update metadata. This spreadsheet was originally provided by the former content server creator, Stellent. I am actually unaware of the name or names of the original author or authors and as such have not credited them here. Leave your name to take credit! Some people love it. Some people hate it. Either way, it has been useful to me.
The original style sheet allowed users to specify additional custom columns named after their custom metadata. It offered two buttons. The first was “submit query” which invoked the user defined query string located to the left of the button. The second button “update” would cycle through each of the result records from the query and update the metadata based on the values in the spreadsheet.
I have updated the spreadsheet in two ways. I have added a login button which simply causes a prompt for user credentials. The importance of this button is the reduction in steps needed to update secured content. With the original spreadsheet the user first had to search on public content only and invoke an update which then prompted for credentials after which the user could conduct another search which would then have the credentials to access secured content. With the login button we can now skip this cycle. The second change is a new worksheet which contains configuration variables for the searches. Currently there are three configuration variables including ResultCount, SortField and SortOrder.

Additionally I often get asked how one can use this spreadsheet to update metadata only check-in’s. The trick is an additional column named createPrimaryMetaFile. This column should be set to TRUE if that record represents a metadata only check in.



This file and all updates to it are presented here as-is with no support implied or otherwise. As always, use at your own risk.
References:
remoteMetadataUpdater_20080924.xls (194 KB)
As a result of one of the more recent core updates for oracle content server the actual update screen has several new pieces of data available to help you with the install. I’m not exactly sure when these pieces started showing up in the component update screen but they’re very handy.
There are several ways to execute iDocScript from Java, but in this quick example we will use a PageMerger object. There are several ways to get ahold of a PageMerger object. If you are executing in a context where a service object is readily available you may be able to get a PageMerger object reference with code like this: PageMerger pm = m_service.m_pageMerger;
If that doesn't work for you I would try something like: PageMerger pm = new PageMerger(databinder, executioncontext);
Now that you have your merger object you can execute all kinds of iDocScript code, an example of which might be: pm.evaluateScript("<$lc(\"wwMyString\")$>");
Occasionally, you might have the need to perform what is known as a metadata only check-in. To perform this action you will need a configuration variable known as AllowPrimaryMetaFile. This variable allows users to check in metadata only records. Similarly there is another configuration variable you may want to keep in mind known as AllowAlternateMetaFile. These settings will create check boxes next to the primary and alternate file inputs. This might look like:
These variables should be set to true in the config.cfg file. They can also be set through the admin server in the general configuration. These changes will require a content server restart.
Why would one want to use a metadata only check-in? Often these serve as the records to track things like places or people. Perhaps they can even represent reusable hyperlinks. These data records are then used with tools such as Site Studio in which a designer can create pages and craft the data records into some type of meaningful display.
References AllowPrimaryMetaFile AllowAlternateMetaFile createPrimaryMetaFile createAlternateMetaFile
It’s early in the project and you create a nifty Java application to access content server. It executes a few services and generally accomplishes some black wizardry that people “oh” and “ah” over. Everything is going well. You are just about to board the corporate jet for that all expense paid developer retreat in Hawaii when they call you back with a problem.
Customer xyz decided they wanted to use the active directory integration everywhere in the content server and now Nify App does not work. WHAT COULD IT BE? After some truly Sherlock-like investigation work you find out they have switched the Default Authentication mechanism from Basic to NTLM. You quickly dial, “HOLD the plane, I can fix this and still make it!”
Within a minute you have your code open and spot the problem, yes, yes, of course, you will need to set a request property. Your fingers fly across the keys pouring out something akin to these pearls of wisdom: URL url = new URL(URL);
HttpURLConnection urlConn = (HttpURLConnection)url.openConnection();
urlConn.setRequestProperty ("Cookie", "IntradocAuth=basic");
You casually remark on the way out the door to your stunned co-worker that this enhancement will allow your code to continue connecting with Idc Security, thereby working just fine.
Reality: While the context of this story may be a bit far-fetched the code is not. Thanks Matt Pelham for this tidbit.
In the oracle forums today a question came up about how to add custom actions to the menus in the actions drop downs for the Content Information page (sometimes called the Doc Info page). I wanted to dive into this a little more because in 10gR3 the way the developers crafted the menus is much more extensible. It is very nice. Somebody should get a raise.
There are at least two possibilities for increasing metadata field sizes. The request most often heard inquires about increasing the default memo field size (which is originally 255 characters). The second avenue is to increase the size for a single one-off metadata field.
Expanding Default Memo Field Size
We can use a configuration variable within Content Server named "MemoFieldSize" to increase the default size of new memo fields beyond the original limit of 255 characters. Keep in mind this affects memo fields that you create AFTER you add this configuration and restart content server. For fields that have already been created you will also need to go into the database and directly increase the column size for that individual metadata field within the DocMeata table.
If you operate in a database with UTF8 encoding you should keep in mind that this can affect that actual number of characters your users will be able to input. Oracle has a 4000 byte per column limit for varchar2/nvarchar2 data types. Hence, if you set the column to the 4,000 byte maximum and each character takes 3 bytes of space you get roughly 1,333 characters to work with.
So, what to do where, when and how. Log into your content server with administrative privileges and select Admin Server from the Administration menu. Click the button for the instance you will be working with and then select General Configuration from the left hand menu. Add MemoFieldSize=1024 as a new line in the variables list and click save. Restart. Similarly you could go directly to the file system and add this configuration setting to the config.cfg file. Oh, and don’t forget to get out your favorite database manipulation device and increase those columns sizes.
Expanding a Single Field
Great, right, so that’s all nice and what not but I don’t want to increase ALL my memo fields. I only want to increase the size of a single field. Well sure you do, who wouldn’t? In this case you can again use config.cfg or go through the admin server to add xMyMetadatafield:maxLength=1024 or whatever your new field size is meant to be. Again, change the table definition in the database and restart your content server.
First Note: increasing field sizes also more than likely will increase indexing and searching time. More stuff equals more time. Pretty simple, but a reminder of that fact is relevant.
Second Note: I performed these actions on a 10gR3 content server and 11g database with existing content. The field widening did NOT erase my data. Obviously if I were to restrict down the field size instead of widen the field my data would have been truncated.
You can search the book and read the book. Obviously no print or copy from (which makes sense), but for a quick lookup it sure is handy.
http://books.google.com/books?id=TiUzMYbpg2MC&printsec=frontcover&dq=idocscript+trace
I am a little late on the delivery of this notice but Oracle has placed out for download several new items. First up is an updated installer for the Content Server that reads version 10.1.3.3.3 which you can get here. Or you can visit MetaLink to get patches for you 10.1.3.3.2 and older content servers to bring them up to date here.
One of the things included in this pack is the OracleTextSearch component that can be used with Oracle 11g database. It provides snippets of the search term in context of the content as well as a kind of drill down menu system that can be based on Security Group or Document Type for example. I have not played with this as much as I would like to have at this point, but it is running (thanks Anton) and I have a quick picture here. The bold search term is a bit hard to see in my image, but it is there:

Sometimes you have a Content ID and need to find the path to the Vault file. If you are in a JSP (Java Server Page) or in a Java Class in your backend component you can use this method. 10gR3 introduces the FileStoreProvider component that is not necessarily compatible with this method. I'll try to conjure up a FileStoreProvider compatible version in the future, someday. If you already have one and want to share please drop me a note! This is not without issue I suppose but it should get you started:
The other day I was trying to execute a search against content server in some JSP's (Java Server Page) and I wanted to perform a multi column sort, similar to how the old Multi-Sort component used to work. The content server in question was configured for DATABASE.FULLTEXT. Turns out, this is simple to perform. When you form your URL or binder (Local Data?) you need a variable named SortSpec and it should start with "order by" and follow the basic rules of a database query.
Example:
SortSpec=order by dDocType asc, dDocName desc
Another example: http://yourserver/instance/idcplg?<original query>&SortSpec=order%20by%20dDocType%20desc,%20dDocName%20asc
If you have never been to an Open World before and you are planning on going this year you will first have to deal with the general "Shock & Awe" of the size of the thing. Once you move past that you will likely be buried deep in trying to figure out what sessions to attend and a fair bit of social networking. At some point you are bound to notice this odd thing called Unconference. Un-what? It is called the Unconference, and it is a pretty neat concept.
This is a place where rookies as well as professional presenters can setup a session about what they feel is important with information they want to share with the community. Similar to the other presentations you go to you may (or may not) see a demonstration, a PowerPoint or some other kind of general presentation, but these tend to be less formal all the way up to entirely adhoc. You can check out the time slots and the proposed sessions here:
http://wiki.oracle.com/page/Oracle+Open World+Unconference?t=anon
Unfortunately at this time I do not see much on Fusion ECM. However, over on the Bex Huff blog he has indicated recently he may give his Enterprise 2.0 Rant presentation at the Oracle Open World Unconference. If you would like to get a sneak peek then head over and check out some of the info he's already got available on that subject:
http://bexhuff.com/2008/07/enterprise-2-0-rant-available-for-all
He also talks about some additional items he will be presenting here:
http://bexhuff.com/2008/08/six-weeks-till-open-world
Unconference is not for everyone all the time, but it certainly is a good compliment to the "structured" presetnations deployed throughout the rest of the conference. Each year is different, but the value of this particular part is soley dependent on the efforts put forth by the community. So, if Unconference flops this year, I guess it is on us.
This is just a quick introduction to batch loading content into content server with the Batch Loader application. The application can be run from the command line as well as in graphical mode. I normally run it in graphical mode.
I also like to put the check mark in the box to produce an errors file. This file is kind of neat, if anything fails it is placed in that file where you can tweak the metadata and then point batch loader at that file to attempt loading all the content that failed to load. Why might things fail? Perhaps you forgot one of the required fields like dSecurityGroup or perhaps you performed a check-in using a particular metadata value that did not exist in a validated list.
Usually you will need to add a setting to the intradoc.cfg file called Batch Loader User Name. This setting in your configuration might look like this: BatchLoaderUserName=sysadmin
I am sure you could come up with better values to put in this field besides “sysadmin”, but for the sake of this demonstration/test this should get you running pretty easily.
NOTE: intradoc.cfg, not config.cfg.
Now you must construct the batch load file. Nothing scary here, just a text file. This file contains key=value pairs one to a line of metadata and values and uses hash/pound characters (#) to begin lines that are comments, like this: # This is a comment
Action=insert
dDocType=ADCCT
dDocTitle=Product Details
dDocAuthor=sysadmin
dSecurityGroup=Public
primaryFile=<path to file>
dInDate=7/23/2008
dDocName=TestContentID
<<EOD>>
What if you wanted to perform a metadata only check in? Try something like this: # This is a comment
Action=insert
dDocType=ADCCT
dDocTitle=Product Details
dDocAuthor=sysadmin
dSecurityGroup=Public
#primaryFile=<path to file>
dInDate=7/23/2008
dDocName=TestContentID
createPrimaryMetaFile=true
<<EOD>>
Sometimes we encounter the need to perform a search in content server that requires a lot of work with the <OR> query operator. Between that and a few other variables it might be possible to craft a query that is too long for content server. This happens especially with generated queries. If you are using universal query syntax or a verity engine for your search engine you might also encounter this. If the data you are searching on is metadata based you might be better off temporarily switching over to a database based search on the fly to find your results. By adding this setting to the query string you can change how content server interprets your search: SearchQueryFormat=DATABASE
In most installations the Search Query Format setting will default to UNIVESAL. Now that you have switched over to a database based search you can set your query string using the IN operator for a much shorter query converting from something like this: QueryText=xType <MATCHES> `A` <OR> xType <MATCHES> `B` <OR> xType <MATCHES> `C` <OR> xType <MATCHES> `D`
Into: QueryText=xType IN (‘A’, ‘B’, ‘C’, ‘D’)
If you’re on a Database Full Text setup to start with you can still do this type of thing AND use full text like this: QueryText=( xType IN (‘A’, ‘B’, ‘C’, ‘D’)) and (<ftx>keyword</ftx>)
Perhaps the best thing you can do is at least take a moment to evaluate why you must have so much “or” based logic in your query in the first place. Or is almost always one of the most costly instructions.
Alex Suhre just posted to the Oracle ECM Forum a link to a JavaScript based HDA data parser that allows you to paste HDA formatted data into a box and get a more human readable view of that data. It looks nice, and I have tried a few pieces of data in there and it worked well. I have not put it through the paces to see how it handles odd data or characters. It looks like you can download it as well, although you have to supply some information to be able to do so.
Real world applications? Well...not sure just yet, but it is neat, and it is always nice when a tool is turned over for community use.
Over on David Roe’s Blog "Content on Content Management" he has recently posted a pretty good article on the newly added Content Server JCR Repository Adapter. I really liked his post because he presents this with a curious but wary attitude and then goes on to present some of the history of the process and the political landscape this "standard" traversed to get to where it is today.
Why was his general attitude important? Well, he did not just jump right up and say "Hey, look what got published, go use it now because it is simply the best." He begins to present pros and cons about his personal feelings on JSR/JCR process and how vendors can use this as part of their sales pitch and why that is almost comical. Finally, because he presents it with a bit of caution I am a lot more apt to take it seriously.
Why is the history important? Sometimes history is not all that important but sometimes that political/historical take can give you insight into standards that were driven by an agenda that may not be in the best interests of the community as a whole. As an example, look at Microsoft and their OOXML standard. If someone told you OOXML was a standard and you blindly followed it you may wish you had known the back story of that all along, especially if the standards ratification ends up getting overturned later.
To wrap up: great presentation, great insight. Oh, and the topic was interesting too!
If you are trying to squeeze additional performance out of your production servers you might look into adding the setting DisableSharedCacheChecking. This would be placed in your config.cfg file or under general configuration through the admin server. As always, it may help to perform some kind of analysis or metrics gathering prior to adding the configuration and then re-analyze after configuration implementation. What this boils down to is content server watching dynamic html resource includes in components to see if they need to be reloaded. DisableSharedCacheChecking=true
In other words: if in place on a production server (where you would not be changing includes like you would a development instance) this setting can alleviate a measureable amount of file system activity. This should translate into a performance gain in some fashion. Or to say this as confusingly as possible: a reduction in performance degradation…I just thought that would be fun to say.
Potential flamebait warning: And as we all know, disks are slooowww. Maybe I just hook the disks up wrong? I hope I hooked the disks up...
Using "View Server Output" from the admin server can tell you a lot about what is going on inside your content server. The server output can accumulate so much information it can easily be overwhelming. To help with this we are going to take a closer look at the tracing sections and how we can expand the built in list of sections to allow us to trace and troubleshoot the code we build for content server. The information detailed in server output depends on your configuration setup in the System Audit page:

The comma separated list of active tracing sections can be saved into config.cfg under TraceSectionsList. The checkbox next to Full Verbose Tracing would represent TraceIsVerbose in the config.cfg file. Descriptions of these can be found in the IDOC Script Reference Guide. Recall your config.cfg file is in the <install>/config directory, not in the bin directory. The drop down list is filled with sections you can use to narrow or expand your tracing output with.
The server output does not show all activity from all of history. It only displays the most recent activity, and if you are planning on dumping out the full contents of a DataBinder you probably will miss some of the data. On windows, it comes in handy during a full-on-debug-session to add UseRedirectedOutput to your config.cfg file. This will dump the log out to a file on disk. Do not forget to turn this off later or you may run out of disk space or enjoy some decreasing performance metrics.
Excellent, with this basic information under our belt we can now look at how you might add a trace section to that drop down. Say for example you have some code you would like to instrument with tracing so you can see it in server output. Just how might you add your custom-section to the drop down list?




So, having replaced the defaulted information with my specific information I end up with the adjusted resource file looking something like this:
<tr>
<td>TraceSample</td>
<td>Example of custom section tracing</td>
<td>false</td>
</tr>
Having used component manager or component wizard to ENABLE my component (you enabled yours right?) and restarted my content server (you restarted yours right?) I can now see my new custom tracing section in the drop down list in the System Audit page:

Whew. If you have made it this far please stick around a little longer, we are finally ready for the big payoff. We understand tracing now, we understand how to add sections to be traced. So, please, please just tell us how to instrument the code to take advantage of this already! To make use of this in IdocScript use the trace function like this:
IdocScript Tracing
<$trace("message", "#console", "CustomTraceSectionName")$>
So, for the example section I created I would write something like:
<$trace("Trace Test!", "#console", "TraceSample")$>
One word of caution, sometimes when you copy code like this off the web the quotes get out of whack (technical term!). So if you have problems, when you paste this in try retyping the quotes. Or, once installed you could use the test template included in the example component to see how things work.
Java Tracing
If you wanted to use this in Java code you can use SystemUtils.trace("CustomTraceSectionName", "Your Message"); to instrument your Java code for tracing. Inside your Java code you can also take advantage of the "Full Verbose Tracing" checkbox setting by testing the value of SystemUtils.m_verbose, like this:
if (SystemUtils.m_verbose)
{
SystemUtils.trace("TraceSample", "Tracing from my java code against my custom trace section");
}
You can also dump information about an exception with some code like this:
SystemUtils.traceDumpException("filestore", "Error encountered saving file to file store.", e);
Additional References
IDOCScript Online Reference Guide (HTML Version)
IDOCScript Online Reference Guide (PDF Version)
TracingSample_17JUL2008.zip (Example Component)
Bex Huff weighs in on the challenges of ECM 2.0 with some practical advice and warnings.
Enterprise 2.0 is an emerging social and technical movement towards helping your business practices evolve. At its heart, its goals are to empower the right kind of change by connecting decision makers to information, to services and to people. -Brian "Bex" Huff
Now, granted, discussion about ECM 2.0 isn't anything new, I mean we have posts about this going back well into 2007 and farther, but I think we are starting to see some results of this discussion coming around. I would wager the offerings placed before us are still newly hatched, but a year ago it was mostly talk and smoke and mirrors. Several people that are familiar with the Content Management arena are already familiar with the Blog/Wiki capability of SharePoint. SharePoint is often called the "collaborative interface" or "collaborative front-end" by the other vendors who then try to position themselves as a potential backend for SharePoint. Oops…getting off track, that's a discussion for another time.
So, does anyone other than Huff want to wager a description or definition of ECM 2.0? I'm certainly not willful enough yet to do so. As this blog is generally in support of Oracle Fusion ECM (formerly Stellent, formerly Xpedio, formerly…well you get the idea), we would normally focus in that area, however this topic is fairly important to grasp from other views as well. Hence, OpenText defines ECM 2.0 as:
"Enterprise 2.0 Content Management: Provide flexible use of wikis, forums, blogs, tagging, and real-time collaboration. Provide advanced handling of rich-media content, with special emphasis on video, which is quickly becoming the de-facto format for 2.0 style work. "
Well, great. That sounds kind of fun. Honestly, I'm not sure I speak marketing enough to truly discern what "defacto format for 2.0 style work" is subliminally saying to me, but sure we can say that.
What's that? Oh, you have Oracle Fusion ECM and want to do some of this? Right, I almost forgot the basis of the blog. Thanks for bringing me back in. There are a variety of components available for your content server that add enhancements geared towards this discussion. First, you may want to RSS enable your content server. Again, to reference Bex's site you can get the Sample Blogs Component or the Sample Wikis Component off his ECM Library page.
Awesome! So now I can create blogs and wikis in content server just like SharePoint and others? Uh…no. Sorry, I might have misled you. Just a little. The point is, these are sample add-on's to content server that show some of the things that can be done. In truth, these have existed for a good while. If anything, they demonstrate the power of the content server architecture to add new features quickly without a new release. See, OpenText came out with a new release for all this while the folks at what was Stellent at the time kicked these out as a new feature with their component architecture without requiring a big new release and upgrade.
Welcome to the inaugural post for coreContentOnly.com! I am, of course, obligated to demonstrate the use of the coreContentOnly flag in my first post. I wanted to present an actual concept out of the gate and I will follow up later with a post about who I am and my agenda.
The concept is simple. By placing the string coreContentOnly=1 in the URL while visiting a page in Content Server you can reduce the page to the core content only (yes, hence the flag name!). This page reduction strips away top menus, left menus, headers, footers, etc. One might wonder how this is useful. Various activities in Desktop Integration and Site Studio Designer take advantage of this scenario. This little bit of magic is possible because of the way the template type portions of the page such as headers and footers are coded in the content server core. In other words, it is very possible for you to create a layout not using base content server includes and not have this functionality work for you. Hopefully this is not a surprise for anyone!
Let's see this in action:
|
Copyright © 2008 Jason Stortz. All rights reserved.
|
|