View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.jxr;
20  
21  import java.io.IOException;
22  import java.nio.file.Path;
23  import java.nio.file.Paths;
24  import java.util.List;
25  import java.util.Locale;
26  
27  import org.apache.maven.jxr.ant.DirectoryScanner;
28  import org.apache.maven.jxr.pacman.PackageManager;
29  import org.slf4j.Logger;
30  import org.slf4j.LoggerFactory;
31  
32  /**
33   * Main entry point into Maven used to kick off the XReference code building.
34   *
35   * @author <a href="mailto:burton@apache.org">Kevin A. Burton</a>
36   */
37  public class JXR {
38      private static final Logger LOGGER = LoggerFactory.getLogger(JXR.class);
39  
40      private final PackageManager pkgmgr;
41  
42      /**
43       * Handles taking .java files and changing them into html. "More than meets
44       * the eye!" :)
45       */
46      private final JavaCodeTransform transformer;
47  
48      /**
49       * The default list of include patterns to use.
50       */
51      private static final String[] DEFAULT_INCLUDES = {"**/*.java"};
52  
53      /**
54       * Path to destination.
55       */
56      private Path destDir;
57  
58      private Locale locale;
59  
60      private String inputEncoding;
61  
62      private String outputEncoding;
63  
64      /**
65       * Relative path to javadocs, suitable for hyperlinking.
66       */
67      private Path javadocLinkDir;
68  
69      /**
70       * The revision of the module currently being processed.
71       */
72      private String revision;
73  
74      /**
75       * The list of exclude patterns to use.
76       */
77      private String[] excludes = null;
78  
79      /**
80       * The list of include patterns to use.
81       */
82      private String[] includes = DEFAULT_INCLUDES;
83  
84      public JXR(PackageManager pkgmgr, JavaCodeTransform transformer) {
85          this.pkgmgr = pkgmgr;
86          this.transformer = transformer;
87      }
88  
89      /**
90       * Now that we have instantiated everything. Process this JXR task.
91       *
92       * @param packageManager package manager
93       * @param sourceDir source directory.
94       * @param bottom bottom text
95       * @throws IOException on transformation error
96       */
97      public void processPath(PackageManager packageManager, Path sourceDir, String bottom) throws IOException {
98          DirectoryScanner ds = new DirectoryScanner();
99          // I'm not sure why we don't use the directoryScanner in packageManager,
100         // but since we don't we need to set includes/excludes here as well
101         ds.setExcludes(excludes);
102         ds.setIncludes(includes);
103         ds.addDefaultExcludes();
104 
105         ds.setBasedir(sourceDir.toString());
106         ds.scan();
107 
108         // now get the list of included files
109 
110         String[] files = ds.getIncludedFiles();
111 
112         for (String file : files) {
113             Path sourceFile = sourceDir.resolve(file);
114 
115             if (isJavaFile(sourceFile.toString())) {
116                 String newFileName = file.replaceFirst(".java$", ".html");
117 
118                 transform(sourceFile, this.destDir.resolve(newFileName), bottom);
119             }
120         }
121     }
122 
123     /**
124      * Check to see if the file is a Java source file.
125      *
126      * @param filename The name of the file to check
127      * @return {@code true} if the file is a Java file
128      */
129     public static boolean isJavaFile(String filename) {
130         return filename.endsWith(".java");
131     }
132 
133     /**
134      * Checks to see if the file is an HTML file.
135      *
136      * @param filename The name of the file to check
137      * @return {@code true} if the file is an HTML file
138      */
139     public static boolean isHtmlFile(String filename) {
140         return filename.endsWith(".html");
141     }
142 
143     /**
144      * Sets the destination.
145      *
146      * @param dest destination
147      */
148     public void setDest(Path dest) {
149         this.destDir = dest;
150     }
151 
152     /**
153      * Sets the locale.
154      *
155      * @param locale locale
156      */
157     public void setLocale(Locale locale) {
158         this.locale = locale;
159     }
160 
161     /**
162      * Sets the input encoding.
163      *
164      * @param inputEncoding input encoding
165      */
166     public void setInputEncoding(String inputEncoding) {
167         this.inputEncoding = inputEncoding;
168     }
169 
170     /**
171      * Sets the output encoding.
172      *
173      * @param outputEncoding output encoding
174      */
175     public void setOutputEncoding(String outputEncoding) {
176         this.outputEncoding = outputEncoding;
177     }
178 
179     /**
180      * Sets the relative path to javadocs.
181      * @param javadocLinkDir path to javadocs
182      */
183     public void setJavadocLinkDir(Path javadocLinkDir) {
184         // get a relative link to the javadocs
185         this.javadocLinkDir = javadocLinkDir;
186     }
187 
188     /**
189      * Sets the revision.
190      *
191      * @param revision revision
192      */
193     public void setRevision(String revision) {
194         this.revision = revision;
195     }
196 
197     /**
198      * Performs the cross-referencing.
199      *
200      * @param sourceDirs source directories
201      * @param templateDir template directory
202      * @param windowTitle window title
203      * @param docTitle document title
204      * @param bottom bottom text
205      * @throws IOException on I/O error
206      * @throws JxrException on Velocity error
207      */
208     public void xref(List<String> sourceDirs, String templateDir, String windowTitle, String docTitle, String bottom)
209             throws IOException, JxrException {
210         pkgmgr.setExcludes(excludes);
211         pkgmgr.setIncludes(includes);
212 
213         // go through each source directory and xref the java files
214         for (String dir : sourceDirs) {
215             Path path = Paths.get(dir).toRealPath();
216 
217             pkgmgr.process(path);
218 
219             processPath(pkgmgr, path, bottom);
220         }
221 
222         // once we have all the source files xref'd, create the index pages
223         DirectoryIndexer indexer = new DirectoryIndexer(pkgmgr, destDir.toString());
224         indexer.setOutputEncoding(outputEncoding);
225         indexer.setTemplateDir(templateDir);
226         indexer.setWindowTitle(windowTitle);
227         indexer.setDocTitle(docTitle);
228         indexer.setBottom(bottom);
229         indexer.process();
230     }
231 
232     // ----------------------------------------------------------------------
233     // private methods
234     // ----------------------------------------------------------------------
235     /**
236      * Given a source file transform it into HTML and write it to the
237      * destination (dest) file.
238      *
239      * @param sourceFile The java source file
240      * @param destFile The directory to put the HTML into
241      * @param bottom The bottom footer text just as in the package pages
242      * @throws IOException if the transform can't happen for some reason
243      */
244     private void transform(Path sourceFile, Path destFile, String bottom) throws IOException {
245         LOGGER.debug(sourceFile + " -> " + destFile);
246 
247         // get a relative link to the javadocs
248         Path javadoc = javadocLinkDir != null ? getRelativeLink(destFile.getParent(), javadocLinkDir) : null;
249         transformer.transform(
250                 sourceFile, destFile, locale, inputEncoding, outputEncoding, javadoc, this.revision, bottom);
251     }
252 
253     /**
254      * Creates a relative link from one directory to another.
255      *
256      * Example:
257      * given {@code /foo/bar/baz/oink}
258      * and {@code /foo/bar/schmoo}
259      *
260      * this method will return a string of {@code "../../schmoo/"}
261      *
262      * @param fromDir The directory from which the link is relative.
263      * @param toDir The directory into which the link points.
264      * @return a String of format {@code "../../schmoo/"}
265      */
266     private static Path getRelativeLink(Path fromDir, Path toDir) {
267         return fromDir.relativize(toDir);
268     }
269 
270     public void setExcludes(String[] excludes) {
271         this.excludes = excludes;
272     }
273 
274     public void setIncludes(String[] includes) {
275         if (includes == null) {
276             // We should not include non-java files, so we use a sensible default pattern
277             this.includes = DEFAULT_INCLUDES;
278         } else {
279             this.includes = includes;
280         }
281     }
282 }