View Javadoc

1   /*
2    * @(#)$Id: AbstractJavafxdocMojo.java 69 2010-05-13 14:21:43Z nderwin $
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, software
11   * 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 and
14   * limitations under the License.
15   * under the License.
16   */
17  
18  package net.sf.jfxdplugin;
19  
20  import java.io.File;
21  import java.io.FileNotFoundException;
22  import java.io.IOException;
23  import java.text.MessageFormat;
24  import java.util.ArrayList;
25  import java.util.Arrays;
26  import java.util.Collection;
27  import java.util.Collections;
28  import java.util.HashMap;
29  import java.util.List;
30  import java.util.Locale;
31  import java.util.Map;
32  import java.util.Properties;
33  import java.util.ResourceBundle;
34  import java.util.regex.PatternSyntaxException;
35  import org.apache.commons.lang.SystemUtils;
36  import org.apache.maven.artifact.Artifact;
37  import org.apache.maven.artifact.versioning.ArtifactVersion;
38  import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
39  import org.apache.maven.execution.MavenSession;
40  import org.apache.maven.plugin.AbstractMojo;
41  import org.apache.maven.project.MavenProject;
42  import org.apache.maven.reporting.MavenReportException;
43  import org.apache.maven.toolchain.Toolchain;
44  import org.apache.maven.toolchain.ToolchainManager;
45  import org.codehaus.plexus.util.FileUtils;
46  import org.codehaus.plexus.util.ReaderFactory;
47  import org.codehaus.plexus.util.StringUtils;
48  import org.codehaus.plexus.util.cli.CommandLineException;
49  import org.codehaus.plexus.util.cli.CommandLineUtils;
50  import org.codehaus.plexus.util.cli.Commandline;
51  import org.codehaus.plexus.util.cli.DefaultConsumer;
52  
53  /**
54   * Base class for the Javafxdoc mojo.  This class contains the majority of the
55   * mojo functionality.
56   * <p>
57   * Based on the Maven Javadoc Plugin version 2.6.
58   *
59   * @author Nathan Erwin
60   * @author <a href="mailto:brett@apache.org">Brett Porter</a>
61   * @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a>
62   * @version $Revision: 69 $ $Date: 2010-05-13 10:21:43 -0400 (Thu, 13 May 2010) $
63   * @since 1.0
64   * @see <a href="http://maven.apache.org/plugins/maven-javadoc-plugin/">
65   * http://maven.apache.org/plugins/maven-javadoc-plugin/</a>
66   * @requiresDependencyResolution compile
67   */
68  public abstract class AbstractJavafxdocMojo extends AbstractMojo {
69  
70      /**
71       * The default Javafxdoc API URLs according to the
72       * <a href="http://java.sun.com/reference/api/index.html">Sun/Oracle API
73       * Specifications</a>.
74       * <pre>
75       * &lt;javaFXApiLinks&gt;
76       *   &lt;property&gt;
77       *     &lt;name&gt;api_1.0&lt;/name&gt;
78       *     &lt;value&gt;http://java.sun.com/javafx/1/docs/api/&lt;/value&gt;
79       *   &lt;/property&gt;
80       *   &lt;property&gt;
81       *     &lt;name&gt;api_1.1&lt;/name&gt;
82       *     &lt;value&gt;http://java.sun.com/javafx/1.1/docs/api/&lt;/value&gt;
83       *   &lt;/property&gt;
84       *   &lt;property&gt;
85       *     &lt;name&gt;api_1.2&lt;/name&gt;
86       *     &lt;value&gt;http://java.sun.com/javafx/1.2/docs/api/&lt;/value&gt;
87       *   &lt;/property&gt;
88       *   &lt;property&gt;
89       *     &lt;name&gt;api_1.3&lt;/name&gt;
90       *     &lt;value&gt;http://java.sun.com/javafx/1.3/docs/api/&lt;/value&gt;
91       * &lt;/javaFXApiLinks&gt;
92       * </pre>
93       */
94      public static final Properties DEFAULT_JAVA_API_LINKS = new Properties();
95      /**
96       * The Javafxdoc script file name when the <code>debug</code> parameter is
97       * on, i.e. javafxdoc.bat or javafxdoc.sh.
98       */
99      protected static final String DEBUG_JAVAFXDOC_SCRIPT_NAME;
100 
101     static {
102         String name = "javafxdoc.sh";
103 
104         if (SystemUtils.IS_OS_WINDOWS) {
105             name = "javafxdoc.bat";
106         }
107 
108         DEBUG_JAVAFXDOC_SCRIPT_NAME = name;
109     }
110     /**
111      * The <code>files</code> file name in the output directory when calling
112      * <code>javafxdoc.exe(or .sh) [&#x40;options] [packagenames] [sourcefiles]
113      * [&#x40;files]</code>.
114      */
115     protected static final String FILES_FILE_NAME = "files";
116     /**
117      * The <code>options</code> file name in the output directory when calling
118      * <code>javafxdoc.exe(or .sh) [&#x40;options] [packagenames] [sourcefiles]
119      * [&#x40;files]</code>.
120      */
121     protected static final String OPTIONS_FILE_NAME = "options";
122     /**
123      * The default JavaFX version (1.0) to use if no other viable version can be
124      * found.
125      */
126     protected static final float DEFAULT_JAVAFX_VERSION = 1.0f;
127     /**
128      * For Javafxdoc options that appear since JavaFX 1.3.
129      */
130     protected static final float SINCE_JAVAFXDOC_1_3 = 1.3f;
131     /** @component */
132     private ToolchainManager toolchainManager;
133     // Mojo parameters in alphabetical order
134     /**
135      * Set this to 'true' to debug the Javafxdoc plugin. With this,
136      * the execution script and 'files' files are provided.
137      * <br/>
138      *
139      * @parameter expression="${debug}" default-value="false"
140      */
141     private boolean debug = false;
142     /**
143      * Specifies whether the build will continue even if there are errors.
144      *
145      * @parameter expression="${failOnError}" default-value="false"
146      */
147     private boolean failOnError = false;
148     /**
149      * Sets the absolute path of the Javafxdoc Tool executable to use. A mere
150      * directory specification is sufficient to have the plugin use "javafxdoc"
151      * or "javafxdoc.exe" respectively from this directory.
152      *
153      * @parameter expression="${javafxdocExecutable}"
154      */
155     private String javafxdocExecutable;
156     /**
157      * The Maven Project Object.
158      *
159      * @parameter expression="${project}"
160      * @required
161      * @readonly
162      */
163     private MavenProject project;
164     /**
165      * The current build session instance. This is used for
166      * toolchain manager API calls.
167      *
168      * @parameter expression="${session}"
169      * @required
170      * @readonly
171      */
172     private MavenSession session;
173     //
174     // Javafxdoc parameters in alphabetical order
175     //
176     /**
177      * Passes the specified flag directly to the runtime system.
178      * Example:
179      * <pre>
180      * &lt;additionalJOptions&gt;
181      *  &lt;additionalJOption&gt;-Xss128m&lt;/additionalJOption&gt;
182      * &lt;/additionalJOptions&gt;
183      * </pre>
184      *
185      * @parameter
186      */
187     private String[] additionalJOptions;
188     /**
189      * Specifies the paths where the boot classes reside.  The paths
190      * are separated with a colon (<code>:</code>) on Solaris and a semi-colon
191      * (<code>;</code>) on Windows.
192      *
193      * @parameter expression="${bootclasspath}"
194      */
195     private String bootclasspath;
196     /**
197      * Uses the sentence break iterator to determine the end of the first
198      * sentence.
199      *
200      * @parameter expression="${breakiterator}" default-value="false"
201      */
202     private boolean breakiterator = false;
203     /**
204      * Specifies the class file that starts the doclet used in generating the
205      * documentation.
206      *
207      * @parameter expression="${doclet}"
208      */
209     private String doclet;
210     /**
211      * Specifies the path to the doclet starting class file (specified with
212      * the <code>-doclet</code> option) and any jar files it depends on.
213      *
214      * @parameter expression="${docletPath}"
215      */
216     private String docletPath;
217     /**
218      * Specifies the encoding name of the source files.  If not specificed, the
219      * encoding value will be the value of the
220      * <code>project.build.sourceEncoding</code> property.
221      *
222      * @parameter expression="${encoding}" default-value="${project.build.sourceEncoding}"
223      */
224     private String encoding;
225     /**
226      * Unconditionally excludes the specified packages and their subpackages.
227      * Multiple packages can be separated by colons (<code>:</code>).
228      *
229      * @parameter expression="${excludePackageNames}"
230      */
231     private String excludePackageNames;
232     /**
233      * Specifies the directories where extension classes reside.  Separate
234      * directories in dirlist with a colon (<code>:</code>) on Solaris and a
235      * semi-colon (<code>;</code>) on Windows.
236      *
237      * @parameter expression="${extdirs}"
238      */
239     private String extdirs;
240     /**
241      * Specifies the locale that javafxdoc uses when generating documentation.
242      *
243      * @parameter expression="${locale}"
244      */
245     private String locale;
246     /**
247      * Specifies the JavaFX platform.  Valid values are "desktop" (default),
248      * "mobile", or "tv" (as of JavaFX 1.3).
249      *
250      * @parameter expression="${profile}" default-value="desktop"
251      */
252     private String profile = "desktop";
253     /**
254      * Shuts off status messages.  Maybe.
255      *
256      * @parameter expression="${quiet}" default-value="false"
257      */
258     private boolean quiet = false;
259     /**
260      * Specifies the access level for classes and members to show in the
261      * JavaFXDocs. Possible values are
262      * <ul>
263      * <li>public (Show only public classes and members)</li>
264      * <li>protected (Show protected/public classes and members (default))</li>
265      * <li>package (Show package/protected/public classes and members)</li>
266      * <li>private (Show all classes and members)</li>
267      * </ul>
268      * <br/>
269      *
270      * @parameter expression="${show}" default-value="protected"
271      */
272     private String show = "protected";
273     /**
274      * Provides source compatability with the specified release.
275      *
276      * @parameter expression="${source}"
277      */
278     private String source;
279     /**
280      * Specifies the source paths where the subpackages are located.  The paths
281      * are separated with a colon (<code>:</code>) on Solaris and a semi-colon
282      * (<code>;</code>) on Windows.
283      *
284      * @parameter expression="${sourcePath}"
285      */
286     private String sourcePath;
287     /**
288      * Generates documentation from source files in the specified packages and
289      * recursively in their subpackages.
290      *
291      * @parameter expression="${subpackages}"
292      */
293     private String subpackages;
294     /**
295      * Provides more detailed messages while Javafxdoc is running.
296      *
297      * @parameter expression="${verbose}" default-value="false"
298      */
299     private boolean verbose = false;
300     //
301     // Standard doclet parameters in alphabetical order
302     //
303     /**
304      * Prevents generating the HTML files for the documentation.
305      *
306      * @parameter expression="${nohtml}" default-value="false"
307      */
308     private boolean nohtml = false;
309     /**
310      * Specifies the destination directory where javafxdoc saves the generated
311      * HTML files.
312      *
313      * @parameter expression="${outputDirectory}" default-value="${project.build.directory}/apidocs"
314      */
315     private File outputDirectory;
316     /**
317      * Specifies the XML output file.
318      *
319      * @parameter expression="${outputFile}"
320      */
321     private File outputFile;
322     /**
323      * Specifies the XSL file to use for transforming the documentation.
324      *
325      * @parameter expression="${xsltfile}"
326      */
327     private File xsltfile;
328     /**
329      * Specifies the master CSS file for the HTML output.
330      *
331      * @parameter expression="${mastercss}"
332      */
333     private String mastercss;
334     /**
335      * Specifies an additional CSS file for the HTML output.
336      *
337      * @parameter expression="${extracss}"
338      */
339     private String extracss;
340     /**
341      * Specifies an additional JavaScript file for the HTML output.
342      *
343      * @parameter expression="${extrajs}"
344      */
345     private String extrajs;
346     /**
347      * Passes the specified xsl parameter to the xsl transformer.
348      * Example:
349      * <pre>
350      * &lt;additionalXslOptions&gt;
351      *  &lt;additionalXslOption&gt;extra-js=xtra.js&lt;/additionalXslOption&gt;
352      * &lt;/additionalXslOptions&gt;
353      * </pre>
354      *
355      * @parameter
356      */
357     private String[] additionalXslOptions;
358     /**
359      * Specifies additional XML input files that contain package/class
360      * information to be transformed into the HTML output.
361      *
362      * @parameter
363      */
364     private File[] inputFiles;
365     private Locale cachedLocale;
366     private float javafxdocVersion = DEFAULT_JAVAFX_VERSION;
367 
368     /**
369      * Returns the additional -J option value.
370      *
371      * @return the additional -J option value
372      */
373     public String[] getAdditionalJOptions() {
374         return additionalJOptions;
375     }
376 
377     /**
378      * Specifies the additional -J option value.
379      *
380      * @param additionalJOptions the additional -J option value
381      */
382     public void setAdditionalJOptions(final String[] additionalJOptions) {
383         this.additionalJOptions = additionalJOptions;
384     }
385 
386     /**
387      * Returns the additional Xsl options value.
388      *
389      * @return the additional Xsl options value
390      */
391     public String[] getAdditionalXslOptions() {
392         return additionalXslOptions;
393     }
394 
395     /**
396      * Specifies the additional Xsl option value.
397      *
398      * @param additionalXslOptions the additional Xsl option value
399      */
400     public void setAdditionalXslOptions(final String[] additionalXslOptions) {
401         this.additionalXslOptions = additionalXslOptions;
402     }
403 
404     /**
405      * Returns the boot class path.
406      *
407      * @return the boot class path
408      */
409     public String getBootclasspath() {
410         return bootclasspath;
411     }
412 
413     /**
414      * Specifies the boot class path.
415      *
416      * @param bootclasspath the boot class path
417      */
418     public void setBootclasspath(final String bootclasspath) {
419         this.bootclasspath = bootclasspath;
420     }
421 
422     /**
423      * Returns whether the sentence break iterator is used.
424      *
425      * @return whether the sentence break iterator is used
426      */
427     public boolean isBreakiterator() {
428         return breakiterator;
429     }
430 
431     /**
432      * Specifies whether the sentence break iterator is used.
433      *
434      * @param breakiterator whether the sentence break iterator is used
435      */
436     public void setBreakiterator(final boolean breakiterator) {
437         this.breakiterator = breakiterator;
438     }
439 
440     /**
441      * Returns whether the plugin is in debug mode.
442      *
443      * @return whether the plugin is in debug mode
444      */
445     public boolean isDebug() {
446         return debug;
447     }
448 
449     /**
450      * Specifies whether the plugin is in debug mode.
451      *
452      * @param debug whether the plugin is in debug mode
453      */
454     public void setDebug(final boolean debug) {
455         this.debug = debug;
456     }
457 
458     /**
459      * Returns the doclet for HTML generation.
460      *
461      * @return the doclet for HTML generation
462      */
463     public String getDoclet() {
464         return doclet;
465     }
466 
467     /**
468      * Specifies the doclet for HTML generation.
469      *
470      * @param doclet the doclet for HTML generation
471      */
472     public void setDoclet(final String doclet) {
473         this.doclet = doclet;
474     }
475 
476     /**
477      * Returns the path to the doclet for HTML generation.
478      *
479      * @return the path to the doclet for HTML generation
480      */
481     public String getDocletPath() {
482         return docletPath;
483     }
484 
485     /**
486      * Specifies the path to the doclet for HTML generation.
487      *
488      * @param docletPath the path to the doclet for HTML generation
489      */
490     public void setDocletPath(final String docletPath) {
491         this.docletPath = docletPath;
492     }
493 
494     /**
495      * Returns the output encoding.
496      *
497      * @return the output encoding
498      */
499     public String getEncoding() {
500         return encoding;
501     }
502 
503     /**
504      * Specifies the output encoding.
505      *
506      * @param encoding the output encoding
507      */
508     public void setEncoding(final String encoding) {
509         this.encoding = encoding;
510     }
511 
512     /**
513      * Returns the list of package names to exclude.
514      *
515      * @return the list of package names to exclude
516      */
517     public String getExcludePackageNames() {
518         return excludePackageNames;
519     }
520 
521     /**
522      * Specifies the list of package names to exclude.
523      *
524      * @param excludePackageNames the list of package names to exclude
525      */
526     public void setExcludePackageNames(final String excludePackageNames) {
527         this.excludePackageNames = excludePackageNames;
528     }
529 
530     /**
531      * Returns the extension directories.
532      *
533      * @return the extension directories
534      */
535     public String getExtdirs() {
536         return extdirs;
537     }
538 
539     /**
540      * Specifies the extension directories.
541      *
542      * @param extdirs the extension directories
543      */
544     public void setExtdirs(final String extdirs) {
545         this.extdirs = extdirs;
546     }
547 
548     /**
549      * Returns the extra CSS file to use.
550      *
551      * @return the extra CSS file to use
552      */
553     public String getExtracss() {
554         return extracss;
555     }
556 
557     /**
558      * Specifies the extra CSS file to use.
559      *
560      * @param extracss the extra CSS file to use
561      */
562     public void setExtracss(final String extracss) {
563         this.extracss = extracss;
564     }
565 
566     /**
567      * Returns the extra JavaScript file to use.
568      *
569      * @return the extra JavaScript file to use
570      */
571     public String getExtrajs() {
572         return extrajs;
573     }
574 
575     /**
576      * Specifies the extra JavaScript file to use.
577      *
578      * @param extrajs the extra JavaScript file to use
579      */
580     public void setExtrajs(final String extrajs) {
581         this.extrajs = extrajs;
582     }
583 
584     /**
585      * Returns whether the plugin fails on errors.
586      *
587      * @return whether the plugin fails on errors
588      */
589     public boolean isFailOnError() {
590         return failOnError;
591     }
592 
593     /**
594      * Specifies whether the plugin fails on errors.
595      *
596      * @param failOnError whether the plugin fails on errors
597      */
598     public void setFailOnError(final boolean failOnError) {
599         this.failOnError = failOnError;
600     }
601 
602     /**
603      * Returns the XML input file.
604      *
605      * @return the XML input file
606      */
607     public File[] getInputFiles() {
608         return inputFiles;
609     }
610 
611     /**
612      * Specifies the XML input file.
613      *
614      * @param inputFiles the XML input file
615      */
616     public void setInputFiles(final File[] inputFiles) {
617         this.inputFiles = inputFiles;
618     }
619 
620     /**
621      * Returns the location of the Javafxdoc executable.
622      *
623      * @return the location of the Javafxdoc executable
624      */
625     public String getJavafxdocExecutable() {
626         return javafxdocExecutable;
627     }
628 
629     /**
630      * Specifies the location of the Javafxdoc executable.
631      *
632      * @param javafxdocExecutable the location of the Javafxdoc executable
633      */
634     public void setJavafxdocExecutable(final String javafxdocExecutable) {
635         this.javafxdocExecutable = javafxdocExecutable;
636     }
637 
638     /**
639      * Returns the documentation locale.
640      *
641      * @return the documentation locale
642      */
643     public String getLocale() {
644         if (null == locale) {
645             locale = Locale.getDefault().toString();
646         }
647         return locale;
648     }
649 
650     /**
651      * Specifies the documentation locale.
652      *
653      * @param locale the documentation locale
654      */
655     public void setLocale(final String locale) {
656         this.locale = locale;
657         this.cachedLocale = null;
658     }
659 
660     /**
661      * Returns the location of the master CSS file.
662      *
663      * @return the location of the master CSS file
664      */
665     public String getMastercss() {
666         return mastercss;
667     }
668 
669     /**
670      * Specifies the location of the master CSS file.
671      *
672      * @param mastercss the location of the master CSS file
673      */
674     public void setMastercss(final String mastercss) {
675         this.mastercss = mastercss;
676     }
677 
678     /**
679      * Returns whether HTML files are generated.
680      *
681      * @return whether HTML files are generated
682      */
683     public boolean isNohtml() {
684         return nohtml;
685     }
686 
687     /**
688      * Specifies whether HTML files are generated.
689      *
690      * @param nohtml whether HTML files are generated
691      */
692     public void setNohtml(final boolean nohtml) {
693         this.nohtml = nohtml;
694     }
695 
696     /**
697      * Returns the output directory for the plugin.
698      *
699      * @return the output directory for the plugin
700      */
701     public File getOutputDirectory() {
702         return outputDirectory;
703     }
704 
705     /**
706      * Specifies the output directory for the plugin.
707      *
708      * @param outputDirectory the output directory for the plugin
709      */
710     public void setOutputDirectory(final File outputDirectory) {
711         this.outputDirectory = outputDirectory;
712     }
713 
714     /**
715      * Returns the XML output file.
716      *
717      * @return the XML output file
718      */
719     public File getOutputFile() {
720         return outputFile;
721     }
722 
723     /**
724      * Specifies the XML output file.
725      *
726      * @param outputFile the XML output file
727      */
728     public void setOutputFile(final File outputFile) {
729         this.outputFile = outputFile;
730     }
731 
732     /**
733      * Returns the Maven project object.
734      *
735      * @return the Maven project object
736      */
737     public MavenProject getProject() {
738         return project;
739     }
740 
741     /**
742      * Specifies the Maven project object.
743      *
744      * @param project the Maven project object
745      */
746     public void setProject(final MavenProject project) {
747         this.project = project;
748     }
749 
750     /**
751      * Returns the JavaFX platform name.
752      *
753      * @return the JavaFX platform name
754      */
755     public String getProfile() {
756         return profile;
757     }
758 
759     /**
760      * Specifies the JavaFX platform name (desktop, mobile, tv).
761      *
762      * @param profile the JavaFX platform name
763      */
764     public void setProfile(String profile) {
765         if ("desktop".equals(profile)) {
766             this.profile = profile;
767         } else if ("mobile".equals(profile)) {
768             this.profile = profile;
769         } else if ("tv".equals(profile)) {
770             this.profile = profile;
771         }
772     }
773 
774     /**
775      * Returns whether the plugin operates in quiet mode.
776      *
777      * @return whether the plugin operates in quiet mode
778      */
779     public boolean isQuiet() {
780         return quiet;
781     }
782 
783     /**
784      * Specifies whether the plugin operates in quiet mode.
785      *
786      * @param quiet whether the plugin operates in quiet mode
787      */
788     public void setQuiet(final boolean quiet) {
789         this.quiet = quiet;
790     }
791 
792     /**
793      * Returns the Maven session object.
794      *
795      * @return the Maven session object
796      */
797     public MavenSession getSession() {
798         return session;
799     }
800 
801     /**
802      * Returns the visibility level to show in the documentation.
803      *
804      * @return the visibility level to show in the documentation
805      */
806     public String getShow() {
807         return show;
808     }
809 
810     /**
811      * Specifies the visibility level to show in the documentation.
812      *
813      * @param show the visibility level to show in the documentation
814      */
815     public void setShow(final String show) {
816         this.show = show;
817     }
818 
819     /**
820      * Returns the version of the source code.
821      *
822      * @return the version of the source code
823 
824      */
825     public String getSource() {
826         return source;
827     }
828 
829     /**
830      * Specifies the version of the source code.
831      *
832      * @param source the version of the source code
833      */
834     public void setSource(final String source) {
835         this.source = source;
836     }
837 
838     /**
839      * Returns the path to the source code.
840      *
841      * @return the path to the source code
842      */
843     public String getSourcePath() {
844         return sourcePath;
845     }
846 
847     /**
848      * Specifies the path to the source code.
849      *
850      * @param sourcePath the path to the source code
851      */
852     public void setSourcePath(final String sourcePath) {
853         this.sourcePath = sourcePath;
854     }
855 
856     /**
857      * Returns the sub packages to document.
858      *
859      * @return the sub packages to document
860      */
861     public String getSubpackages() {
862         return subpackages;
863     }
864 
865     /**
866      * Specifies the sub packages to document.
867      *
868      * @param subpackages the sub packages to document
869      */
870     public void setSubpackages(final String subpackages) {
871         this.subpackages = subpackages;
872     }
873 
874     /**
875      * Returns the toolchain manager.
876      *
877      * @return the toolchain manager
878      */
879     protected ToolchainManager getToolchainManager() {
880         return toolchainManager;
881     }
882 
883     /**
884      * Specifies the toolchain manager.
885      *
886      * @param toolchainManager the toolchain manager
887      */
888     protected void setToolchainManager(
889             final ToolchainManager toolchainManager) {
890         this.toolchainManager = toolchainManager;
891     }
892 
893     /**
894      * Returns whether the plugin operates in verbose mode.
895      *
896      * @return whether the plugin operates in verbose mode
897      */
898     public boolean isVerbose() {
899         return verbose;
900     }
901 
902     /**
903      * Specifies whether the plugin operates in verbose mode.
904      *
905      * @param verbose whether the plugin operates in verbose mode
906      */
907     public void setVerbose(final boolean verbose) {
908         this.verbose = verbose;
909     }
910 
911     /**
912      * Returns the XSL transformation file.
913      *
914      * @return the XSL transformation file
915      */
916     public File getXsltfile() {
917         return xsltfile;
918     }
919 
920     /**
921      * Specifies the XSL transformation file.
922      *
923      * @param xsltfile the XSL transformation file
924      */
925     public void setXsltfile(final File xsltfile) {
926         this.xsltfile = xsltfile;
927     }
928 
929     /**
930      * Method that indicates whether the javafxdoc can be generated or not.
931      * If the project does not contain any source files and no subpackages are
932      * specified, the plugin will terminate.
933      *
934      * @param files the project files
935      * @return a boolean that indicates whether javafxdoc report can be
936      * generated or not
937      */
938     protected boolean canGenerateReport(final List<String> files) {
939         boolean canGenerate = true;
940 
941         if ((files.isEmpty()) && (StringUtils.isEmpty(getSubpackages()))) {
942             canGenerate = false;
943         }
944 
945         return canGenerate;
946     }
947 
948     /**
949      * Runs the report for the given parameters.
950      *
951      * @throws MavenReportException if problems are found during generation
952      */
953     protected void executeReport() throws MavenReportException {
954         List<String> sourcePaths = getSourcePaths();
955         List<String> files = getFiles(sourcePaths);
956         if (!canGenerateReport(files)) {
957             return;
958         }
959 
960         List<String> packageNames = getPackageNames(sourcePaths, files);
961         List<String> filesWithUnnamedPackages =
962                 getFilesWithUnnamedPackages(sourcePaths, files);
963 
964         // find the javafxdoc executable
965         String jExecutable;
966         try {
967             jExecutable = findJavafxdocExecutable();
968         } catch (IOException ex) {
969             throw new MavenReportException(ex.getMessage(), ex);
970         }
971 
972         // set the JavaFX version
973         setJavafxdocVersion(new File(jExecutable));
974 
975         // set up the output directory
976         if (getOutputDirectory().exists()) {
977             if (!getOutputDirectory().isDirectory()) {
978                 throw new MavenReportException(formatMessage(
979                         "report.javafxdoc.not.directory",
980                         getOutputDirectory()));
981             }
982             if (!getOutputDirectory().canWrite()) {
983                 throw new MavenReportException(formatMessage(
984                         "report.javafxdoc.not.writable", getOutputDirectory()));
985             }
986         }
987         getOutputDirectory().mkdirs();
988 
989         // create command line for Javafxdoc
990         Commandline cmd = new Commandline();
991         cmd.getShell().setQuotedArgumentsEnabled(false);
992         cmd.setWorkingDirectory(getOutputDirectory().getAbsolutePath());
993         cmd.setExecutable(jExecutable);
994 
995         // -J flag won't work in the options file
996         if (null != getAdditionalJOptions()) {
997             for (String opt : getAdditionalJOptions()) {
998                 cmd.createArg().setValue("-J" + opt);
999             }
1000         }
1001 
1002         // kind of a hack...  but "-profile blah" doesn't always work...
1003         cmd.createArg().setValue("-profile");
1004         if ((getJavafxdocVersion() < SINCE_JAVAFXDOC_1_3) && "tv".equals(
1005                 getProfile())) {
1006             cmd.createArg().setValue("desktop");
1007         } else {
1008             cmd.createArg().setValue(getProfile());
1009         }
1010 
1011         List<String> arguments = new ArrayList<String>();
1012 
1013         // wrap Javafxdoc options
1014         addJavafxdocOptions(arguments, sourcePaths);
1015 
1016         // wrap Standard doclet Options
1017         if (StringUtils.isEmpty(doclet)) {
1018             addStandardDocletOptions(arguments, getOutputDirectory());
1019         }
1020 
1021         addCommandLineOptions(cmd, arguments, getOutputDirectory());
1022 
1023         // write packages in the command line
1024         if (!packageNames.isEmpty()) {
1025             // write argfile file and include it in the command line
1026             addCommandLineArgFile(cmd, getOutputDirectory(),
1027                     filesWithUnnamedPackages);
1028         } else {
1029             // write argfile file and include it in the command line
1030             addCommandLineArgFile(cmd, getOutputDirectory(), files);
1031         }
1032 
1033         // Execute command line
1034         executeJavafxdocCommandLine(cmd, getOutputDirectory());
1035     }
1036 
1037     /**
1038      * Formats the messages from the resource bundle with the given arguments.
1039      *
1040      * @param message the message key in the resource bundle
1041      * @param args variable list of arguments to the message
1042      * @return a string containing the formatted message
1043      */
1044     protected String formatMessage(final String message, final Object... args) {
1045         String msg = getBundle(getLocaleObject()).getString(message);
1046         MessageFormat formatter = new MessageFormat("", getLocaleObject());
1047         formatter.applyPattern(msg);
1048         return formatter.format(args);
1049     }
1050 
1051     /**
1052      * Gets the resource bundle for the specified locale.
1053      *
1054      * @param specificLocale the locale of the currently generated report
1055      * @return the resource bundle for the requested locale
1056      */
1057     protected ResourceBundle getBundle(final Locale specificLocale) {
1058         Locale localeToUse = specificLocale;
1059 
1060         if (null == specificLocale) {
1061             localeToUse = Locale.getDefault();
1062         }
1063 
1064         return ResourceBundle.getBundle("javafxdoc-report", localeToUse,
1065                 getClass().getClassLoader());
1066     }
1067 
1068     /**
1069      * Method to get the files on the specified source paths.
1070      *
1071      * @param sourcePaths a List that contains the paths to the source files
1072      * @return a List that contains the specific path for every source file
1073      */
1074     protected List<String> getFiles(final List<String> sourcePaths) {
1075         List<String> files = new ArrayList<String>();
1076 
1077         if (StringUtils.isEmpty(getSubpackages())) {
1078             String[] excludedPackages = getExcludedPackages();
1079 
1080             for (String path : sourcePaths) {
1081                 File sourceDirectory = new File(path);
1082                 JavafxdocUtil.addFilesFromSource(files, sourceDirectory,
1083                         excludedPackages);
1084             }
1085         }
1086 
1087         return files;
1088     }
1089 
1090     /**
1091      * Returns the javafxdoc tool version.
1092      *
1093      * @return the javafxdoc tool version
1094      */
1095     protected float getJavafxdocVersion() {
1096         return javafxdocVersion;
1097     }
1098 
1099     /**
1100      * Constructs a Locale object from the specified <code>locale</code>.
1101      *
1102      * @return a Locale object based on the <code>locale</code> parameter
1103      * @see AbstractJavafxdocMojo#setLocale(java.lang.String)
1104      */
1105     protected Locale getLocaleObject() {
1106         if (null == cachedLocale) {
1107             String result[] = getLocale().split("_");
1108 
1109             String language = result[0];
1110 
1111             String country = "";
1112             if (result.length > 1) {
1113                 country = result[1];
1114             }
1115 
1116             String variant = "";
1117             if (result.length > 2) {
1118                 variant = result[2];
1119             }
1120 
1121             cachedLocale = new Locale(language, country, variant);
1122         }
1123 
1124         return cachedLocale;
1125     }
1126 
1127     /**
1128      * Returns the artifacts for the project.
1129      *
1130      * @param p the Maven project
1131      * @return the project artifacts
1132      */
1133     @SuppressWarnings("unchecked")
1134     protected List<Artifact> getProjectArtifacts(final MavenProject p) {
1135         return p.getCompileArtifacts();
1136     }
1137 
1138     /**
1139      * Method to get the source paths.  If no source path is specified in the
1140      * parameter, the compile source roots of the project will be used.
1141      *
1142      * @return a List of the project absolute source paths
1143      * @see JavafxdocUtil#pruneDirs(org.apache.maven.project.MavenProject,
1144      * java.util.List)
1145      */
1146     protected List<String> getSourcePaths() {
1147         List<String> sourcePaths;
1148 
1149         if (StringUtils.isEmpty(getSourcePath())) {
1150             sourcePaths = new ArrayList<String>(JavafxdocUtil.pruneDirs(
1151                     getProject(),
1152                     getProjectSourceRoots(getProject())));
1153 
1154             if (null != getProject().getExecutionProject()) {
1155                 sourcePaths.addAll(JavafxdocUtil.pruneDirs(getProject(),
1156                         getExecutionProjectSourceRoots(getProject())));
1157             }
1158         } else {
1159             String separator = "[:]";
1160             if (SystemUtils.IS_OS_WINDOWS) {
1161                 separator = "[;]";
1162             }
1163             sourcePaths = new ArrayList<String>(Arrays.asList(getSourcePath().
1164                     split(separator)));
1165         }
1166 
1167         sourcePaths = JavafxdocUtil.pruneDirs(getProject(), sourcePaths);
1168 
1169         return sourcePaths;
1170     }
1171 
1172     private void addArgIf(final List<String> arguments, final boolean b,
1173             final String value) {
1174         if (b) {
1175             arguments.add(value);
1176         }
1177     }
1178 
1179     private void addArgIfNotEmpty(final List<String> arguments,
1180             final String key, final String value) {
1181         if (StringUtils.isNotEmpty(value)) {
1182             if (StringUtils.isNotEmpty(key)) {
1183                 arguments.add(key);
1184             }
1185 
1186             String[] result = value.split(",");
1187             for (String token : result) {
1188                 token = token.trim();
1189 
1190                 if (StringUtils.isNotEmpty(token)) {
1191                     arguments.add(token);
1192                 }
1193             }
1194         }
1195     }
1196 
1197     private void addCommandLineArgFile(final Commandline cmd,
1198             final File outputDir, final List<String> files) throws
1199             MavenReportException {
1200         File argfileFile = new File(outputDir, FILES_FILE_NAME);
1201 
1202         try {
1203             FileUtils.fileWrite(argfileFile.getAbsolutePath(),
1204                     StringUtils.join(files.iterator(),
1205                     SystemUtils.LINE_SEPARATOR));
1206         } catch (IOException ex) {
1207             throw new MavenReportException(
1208                     formatMessage("report.javafxdoc.tempfile.write.fail",
1209                     argfileFile.getName()), ex);
1210         }
1211 
1212         cmd.createArg().setValue("@" + FILES_FILE_NAME);
1213 
1214         if (!isDebug()) {
1215             argfileFile.deleteOnExit();
1216         }
1217     }
1218 
1219     private void addCommandLineOptions(final Commandline cmd,
1220             final List<String> arguments, final File javadocOutputDirectory)
1221             throws MavenReportException {
1222         File optionsFile = new File(javadocOutputDirectory, OPTIONS_FILE_NAME);
1223 
1224         StringBuilder options = new StringBuilder();
1225         options.append(StringUtils.join(arguments.toArray(new String[0]),
1226                 SystemUtils.LINE_SEPARATOR));
1227 
1228         try {
1229             FileUtils.fileWrite(optionsFile.getAbsolutePath(),
1230                     StringUtils.join(arguments.iterator(),
1231                     SystemUtils.LINE_SEPARATOR));
1232         } catch (IOException ex) {
1233             throw new MavenReportException(
1234                     formatMessage("report.javafxdoc.tempfile.write.fail",
1235                     optionsFile.getName()), ex);
1236         }
1237 
1238         cmd.createArg().setValue("@" + OPTIONS_FILE_NAME);
1239 
1240         if (!isDebug()) {
1241             optionsFile.deleteOnExit();
1242         }
1243     }
1244 
1245     private void addJavafxdocOptions(final List<String> arguments,
1246             final List<String> sourcePaths) throws MavenReportException {
1247         validateJavafxdocOptions();
1248 
1249         // locale must be the first argument otherwise javafxdoc complains
1250         addArgIfNotEmpty(arguments, "-locale", getLocale());
1251 
1252         addArgIfNotEmpty(arguments, "-bootclasspath",
1253                 JavafxdocUtil.quotedPathArgument(getBootclasspath()));
1254 
1255         addArgIf(arguments, isBreakiterator(), "-breakiterator");
1256 
1257         addArgIfNotEmpty(arguments, "-classpath",
1258                 JavafxdocUtil.quotedPathArgument(getClassPath()));
1259 
1260         if (StringUtils.isNotEmpty(getDoclet())) {
1261             addArgIfNotEmpty(arguments, "-doclet",
1262                     JavafxdocUtil.quotedArgument(getDoclet()));
1263             addArgIfNotEmpty(arguments, "-docletpath",
1264                     JavafxdocUtil.quotedPathArgument(getDocletPath()));
1265         }
1266 
1267         if (StringUtils.isEmpty(getEncoding())) {
1268             getLog().warn(formatMessage("report.javafxdoc.encoding.warning",
1269                     ReaderFactory.FILE_ENCODING));
1270         }
1271         addArgIfNotEmpty(arguments, "-encoding", getEncoding());
1272 
1273         addArgIfNotEmpty(arguments, "-exclude",
1274                 getExcludedPackages(sourcePaths));
1275 
1276         addArgIfNotEmpty(arguments, "-extdirs",
1277                 JavafxdocUtil.quotedPathArgument(getExtdirs()));
1278 
1279         // "-public" || "-protected" || "-package" || "-private"
1280         addArgIf(arguments, StringUtils.isNotEmpty(getAccessLevel()),
1281                 getAccessLevel());
1282 
1283         addArgIf(arguments, isQuiet(), "-quiet");
1284 
1285         addArgIfNotEmpty(arguments, "-source", JavafxdocUtil.quotedArgument(
1286                 getSource()));
1287 
1288         if ((StringUtils.isEmpty(getSourcePath()))
1289                 && (StringUtils.isNotEmpty(getSubpackages()))) {
1290             setSourcePath(StringUtils.join(sourcePaths.iterator(),
1291                     File.pathSeparator));
1292         }
1293         if (StringUtils.isNotEmpty(getSourcePath())) {
1294             addArgIfNotEmpty(arguments, "-sourcepath",
1295                     JavafxdocUtil.quotedPathArgument(
1296                     buildSourcePath(sourcePaths)));
1297             addArgIfNotEmpty(arguments, "-subpackages", getSubpackages());
1298         }
1299 
1300         addArgIf(arguments, isVerbose(), "-verbose");
1301     }
1302 
1303     private void addStandardDocletOptions(final List<String> arguments,
1304             final File outputDir) {
1305 
1306         addArgIfNotEmpty(arguments, "-d",
1307                 JavafxdocUtil.quotedPathArgument(outputDir.toString()));
1308 
1309         addArgIfNotEmpty(arguments, "-extracss", JavafxdocUtil.
1310                 quotedPathArgument(getExtracss()));
1311 
1312         addArgIfNotEmpty(arguments, "-extrajs", JavafxdocUtil.
1313                 quotedPathArgument(getExtrajs()));
1314 
1315         if (null != getInputFiles()) {
1316             for (File file : getInputFiles()) {
1317                 addArgIfNotEmpty(arguments, "-i", JavafxdocUtil.
1318                         quotedPathArgument(file.toString()));
1319             }
1320         }
1321 
1322         addArgIfNotEmpty(arguments, "-mastercss", JavafxdocUtil.
1323                 quotedPathArgument(getMastercss()));
1324 
1325         addArgIf(arguments, isNohtml(), "-nohtml");
1326 
1327         if (null != getOutputFile()) {
1328             addArgIfNotEmpty(arguments, "-o",
1329                     JavafxdocUtil.quotedPathArgument(
1330                     getOutputFile().toString()));
1331         }
1332 
1333         if (null != getAdditionalXslOptions()) {
1334             for (String opt : getAdditionalXslOptions()) {
1335                 addArgIfNotEmpty(arguments, "-xsl:", opt);
1336             }
1337         }
1338 
1339         if (null != getXsltfile()) {
1340             addArgIfNotEmpty(arguments, "-xsltfile", JavafxdocUtil.
1341                     quotedPathArgument(getXsltfile().getAbsolutePath()));
1342         }
1343     }
1344 
1345     private String buildSourcePath(final List<String> sourcePaths) {
1346         String srcPath = null;
1347 
1348         if ((StringUtils.isEmpty(getSubpackages()))
1349                 || (StringUtils.isNotEmpty(getSourcePath()))) {
1350             srcPath = StringUtils.join(sourcePaths.iterator(),
1351                     File.pathSeparator);
1352         }
1353 
1354         return srcPath;
1355     }
1356 
1357     private void executeJavafxdocCommandLine(final Commandline cmd,
1358             final File outputDir) throws MavenReportException {
1359         String cmdLine = CommandLineUtils.toString(cmd.getCommandline()).
1360                 replaceAll("'", "");
1361 
1362         getLog().debug(cmdLine);
1363 
1364         if (isDebug()) {
1365             File commandLineFile = new File(outputDir,
1366                     DEBUG_JAVAFXDOC_SCRIPT_NAME);
1367             try {
1368                 FileUtils.fileWrite(commandLineFile.getAbsolutePath(), cmdLine);
1369 
1370                 if (!SystemUtils.IS_OS_WINDOWS) {
1371                     Runtime.getRuntime().exec(new String[]{
1372                                 "chmod",
1373                                 "a+x",
1374                                 commandLineFile.getAbsolutePath()
1375                             });
1376                 }
1377             } catch (IOException ex) {
1378                 throw new MavenReportException(
1379                         formatMessage("report.javafxdoc.debug.write.fail",
1380                         commandLineFile.getName()), ex);
1381             }
1382         }
1383 
1384         CommandLineUtils.StringStreamConsumer err =
1385                 new CommandLineUtils.StringStreamConsumer();
1386         try {
1387             int exitCode = CommandLineUtils.executeCommandLine(cmd,
1388                     new DefaultConsumer(), err);
1389 
1390             if (0 != exitCode) {
1391                 throw new MavenReportException(
1392                         formatMessage("report.javafxdoc.execution.fail",
1393                         exitCode, err.getOutput(), cmdLine));
1394             }
1395         } catch (CommandLineException ex) {
1396             throw new MavenReportException(
1397                     formatMessage("report.javafxdoc.execution.exception",
1398                     ex.getMessage()), ex);
1399         }
1400 
1401         if (StringUtils.isNotEmpty(err.getOutput())) {
1402             getLog().warn(formatMessage("report.javafxdoc.warnings"));
1403 
1404             String result[] = err.getOutput().split("\n");
1405             for (String token : result) {
1406                 getLog().warn(token.trim());
1407             }
1408         }
1409     }
1410 
1411     private String findJavafxdocExecutable() throws IOException {
1412         Toolchain tc = getToolchain();
1413 
1414         if (tc != null) {
1415             getLog().info(formatMessage("report.javafxdoc.toolchain.info", tc));
1416             if (getJavafxdocExecutable() != null) {
1417                 getLog().warn(
1418                         formatMessage("report.javafxdoc.toolchain.ignored",
1419                         getJavafxdocExecutable()));
1420             } else {
1421                 setJavafxdocExecutable(tc.findTool("javafxdoc"));
1422             }
1423         }
1424 
1425         String javafxdocCommand = "javafxdoc";
1426         if (SystemUtils.IS_OS_WINDOWS) {
1427             javafxdocCommand = javafxdocCommand + ".exe";
1428         }
1429 
1430         File javafxdocExe = null;
1431 
1432         // user defined javafxdoc
1433         if (StringUtils.isNotEmpty(getJavafxdocExecutable())) {
1434             javafxdocExe = new File(getJavafxdocExecutable());
1435 
1436             if (javafxdocExe.isDirectory()) {
1437                 javafxdocExe = new File(javafxdocExe, javafxdocCommand);
1438             }
1439 
1440             if (SystemUtils.IS_OS_WINDOWS
1441                     && javafxdocExe.getName().indexOf('.') < 0) {
1442                 javafxdocExe = new File(javafxdocExe.getPath() + ".exe");
1443             }
1444 
1445             if (!javafxdocExe.isFile()) {
1446                 throw new IOException(
1447                         formatMessage("report.javafxdoc.no.executable",
1448                         javafxdocExe));
1449             }
1450 
1451             return javafxdocExe.getAbsolutePath();
1452         }
1453 
1454         // try to find it from the JAVAFX_HOME environment variable
1455         Properties env = CommandLineUtils.getSystemEnvVars();
1456         String javafxHome = env.getProperty("JAVAFX_HOME");
1457 
1458         if (StringUtils.isEmpty(javafxHome)) {
1459             throw new IOException(formatMessage(
1460                     "report.javafxdoc.no.javafx.home"));
1461         }
1462 
1463         File homeFile = new File(javafxHome);
1464         if ((!homeFile.exists()) || (!homeFile.isDirectory())) {
1465             throw new IOException(formatMessage(
1466                     "report.javafxdoc.invalid.javafx.home", javafxHome));
1467         }
1468 
1469         javafxdocExe = new File(javafxHome + File.separator + "bin",
1470                 javafxdocCommand);
1471 
1472         if ((!javafxdocExe.exists()) || (!javafxdocExe.isFile())) {
1473             throw new IOException(
1474                     formatMessage("report.javafxdoc.invalid.executable",
1475                     javafxdocExe));
1476         }
1477 
1478         return javafxdocExe.getAbsolutePath();
1479     }
1480 
1481     private String getAccessLevel() {
1482         String accessLevel = "-protected";
1483         if ("public".equalsIgnoreCase(getShow())
1484                 || "protected".equalsIgnoreCase(getShow())
1485                 || "package".equalsIgnoreCase(getShow())
1486                 || "private".equalsIgnoreCase(getShow())) {
1487             accessLevel = "-" + getShow().toLowerCase();
1488         } else {
1489             getLog().error(formatMessage(
1490                     "report.javafxdoc.illegal.access.level", getShow()));
1491         }
1492 
1493         return accessLevel;
1494     }
1495 
1496     private String getClassPath() throws MavenReportException {
1497         List<File> classpathElements = new ArrayList<File>();
1498         Map<String, Artifact> compileArtifactMap =
1499                 new HashMap<String, Artifact>();
1500 
1501         classpathElements.addAll(getProjectBuildOutputDirs(getProject()));
1502 
1503         populateCompileArtifactMap(compileArtifactMap, getProjectArtifacts(
1504                 getProject()));
1505 
1506         for (String key : compileArtifactMap.keySet()) {
1507             Artifact a = compileArtifactMap.get(key);
1508             classpathElements.add(a.getFile());
1509         }
1510 
1511         // try to add in the jars in the SDK lib directory
1512         try {
1513             Properties env = CommandLineUtils.getSystemEnvVars();
1514             String javafxHome = env.getProperty("JAVAFX_HOME");
1515             File libDir = new File(javafxHome + File.separator + "lib");
1516             if ((libDir.exists()) && (libDir.isDirectory())) {
1517                 for (File f : libDir.listFiles()) {
1518                     if ((f.isFile()) && (f.getName().toLowerCase().endsWith(
1519                             ".jar"))) {
1520                         classpathElements.add(f);
1521                     } else {
1522                         if (f.isDirectory()) {
1523                             for (File sf : f.listFiles()) {
1524                                 if ((sf.isFile()) && (sf.getName().
1525                                         toLowerCase().endsWith(".jar"))) {
1526                                     classpathElements.add(sf);
1527                                 }
1528                             }
1529                         }
1530                     }
1531                 }
1532             }
1533         } catch (IOException ex) {
1534             // don't fail the process, just log it and move on
1535             getLog().error(ex.getMessage());
1536         }
1537 
1538         return StringUtils.join(classpathElements.iterator(),
1539                 File.pathSeparator);
1540     }
1541 
1542     private String[] getExcludedPackages() {
1543         String[] excludePackages = {};
1544 
1545         if (getExcludePackageNames() != null) {
1546             excludePackages = getExcludePackageNames().split("[ ,:;]");
1547         }
1548         for (int i = 0; i < excludePackages.length; i++) {
1549             excludePackages[i] = excludePackages[i].replace('.',
1550                     File.separatorChar);
1551         }
1552 
1553         return excludePackages;
1554     }
1555 
1556     private String getExcludedPackages(final List<String> sourcePaths) {
1557         List<String> excludedNames = null;
1558 
1559         if (StringUtils.isNotEmpty(getSourcePath()) && StringUtils.isNotEmpty(
1560                 getSubpackages())) {
1561             String[] excludedPackages = getExcludedPackages();
1562             String[] subpackagesList = subpackages.split("[:]");
1563 
1564             excludedNames = JavafxdocUtil.getExcludedNames(sourcePaths,
1565                     subpackagesList, excludedPackages);
1566         }
1567 
1568         String excludeArg = "";
1569         if ((StringUtils.isNotEmpty(getSubpackages()))
1570                 && (null != excludedNames) && (0 < excludedNames.size())) {
1571             // add the excludedpackage names
1572             for (String str : excludedNames) {
1573                 excludeArg = excludeArg + str + ":";
1574             }
1575             excludeArg = excludeArg.substring(0, excludeArg.length() - 1);
1576         }
1577 
1578         return excludeArg;
1579     }
1580 
1581     private List<String> getExecutionProjectSourceRoots(final MavenProject p) {
1582         if ("pom".equals(
1583                 p.getExecutionProject().getPackaging().toLowerCase())) {
1584             return Collections.emptyList();
1585         }
1586 
1587         return p.getExecutionProject().getCompileSourceRoots();
1588     }
1589 
1590     private List<String> getFilesWithUnnamedPackages(
1591             final List<String> sourcePaths, final List<String> files) {
1592         return getPackageNamesOrFilesWithUnnamedPackages(sourcePaths, files,
1593                 false);
1594     }
1595 
1596     private List<File> getProjectBuildOutputDirs(final MavenProject p) {
1597         if (StringUtils.isEmpty(p.getBuild().getOutputDirectory())) {
1598             return Collections.emptyList();
1599         }
1600 
1601         return Collections.singletonList(new File(p.getBuild().
1602                 getOutputDirectory()));
1603     }
1604 
1605     private List<String> getPackageNames(final List<String> sourcePaths,
1606             final List<String> files) {
1607         return getPackageNamesOrFilesWithUnnamedPackages(sourcePaths, files,
1608                 true);
1609     }
1610 
1611     private List<String> getPackageNamesOrFilesWithUnnamedPackages(
1612             final List<String> sourcePaths, final List<String> files,
1613             final boolean onlyPackageName) {
1614         List<String> returnList = new ArrayList<String>();
1615 
1616         if (!StringUtils.isEmpty(getSourcePath())) {
1617             return returnList;
1618         }
1619 
1620         for (String currentFile : files) {
1621             currentFile = currentFile.replace('\\', '/');
1622 
1623             for (String currentSourcePath : sourcePaths) {
1624                 currentSourcePath = currentSourcePath.replace('\\', '/');
1625 
1626                 if (!currentSourcePath.endsWith("/")) {
1627                     currentSourcePath += "/";
1628                 }
1629 
1630                 if (currentFile.indexOf(currentSourcePath) != -1) {
1631                     String packagename =
1632                             currentFile.substring(currentSourcePath.length()
1633                             + 1);
1634                     if (onlyPackageName && packagename.lastIndexOf("/") != -1) {
1635                         packagename = packagename.substring(0, packagename.
1636                                 lastIndexOf("/"));
1637                         packagename = packagename.replace('/', '.');
1638 
1639                         if (!returnList.contains(packagename)) {
1640                             returnList.add(packagename);
1641                         }
1642                     }
1643                     if ((!onlyPackageName)
1644                             && (packagename.lastIndexOf("/") == -1)) {
1645                         returnList.add(currentFile);
1646                     }
1647                 }
1648             }
1649         }
1650 
1651         return returnList;
1652     }
1653 
1654     private List<String> getProjectSourceRoots(final MavenProject p) {
1655         if ("pom".equals(p.getPackaging().toLowerCase())) {
1656             return Collections.emptyList();
1657         }
1658 
1659         return p.getCompileSourceRoots();
1660     }
1661 
1662     private Toolchain getToolchain() {
1663         Toolchain tc = null;
1664         if (getToolchainManager() != null) {
1665             tc = getToolchainManager().getToolchainFromBuildContext("jdk",
1666                     getSession());
1667         }
1668 
1669         return tc;
1670     }
1671 
1672     private void populateCompileArtifactMap(
1673             final Map<String, Artifact> compileArtifactMap,
1674             final Collection<Artifact> artifactList)
1675             throws MavenReportException {
1676         if (artifactList != null) {
1677             for (Artifact newArtifact : artifactList) {
1678                 File file = newArtifact.getFile();
1679 
1680                 if (null == file) {
1681                     throw new MavenReportException(
1682                             formatMessage("report.javafxdoc.artifact.error",
1683                             newArtifact.getGroupId(),
1684                             newArtifact.getArtifactId(),
1685                             newArtifact.getVersion()));
1686                 }
1687 
1688                 if (null != compileArtifactMap.get(newArtifact.
1689                         getDependencyConflictId())) {
1690                     Artifact oldArtifact =
1691                             compileArtifactMap.get(newArtifact.
1692                             getDependencyConflictId());
1693                     ArtifactVersion oldVersion = new DefaultArtifactVersion(
1694                             oldArtifact.getVersion());
1695                     ArtifactVersion newVersion = new DefaultArtifactVersion(
1696                             newArtifact.getVersion());
1697 
1698                     if (newVersion.compareTo(oldVersion) > 0) {
1699                         compileArtifactMap.put(newArtifact.
1700                                 getDependencyConflictId(),
1701                                 newArtifact);
1702                     }
1703                 } else {
1704                     compileArtifactMap.put(
1705                             newArtifact.getDependencyConflictId(), newArtifact);
1706                 }
1707             }
1708         }
1709     }
1710 
1711     private void setJavafxdocVersion(File file) {
1712         float version = DEFAULT_JAVAFX_VERSION;
1713 
1714         try {
1715             version = JavafxdocUtil.getJavafxdocVersion(file);
1716         } catch (CommandLineException ex) {
1717             getLog().warn(ex.getMessage());
1718         } catch (FileNotFoundException ex) {
1719             getLog().warn(ex.getMessage());
1720         } catch (PatternSyntaxException ex) {
1721             getLog().warn(ex.getMessage());
1722         } catch (IllegalArgumentException ex) {
1723             getLog().warn(ex.getMessage());
1724         }
1725 
1726         javafxdocVersion = version;
1727     }
1728 
1729     private void validateJavafxdocOptions() throws MavenReportException {
1730         // encoding
1731         if ((StringUtils.isNotEmpty(getEncoding()))
1732                 && (!JavafxdocUtil.validateEncoding(getEncoding()))) {
1733             throw new MavenReportException(formatMessage(
1734                     "report.javafxdoc.unsupported.encoding", getEncoding()));
1735         }
1736     }
1737 }