Skip to content

Javadoc Generation_140575016

nxi edited this page Apr 9, 2015 · 1 revision
Created by Tony Lam, last modified on Mar 03, 2010

Introduction

Javadoc is an important form of documentation or reference for developers doing their daily programming job. Many useful information such as API contracts, class inheritance trees and package descriptions can be found in the Javadoc. As part of our build system, we have introduced the Javadoc generator so that up-to-date Javadoc can be created.

How does the generator work?

The Javadoc generator is effectively an ANT script that calls the javadoc ANT task under the Eclipse ant runner. However, since we are limited to show public APIs (that is, the exported packages declared in the OSGi manifest.mf for each plug-in), the ANT script has to be smart on knowing which packages it should look at for Javadoc generation. As the result, the ANT script is actually a generated file from another Python script which reads the OSGi information from selected plug-ins.

Python ANT script generator

# Properties
#eg "D:/workspace/g2/plugins/"
path = "" 
#eg "javadoc.xml"
outputFile = ""
# Set memory and proxy
jvmarg = "-J-DproxyHost=my_proxy_host -J-DproxyPort=my_proxy_port -J-Xms512m -J-Xmx512m"
# eg "./gumtree/r1.4"
destdir = ""
# This should be obtain from the generated ANT script from Eclipse, and replace "\" with "/"
classpath= ...

plugins = [# Runtime
           "org.gumtree.runtime",
           # Core
           "org.gumtree.core",
           "org.gumtree.core.dataaccess",
           "org.gumtree.core.persistence",
           # UI
           "org.gumtree.ui",
           "org.gumtree.ui.workbenchsupport",
           # Server
           "org.json",
           # Workbench
           "org.gumtree.dashboard.ui",
           "org.gumtree.dashboard.ui.rcp",
           "org.gumtree.dashboard2.ui",
           "org.gumtree.scripting.core",
           "org.gumtree.scripting.ui",
           "org.gumtree.sidebar.ui",
           "org.gumtree.ui.cli",
           "org.gumtree.ui.navigator",
           "org.gumtree.ui.spy",
           "org.gumtree.ui.terminal",
           "org.gumtree.ui.views",
           "org.gumtree.ui.workbench",
           "org.gumtree.workflow.ui",
           # Numeric
           "au.gov.ansto.bragg.datastructures",
           "au.gov.ansto.bragg.errorpropagation",
           "au.gov.ansto.bragg.freehep.jas3",
           "org.gumtree.data.common",
           "org.gumtree.data.gdm",
           # Kuranda
           "au.gov.ansto.bragg.kuranda",
           "au.gov.ansto.bragg.kuranda.dom",
           # Cicada
           "au.gov.ansto.bragg.cicada",
           "au.gov.ansto.bragg.cicada.dam",
           "au.gov.ansto.bragg.cicada.dom",
           "au.gov.ansto.bragg.cicada.dra",
           "au.gov.ansto.bragg.process",
           # Kakadu
           "au.gov.ansto.bragg.kakadu.core",
           "au.gov.ansto.bragg.kakadu.dom",
           "au.gov.ansto.bragg.kakadu.ui",
           # SICS
           "ch.psi.sics.hipadaba",
           "org.gumtree.gumnix.sics.batch.ui",
           "org.gumtree.gumnix.sics.core",
           "org.gumtree.gumnix.sics.dom",
           "org.gumtree.gumnix.sics.ui",
           "org.gumtree.vis.opengl",
           # NBI Common
           "au.gov.ansto.bragg.common.dra.algoLib",
           "au.gov.ansto.bragg.experiment.core",
           "au.gov.ansto.bragg.experiment.script",
           "au.gov.ansto.bragg.hm.core",
           "au.gov.ansto.bragg.nbi.dom",
           "au.gov.ansto.bragg.nbi.dra",
           "au.gov.ansto.bragg.nbi.exp",
           "au.gov.ansto.bragg.nbi.jepp",
           "au.gov.ansto.bragg.nbi.ui",
           "au.gov.ansto.bragg.nbi.ui.intro",
           "org.gumtree.data.hdf.ui",
           "org.gumtree.scripting.jepp",
           # Echidna
           "au.gov.ansto.bragg.echidna.dra",
           "au.gov.ansto.bragg.echidna.dra.algolib",
           "au.gov.ansto.bragg.echidna.exp",
           "au.gov.ansto.bragg.echidna.ui",
           # Kowari
           "au.gov.ansto.bragg.kowari.dra",
           "au.gov.ansto.bragg.kowari.exp",
           "au.gov.ansto.bragg.kowari.ui",
           # Platypus
           "au.gov.ansto.bragg.platypus.ui",
           # Quokka
           "au.gov.ansto.bragg.quokka.core",
           "au.gov.ansto.bragg.quokka.dra",
           "au.gov.ansto.bragg.quokka.dra.algolib",
           "au.gov.ansto.bragg.quokka.exp",
           "au.gov.ansto.bragg.quokka.ui",
           "au.gov.ansto.bragg.quokka2.core",
           "au.gov.ansto.bragg.quokka2.ui",
           # Wombat
           "au.gov.ansto.bragg.wombat.core",
           "au.gov.ansto.bragg.wombat.dra",
           "au.gov.ansto.bragg.wombat.dra.algolib",
           "au.gov.ansto.bragg.wombat.exp",
           "au.gov.ansto.bragg.wombat.ui"]
           
links = ["../../eclipse/galileo/",
         "../../xstream/1.3.0/",
         "http://www.osgi.org/javadoc/r4v42/",
         "http://java.sun.com/javase/6/docs/api/"]

# Load the OSGi MANIFEST.MF into a dictionary
def loadManifest(filename):
    f = open(filename)
    key = None
    dict = {}
    for line in f:
        tokens = line.split(': ')
        if len(tokens) > 1:
            key = tokens[0]
            value = tokens[1].strip()
            dict.setdefault(key, value)
        else :
            dict[key] = dict[key] + tokens[0].strip()
    f.close()
    return dict

# Extract the packages name from a plug-in
def findExportPackages(pluginId):
    dict = loadManifest(path + pluginId + "/META-INF/MANIFEST.MF")
    packages = []
    if dict.has_key("Export-Package"):
        for package in dict["Export-Package"].split(","):
            packages.append(package)
    return packages
    
def createScript():
    doc = Document()

    project = doc.createElement("project")
    project.setAttribute("default", "javadoc")
    doc.appendChild(project)

    target = doc.createElement("target")
    target.setAttribute("name", "javadoc")
    project.appendChild(target)

    javadoc = doc.createElement("javadoc")
    javadoc.setAttribute("access", "public")
    javadoc.setAttribute("additionalparam", jvmarg)
    javadoc.setAttribute("author", "true")
    javadoc.setAttribute("classpath", classpath)
    javadoc.setAttribute("destdir", destdir)
    javadoc.setAttribute("nodeprecated", "false")
    javadoc.setAttribute("nodeprecatedlist", "false")
    javadoc.setAttribute("noindex", "false")
    javadoc.setAttribute("nonavbar", "false")
    javadoc.setAttribute("notree", "false")
    
    packagenames = ""
    for plugin in plugins:
        for package in findExportPackages(plugin):
            packagenames = packagenames + package + ","
    javadoc.setAttribute("packagenames", packagenames)
    
    javadoc.setAttribute("source", "1.6")
    
    sourcePath = ""
    for plugin in plugins:
        sourcePath = sourcePath + path + plugin + "/src;"
    javadoc.setAttribute("sourcePath", sourcePath)
    
    javadoc.setAttribute("splitindex", "true")
    javadoc.setAttribute("use", "true")
    javadoc.setAttribute("version", "true")
    # See: http://western-skies.blogspot.com/2008/08/ant-javadoc-and-createprocess-error87.html
    javadoc.setAttribute("useexternalfile", "yes")
    target.appendChild(javadoc)

    for linkURL in links:
        link = doc.createElement("link")
        link.setAttribute("href", linkURL)
        javadoc.appendChild(link)

    return doc

if __name__ == "__main__":
    path = sys.argv[1]
    outputFile = sys.argv[2]
    destdir = sys.argv[3]
    f = open(outputFile, "w+")
    f.write(createScript().toprettyxml(indent="    "))
    f.close()
Above is the Python script for generation the ANT xml script. It takes three arguments:
  • Path of the plug-ins (workspace)
  • Output location for the ANT script
  • Javadoc destination
Notes:
  • The plug-ins that you want to be included to Javadoc is in the plugins global variable.
  • This script assume the Java source can be found under /src folder for each plugin
  • When it reads the exported package list from the OSGi manifest.mf file, it assume each entry has no additional attributes (ed ;uses:="..." or ;version="..."). This restriction may be fixed in the future.
  • This script sets useexternalfile to yes in order to avoid "error 87" when it runs on the Eclipse ANT runner (see: http://western-skies.blogspot.com/2008/08/ant-javadoc-and-createprocess-error87.html)
  • The classpath variable is very tricky. Since we cannot gather classpath for generating Javadoc without accessing the Eclipse PDE runtime, we need to pre-generate the classpath entries and copy into the Python script.

Build procedures

The build process comes in two parts: manual preparation and daily automation. Due to the limitation of technology, when there are changes in plug-in dependency (use of new third party plugins) or introducing new plugins, the Python script has to be changed. Preparation (happens when plugin organisation is changed)
  • Configure Eclipse IDE to point to javadoc.exe (should only be done once)
  • Change the plugins variable in Python script to add or remove plugins that will be included for Javadoc
  • Change the classpath variable in Python script to include new jars (dependency). The classpath variable can be generated in Eclipse in the following steps:
    • Select all plugins in your workspace, and Click Project-> Generate Javadoc... from the menu.
    • In the second page of dialog, select all referenced archives
    • Click to save settings in an ANT script
    • Copy the classpath attribute and paste into the Python script
Automation (happens daily with CruiseControl)
  • Clean all generated contents
  • Run Python to generate the ANT script
  • Run the ANT script under the Eclipse ANT runner to Javadoc generation
  • Copy files to archive area
  • Clean all generated contents again
The Javadoc is then already to publish. The website should be setup in the following structure in order to make the cross reference (referencing GumTree API to say Eclipse API) happen.
/javadoc (arbitrary)
+/eclipse
-+/gaolileo (verision)
--+<all javadoc from eclipse goes here)
+xstream
-+/1.3.0 (version)
--+<all javadoc from xstream goes here)
+gumtree
-+/r1.4 (version)
--+<all javadoc from the build system goes here)
-+/r1.5
...
Document generated by Confluence on Apr 01, 2015 00:11
Clone this wiki locally