Friday, September 29, 2006

Java - Dynamic code generation using XDoclet

Usually XDoclet is used through Ant or an IDE that launches XDoclet, mainly for generating configuration files. But if you would like to generate source and descriptors at runtime from the user input, then here is the solution or hack, whatever you call it.

XDoclet finds all the tags and its attributes specified in the Javadoc section of the class and its methods.
An instance of SourceClass(found in XJavaDoc) holds all the details of the source file read. It contains collection of XMethods representing methods and XFields representing properties.
These xmethods and xfields contain all the details(return type, parameters) and tags defined in the source file for the corresponding method or property.

Instead of writing a Java source file with XDoclet tags, we have to create an instance of any of the implementation classes of XClass interface such as SourceClass and provide it to the XDoclet module which is going to handle the tags; for eg: HibernateSubTask.

Creating an instance of SourceClass

XTagFactory tagFoctory = new XTagFactory();
XJavaDoc jDoc = new XJavaDoc();
File sourceFile = new File(yourClassName+".java");
try {
sourceFile .createNewFile();
sourceFile .deleteOnExit();
SourceClass sourceClass = new SourceClass(jDoc, tempFile, tagFoctory);
sourceClass.setQualifiedName(qualifiedClassNameOfYourClass);
} catch (IOException e) {

e.printStackTrace();
}


A temporary SourceClass is ready, now we have to add the getter methods for the properties in the class to be generated. Properties or fields are generated based on the methods defined for the properties. MethodImpl is the implementation class for XMethod interface.

MethodImpl method = new MethodImpl(sourceClass, sourceClass.getTagFactory());
method.setReturnType(returnTypeOfMethod);
method.setName("get"+propertyName);
method.addModifier(0); // public access specifier

To access some of the package level properties and methods in these classes, you will have to create your source files under xjavadoc package.

method.getDoc().addTag(tagName,tagValues);
//eg: tagName - hibernate.id, tagValue - name="empid"
sourceClass.addMethod(method);

The method level tags are added to the method's xJavaDoc as shown above.
The class level tags such as hibernate.class are added to the sourceClass's xJavaDoc in the similar fashion.

So we are done with our SourceClass that holds all the tags required by XDoclet to generate code. Now you will have to create an instance of the XDoclet module ant subtask(eg: HibernateSubTask) and set the sourceclass to it.

task.setCurrentClass(sourceClass);
task.execute();

And execute the task! That's it.
(I have not discussed about the ant subtask configurations, please find the necessary things required for the particular module)

Tuesday, September 26, 2006

Java - File.listFiles() returns null for temporary folders

To find all the files in a given directory we use the method listFiles() in the File class.
It will return all the files and sub directories in the given File, if its a directory and null otherwise.

File dir = new File("/home/user/");
File [] filesAndFolders = dir.listFiles();

This works fine for all the folders in the system except for the temporary folders, such as a temporarily unzipped archive. For example, if u try to list all the files of a deployed web application, which is actually maintained by the container as a temporary folder for deployed web archives, File.listFiles() will return null.

Today i found this while trying to read all the jar files in the WEB-INF/lib directory of a deployed web application.

Saturday, September 23, 2006

Can't add dynamic HTML content to a table in IE.

I found that adding HTML elements dynamically using JavaScript into a table, doesn't work in IE. Works fine in Gecko based browsers.

var placeHolder = document.getElementById("tableID");
var newElement = document.createElement("tr");
newElement.innerHTML = "Dynamic content";
placeHolder.appendChild(newElement);

This doesn't work as expected in IE.
If u want a workaround for this problem, then you may create a DIV element inside a or .

var placeHolder = document.getElementById("tdOrtrID");
var newElement = document.createElement("div");
newElement.innerHTML = "Dynamic content";
placeHolder.appendChild(newElement);

This works properly, but you have to handle the layout problems since its not a tr element.

My Technical Experience

I'm a programmer who loves to explore the whole of programming world; not bound to a single language. I always keep track for new softwares and libraries, by googling. I love system programming using C, but i was thrown into Java world for the past two years.
I'll be dumping my daily bookmarks and findings to this page.
All are welcome to comment on my dumps.