package org.apache.maven.plugin;
/*
* LICENSE
*/
import java.io.File;
import java.io.FileWriter;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.exception.MethodInvocationException;
import org.apache.velocity.exception.ParseErrorException;
import org.apache.velocity.exception.ResourceNotFoundException;
import com.thoughtworks.qdox.JavaDocBuilder;
import com.thoughtworks.qdox.model.JavaClass;
import com.thoughtworks.qdox.model.JavaSource;
/**
* @author <a href="mailto:trygvis@inamo.no">Trygve Laugstøl</a>
* @version $Id$
*/
public class ApiDocsPlugin
{
// parameters
private File sourceDirectory;
private File outputDirectory;
private String title;
// members
private JavaDocBuilder builder;
private VelocityEngine velocity;
private Map classes;
// ----------------------------------------------------------------------
// Plugin Implementation
// ----------------------------------------------------------------------
public void execute()
throws Exception
{
initializeSources();
initializeVelocity();
generateClassDocs();
generateListDocs();
// misc
Template template = getTemplate( "templates/style.css.vm" );
File outputFile = new File( outputDirectory, "style.css" );
FileWriter output = new FileWriter( outputFile );
VelocityContext context = createVelocityContext( null );
template.merge( context, output );
output.close();
}
public void initializeSources()
throws Exception
{
if ( !outputDirectory.exists() && !outputDirectory.mkdirs() )
{
throw new Exception( "Could not make the output directory: '" + outputDirectory.getAbsolutePath() );
}
builder = new JavaDocBuilder();
debug( "outputDirectory: " + outputDirectory );
debug( "sourceDirectory: " + sourceDirectory );
builder.addSourceTree( sourceDirectory );
classes = new TreeMap();
JavaSource[] sources = builder.getSources();
for ( int i = 0; i < sources.length; i++ )
{
JavaClass[] javaClasses = sources[ i ].getClasses();
for ( int j = 0; j < javaClasses.length; j++ )
{
classes.put( javaClasses[ j ].asType().getValue(), new ApiClass( javaClasses[ j ] ) );
}
}
}
public void generateClassDocs()
throws Exception
{
Iterator it = classes.values().iterator();
while ( it.hasNext() )
{
generateDocsForClass( (ApiClass) it.next() );
}
}
public void generateListDocs()
throws Exception
{
VelocityContext context = createVelocityContext( null );
// initialize the velocity context
context.put( "classes", classes );
Template template = getTemplate( "templates/all-classes.vm" );
FileWriter output = new FileWriter( new File( outputDirectory, "all-classes.html" ) );
template.merge( context, output );
output.close();
}
private void generateDocsForClass( ApiClass clazz )
throws Exception
{
debug( "Generating docs for: " + clazz.getFullName() );
VelocityContext context = createVelocityContext( clazz );
// initialize the velocity context
context.put( "class", clazz );
Template template = getTemplate( "templates/class.vm" );
File outputFile = getOutputFile( clazz.getFullName() );
FileWriter output = new FileWriter( outputFile );
template.merge( context, output );
output.close();
}
// ----------------------------------------------------------------------
// Accessors
// ----------------------------------------------------------------------
/**
* @return Returns the outputDirectory.
*/
public File getOutputDirectory()
{
return outputDirectory;
}
/**
* @param outputDirectory The outputDirectory to set.
*/
public void setOutputDirectory( File outputDirectory )
{
this.outputDirectory = outputDirectory;
}
/**
* @return Returns the sourceDirectory.
*/
public File getSourceDirectory()
{
return sourceDirectory;
}
/**
* @param sourceDirectory The sourceDirectory to set.
*/
public void setSourceDirectory( File sourceDirectory )
{
this.sourceDirectory = sourceDirectory;
}
public ApiClass getApiClass( String name )
{
return (ApiClass) classes.get( name );
}
// ----------------------------------------------------------------------
// Accessors
// ----------------------------------------------------------------------
private void initializeVelocity()
throws Exception
{
velocity = new VelocityEngine();
velocity.setProperty( "runtime.log.logsystem.class", VelocityLogger.class.getName() );
velocity.setProperty( "resource.loader", "classpath" );
velocity.setProperty( "classpath.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader" );
velocity.init();
}
private Template getTemplate( String template )
throws Exception
{
try
{
return velocity.getTemplate( template );
}
catch ( ResourceNotFoundException ex )
{
throw new Exception( "Exception while getting template", ex );
}
catch ( ParseErrorException ex )
{
throw new Exception( "Exception while getting template", ex );
}
catch ( MethodInvocationException ex )
{
throw new Exception( "Exception while getting template", ex );
}
catch ( Exception ex )
{
throw new Exception( "Exception while getting template", ex );
}
}
private File getOutputFile( String clazz )
{
clazz = clazz.replace( '.', File.separatorChar );
File file = new File( outputDirectory, clazz + ".html" );
int index = clazz.lastIndexOf( File.separatorChar );
if ( index != -1 )
{
File dir = new File( outputDirectory, clazz.substring( 0, index ) );
dir.mkdirs();
}
return file;
}
private VelocityContext createVelocityContext( ApiClass clazz )
{
VelocityContext context = new VelocityContext();
if ( title == null )
{
context.put( "title", "API Documentation" );
}
else
{
context.put( "title", title );
}
String rootPage = ".";
if ( clazz != null )
{
int i = clazz.getFullName().indexOf( '.' );
while ( i != -1 )
{
rootPage += "/..";
i = clazz.getFullName().indexOf( '.', i + 1 );
}
}
context.put( "rootPage", rootPage );
return context;
}
private void debug( String msg )
{
System.err.println( msg );
}
private void info( String msg )
{
System.out.println( msg );
}
}