View Javadoc

1   /*
2    * Copyright 2007 scala-tools.org
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *    http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing,
11   * software distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions
14   * and limitations under the License.
15   */
16  package org.scala_tools.maven;
17  
18  import java.io.File;
19  import java.io.IOException;
20  import java.util.Calendar;
21  import java.util.Locale;
22  
23  import org.apache.maven.reporting.MavenReport;
24  import org.apache.maven.reporting.MavenReportException;
25  import org.codehaus.doxia.sink.Sink;
26  import org.codehaus.plexus.util.StringUtils;
27  
28  /**
29   * Produces Scala API documentation.
30   *
31   * @goal doc
32   * @requiresDependencyResolution compile
33   */
34  public class ScalaDocMojo extends ScalaMojoSupport implements MavenReport {
35      /**
36       * Specify window title of generated HTML documentation.
37       *
38       * @parameter expression="${windowtitle}"
39       *            default-value="${project.name} ${project.version} API"
40       */
41      protected String windowtitle;
42  
43      /**
44       * Specifies the text to be placed at the bottom of each output file. If you
45       * want to use html you have to put it in a CDATA section, eg.
46       * <![CDATA[Copyright 2005, <a
47       * href="http://www.mycompany.com">MyCompany, Inc.<a>]]>
48       *
49       * @parameter expression="${bottom}"
50       *            default-value="Copyright (c) {inceptionYear}-{currentYear} {organizationName}. All Rights Reserved."
51       */
52      protected String bottom;
53  
54      /**
55       * Charset for cross-platform viewing of generated documentation.
56       *
57       * @parameter expression="${charset}" default-value="ISO-8859-1"
58       */
59      protected String charset;
60  
61      /**
62       * Include title for the overview page.
63       *
64       * @parameter expression="${doctitle}"
65       *            default-value="${project.name} ${project.version} API"
66       */
67      protected String doctitle;
68  
69      /**
70       * Include footer text for each page.
71       *
72       * @parameter expression="${footer}"
73       */
74      protected String footer;
75  
76      /**
77       * Include header text for each page
78       *
79       * @parameter expression="${header}"
80       */
81      protected String header;
82  
83      /**
84       * Generate source in HTML
85       *
86       * @parameter expression="${linksource}" default="true"
87       */
88      protected boolean linksource;
89  
90      /**
91       * Suppress description and tags, generate only declarations
92       *
93       * @parameter expression="${nocomment}" default="false"
94       */
95      protected boolean nocomment;
96  
97      /**
98       * File to change style of the generated documentation
99       *
100      * @parameter expression="${stylesheetfile}"
101      */
102     protected File stylesheetfile;
103 
104     /**
105      * Include top text for each page
106      *
107      * @parameter expression="${top}"
108      */
109     protected String top;
110 
111     /**
112      * @parameter expression="${project.build.sourceDirectory}/../scala"
113      */
114     protected File sourceDir;
115 
116     /**
117      * Specifies the destination directory where scalaDoc saves the generated
118      * HTML files.
119      *
120      * @parameter expression="scaladocs"
121      * @required
122      */
123     private String outputDirectory;
124 
125     /**
126      * Specifies the destination directory where javadoc saves the generated HTML files.
127      *
128      * @parameter expression="${project.reporting.outputDirectory}/scaladocs"
129      * @required
130      */
131     private File reportOutputDirectory;
132 
133     /**
134      * The name of the Scaladoc report.
135      *
136      * @since 2.1
137      * @parameter expression="${name}" default-value="ScalaDocs"
138      */
139     private String name;
140 
141     /**
142      * The description of the Scaladoc report.
143      *
144      * @since 2.1
145      * @parameter expression="${description}" default-value="ScalaDoc API
146      *            documentation."
147      */
148     private String description;
149 
150     /**
151      * className (FQN) of the main scaladoc to use, if not define, the the scalaClassName is used
152      *
153      * @parameter expression="${maven.scaladoc.className}"
154      */
155     protected String scaladocClassName;
156 
157     /**
158      * If you want to use vscaladoc to generate api instead of regular scaladoc, set the version of vscaladoc you want to use.
159      *
160      * @parameter expression="${maven.scaladoc.vscaladocVersion}"
161      */
162     protected String vscaladocVersion;
163 
164 
165     private String[] sourceFiles_ = null;
166     private String[] findSourceFiles() {
167         if (sourceFiles_ == null) {
168             sourceFiles_ = JavaCommand.findFiles(sourceDir, "**/*.scala");
169         }
170         return sourceFiles_;
171     }
172 
173     public boolean canGenerateReport() {
174         try {
175             sourceDir = sourceDir.getCanonicalFile();
176         } catch (IOException exc) {
177             sourceDir = sourceDir.getAbsoluteFile();
178         }
179         return sourceDir.exists() && (findSourceFiles().length != 0);
180     }
181 
182     public boolean isExternalReport() {
183         return true;
184     }
185 
186     public String getCategoryName() {
187         return CATEGORY_PROJECT_REPORTS;
188     }
189 
190     public String getDescription(Locale locale) {
191         if (StringUtils.isEmpty(description)) {
192             return "ScalaDoc API documentation";
193         }
194         return description;
195     }
196 
197     public String getName(Locale locale) {
198         if (StringUtils.isEmpty(name)) {
199             return "ScalaDocs";
200         }
201         return name;
202     }
203 
204     public String getOutputName() {
205         return outputDirectory + "/index";
206     }
207 
208     public File getReportOutputDirectory() {
209         if (reportOutputDirectory == null) {
210             reportOutputDirectory = new File(project.getReporting().getOutputDirectory(), outputDirectory);
211         }
212         return reportOutputDirectory;
213     }
214 
215     public void setReportOutputDirectory(File reportOutputDirectory) {
216         this.reportOutputDirectory = new File(reportOutputDirectory, outputDirectory);
217     }
218 
219     @Override
220     public void doExecute() throws Exception {
221         // SiteRendererSink sink = siteRenderer.createSink(new
222         // File(project.getReporting().getOutputDirectory(), getOutputName() +
223         // ".html");
224         generate(null, Locale.getDefault());
225     }
226 
227 
228     @Override
229     protected JavaCommand getScalaCommand() throws Exception {
230         String oldClazz = scalaClassName;
231         boolean isPreviousScala271 = (new VersionNumber("2.7.1").compareTo(new VersionNumber(scalaVersion)) > 0);
232         if (!isPreviousScala271) {
233             scalaClassName = "scala.tools.nsc.ScalaDoc";
234         }
235         if (StringUtils.isNotEmpty(scaladocClassName)) {
236             scalaClassName = scaladocClassName;
237         }
238         JavaCommand cmd = getEmptyScalaCommand(scalaClassName);
239         cmd.addArgs(args);
240         cmd.addJvmArgs(jvmArgs);
241         if (isPreviousScala271){
242             cmd.addArgs("-Ydoc");
243         }
244         scalaClassName = oldClazz;
245         return cmd;
246     }
247 
248     @SuppressWarnings("unchecked")
249     public void generate(Sink sink, Locale locale) throws MavenReportException {
250         try {
251             if (!canGenerateReport()) {
252                 getLog().warn("No source files found in " + sourceDir);
253                 return;
254             }
255 
256             File reportOutputDir = getReportOutputDirectory();
257             if (!reportOutputDir.exists()) {
258                 reportOutputDir.mkdirs();
259             }
260             if (StringUtils.isNotEmpty(vscaladocVersion)) {
261                 scaladocClassName = "org.scala_tools.vscaladoc.Main";
262                 BasicArtifact artifact = new BasicArtifact();
263                 artifact.artifactId = "vscaladoc";
264                 artifact.groupId = "org.scala-tools";
265                 artifact.version = vscaladocVersion;
266                 dependencies = new BasicArtifact[]{artifact};
267             }
268             JavaCommand jcmd = getScalaCommand();
269             jcmd.addOption("-classpath", JavaCommand.toMultiPath(project.getCompileClasspathElements()));
270             jcmd.addOption("-d", reportOutputDir.getAbsolutePath());
271             jcmd.addOption("-sourcepath", sourceDir.getAbsolutePath());
272             jcmd.addOption("-bottom", getBottomText());
273             jcmd.addOption("-charset", charset);
274             jcmd.addOption("-doctitle", doctitle);
275             jcmd.addOption("-footer", footer);
276             jcmd.addOption("-header", header);
277             jcmd.addOption("-linksource", linksource);
278             jcmd.addOption("-nocomment", nocomment);
279             jcmd.addOption("-stylesheetfile", stylesheetfile);
280             jcmd.addOption("-top", top);
281             jcmd.addOption("-windowtitle", windowtitle);
282             for (String x : findSourceFiles()) {
283                 jcmd.addArgs(sourceDir + File.separator + x);
284             }
285             jcmd.run(displayCmd);
286         } catch (MavenReportException exc) {
287             throw exc;
288         } catch (RuntimeException exc) {
289             throw exc;
290         } catch (Exception exc) {
291             throw new MavenReportException("wrap: " + exc.getMessage(), exc);
292         }
293     }
294 
295     /**
296      * Method that sets the bottom text that will be displayed on the bottom of
297      * the javadocs.
298      *
299      * @param inceptionYear the year when the project was started
300      * @return a String that contains the text that will be displayed at the
301      *         bottom of the javadoc
302      */
303     private String getBottomText() {
304         String inceptionYear = project.getInceptionYear();
305         int actualYear = Calendar.getInstance().get(Calendar.YEAR);
306         String year = String.valueOf(actualYear);
307 
308         String theBottom = StringUtils.replace(bottom, "{currentYear}", year);
309 
310         if (inceptionYear != null) {
311             if (inceptionYear.equals(year)) {
312                 theBottom = StringUtils.replace(theBottom, "{inceptionYear}-", "");
313             } else {
314                 theBottom = StringUtils.replace(theBottom, "{inceptionYear}", inceptionYear);
315             }
316         } else {
317             theBottom = StringUtils.replace(theBottom, "{inceptionYear}-", "");
318         }
319 
320         if (project.getOrganization() == null) {
321             theBottom = StringUtils.replace(theBottom, " {organizationName}", "");
322         } else {
323             if ((project.getOrganization() != null) && (StringUtils.isNotEmpty(project.getOrganization().getName()))) {
324                 if (StringUtils.isNotEmpty(project.getOrganization().getUrl())) {
325                     theBottom = StringUtils.replace(theBottom, "{organizationName}", "<a href=\"" + project.getOrganization().getUrl() + "\">" + project.getOrganization().getName() + "</a>");
326                 } else {
327                     theBottom = StringUtils.replace(theBottom, "{organizationName}", project.getOrganization().getName());
328                 }
329             } else {
330                 theBottom = StringUtils.replace(theBottom, " {organizationName}", "");
331             }
332         }
333 
334         return theBottom;
335     }
336 }