Showing posts with label Documentum. Show all posts
Showing posts with label Documentum. Show all posts

Tuesday, January 5, 2010

Action Preconditions in Documentum

Action precondition classes checks whether an action can be performed or not. Action precondition classes renders an action control as enabled or disabled. The structure of an action precondition class is as follows:
public class TestActionPrecondition implements IActionPrecondition
{
public String[] getRequiredParams()
{
return new String[0];
}

public boolean queryExecute(String strAction, IConfigElement config, ArgumentList arg, Context context, Component component)
{
boolean isActionEnabled = false;
String object_name=(String)arg.get(“object_name”);
return isActionEnabled;
}
}

An action precondition class implements IActionPrecondition interface and overrides the queryExecute method of that interface. queryExecute() method returns a boolean value which determines whether the corresponding action will be enabled or disabled.

The corresponding action xml will be :


<config>
<scope>
<action id="test_action">
<params>
<param name="object_name" required="true"/>

</params>
<preconditions>
<precondition class="com.poc.TestActionPrecondition"></precondition>
</preconditions>
<execution class="com.documentum.web.formext.action.LaunchComponent">
<component>report_history_component</component>
<navigation>jump</navigation>
</execution>
</action>
</scope>
</config>



The jsp part of the component from where the action will be called is described below. An action link is used for the purpose:






<dmf:datagridRow height='15' altclass="row1" cssclass="row2" width="100%">
<td width="10%" align="center">
<dmfx:actionlink name="user_report_view" action='test_action' showifinvalid="true" datefield="process_name" >
<dmf:argument name="object_name" datafield="object_name"/>
</dmfx:actionlink>
</td>
</dmf:datagridRow>

A typical scenario of using action precondition can be a requirement where roles are created dynamically and based on those roles action links are getting generated dynamically. The logged in user will have access to the action link(s) iff that user is present in the corresponding role(s).
For roles which are not created dynamically and are fixed, documentum’s out of box RolePrecondition can also be used. Also, just by mentioning scope=<role_name> , in action xml, role based action control enable/disable feature can be achieved.

CAUTION: Please avoid putting codes that access the docbase(for e.g dql queries and dfc api call) as much as possible in queryExecute() method because the method will get executed for each and every action links generated .So that can be a performance bottleneck.

Wednesday, June 10, 2009

Firing query inside a loop is a sin

Please donot fire a query inside a loop.Otherwise the performance problem your application will face is unimaginable. There is ALWAYS a way around.You can always solve the problem by firing the query outside the loop(using 'join' or 'in' statement or whatever).It doesn't matter if you need to write a complex and lengthy code to solve the problem by firing the query outside the loop.But please please don't fire it inside the loop.Otherwise almighty(a.k.a customer) will never forgive you.

Note:Be careful while using 'in' statement.If tokens inside the 'in' exceeds 490 in number,yacc Overflow Exception will occur. But there is a smart way around. Refer to following Robin's post.

Friday, January 30, 2009

Excessive Logging Sucks up Application Performance

I have seen some people performing logging operation unnessasarily.According to them,logging helps to idenify bugs quickly.But excessive use of logging can have a very serious impact on the performance of the application.I think if some errors occour,then those can be easily detected by logging the exception stacktrace.So I think,logging only stack trace info in catch section (java code) can help in improving performance a lot(most of the bugs can be traced from the error stack).Also , logging start and end of methods gives a good idea about the program flow.Apart from that logging should be avoided as much as possible because logging requires disk access which is always an expensive operation in terms of performance.

Thursday, September 11, 2008

Ticket Based Authentication for Documentum-Helps to Implement Single Sign On

I feel ticket based authentication for documentum can help in implementing single signon process from another application B. An intermediate servlet between Documentum and that application can do the trick. The steps are as follows:
1.Create a super user account in documentum(if not already present).
1. Create user accounts with identical username in documentum as present in application B.(You can use jobs for that)
2.Keep the Documentum super user password encrypted in a properties file.
3. Fetch the Username of the user logged into the application B using application B’s API into the servlet.
4.Get the documentum super user session in the servlet.
5.Use documentum super user session to get the documentum login ticket of the user(username fetched using app B's API) logged in to the application B.
The servlet will then launch the webtop using this login ticket.

The servlet code should be like this:
public class SSOServlet extends HttpServlet
{
IDfSession session=null;
IDfSessionManager sessMgr=null;
private String superUserName="admin"; //super user name is hardcoded(can be kept in properties file)
private String superUserPwd="adminpwd"; //super user password is hardcoded(can be kept in properties file)

private String username="test_user ";//username should come for application B API

private String docbaseName="Test_DocBase";
private IDfSession getDfSession() throws DfException
{
IDfClientX moClientX =new DfClientX();
IDfClient client = moClientX.getLocalClient();
//create an IDfLoginInfo object named "loginInfoObj"
IDfLoginInfo loginInfoObj = moClientX.getLoginInfo();
loginInfoObj.setUser(superUserName);
loginInfoObj.setPassword(superUserPwd);
loginInfoObj.setDomain("");
sessMgr= client.newSessionManager();
sessMgr.setIdentity(docbaseName, loginInfoObj);
session = sessMgr.getSession(docbaseName);
return session;
}

public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException
{
PrintWriter out = response.getWriter();
try
{
String loginTicket=getDfSession().getLoginTicketForUser(username);
String url="/webtop/component/main?ticket="+loginTicket+" &username="+username+" &docbase="+ docbaseName;
response.sendRedirect(url);
}
catch(DfException dfe)
{
out.println("Inside Exception");
dfe.printStackTrace();
}
}
}

This servlet should be invoked from application B. The servlet will launch the webtop.

Thursday, April 17, 2008

Parsing XML present within Documentum Server

Here is the Java method for parsing an XML file present within documentum. In this case JDOM has been used for the parsing purpose . Other Document parsers can also be used.

/*The argument of the method is the documentum session object and r_object_id of the xml document. The method returns a org.jdom.Document object which can then be used to parse the XML file (ref: http://www.jdom.org/) .*/

private Document parseXML(IDfSession losession,String r_object_id)
{
IDfSysObject xmlObj =null;
Document document=null;
try
{
xmlObj =(IDfSysObject) losession.getObject(new DfId(r_object_id));
System.out.println("objectname= "+xmlObj.getObjectName());
ByteArrayInputStream bis=xmlObj.getContent();
/*getContent() method returns a ByteArrayInputStream object of the file present in
content server. This method is also helpful in reading files having other extensions. */
SAXBuilder builder = new SAXBuilder();
document = builder.build(bis);
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
return document;
}
}