Monday, February 16, 2009

Useful Unix Commands for beginners

(1) Copy directory:

cp -r <source_dir_path> <dest_dir_path>

(2) To recursively change file permissions for the entire directory:
chmod -R 777 <dir_name>

(3) To send contents of a text file as mail:
mail mail.id@domain.com < /tmp/file.txt

(4) To change your account Password:
passwd <yourUserName>

(5) To set an Environment Variable:

export VAR_NAME='value'
Examples:
  • export ANT_HOME='/export/opt/apache-ant-1.7.1'
  • export PATH=${ANT_HOME}/bin:${PATH}

(6) Secure copy a directory from one machine to another:
scp -r userName@hostname.com:<srcdir_path>/* <destdir_path>

(7) Viewing installed programs in Unix:
rpm -q [package_name] : shows if the package named 'package_name' is installed
rpm -qa : shows all the installed packages



(8) Installing & Uninstalling programs in Unix
rpm -i /filename.rpm : to install a package
rpm -e [package_name] : to uninstall package named 'package_name'




The list will keep growing.. :)

Monday, February 9, 2009

About Writing comments in your code..

"Write such a code that you don't have to write code comments."

I don't remember the who said this, but I firmly believe in what he said. I think the class names, method names and variable names should be meaningful and there should be enough (doesn't mean 'too many') blank lines at appropriate places. Proper indentation is also must.

If you make sure you have all of this, there should not be much problem reading your code for someone else..

Friday, February 6, 2009

Joke of the day!!

Never let your boss know that you're writing blogs,

you'll end up writing documentation of your project!!

Friday, May 30, 2008

Authenticating Struts2 Applications using Interceptor

When I needed to introduce authentication into my existing application, I tried searching for an Interceptor written and shared by someone on internet. And as I guessed, I found some really helpful pieces of code, ready-to-use.

As I closely observed them, I found that they were implemented in almost similar fashion. What was common in both of them was the fact that 'interceptor was authenticating the user on login attempt'. I somehow wasn't comfortable with the idea of putting business logic in Interceptor. I thought, when a user is trying to log on to the system, a Login action should be called to Log the user into the system. I believe the interceptor should only keep a watch on the requests rather than processing them. Let request-processing be done by Actions.

So I wrote my own AuthenticationInterceptor.

  • It doesn't authenticate the user by itself, but just allows the 'LoginAttempt Request' being submitted to 'Login Action'.
  • When an un-authenticated user is attempting to invoke any action, it redirects request to Login page.
  • It just 'observes' all requests from an authenticated user.

I believe the code is self explanatory. Let me know if anything is not clear.

/**
* @author Rushikesh Thakkar
*/

@SuppressWarnings({"serial", "unchecked"})
public class AuthenticationInterceptor extends AbstractInterceptor {

private Map request, session;
public String intercept (ActionInvocation invocation) throws Exception {

session = invocation.getInvocationContext().getSession();
request = invocation.getInvocationContext().getParameters();

User user = (User) session.get(Constants.USER_KEY);

// CHECK IF THE USER IS ATTEMPTING TO LOGIN
boolean loginAttempt = request.get(Constants.LOGIN_ATTEMPT) == null ? false : true;

// CHECK IF THE USER IS ATTEMPTING TO LOGOUT
boolean logoutAttempt = request.get(Constants.LOGOUT_ATTEMPT) == null ? false : true;

System.out.println("__loginAttempt: " + loginAttempt);
System.out.println("__logoutAttempt: " + logoutAttempt);

if (user != null) { // USER IS ALREADY LOGGED IN
nbsp;if (!loginAttempt && logoutAttempt) // USER IS TRYING TO LOGOUT
return invocation.invoke();
else // USER IS TRYING TO PERFORM SOME BUSINESS-ACTION
return invocation.invoke();

} else { // USER IS NOT LOGGED IN
System.out.println("#12");
if (loginAttempt) { // USER IS TRYING TO LOGIN
return invocation.invoke();
} else // USER IS TRYING TO PERFORM SOME BUSINESS-ACTION
return "show-login";
}
}
}


Disclaimer: The code may not be perfect. Please test is thoroughly before using, and let me know if any correction is needed.

Thursday, May 29, 2008

Writing WSDL Manually for an existing WebService

Once upon a time, there were no sophisticated frameworks for developing WebServices. As WebServices started becoming popular, the need to have an API implementing SOAP protocol was realized. Apache SOAP project was one of the earliest implementation of Simple Object Access Protocol (SOAP). It provided support for manipulating SOAP messages. It was good enough at that stage. Many WebServices were developed using Apache SOAP, that are still being used.

I had to develop consumer for one such legacy WebService. I didn't get the WSDL for that WebService, so I had to write it myself.

A WSDL is made up of the following sections:

1. Types (simply, XML Schema of the SOAP Messages)
2. Messages
3. Port Types
4. Bindings
5. Services

If you ask me, writing Types is the most challenging task in such cases. If you manage to create Types properly then everything else just follows. So, I started with writing 'Types' first.

If one has an XML message, there are several tools to generate its schema - and that's what you need!! So, if you get the SOAP messages received by the WebService, then you can generate schema using such schema-generator tool, and your 'Types' section is ready!!

I used Axis utility TCPMON for monitoring SOAP messages received by the legacy WebService. After collecting SOAP messages for all the operations, now I needed to generate Schema from it. I used the following Schema Generator tools for that.

HitSoftware xml utilities
WebDeveloper Toolbar for Mozilla Firefox

Finally, I completed the 'Types' section of WSDL. As I already mentioned, writing the other sections is not so difficult. Carefully reading an existing WSDL or WSDL Specification can be helpful while doing so.


Another very important thing you need to take care of while writing WSDL is <wsdl:definitions targetNamespace .. >. It has to be exactly the same as xmlns of the SOAP Message wrapped inside <soap-env:body></soap-env:body>. Here's the example of the same:

SOAP message:

<?xml version="1.0" encoding="UTF-8"?>

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

<soapenv:Body>
<getServerStatusResponse xmlns="http://webservice.rst.com">
<getServerStatusReturn>
<message>Service is alive</message>
<status>0</status>
</getServerStatusReturn>
</getServerStatusResponse>
</soapenv:Body>
</soapenv:Envelope>

for it's WSDL should be:
<wsdl:definitions
targetNamespace="http://webservice.rst.com"
xmlns:apachesoap="http://xml.apache.org/xml-soap"
xmlns:impl="http://webservice.rst.com"
xmlns:intf="http://webservice.rst.com"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">

I think this should be enough to start with. All the best!!

Tuesday, April 29, 2008

Running Axis wsdl2java from within Maven2 pom.xml

I needed to generate Axis infrastructure classes using wsdl2java for my web-service client application. I had to generate java classes from two WSDLs into two different packages respectively. I found one Maven2 plugin for that, but it has a limitation that I can not specify different packages for different WSDLs. I tried putting the same plugin twice in for both WSDLs specifying different package for each WSDL, but that too didn't work as it generated *.java files only for first declaration.

So I had to use Axis's ant tasks for wsdl2java. I did it like this:

<build>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>generate-sources</phase>
<configuration>
<tasks>
<path id="compile_classpath" refid="maven.compile.classpath"/>
<taskdef resource="axis-tasks.properties" classpathref="compile_classpath" />

<property name="legacyService.wsdl" value="src/main/resources/ref-wsdl/legacy.wsdl"/>
<property name="newOne.wsdl" value="http://your.host/service.wsdl"/>
<property name="generated.dir" value="src/main/java"/>

<axis-wsdl2java output="${generated.dir}" verbose="true" url="${legacyService.wsdl}" >
<mapping namespace="urn:ServiceNameSpace" package="com.rst.webservice.legacy.client.axis14.util" />
</axis-wsdl2java>
<axis-wsdl2java output="${generated.dir}" verbose="true" url="${newOne.wsdl}" >
<mapping namespace="http://webservice.rst.com" package="com.rst.webservice.newone.client.axis14.util" />
</axis-wsdl2java>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

<dependencies>
<!-- ..... -->
<dependency>
<groupId>org.apache.axis</groupId>
<artifactId>axis-ant</artifactId>
<version>1.4</version>
</dependency>
<!-- ..... -->
<dependencies>

Now, if you observe the above piece of pom.xml, axis:wsdl2java task is executed in 'generate-sources' phase, and Maven needs axis-ant.jar to execute that, but
it is not available to Maven by default. So we need to provide Maven with this dependency.

How to provide this dependency to maven?
Now that's tricky, if you see the Documentation page about
Maven Classpaths for ant-tasks then you would notice that the classpath that Maven refers to for executing various goals is not available as built-in variable. So I could have defined a path variable with hard-coded path to axis-ant.jar or I could define a 'dependency' to axis-ant and refer to maven.compile.classpath. And as you see I chose the second approach.

Showing dynamic User Interface using Struts2

The main purpose for writing this post is to help understand the compilation process of a Struts2 JSP, and to highlight how useful the OGNL expression can be.

I had to make a form that would display different sets of text-fields in different situations. So I did something like what follows:

Action:

public class ShowDynamicForm extends ActionSupport {

private List fields = new ArrayList (); //will be iterated in the following JSP

public String execute() throws Exception {
//The list: 'fields' can be populated from database depending on requirement
fields.add("name");
fields.add("number");
fields.add("class");
fields.add("result");

return SUCCESS;
}

public List getFields() {
return fields;
}
public void setFields(List fields) {
this.fields = fields;
}
}

JSP: The jsp is the most important artifact to understand. It mainly does the following:
- Iterates the list (populated by ShowDynamicForm action) and
- Dynamically renders labels and text-boxes for the required fields using OGNL expressions.
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>

<%-- author: Rushikesh Thakkar --%>

<html>
<body>
<s:i18n name="labels">
<table border="0" bordercolor="gray" cellpadding="5" cellspacing="0">
<tr>

<s:iterator value="fields" status="status" id="field">

<td><s:text name="%{fields[#status.index]}"/></td>
<td><s:textfield name="field.%{fields[#status.index]}" theme="simple" value="%{#status.index}" /></td>
<s:if test="#status.even">
</tr>
</s:if>
</s:iterator>

</table>

</s:i18n>
</body>
</html>

Explanation: First, the OGNL expressions are evaluated in the JSP. This helps
<s:text /> and <s:textfield /> get values for their attributes 'name' and 'value'. So in the first pass
<s:text name="%{fields[#status.index]}"/> becomes
<s:text name="name"></s:text> and similarly for
<s:textfield name="field.%{fields[#status.index]}" theme="simple" value="%{#status.index}" /> for entire itearation.
And then its simple to understand. I am using the following labels.properties file to provide values for
<s:text /> tag.

labels.properties:
name=Student Name
number=Roll No.
class=Class
result:Result