QDox is a library which allows you to parse a java source file and extract instance variables, methods and even JavaDoc tags from it. Quite some time ago, I had used QDox for a little tool that generates implementation source code for java beans. When writing java bean sources, you usually have to write the same code template again and again for every single bean property. Each time, the template has to include an instance variable, a getter and a setter method and a constant for the property name.
With the code generation tool, you can just create an abstract template class for the bean that holds a single abstract getter method for each bean property. Here is an example with a bean for an employee:
public abstract class EmployeeTemplate {
public abstract SkillTemplate getSkill();
public abstract String getName();
}
The template source has all information necessary to generate an implementation source file with the code items mentioned above.
public abstract class GenBeanEmployee extends EmployeeTemplate {
public static final String PROPERTY_SKILL = "skill";
public static final String PROPERTY_NAME = "name";
private SkillTemplate m_skill;
private java.lang.String m_name;
public SkillTemplate getSkill () {
return m_skill;
}
public void setSkill(SkillTemplate skill) {
m_skill = skill;
}
public java.lang.String getName () {
return m_name;
}
public void setName (java.lang.String name) {
m_name = name;
}
}
The tool is still being used today. Recently the project migrated from Java 1.4 to Java 5. Unsurprisingly, it didn’t take long for the first template to become a generic class. Designed for a Java 1.4 environment, the tool was of course not able to handle generic templates.
To fix this, the generated implementation source needs to adopt any generic parameters from the template. A template class header like
public abstract class EmployeeTemplate<S extends SkillTemplate>
should result in a generated implementation class header like
public abstract class GenBeanEmployee<S extends SkillTemplate>
extends EmployeeTemplate<S>
So, the tool needs to extract the generic parameters from the template class. However, the QDox parser does not provide this information by default. This is obviously a missing feature. Luckily, it is not too difficult to modify the sources and upgrade the package.
When I experimented with the output of the parser, it turned out that it actually recognizes the parameters from the class during the parsing process. This is due to the fact that the parser can actually handle type parameters for methods. Any recognized parameter – regardless of whether it originates from a method or a class definition – is stored with the structure used for methods. So, the recognized generic parameters from the class definition are falsely added to the first instance method found.
This can easily be fixed by first storing the recognized items in a separate instance variable within the Parser.java file. Then, the type parameters can be added either for the class definition or a method definition, depending on which is parsed next. In order to be able to store the type parameters with the class definition, an appropriate variable needs to be added in the JavaClass.java and ClassDef.java files. Finally, the parsed class parameters need to be set within the ModelBuilder.java file.
With these small additions, I can continue to use the QDox parser for the code generation tool that now also handles generic classes. I had briefly looked into possible alternatives, but did not find any other library that nearly had all of the features required for the task. Most of the other options did not even provide any support for generics at all. If you are interested, you can download the modified source files here. They are based on QDox version 1.10.1.
