Thursday, August 26, 2010

Bus Factor

Recently I came across a pretty interesting term called Bus Factor in a software project.
















According to Wikipedia,the bus factor is the total number of key developers who would need to be incapacitated, (as by getting hit by a bus) to send the project into such disarray that it would not be able to proceed.

Obviously,for project managers,its important to increase the Bus Factor as much as possible....and for developers (like me) its important to try to keep it as low as possible :) .

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.

Wednesday, July 30, 2008

Tiff to PDF conversion Using Java

Recently I had converted tiff to pdf using java and IText API.Both the jar as well
as source code can be found in the following urls:
http://www.lowagie.com/iText/download.html
http://itextdocs.lowagie.com/tutorial/objects/images/tiff/index.php

Thursday, July 10, 2008

Solution to a coding puzzle .

Recently I came across a coding puzzle posted in Cedric Beust's weblog(http://beust.com/weblog/).The puzzle is:

Write a counter function that counts from 1 to max but only returns numbers whose digits don't repeat.

For example, part of the output would be:

8, 9, 10, 12 (11 is not valid)
98, 102, 103 (99, 100 and 101 are not valid)
5432, 5436, 5437 (5433, 5434 and 5435 are not valid)
Also:
Display the biggest jump (in the sequences above, it's 4: 98 -> 102)
Display the total count of numbers
Give these two values for max=10000

Though I know that my solution is not that good because I am converting the numbers to string for solving the problem, but still its working....Please post a better approach if you have any......


public class Puzzle
{
//Method for comparing digits of a number with each other
private boolean compareDigits(int number)
{
String digitString=null; //holds string representation of numbers.
digitString=new Integer(number).toString();
boolean flag=true;
for(int strcount=0;strcount<digitString.length();strcount++)
{
for(int temp=strcount+1;temp<digitString.length();temp++)
{
if(digitString.substring(strcount,strcount+1).equalsIgnoreCase(digitString.substring(temp,temp+1)))
{
flag=false;
}
}
}
return flag;
}


public static void main(String []args)
{
int max=new Integer(args[0]).intValue();//holds the maximum number
int counter=0; //holds the count of numbers printed
int biggestJump=0;
int prevInteger=0;
Puzzle puzzleObj=new Puzzle();
for(int num=1;num<=max;num++)
{
boolean isPrintable=puzzleObj.compareDigits(num); //isPrintable is true if the number doesn't have any repeating digit
if(isPrintable)
{
if(biggestJump<(num-prevInteger))
{
biggestJump=num-prevInteger;
}
prevInteger=num;
System.out.println(num);
counter++;
}


}
System.out.println("Total count of numbers is:"+counter);
System.out.println("Biggest Jump="+biggestJump);

}

}