View Javadoc

1   package org.apache.maven.jxr;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.maven.jxr.ant.DirectoryScanner;
23  import org.apache.maven.jxr.log.Log;
24  import org.apache.maven.jxr.pacman.FileManager;
25  import org.apache.maven.jxr.pacman.PackageManager;
26  
27  import java.io.File;
28  import java.io.FileNotFoundException;
29  import java.io.IOException;
30  import java.util.Iterator;
31  import java.util.LinkedList;
32  import java.util.List;
33  import java.util.Locale;
34  
35  /**
36   * Main entry point into Maven used to kick off the XReference code building.
37   *
38   * @author <a href="mailto:burton@apache.org">Kevin A. Burton</a>
39   * @version $Id: JXR.java 692692 2008-09-06 17:34:46Z hboutemy $
40   */
41  public class JXR
42  {
43      /**
44       * The Log.
45       */
46      private Log log;
47  
48      /**
49       * Description of the Notice.
50       */
51      public static final String NOTICE = "This page was automatically generated by "
52          + "<a href=\"http://maven.apache.org/\">Maven</a>";
53  
54      /**
55       * The default list of include patterns to use.
56       */
57      private static final String[] DEFAULT_INCLUDES = {"**/*.java"};
58  
59      /**
60       * Path to destination.
61       */
62      private String dest = "";
63  
64      private Locale locale;
65  
66      private String inputEncoding;
67  
68      private String outputEncoding;
69  
70      /**
71       * Relative path to javadocs, suitable for hyperlinking.
72       */
73      private String javadocLinkDir;
74  
75      /**
76       * Handles taking .java files and changing them into html. "More than meets
77       * the eye!" :)
78       */
79      private JavaCodeTransform transformer;
80  
81      /**
82       * The revision of the module currently being processed.
83       */
84      private String revision;
85  
86      /**
87       * The list of exclude patterns to use.
88       */
89      private String[] excludes = null;
90  
91      /**
92       * The list of include patterns to use.
93       */
94      private String[] includes = DEFAULT_INCLUDES;
95  
96      /**
97       * Now that we have instantiated everything. Process this JXR task.
98       *
99       * @param packageManager
100      * @param source
101      * @throws IOException
102      */
103     public void processPath( PackageManager packageManager, String source )
104         throws IOException
105     {
106         this.transformer = new JavaCodeTransform( packageManager );
107 
108         DirectoryScanner ds = new DirectoryScanner();
109         // I'm not sure why we don't use the directoryScanner in packageManager,
110         // but since we don't we need to set includes/excludes here as well
111         ds.setExcludes( excludes );
112         ds.setIncludes( includes );
113         ds.addDefaultExcludes();
114 
115         File dir = new File( source );
116 
117         if ( !dir.exists() )
118         {
119             if ( !dir.mkdirs() )
120             {
121                 throw new IllegalStateException(
122                     "Your source directory does not exist and could not be created:" + source );
123             }
124         }
125 
126         ds.setBasedir( source );
127         ds.scan();
128 
129         //now get the list of included files
130 
131         String[] files = ds.getIncludedFiles();
132 
133         for ( int i = 0; i < files.length; ++i )
134         {
135             String src = source + System.getProperty( "file.separator" ) + files[i];
136 
137             if ( isJavaFile( src ) )
138             {
139                 transform( src, getDestination( source, src ) );
140             }
141 
142         }
143     }
144 
145     /**
146      * Check to see if the file is a Java source file.
147      *
148      * @param filename The name of the file to check
149      * @return <code>true</true> if the file is a Java file
150      */
151     public static boolean isJavaFile( String filename )
152     {
153         File file = new File( filename );
154         return filename.endsWith( ".java" ) && file.length() > 0;
155     }
156 
157     /**
158      * Check to see if the file is an HTML file.
159      *
160      * @param filename The name of the file to check
161      * @return <code>true</true> if the file is an HTML file
162      */
163     public static boolean isHtmlFile( String filename )
164     {
165         return filename.endsWith( ".html" );
166     }
167 
168     /**
169      * Get the path to the destination files.
170      *
171      * @return The path to the destination files
172      */
173     public String getDest()
174     {
175         return this.dest;
176     }
177 
178     /**
179      * @param dest
180      */
181     public void setDest( String dest )
182     {
183         this.dest = dest;
184     }
185 
186     /**
187      * @param locale
188      */
189     public void setLocale( Locale locale )
190     {
191         this.locale = locale;
192     }
193 
194     /**
195      * @param inputEncoding
196      */
197     public void setInputEncoding( String inputEncoding )
198     {
199         this.inputEncoding = inputEncoding;
200     }
201 
202     /**
203      * @param outputEncoding
204      */
205     public void setOutputEncoding( String outputEncoding )
206     {
207         this.outputEncoding = outputEncoding;
208     }
209 
210     /**
211      * @param javadocLinkDir
212      */
213     public void setJavadocLinkDir( String javadocLinkDir )
214     {
215         // get a relative link to the javadocs
216         this.javadocLinkDir = javadocLinkDir;
217     }
218 
219     /**
220      * @param transformer
221      */
222     public void setTransformer( JavaCodeTransform transformer )
223     {
224         this.transformer = transformer;
225     }
226 
227     /**
228      * @param revision
229      */
230     public void setRevision( String revision )
231     {
232         this.revision = revision;
233     }
234 
235     /**
236      * @param log
237      */
238     public void setLog( Log log )
239     {
240         this.log = log;
241     }
242 
243     /**
244      * @param sourceDirs
245      * @param templateDir
246      * @param windowTitle
247      * @param docTitle
248      * @param bottom
249      * @throws IOException
250      * @throws JxrException
251      */
252     public void xref( List sourceDirs, String templateDir, String windowTitle, String docTitle, String bottom )
253         throws IOException, JxrException
254     {
255         // first collect package and class info
256         FileManager fileManager = new FileManager();
257         fileManager.setEncoding( inputEncoding );
258 
259         PackageManager pkgmgr = new PackageManager( log, fileManager );
260         pkgmgr.setExcludes( excludes );
261         pkgmgr.setIncludes( includes );
262 
263         // go through each source directory and xref the java files
264         for ( Iterator i = sourceDirs.iterator(); i.hasNext(); )
265         {
266             String path = (String) i.next();
267             path = new File( path ).getCanonicalPath();
268 
269             pkgmgr.process( path );
270 
271             processPath( pkgmgr, path );
272         }
273 
274         // once we have all the source files xref'd, create the index pages
275         DirectoryIndexer indexer = new DirectoryIndexer( pkgmgr, dest );
276         indexer.setOutputEncoding( outputEncoding );
277         indexer.setTemplateDir( templateDir );
278         indexer.setWindowTitle( windowTitle );
279         indexer.setDocTitle( docTitle );
280         indexer.setBottom( bottom );
281         indexer.process( log );
282     }
283 
284     // ----------------------------------------------------------------------
285     // private methods
286     // ----------------------------------------------------------------------
287 
288     /**
289      * Given a filename get the destination on the filesystem of where to store
290      * the to be generated HTML file. Pay attention to the package name.
291      *
292      * @param source
293      * @param filename
294      * @return A String with the store destination.
295      */
296     private String getDestination( String source, String filename )
297     {
298         //remove the source directory from the filename.
299 
300         String dest = filename.substring( source.length(), filename.length() );
301 
302         int start = 0;
303         int end = dest.indexOf( ".java" );
304 
305         if ( end != -1 )
306         {
307             //remove the .java from the filename
308             dest = dest.substring( start, end );
309         }
310 
311         //add the destination directory to the filename.
312         dest = this.getDest() + dest;
313 
314         //add .html to the filename
315 
316         dest = dest + ".html";
317 
318         return dest;
319     }
320 
321     /**
322      * Given a source file transform it into HTML and write it to the
323      * destination (dest) file.
324      *
325      * @param source The java source file
326      * @param dest The directory to put the HTML into
327      * @throws IOException Thrown if the transform can't happen for some reason.
328      */
329     private void transform( String source, String dest )
330         throws IOException
331     {
332         log.debug( source + " -> " + dest );
333 
334         // get a relative link to the javadocs
335         String javadoc = javadocLinkDir != null ? getRelativeLink( dest, javadocLinkDir ) : null;
336         transformer.transform( source, dest, locale, inputEncoding, outputEncoding, javadoc, this.revision );
337     }
338 
339     /**
340      * Creates a relative link from one directory to another.
341      *
342      * Example:
343      * given <code>/foo/bar/baz/oink</code>
344      * and <code>/foo/bar/schmoo</code>
345      *
346      * this method will return a string of <code>"../../schmoo/"</code>
347      *
348      * @param fromDir The directory from which the link is relative.
349      * @param toDir The directory into which the link points.
350      * @return a String of format <code>"../../schmoo/"</code>
351      * @throws java.io.IOException If a problem is encountered while navigating through the directories.
352      */
353     private static String getRelativeLink( String fromDir, String toDir )
354         throws IOException
355     {
356         StringBuffer toLink = new StringBuffer();   // up from fromDir
357         StringBuffer fromLink = new StringBuffer(); // down into toDir
358 
359         // create a List of toDir's parent directories
360         List parents = new LinkedList();
361         File f = new File( toDir );
362         f = f.getCanonicalFile();
363         while ( f != null )
364         {
365             parents.add( f );
366             f = f.getParentFile();
367         }
368 
369         // walk up fromDir to find the common parent
370         f = new File( fromDir );
371         if ( !f.isDirectory() )
372         {
373             // Passed in a fromDir with a filename on the end - strip it
374             f = f.getParentFile();
375         }
376         f = f.getCanonicalFile();
377         f = f.getParentFile();
378         boolean found = false;
379         while ( f != null && !found )
380         {
381             for ( int i = 0; i < parents.size(); ++i )
382             {
383                 File parent = (File) parents.get( i );
384                 if ( f.equals( parent ) )
385                 {
386                     // when we find the common parent, add the subdirectories
387                     // down to toDir itself
388                     for ( int j = 0; j < i; ++j )
389                     {
390                         File p = (File) parents.get( j );
391                         toLink.insert( 0, p.getName() + "/" );
392                     }
393                     found = true;
394                     break;
395                 }
396             }
397             f = f.getParentFile();
398             fromLink.append( "../" );
399         }
400 
401         if ( !found )
402         {
403             throw new FileNotFoundException( fromDir + " and " + toDir + " have no common parent." );
404         }
405 
406         return fromLink.append( toLink.toString() ).toString();
407     }
408 
409     public void setExcludes( String[] excludes )
410     {
411         this.excludes = excludes;
412     }
413 
414 
415     public void setIncludes( String[] includes )
416     {
417         if ( includes == null )
418         {
419             // We should not include non-java files, so we use a sensible default pattern
420             this.includes = DEFAULT_INCLUDES;
421         }
422         else
423         {
424             this.includes = includes;
425         }
426     }
427 }