SyntaxHighlighter

Thursday, November 14, 2013

Creating custom JavaDoc - Doclets


Sometimes in a project we might have to have a report of all the classes and methods being used in the project.
In my recent project, we wanted to generate such a report just to verify whether all our class and method names are consistent as per our coding conventions.
One can easily generate a full-fledged Javadoc, but a full length Javadoc is a lot of information, and most of which will not be required for such cases.
There you can make use of a Doclet. It is kind of an extension to Javadoc which allows you to create Java class/method and other construct documentation just upto the level of detail you need. You need to write a very small Java class/application and you get your own customized javadoc – called "Doclet".

Below is step by step example to achieve the same:
Prerequisites:

  1. You should have a Java project for which you want to create the custom javadoc details
  2. The doclet API class files are in the lib/tools.jar file in the Java SDK. When you compile a doclet, the tools.jar must be on the class path. You can use the -classpath option on javac for this purpose. You can also link the jar as external library to your simple Java program you are writing if you are using an IDE like eclipse.

Step 1: Create a simple Java class which implements the function
public static boolean start(RootDoc root) { … } and

Step 2: Import the Doclet library in this Java file - import com.sun.javadoc.*;
You can have a Java class as simple as shown below:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
public class CustomDoclet {
private final static String PATH = "<PATH To Where Your Javadoc should be saved";
    private final static String FILENAME = "Javadoc.txt";

    public static boolean start(RootDoc root) {
        try {
            String filename = PATH + FILENAME;
            // System.out.println("FileName: " + filename);
            FileWriter output = new FileWriter(filename, true);
            BufferedWriter writer = new BufferedWriter(output);

            PackageDoc[] packages = root.specifiedPackages();
            for (PackageDoc doc : packages) {

                ClassDoc[] classes = doc.allClasses();
                for (ClassDoc classDoc : classes) {
                    System.out.println(classDoc.name());
                    MethodDoc[] methods = classDoc.methods();
                    for (MethodDoc method : methods) {

                        if (method.isPublic()) {

                            writer.write(method.name().toString() + " "
                                    + classDoc.name());
                            writer.newLine();
                        }
                    }
                }

            }
            writer.newLine();
            writer.flush();
            writer.close();
            output.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return true;
    }
}

The above sample can generate a simple text file with all the Classnames and their corresponding public method names.

I will explain what the code does:

First as stated above you should implement the public method -

public static boolean start(RootDoc root), when you compile and run your doclet class this is the method that will be called.

The method takes an argument of type RootDoc, this the root of your project, all the packages and class files will be searched from here onwards.

Next the PackageDoc actually represent each package.

And inside each package you can iterate over each class represented as ClassDoc

And in each ClassDoc you can iterate over all methods – MethodDoc

From the list of MethodDocs I have choose to display only the public ones using isPublic() method.



The rest of the code is just about creating a Text file and putting these discovered class names and their related method named in individual lines.

Step 3: Now to compile you need to keep the tools.jar in the classpath, so you can use

javac -cp "<Your Java location>\lib\tools.jar" <YourJavaClass>.java

Step 4: To run you should use the below command from you project root directory

javadoc -doclet <Your Doclet classname> -docletpath <Physical path where your doclet class is stored> -sourcepath "<your project root folder>" 

You can use several other options while running the Doclet 

packagenames
A series of names of packages, separated by spaces, such as java.lang java.lang.reflect java.awt. You must separately specify each package you want to document. Wildcards are not allowed; use -subpackages for recursion. The Javadoc tool uses -sourcepath to look for these package names. See Example - Documenting One or More Packages
sourcefilenames
A series of source file names, separated by spaces, each of which can begin with a path and contain a wildcard such as asterisk (*). The Javadoc tool will process every file whose name ends with ".java", and whose name, when stripped of that suffix, is actually a legal class name (see information about Identifiers in the Java Language Specification). Therefore, you can name files with dashes (such as X-Buffer), or other illegal characters, to prevent them from being documented. This is useful for test files and template files The path that precedes the source file name determines where javadoc will look for the file. (The Javadoc tool does not use -sourcepath to look for these source file names.) Relative paths are relative to the current directory, so passing in Button.java is identical to ./Button.java. A source file name with an absolute path and a wildcard, for example, is /home/src/java/awt/Graphics*.java. See Example - Documenting One or More Classes. You can also mix packagenames and sourcefilenames, as in Example - Documenting Both Packages and Classes
Generates documentation from source files in the specified packages and recursively in their subpackages. An alternative to supplying packagenames or sourcefilenames.
One or more files that contain a list of Javadoc options, packagenames and sourcefilenames in any order. Wildcards (*) and -J options are not allowed in these files.

Yes it is as simple as that!
Now you can have your own customized Javadoc with only the information you need.
Enjoy docletting!

Sunday, September 8, 2013

Spring Framework - Helping Points

Spring is a long existing framework. However, I came across using it very recently. So thought of putting a few key points of where Spring makes a developer's life easier.

Point 1: Dependency Injection
Perhaps, the most important aspect of Spring framework. After using it, the very simple and basic definition of this feature I can put as :
You have classes and then you have more classes. Each of these classes need certain information or input to work as you expect it to. Spring allows you to define these dependencies.
Or in other words you make sure your class/object gets what it needs to perform before it starts performing.

Point 2: Dependency Checking
I found this really useful. You can make use of simple xml configuration or better still and annotation(@Required) to make sure you provide values for all the properties of a class that is absolutely necessary for your functionality. And Spring helps you to validate whether required values are being set or not before actually your app starts working.

Point 3: AOP
Aspect Oriented Programming enables you to think of underlying aspects/services and design them in simple POJOs (Plain Old Java Objects). Prior to Spring, one would more concentrate on the actors of a particular problem rather than concentrating more on the problem.

The code is self explanatory. You are a person and it just says Hello to you.
The HelloYou class pulls a Person, whose name is your name (set in the Xml config file) and it displays "Hello <Your name>!". That's it!