| package org.apache.maven.jxr; |
| |
| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| import org.apache.maven.jxr.ant.DirectoryScanner; |
| import org.apache.maven.jxr.log.Log; |
| import org.apache.maven.jxr.pacman.FileManager; |
| import org.apache.maven.jxr.pacman.PackageManager; |
| |
| import java.io.File; |
| import java.io.FileNotFoundException; |
| import java.io.IOException; |
| import java.util.Iterator; |
| import java.util.LinkedList; |
| import java.util.List; |
| import java.util.Locale; |
| |
| /** |
| * Main entry point into Maven used to kick off the XReference code building. |
| * |
| * @author <a href="mailto:burton@apache.org">Kevin A. Burton</a> |
| * @version $Id$ |
| */ |
| public class JXR |
| { |
| /** |
| * The Log. |
| */ |
| private Log log; |
| |
| /** |
| * Description of the Notice. |
| */ |
| public static final String NOTICE = "This page was automatically generated by " + |
| "<a href=\"http://maven.apache.org/\">Maven</a>"; |
| |
| /** |
| * The default list of include patterns to use. |
| */ |
| private static final String[] DEFAULT_INCLUDES = {"**/*.java"}; |
| |
| /** |
| * Path to destination. |
| */ |
| private String dest = ""; |
| |
| private Locale locale; |
| |
| private String inputEncoding; |
| |
| private String outputEncoding; |
| |
| /** |
| * Relative path to javadocs, suitable for hyperlinking. |
| */ |
| private String javadocLinkDir; |
| |
| /** |
| * Handles taking .java files and changing them into html. "More than meets |
| * the eye!" :) |
| */ |
| private JavaCodeTransform transformer; |
| |
| /** |
| * The revision of the module currently being processed. |
| */ |
| private String revision; |
| |
| /** |
| * The list of exclude patterns to use. |
| */ |
| private String[] excludes = null; |
| |
| /** |
| * The list of include patterns to use. |
| */ |
| private String[] includes = DEFAULT_INCLUDES; |
| |
| /** |
| * Now that we have instantiated everything. Process this JXR task. |
| * |
| * @param packageManager |
| * @param source |
| * @throws IOException |
| */ |
| public void processPath( PackageManager packageManager, String source ) |
| throws IOException |
| { |
| this.transformer = new JavaCodeTransform( packageManager ); |
| |
| DirectoryScanner ds = new DirectoryScanner(); |
| // I'm not sure why we don't use the directoryScanner in packageManager, |
| // but since we don't we need to set includes/excludes here as well |
| ds.setExcludes( excludes ); |
| ds.setIncludes( includes ); |
| ds.addDefaultExcludes(); |
| |
| File dir = new File( source ); |
| |
| if ( !dir.exists() ) |
| { |
| if ( !dir.mkdirs() ) |
| { |
| throw new IllegalStateException( |
| "Your source directory does not exist and could not be created:" + source ); |
| } |
| } |
| |
| ds.setBasedir( source ); |
| ds.scan(); |
| |
| //now get the list of included files |
| |
| String[] files = ds.getIncludedFiles(); |
| |
| for ( int i = 0; i < files.length; ++i ) |
| { |
| String src = source + System.getProperty( "file.separator" ) + files[i]; |
| |
| if ( isJavaFile( src ) ) |
| { |
| transform( src, getDestination( source, src ) ); |
| } |
| |
| } |
| } |
| |
| /** |
| * Check to see if the file is a Java source file. |
| * |
| * @param filename The name of the file to check |
| * @return <code>true</true> if the file is a Java file |
| */ |
| public static boolean isJavaFile( String filename ) |
| { |
| File file = new File( filename ); |
| return filename.endsWith( ".java" ) && file.length() > 0; |
| } |
| |
| /** |
| * Check to see if the file is an HTML file. |
| * |
| * @param filename The name of the file to check |
| * @return <code>true</true> if the file is an HTML file |
| */ |
| public static boolean isHtmlFile( String filename ) |
| { |
| return filename.endsWith( ".html" ); |
| } |
| |
| /** |
| * Get the path to the destination files. |
| * |
| * @return The path to the destination files |
| */ |
| public String getDest() |
| { |
| return this.dest; |
| } |
| |
| /** |
| * @param dest |
| */ |
| public void setDest( String dest ) |
| { |
| this.dest = dest; |
| } |
| |
| /** |
| * @param locale |
| */ |
| public void setLocale( Locale locale ) |
| { |
| this.locale = locale; |
| } |
| |
| /** |
| * @param inputEncoding |
| */ |
| public void setInputEncoding( String inputEncoding ) |
| { |
| this.inputEncoding = inputEncoding; |
| } |
| |
| /** |
| * @param outputEncoding |
| */ |
| public void setOutputEncoding( String outputEncoding ) |
| { |
| this.outputEncoding = outputEncoding; |
| } |
| |
| /** |
| * @param javadocLinkDir |
| */ |
| public void setJavadocLinkDir( String javadocLinkDir ) |
| { |
| // get a relative link to the javadocs |
| this.javadocLinkDir = javadocLinkDir; |
| } |
| |
| /** |
| * @param transformer |
| */ |
| public void setTransformer( JavaCodeTransform transformer ) |
| { |
| this.transformer = transformer; |
| } |
| |
| /** |
| * @param revision |
| */ |
| public void setRevision( String revision ) |
| { |
| this.revision = revision; |
| } |
| |
| /** |
| * @param log |
| */ |
| public void setLog( Log log ) |
| { |
| this.log = log; |
| } |
| |
| /** |
| * @param sourceDirs |
| * @param templateDir |
| * @param windowTitle |
| * @param docTitle |
| * @param bottom |
| * @throws IOException |
| * @throws JxrException |
| */ |
| public void xref( List sourceDirs, String templateDir, String windowTitle, String docTitle, String bottom ) |
| throws IOException, JxrException |
| { |
| // first collect package and class info |
| FileManager fileManager = new FileManager(); |
| fileManager.setEncoding( inputEncoding ); |
| |
| PackageManager pkgmgr = new PackageManager( log, fileManager ); |
| pkgmgr.setExcludes( excludes ); |
| pkgmgr.setIncludes( includes ); |
| |
| // go through each source directory and xref the java files |
| for ( Iterator i = sourceDirs.iterator(); i.hasNext(); ) |
| { |
| String path = (String) i.next(); |
| path = new File( path ).getCanonicalPath(); |
| |
| pkgmgr.process( path ); |
| |
| processPath( pkgmgr, path ); |
| } |
| |
| // once we have all the source files xref'd, create the index pages |
| DirectoryIndexer indexer = new DirectoryIndexer( pkgmgr, dest ); |
| indexer.setOutputEncoding( outputEncoding ); |
| indexer.setTemplateDir( templateDir ); |
| indexer.setWindowTitle( windowTitle ); |
| indexer.setDocTitle( docTitle ); |
| indexer.setBottom( bottom ); |
| indexer.process( log ); |
| } |
| |
| // ---------------------------------------------------------------------- |
| // private methods |
| // ---------------------------------------------------------------------- |
| |
| /** |
| * Given a filename get the destination on the filesystem of where to store |
| * the to be generated HTML file. Pay attention to the package name. |
| * |
| * @param source |
| * @param filename |
| * @return A String with the store destination. |
| */ |
| private String getDestination( String source, String filename ) |
| { |
| //remove the source directory from the filename. |
| |
| String dest = filename.substring( source.length(), filename.length() ); |
| |
| int start = 0; |
| int end = dest.indexOf( ".java" ); |
| |
| if ( end != -1 ) |
| { |
| //remove the .java from the filename |
| dest = dest.substring( start, end ); |
| } |
| |
| //add the destination directory to the filename. |
| dest = this.getDest() + dest; |
| |
| //add .html to the filename |
| |
| dest = dest + ".html"; |
| |
| return dest; |
| } |
| |
| /** |
| * Given a source file transform it into HTML and write it to the |
| * destination (dest) file. |
| * |
| * @param source The jave source file |
| * @param dest The directory to put the HTML into |
| * @throws IOException Thrown if the transform can't happen for some reason. |
| */ |
| private void transform( String source, String dest ) |
| throws IOException |
| { |
| log.debug( source + " -> " + dest ); |
| |
| // get a relative link to the javadocs |
| String javadoc = javadocLinkDir != null ? getRelativeLink( dest, javadocLinkDir ) : null; |
| transformer.transform( source, dest, locale, inputEncoding, outputEncoding, javadoc, this.revision ); |
| } |
| |
| /** |
| * Creates a relative link from one directory to another. |
| * |
| * Example: |
| * given /foo/bar/baz/oink |
| * and /foo/bar/schmoo |
| * |
| * this method will return a string of "../../schmoo/" |
| * |
| * @param fromDir The directory from which the link is relative. |
| * @param toDir The directory into which the link points. |
| * @return a string of format "../../schmoo/" |
| * @throws java.io.IOException If a problem is encountered while navigating through the directories. |
| */ |
| private static String getRelativeLink( String fromDir, String toDir ) |
| throws IOException |
| { |
| StringBuffer toLink = new StringBuffer(); // up from fromDir |
| StringBuffer fromLink = new StringBuffer(); // down into toDir |
| |
| // create a List of toDir's parent directories |
| List parents = new LinkedList(); |
| File f = new File( toDir ); |
| f = f.getCanonicalFile(); |
| while ( f != null ) |
| { |
| parents.add( f ); |
| f = f.getParentFile(); |
| } |
| |
| // walk up fromDir to find the common parent |
| f = new File( fromDir ); |
| if ( !f.isDirectory() ) { |
| // Passed in a fromDir with a filename on the end - strip it |
| f = f.getParentFile(); |
| } |
| f = f.getCanonicalFile(); |
| f = f.getParentFile(); |
| boolean found = false; |
| while ( f != null && !found ) |
| { |
| for ( int i = 0; i < parents.size(); ++i ) |
| { |
| File parent = (File) parents.get( i ); |
| if ( f.equals( parent ) ) |
| { |
| // when we find the common parent, add the subdirectories |
| // down to toDir itself |
| for ( int j = 0; j < i; ++j ) |
| { |
| File p = (File) parents.get( j ); |
| toLink.insert( 0, p.getName() + "/" ); |
| } |
| found = true; |
| break; |
| } |
| } |
| f = f.getParentFile(); |
| fromLink.append( "../" ); |
| } |
| |
| if ( !found ) |
| { |
| throw new FileNotFoundException( fromDir + " and " + toDir + " have no common parent." ); |
| } |
| |
| return fromLink.append( toLink.toString() ).toString(); |
| } |
| |
| public void setExcludes( String[] excludes ) |
| { |
| this.excludes = excludes; |
| } |
| |
| |
| public void setIncludes( String[] includes ) |
| { |
| if ( includes == null ) |
| { |
| // We should not include non-java files, so we use a sensible default pattern |
| this.includes = DEFAULT_INCLUDES; |
| } |
| else |
| { |
| this.includes = includes; |
| } |
| } |
| } |