Sunday, November 21, 2010

Configuring UCM application in Eclipse IDE

I tried to set up a development environment to create custom Java components for UCM application using Eclipse IDE. There is a step by step procedure available in Bex's book and that should suffice to set up development environment for most people. But somehow I was unable to get it set up and working.

After a lot of trial and error method, I got the Content Server to start from within the IDE. I thought of sharing my experience with those who are new to development of custom Java components.

The following step by step procedure is for UCM 10gR3 and Eclipse version 3.4.2.

First let us create a simple component 'MyFirstComponent' using Component Wizard. Using this component let us change the filename that is displayed to the title entered during check-in.
We can achieve this by writing a filter using validateStandard.

Lets set up the component in Eclipse.

Follow the below steps.
1) Open Eclipse.
2) Windows -> Preferences -> Java Compiler and set it to Java 1.5.
3) File -> New -> Project -> Java Project.
4) Name the project MyFirstComponent and click Next.
5) In the Source tab, click the Browse button which is present at the bottom of the page besides the Default Output Folder text box.
6) In the Folder Selection dialog box, select the project name and click Create New Folder button.
7) In the New Folder dialog box, enter the folder name as classes and click the Advanced>> button.
8) Select the Link to folder in the file system check box. Click browse and browse to the directory ucm/custom/MyFirstComponent/classes. If classes folder is not there, it must be created and then linked.
9) Click OK and set the Default Output Folder to MyFirstComponent/classes.
10) In the Libraries tab, add all the jars needed to be in the class path. Some of the mandatory jars are given below.
ucm/shared/classes/server.zip
ucm/shared/custom/Folders_g/classes.jar
It depends on what all is being used in the components.
11) Click Finish.

Now in the src folder of the project, create a package named myfirstcomponent

Then create the below class file in that package.

package myfirstcomponent;
import intradoc.common.ExecutionContext;
import intradoc.common.ServiceException;
import intradoc.data.DataBinder;
import intradoc.data.DataException;
import intradoc.data.Workspace;
import intradoc.shared.FilterImplementor;

public class MyFilter implements FilterImplementor
{
public int doFilter(Workspace ws, DataBinder binder,
ExecutionContext cxt) throws DataException, ServiceException
{

String title = binder.getLocal("dDocTitle");
String fileName = binder.getLocal("primaryFile");

String newFileName = title + fileName.substring(fileName.lastIndexOf("."));
binder.putLocal("primaryFile",newFileName);

return FilterImplementor.CONTINUE;
}
}

Now build the project, the class file for the above java file, should be created in the path
ucm/custom/MyFirstComponent/classes.

The class file also should be displayed in the classes folder of the proj in Eclipse IDE.

Next configure the above created filter in the component definition file. Open the MyFirstComponent.hda file located in the below location.
ucm/custom/MyFirstComponent/MyFirstComponent.hda

Configure the filters as below.
@ResultSet Filters
4
type
location
parameter
loadOrder
validateStandard
myfirstcomponent.MyFilter
null
1
@end

Select the Project in the Eclipse and click Run Configurations from the Run menu.

Run Configurations dialog box would have opened. Select Java Application from the left menu and click New icon from top.

Give it the name MyServer.
In the Main tab, for the project browse and select our project MyFirstComponent. Then for the Main class enter IdcServer.

In the Arguments tab, in the Working Directory section, select other and enter the below path.
D:\oracle\ucm\server\bin (For you it might be different). You can click FileSystem button and browse and select the directory.

In the Environment tab, click New and enter the following name-value pair
Name : PATH
Value : D:\oracle\ucm\server\shared\os\win32\lib

You can add more libraries, by separating with a semicolon. It purely depends on your project.
Click Apply and Close button.

Now we are all set to start the content server from the IDE. Click Run from the Run menu.

The content server should start in the Eclipse. Now open a browser and type the url for the application. In my case it was http://localhost/idc. Then check-in a file. The filename after check-in should be display the title that was entered during check-in.

To run the in Debug mode, just click Debug from Run menu.

Happy debugging using Eclipse for UCM applications.

Leave your comments if you have any suggestions,corrections or queries. Have a good day..

Saturday, November 6, 2010

Folder Move in Oracle UCM (Stellent)

I would like to share my experience on COLLECTION_MOVE_LOT service of Oracle UCM 10gR3. This is the service which we used for moving folders from one folder to another in our application.

There were few problems when we actually started implementing the move functionality.

First thing is that the folders that were moved and the documents under it did not inherit the metadata values from destination folder. They still retained the same metadata of the source location.

To overcome this issue, a new method was introduced at the end of all methods in COLLECTION_MOVE_LOT service. This new method's purpose is to update the metadata of the moved folders and documents as per the destination collection's metadata. For updation of metadata, we invoked the COLLECTION_UPDATE_META service from this new method.

Let me give an overview of the COLLECTION_UPDATE_META service. The COLLECTION_UPDATE_META service is used to propagate the inheritable metadata of the parent folder to all the child folders and documents under it. The propagation of the metadata to the documents is achieved by invoking the COLLECTION_UPDATE_ALL service from inside the code of the service COLLECTION_UPDATE_META.

So, when the COLLECTION_UPDATE_META service is used along with COLLECTION_MOVE_LOT to propagate the metadata of the destination folder on the folders that got moved, it introduced new problems.

One problem was that although the moved documents' metadata got updated, the web viewable files of all the documents were not physically relocated according to the destination location's account settings. So all the web-viewable files were not accessible after folder move operation. I solved this problem by commenting the code which was invoking the COLLECTION_UPDATE_ALL service and then invoked the UPDATE_DOCINFO service which updates the metadata of the documents plus physically moves the web-viewable files to the correct location.

The other problem was COLLECTION_UPDATE_META service, updates all the folders and documents under a specific folder. But our requirement was to update the metadata of only the folders that got moved and the documents under it. So we had to overwrite the setContentAsCollectionMetadata method which is the method that does the job for the service COLLECTION_UPDATE_META. I just wrote a small logic to propagate the destination folder's metadata only to the folders that got moved and the documents under it.

If you have some inputs, corrections or suggestions on this post, please leave a comment, so that I can improve my application.

Have a good day...

Saturday, October 9, 2010

UCM Security - Need To Know component - sample step by step implementation

Guys,

Recently I came across a requirement which had to restrict the standard UCM Content Server security for few documents. Luckily we found there was already a component provided by Oracle just for that purpose (either to extend or restrict the standard security) named Need To Know.

This component can be downloaded from the Oracle website. Although there was a complete sixty page document for this component, it was no cakewalk for me to get it working. I tried to google but no luck, not much has been written about this component in the internet. So, I thought of writing one and sharing my experience.

The Need to Know component supports customization for Content Security, Search Results, Hit list roles, Content metadata security, and WHERE clause calculation. I will touch upon the Content Security part in this article.

The Need to Know component works on Security Group.

Lets get started with a sample requirement.
Consider a sample UCM application which has three security groups namely "SECGRP1", "SECGRP2" and "CONF_SECGRP". Accounts are enabled (about which we don't bother for this requirement). The requirement is to restrict access to some of the documents belonging to the Security Group "CONF_SECGRP". Even if user "A" has read permission on "CONF_SECGRP" as per standard security, we need to restrict it based upon some query given during check-in or update of the document.

Step 1 - Installation : Install the "Need to Know"(NTK) Component using either Component Manager or Component Wizard. Enable it.

Step 2 - Configuration :
a) Open the Admin Server Page and click the General Configuration link.
b) Under the "Additional Configuration Variables" heading, add the below
entry at the end of the text area.
SpecialAuthGroups=conf_secgrp
Only the security groups specified in the SpecialAuthGroups variable will use
the NTK component. Other security groups will have standard security applied.
c) Add a new metadata field that will be used for content-item level queries
(remember our requirement - restrict users based upon some value).
Add the new metadata field using the Configuration Manager. Use any field
name you wish. Here we name it as "DocDisclosureQuery". The field type
should be "memo". After adding the field, click Update Database Design.
d) Add a hit list role using the User Admin Applet. Create two roles "hitlist-r"
and "hitlist". Give read access to "CONF_SECGRP" for the role hitlist-r and
write access to "CONF_SECGRP" for the role hitlist. Do not assign this role
to any user.
e) Restart the content server.

Step 3 - NTK Administration : In the administration tab, you must be able to see a link for NTK component administration - NTK Configuration Information. Click on that link. NTK Administration screen looks as below.



Now we need to configure the new metadata field and hit list roles that we created in the last step.

a) Configuring the DocDisclosure field :

Click Edit button on the top right corner and select "Content Security Configuration Information" link. Scroll to the bottom of the page, in the
"Other Options" section, select the new metadata field that was created as the Disclosure Field and click Update.


b) Configuring the Hit List Role :

Click Edit button on the top right corner and select "Hit List Roles Configuration Information" link. Select "hitlist-r" role as Query Role and "hitlist" role as Update Role and click Update.



c) Limiting Access :

In the "Content Security Configuration Information" page, under the "Read Options" section, select "Yes" for both "Use Security" and "Limit Access". Since our requirement is to limit read access, we did the above configuration only in the "Read Options" section.

In the "Script" text area, write the below script which will determine the read access, based upon the content-item level query given during check-in or update of the document.

<$if isDisclosureQuery(xDocDisclosureQuery)$>
<$isNTKReadAccess=1$>
<$endif$>

Click Update button.


Now the NTK Configuration Information Page should appear as below reflecting the configurations done till now.



Step 4 : Click the "New Check In" link in the top menu and in the Content Check In form now a new metadata field for DocDisclosureQuery will appear along with a "update" button adjacent besides it.



The DocDisclosureQuery applet will be loaded by clicking the update button adjacent to the DocDisclosureQuery field. This applet will contain all the user attributes which can be used to form a content item level query that determines the access on top of standard security.

Step 5 - Check-in a document :
We are all set to check-in a document, specify a content level query and check whether all this works.

Click "New Check In" link in the menu.
1) Give the title of the document.
2) Select the Security Group - the one that is specified in SpecialAuthGroups.
3) Browse the document.
4) Enter all other metadata as per your application.

5) Content Item Level Query :
Click the Update button adjacent to the DocDisclosureQuery field. In the applet
select the "Field" as "Username", "Operator" as "Is" and Value as should be allowed to view this document>. Click Add button. The query
"Username is selvam" appears in the "Query Expression" text area.
You can form complex queries by making use of different user attributes and the
Add, Update and Merge buttons in the applet. For our example we will stick with
one user attrubute to form the query - Username.



Click Append button. The query should now appear in the DocDisclosureQuery field text area as below. You can even directly edit the query in the DocDisclosureQuery field text area.



Click "Check In". The document is successfully checked in now.

Step 6 - Testing the NTK security :
Login using user "selvam" and try to access the above checked-in document. This user must be able to view the content information page of the document.

Login using any other user who have read access to "CONF_SECGRP" other than "selvam" and try to access the document. "Insufficient Access Privilege" error will be thrown.

This is a very simple example of extending standard UCM security using NTK component.

There is one other thing to be noted here. If in your application, the virtual folders belong to the security group specified in the SpecialAuthGroups, and if the Read Access is limited using NTK component, then users won't be able to view the folders. There will be number of ways to overcome this problem. I did it the following way. There is a filter called "checkExtendedSecurityModelDocAccess". NTK makes use of this filter to extend the standard UCM security. The actual class implementing this filter is "NTKFilter" in the NTK component. So you can override this filter in such a way that the NTK security is not applied for the COLLECTION related services.

Hope this post serves as a good starting point to extend Standard UCM security using NTK component.

Good day..

Sunday, September 5, 2010

Autocomplete feature not working in eclipse

If the auto complete feature is not working in eclipse, then check the below setting in eclipse.

Go to Windows->Preferences->Java->Editor->Content Assist->Advanced and check whether the option "Other Java Proposals(Focused)" is checked or not.

If this option is not ticked, then tick that option. This shall resolve the problem.

Friday, August 27, 2010

Radio Button Functionality in Check boxes

Sometimes we need to implement the functionality of radio buttons using check boxes. It is very rare, but then...... This is just a very simple example..

<HTML>
<HEAD>
<script language='Javascript'>

function disableCheckbox(form)
{
var count = 0;
var loc = "";
var table = document.getElementById('table1');
var rows = table.getElementsByTagName("tr");
if(form.chks.length)
{
for (var j=0;j<form.chks.length;j++)
{
if (form.chks[j].checked)
{
count = 1;
loc = j;
break;
}
}
if(count == 1)
{
for(var j=0;j<form.chks.length;j++)
{
if(j != loc)
{
form.chks[j].disabled='true';
}
else
{
rows[j].className="shaded";
}
}
}
if(count == 0)
{
for(var j=0;j<form.chks.length;j++)
{
form.chks[j].checked=false;
form.chks[j].disabled=false;
rows[j].className="notshaded";
}
}
}
else
{
if(form.chks.checked)
rows[0].className="shaded";
else
rows[0].className="notshaded";
}
}

</script>

<style>
.notshaded {background-color: "#ffffff";}
.shaded{background-color: "#E8E8E8";}
</style>

</HEAD>

<BODY>

<form>

<table id='table1' border="1">

<tr>
<td>
<input type="checkbox" name="chks" value="first" onclick="disableCheckbox(this.form);" disabled='true'/>
</td>
<td>First</td>
</tr>

<tr class="shaded">
<td>
<input type="checkbox" name="chks" value="second" onclick="disableCheckbox(this.form);" checked="true"/>
</td>
<td>Second</td>
</tr>

<tr>
<td>
<input type="checkbox" name="chks" value="third" onclick="disableCheckbox(this.form);" disabled='true'/>
</td>
<td>Third</td>
</tr>

</table>
</form>

</BODY>
</HTML>