All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.squeakysand.jsp.tldgenerator.maven.TldGeneratorMojo Maven / Gradle / Ivy

/*
 * Copyright 2010-2011 Craig S. Dickson (http://craigsdickson.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.squeakysand.jsp.tldgenerator.maven;

import org.apache.maven.plugin.MojoFailureException;
import org.codehaus.doxia.sink.Sink;

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.util.NoSuchElementException;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

import org.codehaus.plexus.util.Os;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;

import org.apache.commons.lang.SystemUtils;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
import org.apache.maven.artifact.resolver.ArtifactResolutionException;
import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
import org.apache.maven.artifact.resolver.ArtifactResolver;
import org.apache.maven.artifact.versioning.ArtifactVersion;
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.model.Plugin;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.javadoc.options.BootclasspathArtifact;
import org.apache.maven.plugin.javadoc.options.DocletArtifact;
import org.apache.maven.plugin.javadoc.options.JavadocPathArtifact;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.MavenProjectBuilder;
import org.apache.maven.project.ProjectBuildingException;
import org.apache.maven.reporting.MavenReportException;
import org.apache.maven.settings.Proxy;
import org.apache.maven.settings.Settings;
import org.apache.maven.toolchain.Toolchain;
import org.apache.maven.toolchain.ToolchainManager;
import org.apache.maven.project.artifact.InvalidDependencyVersionException;
import org.apache.maven.artifact.resolver.MultipleArtifactsNotFoundException;

import org.codehaus.plexus.util.FileUtils;
import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.ReaderFactory;
import org.codehaus.plexus.util.StringUtils;
import org.codehaus.plexus.util.cli.CommandLineException;
import org.codehaus.plexus.util.cli.CommandLineUtils;
import org.codehaus.plexus.util.cli.Commandline;
import org.codehaus.plexus.util.xml.Xpp3Dom;

/**
 * Processes a set of annotated Java classes and also directories containing tag files to generate a Tag Library
 * Descriptor (.tld) file.
 *
 * Much of this code was inspired by the existing classes in org.apache.maven.plugin.javadoc, However due to the
 * design of the code in that package and the poor support for extending existing plugins within the Maven framework,
 * the code was replicated here instead of just being able to extend it.
 *
 * @goal generate
 * @phase generate-sources
 * @requiresDependencyResolution compile
 */
public class TldGeneratorMojo extends AbstractMojo {

//    /**
//     * Classifier used in the name of the javadoc-options XML file, and in the resources bundle
//     * artifact that gets attached to the project. This one is used for non-test javadocs.
//     *
//     * @since 2.7
//     * @see #TEST_JAVADOC_RESOURCES_ATTACHMENT_CLASSIFIER
//     */
//    public static final String JAVADOC_RESOURCES_ATTACHMENT_CLASSIFIER = "javadoc-resources";
//    /**
//     * Classifier used in the name of the javadoc-options XML file, and in the resources bundle
//     * artifact that gets attached to the project. This one is used for test-javadocs.
//     *
//     * @since 2.7
//     * @see #JAVADOC_RESOURCES_ATTACHMENT_CLASSIFIER
//     */
//    public static final String TEST_JAVADOC_RESOURCES_ATTACHMENT_CLASSIFIER = "test-javadoc-resources";
//    /**
//     * The default Javadoc API urls according the
//     * Sun API Specifications:
//     * 
//     * <javaApiLinks>
//     *   <property>
//     *     <name>api_1.3</name>
//     *     <value>http://download.oracle.com/javase/1.3/docs/api/</value>
//     *   </property>
//     *   <property>
//     *     <name>api_1.4</name>
//     *     <value>http://download.oracle.com/javase/1.4.2/docs/api/</value>
//     *   </property>
//     *   <property>
//     *     <name>api_1.5</name>
//     *     <value>http://download.oracle.com/javase/1.5.0/docs/api/</value>
//     *   </property>
//     *   <property>
//     *     <name>api_1.6</name>
//     *     <value>http://download.oracle.com/javase/6/docs/api/</value>
//     *   </property>
//     * </javaApiLinks>
//     * 
// * // * @since 2.6 // */ // public static final Properties DEFAULT_JAVA_API_LINKS = new Properties(); /** The Javadoc script file name when debug parameter is on, i.e. javadoc.bat or javadoc.sh */ private static final String DEBUG_JAVADOC_SCRIPT_NAME = "javadoc." + (SystemUtils.IS_OS_WINDOWS ? "bat" : "sh"); /** The options file name in the output directory when calling: * javadoc.exe(or .sh) @options @packages | @argfile | @files */ private static final String OPTIONS_FILE_NAME = "options"; /** The packages file name in the output directory when calling: * javadoc.exe(or .sh) @options @packages | @argfile | @files */ private static final String PACKAGES_FILE_NAME = "packages"; /** The argfile file name in the output directory when calling: * javadoc.exe(or .sh) @options @packages | @argfile | @files */ private static final String ARGFILE_FILE_NAME = "argfile"; /** The files file name in the output directory when calling: * javadoc.exe(or .sh) @options @packages | @argfile | @files */ private static final String FILES_FILE_NAME = "files"; // /** The current class directory */ // private static final String RESOURCE_DIR = ClassUtils.getPackageName(TldGeneratorMojo.class).replace('.', '/'); // /** Default css file name */ // private static final String DEFAULT_CSS_NAME = "stylesheet.css"; // /** Default location for css */ // private static final String RESOURCE_CSS_DIR = RESOURCE_DIR + "/css"; /** * For Javadoc options appears since Java 1.4. * See * What's New in Javadoc 1.4 * @since 2.1 */ private static final float SINCE_JAVADOC_1_4 = 1.4f; // /** // * For Javadoc options appears since Java 1.4.2. // * See // * What's New in Javadoc 1.4.2 // * @since 2.1 // */ // private static final float SINCE_JAVADOC_1_4_2 = 1.42f; /** * For Javadoc options appears since Java 5.0. * See * What's New in Javadoc 5.0 * @since 2.1 */ private static final float SINCE_JAVADOC_1_5 = 1.5f; // /** // * For Javadoc options appears since Java 6.0. // * See // * Javadoc Technology // * @since 2.4 // */ // private static final float SINCE_JAVADOC_1_6 = 1.6f; // ---------------------------------------------------------------------- // Mojo components // ---------------------------------------------------------------------- // /** // * Archiver manager // * // * @since 2.5 // * @component // */ // private ArchiverManager archiverManager; /** * Factory for creating artifact objects * * @component */ private ArtifactFactory artifactFactory; /** * Used to resolve artifacts of aggregated modules * * @since 2.1 * @component */ private ArtifactMetadataSource artifactMetadataSource; /** * Used for resolving artifacts * * @component */ private ArtifactResolver artifactResolver; /** * Project builder * * @since 2.5 * @component */ private MavenProjectBuilder mavenProjectBuilder; /** @component */ private ToolchainManager toolchainManager; // ---------------------------------------------------------------------- // Mojo parameters // ---------------------------------------------------------------------- /** * The current build session instance. This is used for * toolchain manager API calls. * * @parameter expression="${session}" * @required * @readonly */ private MavenSession session; /** * The Maven Settings. * * @since 2.3 * @parameter default-value="${settings}" * @required * @readonly */ private Settings settings; /** * The Maven Project Object * * @parameter expression="${project}" * @required * @readonly */ private MavenProject project; // /** // * Specify if the Javadoc should operate in offline mode. // * // * @parameter default-value="${settings.offline}" // * @required // * @readonly // */ // private boolean isOffline; // /** // * Specifies the Javadoc resources directory to be included in the Javadoc (i.e. package.html, images...). // *
// * Could be used in addition of docfilessubdirs parameter. // *
// * See docfilessubdirs. // * // * @since 2.1 // * @parameter expression="${basedir}/src/main/javadoc" // * @see #docfilessubdirs // */ // private File javadocDirectory; // /** // * Set an additional parameter(s) on the command line. This value should include quotes as necessary for // * parameters that include spaces. Useful for a custom doclet. // * // * @parameter expression="${additionalparam}" // */ // private String additionalparam; // /** // * Set an additional Javadoc option(s) (i.e. JVM options) on the command line. // * Example: // *
//     * <additionalJOption>-J-Xss128m</additionalJOption>
//     * 
// * See Jflag. // *
// * See vmoptions. // *
// * See Networking Properties. // * // * @since 2.3 // * @parameter expression="${additionalJOption}" // */ // private String additionalJOption; // /** // * A list of artifacts containing resources which should be copied into the // * Javadoc output directory (like stylesheets, icons, etc.). // *
// * Example: // *
//     * <resourcesArtifacts>
//     *   <resourcesArtifact>
//     *     <groupId>external.group.id</groupId>
//     *     <artifactId>external-resources</artifactId>
//     *     <version>1.0</version>
//     *   </resourcesArtifact>
//     * </resourcesArtifacts>
//     * 
// *
// * See Javadoc. // *
// * // * @since 2.5 // * @parameter expression="${resourcesArtifacts}" // */ // private ResourcesArtifact[] resourcesArtifacts; /** * The local repository where the artifacts are located. * * @parameter expression="${localRepository}" */ private ArtifactRepository localRepository; /** * The remote repositories where artifacts are located. * * @parameter expression="${project.remoteArtifactRepositories}" */ private List remoteRepositories; /** * The projects in the reactor for aggregation report. * * @parameter expression="${reactorProjects}" * @readonly */ private List reactorProjects; // /** // * Whether to build an aggregated report at the root, or build individual reports. // * // * @parameter expression="${aggregate}" default-value="false" // * @deprecated since 2.5. Use the goals javadoc:aggregate and javadoc:test-aggregate instead. // */ // private boolean aggregate; // /** // * Set this to true to debug the Javadoc plugin. With this, javadoc.bat(or.sh), // * options, @packages or argfile files are provided in the output directory. // *
// * // * @since 2.1 // * @parameter expression="${debug}" default-value="false" // */ // private boolean debug; /** * Sets the absolute path of the Javadoc Tool executable to use. Since version 2.5, a mere directory specification * is sufficient to have the plugin use "javadoc" or "javadoc.exe" respectively from this directory. */ private String javadocExecutable; // /** // * Version of the Javadoc Tool executable to use, ex. "1.3", "1.5". // * // * @since 2.3 // * @parameter expression="${javadocVersion}" // */ // private String javadocVersion; /** * Version of the Javadoc Tool executable to use as float. */ private float fJavadocVersion = 0.0f; // /** // * Specifies whether the Javadoc generation should be skipped. // * // * @since 2.5 // * @parameter expression="${maven.javadoc.skip}" default-value="false" // */ // private boolean skip; /** * Specifies if the build will fail if there are errors during javadoc execution or not. * * @parameter expression="${maven.javadoc.failOnError}" default-value="true" * @readonly * @since 2.5 */ private boolean failOnError; // /** // * Specifies to use the // * options provided by the Standard Doclet for a custom doclet. // *
// * Example: // *
//     * <docletArtifacts>
//     *   <docletArtifact>
//     *     <groupId>com.sun.tools.doclets</groupId>
//     *     <artifactId>doccheck</artifactId>
//     *     <version>1.2b2</version>
//     *   </docletArtifact>
//     * </docletArtifacts>
//     * <useStandardDocletOptions>true</useStandardDocletOptions>
//     * 
// * // * @parameter expression="${useStandardDocletOptions}" default-value="false" // * @since 2.5 // */ // private boolean useStandardDocletOptions; // /** // * Detect the Javadoc links for all dependencies defined in the project. The detection is based on the default // * Maven conventions, i.e.: ${project.url}/apidocs. // *
// * For instance, if the project has a dependency to // * Apache Commons Lang i.e.: // *
//     * <dependency>
//     *   <groupId>commons-lang</groupId>
//     *   <artifactId>commons-lang</artifactId>
//     * </dependency>
//     * 
// * The added Javadoc -link parameter will be http://commons.apache.org/lang/apidocs. // * // * @parameter expression="${detectLinks}" default-value="false" // * @see #links // * @since 2.6 // */ // private boolean detectLinks; // /** // * Detect the links for all modules defined in the project. // *
// * If {@link #reactorProjects} is defined in a non-aggregator way, it generates default offline links // * between modules based on the defined project's urls. For instance, if a parent project has two projects // * module1 and module2, the -linkoffline will be: // *
// * The added Javadoc -linkoffline parameter for module1 will be // * /absolute/path/to/module2/target/site/apidocs // *
// * The added Javadoc -linkoffline parameter for module2 will be // * /absolute/path/to/module1/target/site/apidocs // * // * @parameter expression="${detectOfflineLinks}" default-value="true" // * @see #offlineLinks // * @since 2.6 // */ // private boolean detectOfflineLinks; // /** // * Detect the Java API link for the current build, i.e. http://download.oracle.com/javase/1.4.2/docs/api/ // * for Java source 1.4. // *
// * By default, the goal detects the Javadoc API link depending the value of the source // * parameter in the org.apache.maven.plugins:maven-compiler-plugin // * (defined in ${project.build.plugins} or in ${project.build.pluginManagement}), // * or try to compute it from the {@link #javadocExecutable} version. // *
// * See Javadoc for the default values. // *
// * // * @parameter expression="${detectJavaApiLink}" default-value="true" // * @see #links // * @see #javaApiLinks // * @see #DEFAULT_JAVA_API_LINKS // * @since 2.6 // */ // private boolean detectJavaApiLink; // /** // * Use this parameter only if the Sun Javadoc API // * urls have been changed or to use custom urls for Javadoc API url. // *
// * See Javadoc // * for the default values. // *
// * // * @parameter expression="${javaApiLinks}" // * @see #DEFAULT_JAVA_API_LINKS // * @since 2.6 // */ // private Properties javaApiLinks; // /** // * Flag controlling content validation of package-list resources. If set, the content of // * package-list resources will be validated. // * // * @parameter expression="${validateLinks}" default-value="false" // * @since 2.8 // */ // private boolean validateLinks; // // ---------------------------------------------------------------------- // // Javadoc Options - all alphabetical // // ---------------------------------------------------------------------- // /** // * Specifies the paths where the boot classes reside. The bootclasspath can contain multiple paths // * by separating them with a colon (:) or a semi-colon (;). // *
// * See bootclasspath. // *
// * // * @parameter expression="${bootclasspath}" // * @since 2.5 // */ // private String bootclasspath; // /** // * Specifies the artifacts where the boot classes reside. // *
// * See bootclasspath. // *
// * Example: // *
//     * <bootclasspathArtifacts>
//     *   <bootclasspathArtifact>
//     *     <groupId>my-groupId</groupId>
//     *     <artifactId>my-artifactId</artifactId>
//     *     <version>my-version</version>
//     *   </bootclasspathArtifact>
//     * </bootclasspathArtifacts>
//     * 
// *
// * See Javadoc. // *
// * // * @parameter expression="${bootclasspathArtifacts}" // * @since 2.5 // */ // private BootclasspathArtifact[] bootclasspathArtifacts; // /** // * Uses the sentence break iterator to determine the end of the first sentence. // *
// * See breakiterator. // *
// * Since Java 1.4. // *
// * // * @parameter expression="${breakiterator}" default-value="false" // */ // private boolean breakiterator; // /** // * Specifies the class file that starts the doclet used in generating the documentation. // *
// * See doclet. // * // * @parameter expression="${doclet}" default-value="com.squeakysand.jsp.tldgenerator.TldGeneratorDoclet" // */ // private String doclet; // /** // * Specifies the artifact containing the doclet starting class file (specified with the -doclet // * option). // *
// * See docletpath. // *
// * Example: // *
//     * <docletArtifact>
//     *   <groupId>com.sun.tools.doclets</groupId>
//     *   <artifactId>doccheck</artifactId>
//     *   <version>1.2b2</version>
//     * </docletArtifact>
//     * 
// *
// * See Javadoc. // *
// * // * @parameter expression="${docletArtifact}" // */ // private DocletArtifact docletArtifact; // /** // * Specifies multiple artifacts containing the path for the doclet starting class file (specified with the // * -doclet option). // *
// * See docletpath. // *
// * Example: // *
//     * <docletArtifacts>
//     *   <docletArtifact>
//     *     <groupId>com.sun.tools.doclets</groupId>
//     *     <artifactId>doccheck</artifactId>
//     *     <version>1.2b2</version>
//     *   </docletArtifact>
//     * </docletArtifacts>
//     * 
// *
// * See Javadoc. // *
// * // * @since 2.1 // * @parameter expression="${docletArtifacts}" // */ // private DocletArtifact[] docletArtifacts; // /** // * Specifies the path to the doclet starting class file (specified with the -doclet option) and // * any jar files it depends on. The docletPath can contain multiple paths by separating them with // * a colon (:) or a semi-colon (;). // *
// * See docletpath. // * // * @parameter expression="${docletPath}" // */ // private String docletPath; /** * Specifies the encoding name of the source files. If not specificed, the encoding value will be the value of the * file.encoding system property. *
* See encoding. *
* Note: In 2.4, the default value was locked to ISO-8859-1 to ensure reproducing build, but * this was reverted in 2.5. *
* * @parameter expression="${encoding}" default-value="${project.build.sourceEncoding}" */ private String encoding; /** * Unconditionally excludes the specified packages and their subpackages from the list formed by * -subpackages. Multiple packages can be separated by commas (,), colons (:) * or semicolons (;). *
* Example: *
     * <excludePackageNames>*.internal:org.acme.exclude1.*:org.acme.exclude2</excludePackageNames>
     * 
*
* See exclude. *
* Since Java 1.4. * * @parameter expression="${excludePackageNames}" */ private String excludePackageNames; // /** // * Specifies the directories where extension classes reside. Separate directories in extdirs with a // * colon (:) or a semi-colon (;). // *
// * See extdirs. // * // * @parameter expression="${extdirs}" // */ // private String extdirs; // /** // * Specifies the locale that javadoc uses when generating documentation. // *
// * See locale. // * // * @parameter expression="${locale}" // */ // private String locale; /** * Specifies the maximum Java heap size to be used when launching the Javadoc tool. * JVMs refer to this property as the -Xmx parameter. Example: '512' or '512m'. * The memory unit depends on the JVM used. The units supported could be: k, kb, * m, mb, g, gb, t, tb. * If no unit specified, the default unit is m. * * @parameter expression="${maxmemory}" */ private String maxmemory; /** * Specifies the minimum Java heap size to be used when launching the Javadoc tool. * JVMs refer to this property as the -Xms parameter. Example: '512' or '512m'. * The memory unit depends on the JVM used. The units supported could be: k, kb, * m, mb, g, gb, t, tb. * If no unit specified, the default unit is m. * * @parameter expression="${minmemory}" */ private String minmemory; // /** // * This option creates documentation with the appearance and functionality of documentation generated by // * Javadoc 1.1. // *
// * See 1.1. // *
// * // * @parameter expression="${old}" default-value="false" // */ // private boolean old; // /** // * Specifies that javadoc should retrieve the text for the overview documentation from the "source" file // * specified by path/filename and place it on the Overview page (overview-summary.html). // *
// * Note: could be in conflict with <nooverview/>. // *
// * See overview. // *
// * // * @parameter expression="${overview}" default-value="${basedir}/src/main/javadoc/overview.html" // */ // private File overview; // /** // * Specifies the proxy host where the javadoc web access in -link would pass through. // * It defaults to the proxy host of the active proxy set in the settings.xml, otherwise it gets the // * proxy configuration set in the pom. // *
// * // * @parameter expression="${proxyHost}" // */ // private String proxyHost; // /** // * Specifies the proxy port where the javadoc web access in -link would pass through. // * It defaults to the proxy port of the active proxy set in the settings.xml, otherwise it gets the // * proxy configuration set in the pom. // *
// * // * @parameter expression="${proxyPort}" // */ // private int proxyPort; // /** // * Shuts off non-error and non-warning messages, leaving only the warnings and errors appear, making them // * easier to view. // *
// * Note: was a standard doclet in Java 1.4.2 (refer to bug ID // * 4714350). // *
// * See quiet. // *
// * Since Java 5.0. // *
// * // * @parameter expression="${quiet}" default-value="false" // */ // private boolean quiet; // /** // * Specifies the access level for classes and members to show in the Javadocs. // * Possible values are: // *
    // *
  • public // * (shows only public classes and members)
  • // *
  • protected // * (shows only public and protected classes and members)
  • // *
  • package // * (shows all classes and members not marked private)
  • // *
  • private // * (shows all classes and members)
  • // *
// *
// * // * @parameter expression="${show}" default-value="protected" // */ // private String show; // /** // * Necessary to enable javadoc to handle assertions present in J2SE v 1.4 source code. // *
// * See source. // *
// * Since Java 1.4. // * // * @parameter expression="${source}" default-value="1.5" // */ // private String source = "1.5"; /** * Specifies the source paths where the subpackages are located. The sourcepath can contain * multiple paths by separating them with a colon (:) or a semi-colon (;). *
* See sourcepath. * * @parameter expression="${sourcepath}" */ private String sourcepath; /** * Specifies the package directory where javadoc will be executed. Multiple packages can be separated by * colons (:). *
* See subpackages. *
* Since Java 1.4. * * @parameter expression="${subpackages}" */ private String subpackages; /** * Provides more detailed messages while javadoc is running. *
* See verbose. *
* * @parameter expression="${verbose}" default-value="false" */ private boolean verbose; // // ---------------------------------------------------------------------- // // Standard Doclet Options - all alphabetical // // ---------------------------------------------------------------------- // /** // * Specifies whether or not the author text is included in the generated Javadocs. // *
// * See author. // *
// * // * @parameter expression="${author}" default-value="true" // */ // private boolean author; // /** // * Specifies the text to be placed at the bottom of each output file.
// * If you want to use html you have to put it in a CDATA section,
// * eg. <![CDATA[Copyright 2005, <a href="http://www.mycompany.com">MyCompany, Inc.<a>]]> // *
// * See bottom. // *
// * // * @parameter expression="${bottom}" // * default-value="Copyright © {inceptionYear}-{currentYear} {organizationName}. All Rights Reserved." // */ // private String bottom; // /** // * Specifies the HTML character set for this document. If not specificed, the charset value will be the value of // * the docencoding parameter. // *
// * See charset. // *
// * // * @parameter expression="${charset}" // */ // private String charset; // /** // * Specifies the encoding of the generated HTML files. If not specificed, the docencoding value will be // * UTF-8. // *
// * See docencoding. // * // * @parameter expression="${docencoding}" default-value="${project.reporting.outputEncoding}" // */ // private String docencoding; // /** // * Enables deep copying of the **/doc-files directories and the specifc resources // * directory from the javadocDirectory directory (for instance, // * src/main/javadoc/com/mycompany/myapp/doc-files and src/main/javadoc/resources). // *
// * See // * docfilessubdirs. // *
// * Since Java 1.4. // *
// * See javadocDirectory. // *
// * // * @parameter expression="${docfilessubdirs}" default-value="false" // * @see #excludedocfilessubdir // * @see #javadocDirectory // */ // private boolean docfilessubdirs; // /** // * Specifies the title to be placed near the top of the overview summary file. // *
// * See doctitle. // *
// * // * @parameter expression="${doctitle}" default-value="${project.name} ${project.version} API" // */ // private String doctitle; // /** // * Excludes any "doc-files" subdirectories with the given names. Multiple patterns can be excluded // * by separating them with colons (:). // *
// * See // * excludedocfilessubdir. // *
// * Since Java 1.4. // * // * @parameter expression="${excludedocfilessubdir}" // * @see #docfilessubdirs // */ // private String excludedocfilessubdir; // /** // * Specifies the footer text to be placed at the bottom of each output file. // *
// * See footer. // * // * @parameter expression="${footer}" // */ // private String footer; // /** // * Separates packages on the overview page into whatever groups you specify, one group per table. The // * packages pattern can be any package name, or can be the start of any package name followed by an asterisk // * (*) meaning "match any characters". Multiple patterns can be included in a group // * by separating them with colons (:). // *
// * Example: // *
//     * <groups>
//     *   <group>
//     *     <title>Core Packages</title>
//     *     <!-- To includes java.lang, java.lang.ref,
//     *     java.lang.reflect and only java.util
//     *     (i.e. not java.util.jar) -->
//     *     <packages>java.lang*:java.util</packages>
//     *   </group>
//     *   <group>
//     *     <title>Extension Packages</title>
//     *      <!-- To include javax.accessibility,
//     *     javax.crypto, ... (among others) -->
//     *     <packages>javax.*</packages>
//     *   </group>
//     * </groups>
//     * 
// * Note: using java.lang.* for packages would omit the java.lang // * package but using java.lang* will include it. // *
// * See group. // *
// * See Javadoc. // *
// * // * @parameter expression="${groups}" // */ // private Group[] groups; // /** // * Specifies the header text to be placed at the top of each output file. // *
// * See header. // * // * @parameter expression="${header}" // */ // private String header; // /** // * Specifies the path of an alternate help file path\filename that the HELP link in the top and bottom // * navigation bars link to. // *
// * Note: could be in conflict with <nohelp/>. // *
// * The helpfile could be an absolute File path. // *
// * Since 2.6, it could be also be a path from a resource in the current project source directories // * (i.e. src/main/java, src/main/resources or src/main/javadoc) // * or from a resource in the Javadoc plugin dependencies, for instance: // *
//     * <helpfile>path/to/your/resource/yourhelp-doc.html</helpfile>
//     * 
// * Where path/to/your/resource/yourhelp-doc.html could be in src/main/javadoc. // *
//     * <build>
//     *   <plugins>
//     *     <plugin>
//     *       <groupId>org.apache.maven.plugins</groupId>
//     *       <artifactId>maven-javadoc-plugin</artifactId>
//     *       <configuration>
//     *         <helpfile>path/to/your/resource/yourhelp-doc.html</helpfile>
//     *         ...
//     *       </configuration>
//     *       <dependencies>
//     *         <dependency>
//     *           <groupId>groupId</groupId>
//     *           <artifactId>artifactId</artifactId>
//     *           <version>version</version>
//     *         </dependency>
//     *       </dependencies>
//     *     </plugin>
//     *     ...
//     *   <plugins>
//     * </build>
//     * 
// * Where path/to/your/resource/yourhelp-doc.html is defined in the // * groupId:artifactId:version javadoc plugin dependency. // *
// * See helpfile. // * // * @parameter expression="${helpfile}" // */ // private String helpfile; // /** // * Adds HTML meta keyword tags to the generated file for each class. // *
// * See keywords. // *
// * Since // * Java 1.4.2. // *
// * Since // * Java 5.0. // *
// * // * @since 2.1 // * @parameter expression="${keywords}" default-value="false" // */ // private boolean keywords; // /** // * Creates links to existing javadoc-generated documentation of external referenced classes. // *
// * Notes: // *
    // *
  1. only used if {@link #isOffline} is set to false.
  2. // *
  3. all given links should have a fetchable /package-list file. For instance: // *
    //     * <links>
    //     *   <link>http://download.oracle.com/javase/1.4.2/docs/api</link>
    //     * <links>
    //     * 
    // * will be used because http://download.oracle.com/javase/1.4.2/docs/api/package-list exists.
  4. // *
  5. if {@link #detectLinks} is defined, the links between the project dependencies are // * automatically added.
  6. // *
  7. if {@link #detectJavaApiLink} is defined, a Java API link, based on the Java version of the // * project's sources, will be added automatically.
  8. // *
// * See link. // * // * @parameter expression="${links}" // * @see #detectLinks // * @see #detectJavaApiLink // */ // private ArrayList links; // /** // * Creates an HTML version of each source file (with line numbers) and adds links to them from the standard // * HTML documentation. // *
// * See linksource. // *
// * Since Java 1.4. // *
// * // * @parameter expression="${linksource}" default-value="false" // */ // private boolean linksource; // /** // * Suppress the entire comment body, including the main description and all tags, generating only declarations. // *
// * See nocomment. // *
// * Since Java 1.4. // *
// * // * @parameter expression="${nocomment}" default-value="false" // */ // private boolean nocomment; // /** // * Prevents the generation of any deprecated API at all in the documentation. // *
// * See nodeprecated. // *
// * // * @parameter expression="${nodeprecated}" default-value="false" // */ // private boolean nodeprecated; // /** // * Prevents the generation of the file containing the list of deprecated APIs (deprecated-list.html) and the // * link in the navigation bar to that page. // *
// * See // * nodeprecatedlist. // *
// * // * @parameter expression="${nodeprecatedlist}" default-value="false" // */ // private boolean nodeprecatedlist; // /** // * Omits the HELP link in the navigation bars at the top and bottom of each page of output. // *
// * Note: could be in conflict with <helpfile/>. // *
// * See nohelp. // *
// * // * @parameter expression="${nohelp}" default-value="false" // */ // private boolean nohelp; // /** // * Omits the index from the generated docs. // *
// * Note: could be in conflict with <splitindex/>. // *
// * See noindex. // *
// * // * @parameter expression="${noindex}" default-value="false" // */ // private boolean noindex; // /** // * Omits the navigation bar from the generated docs. // *
// * See nonavbar. // *
// * // * @parameter expression="${nonavbar}" default-value="false" // */ // private boolean nonavbar; // /** // * Omits the entire overview page from the generated docs. // *
// * Note: could be in conflict with <overview/>. // *
// * Standard Doclet undocumented option. // *
// * // * @since 2.4 // * @parameter expression="${nooverview}" default-value="false" // */ // private boolean nooverview; // /** // * Omits qualifying package name from ahead of class names in output. // * Example: // *
//     * <noqualifier>all</noqualifier>
//     * or
//     * <noqualifier>packagename1:packagename2</noqualifier>
//     * 
// * See noqualifier. // *
// * Since Java 1.4. // * // * @parameter expression="${noqualifier}" // */ // private String noqualifier; // /** // * Omits from the generated docs the "Since" sections associated with the since tags. // *
// * See nosince. // *
// * // * @parameter expression="${nosince}" default-value="false" // */ // private boolean nosince; // /** // * Suppresses the timestamp, which is hidden in an HTML comment in the generated HTML near the top of each page. // *
// * See notimestamp. // *
// * Since // * Java 5.0. // *
// * // * @since 2.1 // * @parameter expression="${notimestamp}" default-value="false" // */ // private boolean notimestamp; // /** // * Omits the class/interface hierarchy pages from the generated docs. // *
// * See notree. // *
// * // * @parameter expression="${notree}" default-value="false" // */ // private boolean notree; // /** // * This option is a variation of -link; they both create links to javadoc-generated documentation // * for external referenced classes. // *
// * See linkoffline. // *
// * Example: // *
//     * <offlineLinks>
//     *   <offlineLink>
//     *     <url>http://download.oracle.com/javase/1.5.0/docs/api/</url>
//     *     <location>../javadoc/jdk-5.0/</location>
//     *   </offlineLink>
//     * </offlineLinks>
//     * 
// *
// * Note: if {@link #detectOfflineLinks} is defined, the offline links between the project modules are // * automatically added if the goal is calling in a non-aggregator way. // *
// * See Javadoc. // *
// * // * @parameter expression="${offlineLinks}" // */ // private OfflineLink[] offlineLinks; // /** // * Specifies the destination directory where javadoc saves the generated HTML files. // *
// * See d. // *
// * // * @parameter expression="${destDir}" alias="destDir" default-value="${project.build.directory}/apidocs" // * @required // */ // protected File outputDirectory; // /** // * Specify the text for upper left frame. // *
// * Since // * Java 1.4.2. // * // * @since 2.1 // * @parameter expression="${packagesheader}" // */ // private String packagesheader; // /** // * Generates compile-time warnings for missing serial tags. // *
// * See serialwarn // *
// * // * @parameter expression="${serialwarn}" default-value="false" // */ // private boolean serialwarn; // /** // * Specify the number of spaces each tab takes up in the source. If no tab is used in source, the default // * space is used. // *
// * Note: was linksourcetab in Java 1.4.2 (refer to bug ID // * 4788919). // *
// * Since // * 1.4.2. // *
// * Since Java 5.0. // * // * @since 2.1 // * @parameter expression="${sourcetab}" alias="linksourcetab" // */ // private int sourcetab; // /** // * Splits the index file into multiple files, alphabetically, one file per letter, plus a file for any index // * entries that start with non-alphabetical characters. // *
// * Note: could be in conflict with <noindex/>. // *
// * See splitindex. // *
// * // * @parameter expression="${splitindex}" default-value="false" // */ // private boolean splitindex; // /** // * Specifies whether the stylesheet to be used is the maven's javadoc stylesheet or // * java's default stylesheet when a stylesheetfile parameter is not specified. // *
// * Possible values: maven or java. // *
// * // * @parameter expression="${stylesheet}" default-value="java" // */ // private String stylesheet; // /** // * Specifies the path of an alternate HTML stylesheet file. // *
// * The stylesheetfile could be an absolute File path. // *
// * Since 2.6, it could be also be a path from a resource in the current project source directories // * (i.e. src/main/java, src/main/resources or src/main/javadoc) // * or from a resource in the Javadoc plugin dependencies, for instance: // *
//     * <stylesheetfile>path/to/your/resource/yourstylesheet.css</stylesheetfile>
//     * 
// * Where path/to/your/resource/yourstylesheet.css could be in src/main/javadoc. // *
//     * <build>
//     *   <plugins>
//     *     <plugin>
//     *       <groupId>org.apache.maven.plugins</groupId>
//     *       <artifactId>maven-javadoc-plugin</artifactId>
//     *       <configuration>
//     *         <stylesheetfile>path/to/your/resource/yourstylesheet.css</stylesheetfile>
//     *         ...
//     *       </configuration>
//     *       <dependencies>
//     *         <dependency>
//     *           <groupId>groupId</groupId>
//     *           <artifactId>artifactId</artifactId>
//     *           <version>version</version>
//     *         </dependency>
//     *       </dependencies>
//     *     </plugin>
//     *     ...
//     *   <plugins>
//     * </build>
//     * 
// * Where path/to/your/resource/yourstylesheet.css is defined in the // * groupId:artifactId:version javadoc plugin dependency. // *
// * See // * stylesheetfile. // * // * @parameter expression="${stylesheetfile}" // */ // private String stylesheetfile; // /** // * Specifies the class file that starts the taglet used in generating the documentation for that tag. // *
// * See taglet. // *
// * Since Java 1.4. // * // * @parameter expression="${taglet}" // */ // private String taglet; // /** // * Specifies the Taglet artifact containing the taglet class files (.class). // *
// * See tagletpath. // *
// * Example: // *
//     * <taglets>
//     *   <taglet>
//     *     <tagletClass>com.sun.tools.doclets.ToDoTaglet</tagletClass>
//     *   </taglet>
//     *   <taglet>
//     *     <tagletClass>package.to.AnotherTagletClass</tagletClass>
//     *   </taglet>
//     *   ...
//     * </taglets>
//     * <tagletArtifact>
//     *   <groupId>group-Taglet</groupId>
//     *   <artifactId>artifact-Taglet</artifactId>
//     *   <version>version-Taglet</version>
//     * </tagletArtifact>
//     * 
// *
// * See Javadoc. // *
// * // * @since 2.1 // * @parameter expression="${tagletArtifact}" // */ // private TagletArtifact tagletArtifact; // /** // * Specifies several Taglet artifacts containing the taglet class files (.class). These taglets class names will be // * auto-detect and so no need to specify them. // *
// * See taglet. // *
// * See tagletpath. // *
// * Example: // *
//     * <tagletArtifacts>
//     *   <tagletArtifact>
//     *     <groupId>group-Taglet</groupId>
//     *     <artifactId>artifact-Taglet</artifactId>
//     *     <version>version-Taglet</version>
//     *   </tagletArtifact>
//     *   ...
//     * </tagletArtifacts>
//     * 
// *
// * See Javadoc. // *
// * // * @since 2.5 // * @parameter expression="${tagletArtifacts}" // */ // private TagletArtifact[] tagletArtifacts; // /** // * Specifies the search paths for finding taglet class files (.class). The tagletpath can contain // * multiple paths by separating them with a colon (:) or a semi-colon (;). // *
// * See tagletpath. // *
// * Since Java 1.4. // * // * @parameter expression="${tagletpath}" // */ // private String tagletpath; // /** // * Enables the Javadoc tool to interpret multiple taglets. // *
// * See taglet. // *
// * See tagletpath. // *
// * Example: // *
//     * <taglets>
//     *   <taglet>
//     *     <tagletClass>com.sun.tools.doclets.ToDoTaglet</tagletClass>
//     *     <!--<tagletpath>/home/taglets</tagletpath>-->
//     *     <tagletArtifact>
//     *       <groupId>group-Taglet</groupId>
//     *       <artifactId>artifact-Taglet</artifactId>
//     *       <version>version-Taglet</version>
//     *     </tagletArtifact>
//     *   </taglet>
//     * </taglets>
//     * 
// *
// * See Javadoc. // *
// * // * @since 2.1 // * @parameter expression="${taglets}" // */ // private Taglet[] taglets; // /** // * Enables the Javadoc tool to interpret a simple, one-argument custom block tag tagname in doc comments. // *
// * See tag. // *
// * Since Java 1.4. // *
// * Example: // *
//     * <tags>
//     *   <tag>
//     *     <name>todo</name>
//     *     <placement>a</placement>
//     *     <head>To Do:</head>
//     *   </tag>
//     * </tags>
//     * 
// * Note: the placement should be a combinaison of Xaoptcmf letters: // *
    // *
  • X (disable tag)
  • // *
  • a (all)
  • // *
  • o (overview)
  • // *
  • p (packages)
  • // *
  • t (types, that is classes and interfaces)
  • // *
  • c (constructors)
  • // *
  • m (methods)
  • // *
  • f (fields)
  • // *
// * See Javadoc. // *
// * // * @parameter expression="${tags}" // */ // private Tag[] tags; // /** // * Specifies the top text to be placed at the top of each output file. // *
// * See 6227616. // *
// * Since Java 6.0 // * // * @since 2.4 // * @parameter expression="${top}" // */ // private String top; // /** // * Includes one "Use" page for each documented class and package. // *
// * See use. // *
// * // * @parameter expression="${use}" default-value="true" // */ // private boolean use; // /** // * Includes the version text in the generated docs. // *
// * See version. // *
// * // * @parameter expression="${version}" default-value="true" // */ // private boolean version; // /** // * Specifies the title to be placed in the HTML title tag. // *
// * See windowtitle. // *
// * // * @parameter expression="${windowtitle}" default-value="${project.name} ${project.version} API" // */ // private String windowtitle; // /** // * Whether dependency -sources jars should be resolved and included as source paths for javadoc generation. // * This is useful when creating javadocs for a distribution project. // * // * @parameter default-value="false" // * @since 2.7 // */ // private boolean includeDependencySources; // /** // * Directory where unpacked project sources / test-sources should be cached. // * // * @parameter default-value="${project.build.directory}/distro-javadoc-sources" // * @since 2.7 // * @see #includeDependencySources // */ // private File sourceDependencyCacheDir; // /** // * Whether to include transitive dependencies in the list of dependency -sources jars to include // * in this javadoc run. // * // * @parameter default-value="false" // * @since 2.7 // * @see #includeDependencySources // */ // private boolean includeTransitiveDependencySources; // /** // * List of included dependency-source patterns. Example: org.apache.maven:* // * // * // * @parameter // * @since 2.7 // * @see #includeDependencySources // */ // private List dependencySourceIncludes; // /** // * List of excluded dependency-source patterns. Example: org.apache.maven.shared:* // * // * // * @parameter // * @since 2.7 // * @see #includeDependencySources // */ // private List dependencySourceExcludes; // /** // * Directory into which assembled {@link JavadocOptions} instances will be written before they // * are added to javadoc resources bundles. // * // * @parameter default-value="${project.build.directory}/javadoc-bundle-options" // * @readonly // * @since 2.7 // */ // private File javadocOptionsDir; // /** // * Transient variable to allow lazy-resolution of javadoc bundles from dependencies, so they can // * be used at various points in the javadoc generation process. // * // * @since 2.7 // */ // private transient List dependencyJavadocBundles; // /** // * Specifies the destination directory where javadoc saves the generated HTML files. // * // * @parameter expression="${reportOutputDirectory}" default-value="${project.reporting.outputDirectory}/apidocs" // * @required // */ // private File reportOutputDirectory; // /** // * The name of the destination directory. // *
// * // * @since 2.1 // * @parameter expression="${destDir}" default-value="apidocs" // */ // private String destDir; // /** // * The name of the Javadoc report to be displayed in the Maven Generated Reports page // * (i.e. project-reports.html). // * // * @since 2.1 // * @parameter expression="${name}" // */ // private String name; // /** // * The description of the Javadoc report to be displayed in the Maven Generated Reports page // * (i.e. project-reports.html). // * // * @since 2.1 // * @parameter expression="${description}" // */ // private String description; // ---------------------------------------------------------------------- // static // ---------------------------------------------------------------------- // static { // DEFAULT_JAVA_API_LINKS.put("api_1.3", "http://download.oracle.com/javase/1.3/docs/api/"); // DEFAULT_JAVA_API_LINKS.put("api_1.4", "http://download.oracle.com/javase/1.4.2/docs/api/"); // DEFAULT_JAVA_API_LINKS.put("api_1.5", "http://download.oracle.com/javase/1.5.0/docs/api/"); // DEFAULT_JAVA_API_LINKS.put("api_1.6", "http://download.oracle.com/javase/6/docs/api/"); // } /** * The description of the Tag Library. Used as the content of the <description> element in the TLD file. * * @parameter default-value="${project.description}" */ private String description; /** * Where the generated TLD file should be written. The default value is the correct location to have the TLD * automatically included in a Jar file in the correct location by the normal Maven build process. * * @parameter default-value="${project.build.outputDirectory}/META-INF" * @required */ private File outputDirectory; /** * @parameter default-value="${project.build.directory}/tldgenerator" * @required */ private File workingDirectory; /** * The namespace for the Tag Library. Used as the content for the <short-name> element in the TLD file. * @parameter * @required */ private String shortName; /** * The minimum Servlet specification that this Tag Library requires. Used as the value of the version * attribute in the <taglib> element in the TLD file. * * @parameter default-value="2.1" * @required */ private String specificationVersion; /** * Where to find the tag file sources. * * @parameter default-value="${basedir}/src/main/resources/META-INF/tags" * @required */ private File tagFilesDir; /** * The version of this Tag Library. Used as the value for the <tlib-version> element in the TLD file. * * @parameter default-value="${project.version}" * @required */ private String tlibVersion; /** * The URI namespace for this Tag Library. Used as the value of the <uri> element in the generated TLD file. * * @parameter default-value="${project.url}" * @required */ private URI uri; /** * The fully qualified class name of a Tag Library validator. Used as the value of the <validator> * element in the generated TLD file. * * @parameter */ private String validator; /** * Indicates if the generator should look for JSP Tag Files when generating the descriptor. * * @parameter default-value="true" * @required */ private Boolean includetagfiles; // public String getOutputName() { // return destDir + "/index"; // } @Override public void execute() throws MojoExecutionException, MojoFailureException { try { // RenderingContext context = new RenderingContext(outputDirectory, "temp.html"); // SiteRendererSink sink = new SiteRendererSink(context); // Locale locale = Locale.getDefault(); // generate(sink, locale); generate(null,null); } catch (MavenReportException e) { failOnError("An error has occurred in report generation", e); } catch (RuntimeException e) { failOnError("An error has occurred in report generation", e); } } private void generate(Sink sink, Locale locale) throws MavenReportException { // outputDirectory = getReportOutputDirectory(); try { // executeReport(locale); executeReport(null); } catch (MavenReportException e) { if (failOnError) { throw e; } getLog().error("Error while creating javadoc report: " + e.getMessage(), e); } catch (RuntimeException e) { if (failOnError) { throw e; } getLog().error("Error while creating javadoc report: " + e.getMessage(), e); } } // /** {@inheritDoc} */ // public String getName(Locale locale) { // if (StringUtils.isEmpty(name)) { // return getBundle(locale).getString("report.javadoc.name"); // } // return name; // } // public File getReportOutputDirectory() { // if (reportOutputDirectory == null) { // return outputDirectory; // } // return reportOutputDirectory; // } // private ResourceBundle getBundle(Locale locale) { // return ResourceBundle.getBundle("javadoc-report", locale, getClass().getClassLoader()); // } private void failOnError(String prefix, Exception e) throws MojoExecutionException { if (failOnError) { if (e instanceof RuntimeException) { throw (RuntimeException) e; } throw new MojoExecutionException(prefix + ": " + e.getMessage(), e); } getLog().error(prefix + ": " + e.getMessage(), e); } /** * The package documentation details the * Javadoc Options used by this Plugin. * * @param unusedLocale the wanted locale (actually unused). * @throws MavenReportException if any */ private void executeReport(Locale unusedLocale) throws MavenReportException { // if (skip) { // getLog().info("Skipping javadoc generation"); // return; // } // if (isAggregator() && !project.isExecutionRoot()) { // return; // } // if (getLog().isDebugEnabled()) { // this.debug = true; // } // // NOTE: Always generate this file, to allow javadocs from modules to be aggregated via // // useDependencySources in a distro module build. // try { // buildJavadocOptions(); // } catch (IOException e) { // throw new MavenReportException("Failed to generate javadoc options file: " + e.getMessage(), e); // } List sourcePaths = getSourcePaths(); List files = getFiles(sourcePaths); if (!canGenerateReport(files)) { return; } List packageNames = getPackageNames(sourcePaths, files); List filesWithUnnamedPackages = getFilesWithUnnamedPackages(sourcePaths, files); // ---------------------------------------------------------------------- // Find the javadoc executable and version // ---------------------------------------------------------------------- String jExecutable; try { jExecutable = getJavadocExecutable(); } catch (IOException e) { throw new MavenReportException("Unable to find javadoc command: " + e.getMessage(), e); } setFJavadocVersion(new File(jExecutable)); // ---------------------------------------------------------------------- // Javadoc output directory as File // ---------------------------------------------------------------------- // File javadocOutputDirectory = new File(getOutputDirectory()); if (workingDirectory.exists() && !workingDirectory.isDirectory()) { throw new MavenReportException("IOException: " + getOutputDirectory() + " is not a directory."); } if (workingDirectory.exists() && !workingDirectory.canWrite()) { throw new MavenReportException("IOException: " + getOutputDirectory() + " is not writable."); } workingDirectory.mkdirs(); // // ---------------------------------------------------------------------- // // Copy all resources // // ---------------------------------------------------------------------- // // copyAllResources(javadocOutputDirectory); // ---------------------------------------------------------------------- // Create command line for Javadoc // ---------------------------------------------------------------------- Commandline cmd = new Commandline(); cmd.getShell().setQuotedArgumentsEnabled(false); // for Javadoc JVM args cmd.setWorkingDirectory(workingDirectory.getAbsolutePath()); cmd.setExecutable(jExecutable); // ---------------------------------------------------------------------- // Wrap Javadoc JVM args // ---------------------------------------------------------------------- addMemoryArg(cmd, "-Xmx", this.maxmemory); addMemoryArg(cmd, "-Xms", this.minmemory); addProxyArg(cmd); // if (StringUtils.isNotEmpty(additionalJOption)) { // cmd.createArg().setValue(additionalJOption); // } List arguments = new ArrayList(); // ---------------------------------------------------------------------- // Wrap Javadoc options // ---------------------------------------------------------------------- addJavadocOptions(arguments, sourcePaths); // ---------------------------------------------------------------------- // Wrap Standard doclet Options // ---------------------------------------------------------------------- // if (StringUtils.isEmpty(doclet) || useStandardDocletOptions) { addStandardDocletOptions(workingDirectory, arguments); // } addTldGeneratorOptions(arguments); // ---------------------------------------------------------------------- // Write options file and include it in the command line // ---------------------------------------------------------------------- if (arguments.size() > 0) { addCommandLineOptions(cmd, arguments, workingDirectory); } // ---------------------------------------------------------------------- // Write packages file and include it in the command line // ---------------------------------------------------------------------- if (!packageNames.isEmpty()) { addCommandLinePackages(cmd, workingDirectory, packageNames); // ---------------------------------------------------------------------- // Write argfile file and include it in the command line // ---------------------------------------------------------------------- if (!filesWithUnnamedPackages.isEmpty()) { addCommandLineArgFile(cmd, workingDirectory, filesWithUnnamedPackages); } } else { // ---------------------------------------------------------------------- // Write argfile file and include it in the command line // ---------------------------------------------------------------------- if (!files.isEmpty()) { addCommandLineArgFile(cmd, workingDirectory, files); } } // ---------------------------------------------------------------------- // Execute command line // ---------------------------------------------------------------------- executeJavadocCommandLine(cmd, workingDirectory); // // delete generated javadoc files only if no error and no debug mode // if (!debug) { // for (int i = 0; i < cmd.getArguments().length; i++) { // String arg = cmd.getArguments()[i].trim(); // // if (!arg.startsWith("@")) { // continue; // } // // File argFile = new File(workingDirectory, arg.substring(1)); // if (argFile.exists()) { // argFile.deleteOnExit(); // } // } // // File scriptFile = new File(workingDirectory, DEBUG_JAVADOC_SCRIPT_NAME); // if (scriptFile.exists()) { // scriptFile.deleteOnExit(); // } // } } // /** // * Indicates whether this goal is flagged with @aggregator. // * // * @return true if the goal is designed as an aggregator, false otherwise. // * @see AggregatorJavadocReport // * @see AggregatorTestJavadocReport // */ // protected boolean isAggregator() { // return false; // } // private JavadocOptions buildJavadocOptions() // throws IOException { // JavadocOptions options = new JavadocOptions(); // // options.setBootclasspathArtifacts(toList(bootclasspathArtifacts)); // options.setDocfilesSubdirsUsed(docfilessubdirs); // options.setDocletArtifacts(toList(docletArtifact, docletArtifacts)); // options.setExcludedDocfilesSubdirs(excludedocfilessubdir); // options.setExcludePackageNames(toList(excludePackageNames)); // options.setGroups(toList(groups)); // options.setLinks(links); // options.setOfflineLinks(toList(offlineLinks)); // options.setResourcesArtifacts(toList(resourcesArtifacts)); // options.setTagletArtifacts(toList(tagletArtifact, tagletArtifacts)); // options.setTaglets(toList(taglets)); // options.setTags(toList(tags)); // // if (getProject() != null && getJavadocDirectory() != null) { // options.setJavadocResourcesDirectory(toRelative(getProject().getBasedir(), getJavadocDirectory().getAbsolutePath())); // } // // File optionsFile = getJavadocOptionsFile(); // FileWriter writer = null; // try { // writer = new FileWriter(optionsFile); // new JavadocOptionsXpp3Writer().write(writer, options); // } finally { // close(writer); // } // // return options; // } private List getSourcePaths() throws MavenReportException { List sourcePaths; // if (StringUtils.isEmpty(sourcepath)) { sourcePaths = new ArrayList(pruneDirs(project, getProjectSourceRoots(project))); // if (project.getExecutionProject() != null) { // sourcePaths.addAll(pruneDirs(project, getExecutionProjectSourceRoots(project))); // } // /* // * Should be after the source path (i.e. -sourcepath '.../src/main/java;.../src/main/javadoc') and // * *not* the opposite. If not, the javadoc tool always copies doc files, even if -docfilessubdirs is // * not setted. // */ // if (getJavadocDirectory() != null) { // File javadocDir = getJavadocDirectory(); // if (javadocDir.exists() && javadocDir.isDirectory()) { // List l = // JavadocUtil.pruneDirs(project, // Collections.singletonList(getJavadocDirectory().getAbsolutePath())); // sourcePaths.addAll(l); // } // } // if (includeDependencySources) { // sourcePaths.addAll(getDependencySourcePaths()); // } // if (isAggregator() && project.isExecutionRoot()) { // for (MavenProject subProject : reactorProjects) { // if (subProject != project) { // List sourceRoots = getProjectSourceRoots(subProject); // // if (subProject.getExecutionProject() != null) { // sourceRoots.addAll(getExecutionProjectSourceRoots(subProject)); // } // // ArtifactHandler artifactHandler = subProject.getArtifact().getArtifactHandler(); // if ("java".equals(artifactHandler.getLanguage())) { // sourcePaths.addAll(JavadocUtil.pruneDirs(subProject, sourceRoots)); // } // // String javadocDirRelative = // PathUtils.toRelative(project.getBasedir(), getJavadocDirectory().getAbsolutePath()); // File javadocDir = new File(subProject.getBasedir(), javadocDirRelative); // if (javadocDir.exists() && javadocDir.isDirectory()) { // List l = // JavadocUtil.pruneDirs(subProject, // Collections.singletonList(javadocDir.getAbsolutePath())); // sourcePaths.addAll(l); // } // } // } // } // } else { // sourcePaths = new ArrayList(Arrays.asList(splitPath(sourcepath))); // sourcePaths = pruneDirs(project, sourcePaths); // if (getJavadocDirectory() != null) { // List l = // JavadocUtil.pruneDirs(project, // Collections.singletonList(getJavadocDirectory().getAbsolutePath())); // sourcePaths.addAll(l); // } // } sourcePaths = pruneDirs(project, sourcePaths); return sourcePaths; } private List getFiles(List sourcePaths) throws MavenReportException { List files = new ArrayList(); if (StringUtils.isEmpty(subpackages)) { String[] excludedPackages = getExcludedPackages(); for (String sourcePath : sourcePaths) { File sourceDirectory = new File(sourcePath); addFilesFromSource(files, sourceDirectory, excludedPackages); } } return files; } private boolean canGenerateReport(List files) { boolean canGenerate = true; if (files.isEmpty() && StringUtils.isEmpty(subpackages)) { canGenerate = false; throw new RuntimeException("cannot generate report"); } return canGenerate; } private List getPackageNames(List sourcePaths, List files) { return getPackageNamesOrFilesWithUnnamedPackages(sourcePaths, files, true); } private List getFilesWithUnnamedPackages(List sourcePaths, List files) { return getPackageNamesOrFilesWithUnnamedPackages(sourcePaths, files, false); } private String getJavadocExecutable() throws IOException { Toolchain tc = getToolchain(); if (tc != null) { getLog().info("Toolchain in javadoc-plugin: " + tc); if (javadocExecutable != null) { getLog().warn( "Toolchains are ignored, 'javadocExecutable' parameter is set to " + javadocExecutable); } else { javadocExecutable = tc.findTool("javadoc"); } } String javadocCommand = "javadoc" + (SystemUtils.IS_OS_WINDOWS ? ".exe" : ""); File javadocExe; // ---------------------------------------------------------------------- // The javadoc executable is defined by the user // ---------------------------------------------------------------------- if (StringUtils.isNotEmpty(javadocExecutable)) { javadocExe = new File(javadocExecutable); if (javadocExe.isDirectory()) { javadocExe = new File(javadocExe, javadocCommand); } if (SystemUtils.IS_OS_WINDOWS && javadocExe.getName().indexOf('.') < 0) { javadocExe = new File(javadocExe.getPath() + ".exe"); } if (!javadocExe.isFile()) { throw new IOException("The javadoc executable '" + javadocExe + "' doesn't exist or is not a file. Verify the parameter."); } return javadocExe.getAbsolutePath(); } // ---------------------------------------------------------------------- // Try to find javadocExe from System.getProperty( "java.home" ) // By default, System.getProperty( "java.home" ) = JRE_HOME and JRE_HOME // should be in the JDK_HOME // ---------------------------------------------------------------------- // For IBM's JDK 1.2 if (SystemUtils.IS_OS_AIX) { javadocExe = new File(SystemUtils.getJavaHome() + File.separator + ".." + File.separator + "sh", javadocCommand); } else if (SystemUtils.IS_OS_MAC_OSX) { javadocExe = new File(SystemUtils.getJavaHome() + File.separator + "bin", javadocCommand); } else { javadocExe = new File(SystemUtils.getJavaHome() + File.separator + ".." + File.separator + "bin", javadocCommand); } // ---------------------------------------------------------------------- // Try to find javadocExe from JAVA_HOME environment variable // ---------------------------------------------------------------------- if (!javadocExe.exists() || !javadocExe.isFile()) { Properties env = CommandLineUtils.getSystemEnvVars(); String javaHome = env.getProperty("JAVA_HOME"); if (StringUtils.isEmpty(javaHome)) { throw new IOException("The environment variable JAVA_HOME is not correctly set."); } if ((!new File(javaHome).exists()) || (!new File(javaHome).isDirectory())) { throw new IOException("The environment variable JAVA_HOME=" + javaHome + " doesn't exist or is not a valid directory."); } javadocExe = new File(env.getProperty("JAVA_HOME") + File.separator + "bin", javadocCommand); } if (!javadocExe.exists() || !javadocExe.isFile()) { throw new IOException("The javadoc executable '" + javadocExe + "' doesn't exist or is not a file. Verify the JAVA_HOME environment variable."); } return javadocExe.getAbsolutePath(); } private void setFJavadocVersion(File jExecutable) throws MavenReportException { float jVersion; try { jVersion = getJavadocVersion(jExecutable); } catch (IOException e) { if (getLog().isWarnEnabled()) { getLog().warn("Unable to find the javadoc version: " + e.getMessage()); getLog().warn("Using the Java version instead of, i.e. " + SystemUtils.JAVA_VERSION_FLOAT); } jVersion = SystemUtils.JAVA_VERSION_FLOAT; } catch (CommandLineException e) { if (getLog().isWarnEnabled()) { getLog().warn("Unable to find the javadoc version: " + e.getMessage()); getLog().warn("Using the Java the version instead of, i.e. " + SystemUtils.JAVA_VERSION_FLOAT); } jVersion = SystemUtils.JAVA_VERSION_FLOAT; } catch (IllegalArgumentException e) { if (getLog().isWarnEnabled()) { getLog().warn("Unable to find the javadoc version: " + e.getMessage()); getLog().warn("Using the Java the version instead of, i.e. " + SystemUtils.JAVA_VERSION_FLOAT); } jVersion = SystemUtils.JAVA_VERSION_FLOAT; } // if (StringUtils.isNotEmpty(javadocVersion)) { // try { // fJavadocVersion = Float.parseFloat(javadocVersion); // } catch (NumberFormatException e) { // throw new MavenReportException("Unable to parse javadoc version: " + e.getMessage(), e); // } // // if (fJavadocVersion != jVersion && getLog().isWarnEnabled()) { // getLog().warn("Are you sure about the parameter? It seems to be " + jVersion); // } // } else { fJavadocVersion = jVersion; // } } protected String getOutputDirectory() { return outputDirectory.getAbsoluteFile().toString(); } // private void copyAllResources(File javadocOutputDirectory) // throws MavenReportException { // // ---------------------------------------------------------------------- // // Copy default resources // // ---------------------------------------------------------------------- // // try { // copyDefaultStylesheet(javadocOutputDirectory); // } catch (IOException e) { // throw new MavenReportException("Unable to copy default stylesheet: " + e.getMessage(), e); // } // // // ---------------------------------------------------------------------- // // Copy javadoc resources // // ---------------------------------------------------------------------- // // if (docfilessubdirs) { // /* // * Workaround since -docfilessubdirs doesn't seem to be used correctly by the javadoc tool // * (see other note about -sourcepath). Take care of the -excludedocfilessubdir option. // */ // try { // copyJavadocResources(javadocOutputDirectory); // } catch (IOException e) { // throw new MavenReportException("Unable to copy javadoc resources: " + e.getMessage(), e); // } // } // // // ---------------------------------------------------------------------- // // Copy additional javadoc resources in artifacts // // ---------------------------------------------------------------------- // // copyAdditionalJavadocResources(javadocOutputDirectory); // } private void addMemoryArg(Commandline cmd, String arg, String memory) { if (StringUtils.isNotEmpty(memory)) { try { cmd.createArg().setValue("-J" + arg + parseJavadocMemory(memory)); } catch (IllegalArgumentException e) { if (getLog().isErrorEnabled()) { getLog().error("Malformed memory pattern for '" + arg + memory + "'. Ignore this option."); } } } } private void addProxyArg(Commandline cmd) { // // backward compatible // if (StringUtils.isNotEmpty(proxyHost)) { // if (getLog().isWarnEnabled()) { // getLog().warn( // "The Javadoc plugin parameter 'proxyHost' is deprecated since 2.4. " // + "Please configure an active proxy in your settings.xml."); // } // cmd.createArg().setValue("-J-DproxyHost=" + proxyHost); // // if (proxyPort > 0) { // if (getLog().isWarnEnabled()) { // getLog().warn( // "The Javadoc plugin parameter 'proxyPort' is deprecated since 2.4. " // + "Please configure an active proxy in your settings.xml."); // } // cmd.createArg().setValue("-J-DproxyPort=" + proxyPort); // } // } if (settings == null || settings.getActiveProxy() == null) { return; } Proxy activeProxy = settings.getActiveProxy(); String protocol = StringUtils.isNotEmpty(activeProxy.getProtocol()) ? activeProxy.getProtocol() + "." : ""; if (StringUtils.isNotEmpty(activeProxy.getHost())) { cmd.createArg().setValue("-J-D" + protocol + "proxySet=true"); cmd.createArg().setValue("-J-D" + protocol + "proxyHost=" + activeProxy.getHost()); if (activeProxy.getPort() > 0) { cmd.createArg().setValue("-J-D" + protocol + "proxyPort=" + activeProxy.getPort()); } if (StringUtils.isNotEmpty(activeProxy.getNonProxyHosts())) { cmd.createArg().setValue( "-J-D" + protocol + "nonProxyHosts=\"" + activeProxy.getNonProxyHosts() + "\""); } if (StringUtils.isNotEmpty(activeProxy.getUsername())) { cmd.createArg().setValue("-J-Dhttp.proxyUser=\"" + activeProxy.getUsername() + "\""); if (StringUtils.isNotEmpty(activeProxy.getPassword())) { cmd.createArg().setValue("-J-Dhttp.proxyPassword=\"" + activeProxy.getPassword() + "\""); } } } } private void addJavadocOptions(List arguments, List sourcePaths) throws MavenReportException { validateJavadocOptions(); // see com.sun.tools.javadoc.Start#parseAndExecute(String argv[]) // addArgIfNotEmpty(arguments, "-locale", quotedArgument(this.locale)); // all options in alphabetical order // if (old && isJavaDocVersionAtLeast(SINCE_JAVADOC_1_4)) { // if (getLog().isWarnEnabled()) { // getLog().warn("Javadoc 1.4+ doesn't support the -1.1 switch anymore. Ignore this option."); // } // } else { // addArgIf(arguments, old, "-1.1"); // } addArgIfNotEmpty(arguments, "-bootclasspath", quotedPathArgument(getBootclassPath())); // if (isJavaDocVersionAtLeast(SINCE_JAVADOC_1_5)) { // addArgIf(arguments, breakiterator, "-breakiterator", SINCE_JAVADOC_1_5); // } addArgIfNotEmpty(arguments, "-classpath", quotedPathArgument(getClasspath())); addArgIfNotEmpty(arguments, "-doclet", quotedArgument("com.squeakysand.jsp.tldgenerator.TldGeneratorDoclet")); // if (StringUtils.isNotEmpty(doclet)) { // addArgIfNotEmpty(arguments, "-doclet", quotedArgument(doclet)); addArgIfNotEmpty(arguments, "-docletpath", quotedPathArgument(getDocletPath())); // } if (StringUtils.isEmpty(encoding)) { getLog().warn( "Source files encoding has not been set, using platform encoding " + ReaderFactory.FILE_ENCODING + ", i.e. build is platform dependent!"); } addArgIfNotEmpty(arguments, "-encoding", quotedArgument(getEncoding())); addArgIfNotEmpty(arguments, "-exclude", getExcludedPackages(sourcePaths), SINCE_JAVADOC_1_4); // addArgIfNotEmpty(arguments, "-extdirs", quotedPathArgument(unifyPathSeparator(extdirs))); // if ((getOverview() != null) && (getOverview().exists())) { // addArgIfNotEmpty(arguments, "-overview", // JavadocUtil.quotedPathArgument(getOverview().getAbsolutePath())); // } // arguments.add(getAccessLevel()); // if (isJavaDocVersionAtLeast(SINCE_JAVADOC_1_5)) { // addArgIf(arguments, quiet, "-quiet", SINCE_JAVADOC_1_5); // } addArgIfNotEmpty(arguments, "-source", quotedArgument("1.6"));//, SINCE_JAVADOC_1_4); if ((StringUtils.isEmpty(sourcepath)) && (StringUtils.isNotEmpty(subpackages))) { sourcepath = StringUtils.join(sourcePaths.iterator(), File.pathSeparator); } addArgIfNotEmpty(arguments, "-sourcepath", quotedPathArgument(getSourcePath(sourcePaths))); if (StringUtils.isNotEmpty(sourcepath) && isJavaDocVersionAtLeast(SINCE_JAVADOC_1_5)) { addArgIfNotEmpty(arguments, "-subpackages", subpackages, SINCE_JAVADOC_1_5); } addArgIf(arguments, verbose, "-verbose"); // addArgIfNotEmpty(arguments, null, additionalparam); } private void addTldGeneratorOptions(List arguments) { addArgIfNotEmpty(arguments, "-shortName", quotedPathArgument(shortName)); addArgIfNotEmpty(arguments, "-description", quotedPathArgument(description)); addArgIfNotEmpty(arguments, "-tlibVersion", quotedPathArgument(tlibVersion)); addArgIfNotEmpty(arguments, "-uri", quotedPathArgument(uri.toString())); addArgIfNotEmpty(arguments, "-validator", quotedPathArgument(validator)); addArgIfNotEmpty(arguments, "-specificationVersion", quotedPathArgument(specificationVersion)); addArgIfNotEmpty(arguments, "-tagFilesDir", quotedPathArgument(tagFilesDir.toString())); addArgIfNotEmpty(arguments, "-includetagfiles", quotedPathArgument(String.valueOf(includetagfiles))); } private void addStandardDocletOptions(File javadocOutputDirectory, List arguments) throws MavenReportException { // validateStandardDocletOptions(); // all options in alphabetical order // addArgIf(arguments, author, "-author"); // addArgIfNotEmpty(arguments, "-bottom", JavadocUtil.quotedArgument(getBottomText()), false, false); // if (!isJavaDocVersionAtLeast(SINCE_JAVADOC_1_5)) { // addArgIf(arguments, breakiterator, "-breakiterator", SINCE_JAVADOC_1_4); // } // addArgIfNotEmpty(arguments, "-charset", JavadocUtil.quotedArgument(getCharset())); addArgIfNotEmpty(arguments, "-d", quotedPathArgument(outputDirectory.toString())); // addArgIfNotEmpty(arguments, "-docencoding", quotedArgument(getDocencoding())); // addArgIf(arguments, docfilessubdirs, "-docfilessubdirs", SINCE_JAVADOC_1_4); // addArgIfNotEmpty(arguments, "-doctitle", JavadocUtil.quotedArgument(getDoctitle()), false, false); // if (docfilessubdirs) { // addArgIfNotEmpty(arguments, "-excludedocfilessubdir", // quotedPathArgument(excludedocfilessubdir), SINCE_JAVADOC_1_4); // } // addArgIfNotEmpty(arguments, "-footer", JavadocUtil.quotedArgument(footer), false, false); // addGroups(arguments); // addArgIfNotEmpty(arguments, "-header", JavadocUtil.quotedArgument(header), false, false); // addArgIfNotEmpty(arguments, "-helpfile", // JavadocUtil.quotedPathArgument(getHelpFile(javadocOutputDirectory))); // addArgIf(arguments, keywords, "-keywords", SINCE_JAVADOC_1_4_2); // if (!isOffline) { // addLinkArguments(arguments); // } // addLinkofflineArguments(arguments); // addArgIf(arguments, linksource, "-linksource", SINCE_JAVADOC_1_4); // if (sourcetab > 0) { // if (fJavadocVersion == SINCE_JAVADOC_1_4_2) { // addArgIfNotEmpty(arguments, "-linksourcetab", String.valueOf(sourcetab)); // } // addArgIfNotEmpty(arguments, "-sourcetab", String.valueOf(sourcetab), SINCE_JAVADOC_1_5); // } // addArgIf(arguments, nocomment, "-nocomment", SINCE_JAVADOC_1_4); // addArgIf(arguments, nodeprecated, "-nodeprecated"); // // addArgIf(arguments, nodeprecatedlist, "-nodeprecatedlist"); // // addArgIf(arguments, nohelp, "-nohelp"); // // addArgIf(arguments, noindex, "-noindex"); // // addArgIf(arguments, nonavbar, "-nonavbar"); // // addArgIf(arguments, nooverview, "-nooverview"); // // addArgIfNotEmpty(arguments, "-noqualifier", JavadocUtil.quotedArgument(noqualifier), SINCE_JAVADOC_1_4); // // addArgIf(arguments, nosince, "-nosince"); // // addArgIf(arguments, notimestamp, "-notimestamp", SINCE_JAVADOC_1_5); // // addArgIf(arguments, notree, "-notree"); // // addArgIfNotEmpty(arguments, "-packagesheader", JavadocUtil.quotedArgument(packagesheader), // SINCE_JAVADOC_1_4_2); // if (!isJavaDocVersionAtLeast(SINCE_JAVADOC_1_5)) // Sun bug: 4714350 // { // addArgIf(arguments, quiet, "-quiet", SINCE_JAVADOC_1_4); // } // addArgIf(arguments, serialwarn, "-serialwarn"); // // addArgIf(arguments, splitindex, "-splitindex"); // addArgIfNotEmpty(arguments, "-stylesheetfile", // JavadocUtil.quotedPathArgument(getStylesheetFile(javadocOutputDirectory))); // if (StringUtils.isNotEmpty(sourcepath) && !isJavaDocVersionAtLeast(SINCE_JAVADOC_1_5)) { // addArgIfNotEmpty(arguments, "-subpackages", subpackages, SINCE_JAVADOC_1_4); // } // addArgIfNotEmpty(arguments, "-taglet", JavadocUtil.quotedArgument(taglet), SINCE_JAVADOC_1_4); // addTaglets(arguments); // addTagletsFromTagletArtifacts(arguments); // addArgIfNotEmpty(arguments, "-tagletpath", JavadocUtil.quotedPathArgument(getTagletPath()), // SINCE_JAVADOC_1_4); // addTags(arguments); // addArgIfNotEmpty(arguments, "-top", JavadocUtil.quotedArgument(top), false, false, SINCE_JAVADOC_1_6); // // addArgIf(arguments, use, "-use"); // // addArgIf(arguments, version, "-version"); // addArgIfNotEmpty(arguments, "-windowtitle", JavadocUtil.quotedArgument(getWindowtitle()), false, false); } private void addCommandLineOptions(Commandline cmd, List arguments, File javadocOutputDirectory) throws MavenReportException { File optionsFile = new File(javadocOutputDirectory, OPTIONS_FILE_NAME); StringBuilder options = new StringBuilder(); options.append(StringUtils.join(arguments.toArray(new String[0]), SystemUtils.LINE_SEPARATOR)); try { FileUtils.fileWrite(optionsFile.getAbsolutePath(), options.toString()); } catch (IOException e) { throw new MavenReportException("Unable to write '" + optionsFile.getName() + "' temporary file for command execution", e); } cmd.createArg().setValue("@" + OPTIONS_FILE_NAME); } private void addCommandLinePackages(Commandline cmd, File javadocOutputDirectory, List packageNames) throws MavenReportException { File packagesFile = new File(javadocOutputDirectory, PACKAGES_FILE_NAME); try { FileUtils.fileWrite(packagesFile.getAbsolutePath(), StringUtils.join(packageNames.toArray(new String[0]), SystemUtils.LINE_SEPARATOR)); } catch (IOException e) { throw new MavenReportException("Unable to write '" + packagesFile.getName() + "' temporary file for command execution", e); } cmd.createArg().setValue("@" + PACKAGES_FILE_NAME); } protected MavenProject getProject() { return project; } /** * @param p not null maven project * @return the list of directories where compiled classes are placed for the given project. These dirs are * added in the javadoc classpath. */ protected List getProjectBuildOutputDirs(MavenProject p) { if (StringUtils.isEmpty(p.getBuild().getOutputDirectory())) { return Collections.emptyList(); } return Collections.singletonList(p.getBuild().getOutputDirectory()); } /** * @param p not null maven project * @return the list of source paths for the given project */ protected List getProjectSourceRoots(MavenProject p) { if ("pom".equals(p.getPackaging().toLowerCase())) { return Collections.emptyList(); } return (p.getCompileSourceRoots() == null ? Collections.EMPTY_LIST : new LinkedList(p.getCompileSourceRoots())); } /** * @param p not null maven project * @return the list of source paths for the execution project of the given project */ protected List getExecutionProjectSourceRoots(MavenProject p) { if ("pom".equals(p.getExecutionProject().getPackaging().toLowerCase())) { return Collections.emptyList(); } return (p.getExecutionProject().getCompileSourceRoots() == null ? Collections.emptyList() : new LinkedList(p.getExecutionProject().getCompileSourceRoots())); } /** * @param p not null maven project * @return the list of artifacts for the given project */ protected List getProjectArtifacts(MavenProject p) { List compileArtifacts = p.getCompileArtifacts(); // getLog().info("compile artifacts: " + ToStringHelper.toString(compileArtifacts)); return (compileArtifacts == null ? Collections.emptyList() : new LinkedList(p.getCompileArtifacts())); } // /** // * @return the current javadoc directory // */ // protected File getJavadocDirectory() { // return javadocDirectory; // } // /** // * @return the title to be placed near the top of the overview summary file // */ // protected String getDoctitle() { // return doctitle; // } // /** // * @return the overview documentation file from the user parameter or from the javadocdirectory // */ // protected File getOverview() { // return overview; // } // /** // * @return the title to be placed in the HTML title tag // */ // protected String getWindowtitle() { // return windowtitle; // } // /** // * @return the charset attribute or the value of {@link #getDocencoding()} if null. // */ // private String getCharset() { // return (StringUtils.isEmpty(charset)) ? getDocencoding() : charset; // } // /** // * @return the docencoding attribute or UTF-8 if null. // */ // private String getDocencoding() { // return (StringUtils.isEmpty(docencoding)) ? ReaderFactory.UTF_8 : docencoding; // } /** * @return the encoding attribute or the value of file.encoding system property if null. */ private String getEncoding() { return (StringUtils.isEmpty(encoding)) ? ReaderFactory.FILE_ENCODING : encoding; } // /** // * Override this method to customize the configuration for resolving dependency sources. The default // * behavior enables the resolution of -sources jar files. // */ // private SourceResolverConfig configureDependencySourceResolution(final SourceResolverConfig config) { // return config.withCompileSources(); // } // /** // * Resolve dependency sources so they can be included directly in the javadoc process. To customize this, // * override {@link AbstractJavadocMojo#configureDependencySourceResolution(SourceResolverConfig)}. // */ // protected final List getDependencySourcePaths() // throws MavenReportException { // try { // if (sourceDependencyCacheDir.exists()) { // FileUtils.forceDelete(sourceDependencyCacheDir); // sourceDependencyCacheDir.mkdirs(); // } // } catch (IOException e) { // throw new MavenReportException("Failed to delete cache directory: " + sourceDependencyCacheDir + "\nReason: " + e.getMessage(), e); // } // // final SourceResolverConfig config = getDependencySourceResolverConfig(); // // final AndArtifactFilter andFilter = new AndArtifactFilter(); // // final List dependencyIncludes = dependencySourceIncludes; // final List dependencyExcludes = dependencySourceExcludes; // // if (isNotEmpty(dependencyIncludes) || isNotEmpty(dependencyExcludes)) { // if (isNotEmpty(dependencyIncludes)) { // andFilter.add(new PatternIncludesArtifactFilter(dependencyIncludes, // !includeTransitiveDependencySources)); // } // // if (isNotEmpty(dependencyExcludes)) { // andFilter.add(new PatternExcludesArtifactFilter(dependencyExcludes, // !includeTransitiveDependencySources)); // } // // config.withFilter(andFilter); // } // // try { // return ResourceResolver.resolveDependencySourcePaths(config); // } catch (final ArtifactResolutionException e) { // throw new MavenReportException("Failed to resolve one or more javadoc source/resource artifacts:\n\n" // + e.getMessage(), e); // } catch (final ArtifactNotFoundException e) { // throw new MavenReportException("Failed to resolve one or more javadoc source/resource artifacts:\n\n" // + e.getMessage(), e); // } // } // /** // * Construct a SourceResolverConfig for resolving dependency sources and resources in a consistent // * way, so it can be reused for both source and resource resolution. // * // * @since 2.7 // */ // private SourceResolverConfig getDependencySourceResolverConfig() { // return configureDependencySourceResolution(new SourceResolverConfig(getLog(), project, localRepository, // sourceDependencyCacheDir, resolver, // factory, artifactMetadataSource, // archiverManager).withReactorProjects(reactorProjects)); // } /** * @param result not null * @return the compile artifacts from the result * @see JavadocUtil#getCompileArtifacts(Set, boolean) */ private List getCompileArtifacts(ArtifactResolutionResult result) { return getCompileArtifacts(result.getArtifacts(), false); } // ---------------------------------------------------------------------- // private methods // ---------------------------------------------------------------------- /** * Method to get the excluded source files from the javadoc and create the argument string * that will be included in the javadoc commandline execution. * * @param sourcePaths the list of paths to the source files * @return a String that contains the exclude argument that will be used by javadoc * @throws MavenReportException */ private String getExcludedPackages(List sourcePaths) throws MavenReportException { List excludedNames = null; if (StringUtils.isNotEmpty(sourcepath) && StringUtils.isNotEmpty(subpackages)) { String[] excludedPackages = getExcludedPackages(); String[] subpackagesList = subpackages.split("[:]"); excludedNames = getExcludedNames(sourcePaths, subpackagesList, excludedPackages); } String excludeArg = ""; if (StringUtils.isNotEmpty(subpackages) && excludedNames != null) { // add the excludedpackage names excludeArg = StringUtils.join(excludedNames.iterator(), ":"); } return excludeArg; } /** * Method to format the specified source paths that will be accepted by the javadoc tool. * * @param sourcePaths the list of paths to the source files that will be included in the javadoc. * @return a String that contains the formatted source path argument, separated by the System pathSeparator * string (colon (:) on Solaris or semi-colon (;) on Windows). * @see File#pathSeparator */ private String getSourcePath(List sourcePaths) { String sourcePath = null; if (StringUtils.isEmpty(subpackages) || StringUtils.isNotEmpty(sourcepath)) { sourcePath = StringUtils.join(sourcePaths.iterator(), File.pathSeparator); } return sourcePath; } /** * Method to get the packages specified in the excludePackageNames parameter. The packages are split * with ',', ':', or ';' and then formatted. * * @return an array of String objects that contain the package names * @throws MavenReportException */ private String[] getExcludedPackages() throws MavenReportException { Set excluded = new LinkedHashSet(); // if (includeDependencySources) { // try { // resolveDependencyBundles(); // } catch (IOException e) { // throw new MavenReportException("Failed to resolve javadoc bundles from dependencies: " + e.getMessage(), e); // } // // if (isNotEmpty(dependencyJavadocBundles)) { // for (JavadocBundle bundle : dependencyJavadocBundles) { // JavadocOptions options = bundle.getOptions(); // if (options != null && isNotEmpty(options.getExcludePackageNames())) { // excluded.addAll(options.getExcludePackageNames()); // } // } // } // } // for the specified excludePackageNames if (StringUtils.isNotEmpty(excludePackageNames)) { excluded.addAll(Arrays.asList(excludePackageNames.split("[,:;]"))); } String[] result = new String[excluded.size()]; if (isNotEmpty(excluded)) { int idx = 0; for (String exclude : excluded) { result[idx] = exclude.replace('.', File.separatorChar); idx++; } } return result; } /** * Method that sets the classpath elements that will be specified in the javadoc -classpath * parameter. * * @return a String that contains the concatenated classpath elements, separated by the System pathSeparator * string (colon (:) on Solaris or semi-colon (;) on Windows). * @throws MavenReportException if any. * @see File#pathSeparator */ private String getClasspath() throws MavenReportException { List classpathElements = new ArrayList(); Map compileArtifactMap = new HashMap(); classpathElements.addAll(getProjectBuildOutputDirs(project)); populateCompileArtifactMap(compileArtifactMap, getProjectArtifacts(project)); // if (isAggregator() && project.isExecutionRoot()) { // try { // for (MavenProject subProject : reactorProjects) { // if (subProject != project) { // classpathElements.addAll(getProjectBuildOutputDirs(subProject)); // // Set dependencyArtifacts = subProject.createArtifacts(artifactFactory, null, null); // if (!dependencyArtifacts.isEmpty()) { // ArtifactResolutionResult result = null; // try { // result = // artifactResolver.resolveTransitively(dependencyArtifacts, subProject.getArtifact(), // subProject.getManagedVersionMap(), // localRepository, // subProject.getRemoteArtifactRepositories(), // artifactMetadataSource); // } catch (MultipleArtifactsNotFoundException e) { // if (checkMissingArtifactsInReactor(dependencyArtifacts, e.getMissingArtifacts())) { // getLog().warn("IGNORED to add some artifacts in the classpath. See above."); // } else { // // we can't find all the artifacts in the reactor so bubble the exception up. // throw new MavenReportException(e.getMessage(), e); // } // } catch (ArtifactNotFoundException e) { // throw new MavenReportException(e.getMessage(), e); // } catch (ArtifactResolutionException e) { // throw new MavenReportException(e.getMessage(), e); // } // // if (result == null) { // continue; // } // // populateCompileArtifactMap(compileArtifactMap, getCompileArtifacts(result)); // // if (getLog().isDebugEnabled()) { // StringBuilder sb = new StringBuilder(); // // sb.append("Compiled artifacts for "); // sb.append(subProject.getGroupId()).append(":"); // sb.append(subProject.getArtifactId()).append(":"); // sb.append(subProject.getVersion()).append('\n'); // for (String key : compileArtifactMap.keySet()) { // Artifact a = compileArtifactMap.get(key); // sb.append(a.getFile()).append('\n'); // } // // getLog().debug(sb.toString()); // } // } // } // } // } catch (InvalidDependencyVersionException e) { // throw new MavenReportException(e.getMessage(), e); // } // } for (Artifact a : compileArtifactMap.values()) { classpathElements.add(a.getFile().toString()); } String result = StringUtils.join(classpathElements.iterator(), File.pathSeparator); // getLog().info("classpath set to be: " + result); return result; } /** * TODO remove the part with ToolchainManager lookup once we depend on * 2.0.9 (have it as prerequisite). Define as regular component field then. * * @return Toolchain instance */ private Toolchain getToolchain() { Toolchain tc = null; if (toolchainManager != null) { tc = toolchainManager.getToolchainFromBuildContext("jdk", session); } return tc; } /** * Method to put the artifacts in the hashmap. * * @param compileArtifactMap the hashmap that will contain the artifacts * @param artifactList the list of artifacts that will be put in the map * @throws MavenReportException if any */ private void populateCompileArtifactMap(Map compileArtifactMap, Collection artifactList) throws MavenReportException { if (artifactList == null) { return; } for (Artifact newArtifact : artifactList) { File file = newArtifact.getFile(); if (file == null) { throw new MavenReportException("Error in plugin descriptor - " + "dependency was not resolved for artifact: " + newArtifact.getGroupId() + ":" + newArtifact.getArtifactId() + ":" + newArtifact.getVersion()); } if (compileArtifactMap.get(newArtifact.getDependencyConflictId()) != null) { Artifact oldArtifact = compileArtifactMap.get(newArtifact.getDependencyConflictId()); ArtifactVersion oldVersion = new DefaultArtifactVersion(oldArtifact.getVersion()); ArtifactVersion newVersion = new DefaultArtifactVersion(newArtifact.getVersion()); if (newVersion.compareTo(oldVersion) > 0) { compileArtifactMap.put(newArtifact.getDependencyConflictId(), newArtifact); } } else { compileArtifactMap.put(newArtifact.getDependencyConflictId(), newArtifact); } } } // /** // * Method that sets the bottom text that will be displayed on the bottom of the // * javadocs. // * // * @return a String that contains the text that will be displayed at the bottom of the javadoc // */ // private String getBottomText() { // int actualYear = Calendar.getInstance().get(Calendar.YEAR); // String year = String.valueOf(actualYear); // // String inceptionYear = project.getInceptionYear(); // // String theBottom = StringUtils.replace(this.bottom, "{currentYear}", year); // // if (inceptionYear != null) { // if (inceptionYear.equals(year)) { // theBottom = StringUtils.replace(theBottom, "{inceptionYear}-", ""); // } else { // theBottom = StringUtils.replace(theBottom, "{inceptionYear}", inceptionYear); // } // } else { // theBottom = StringUtils.replace(theBottom, "{inceptionYear}-", ""); // } // // if (project.getOrganization() == null) { // theBottom = StringUtils.replace(theBottom, " {organizationName}", ""); // } else { // if (StringUtils.isNotEmpty(project.getOrganization().getName())) { // if (StringUtils.isNotEmpty(project.getOrganization().getUrl())) { // theBottom = // StringUtils.replace(theBottom, "{organizationName}", "" + project.getOrganization().getName() // + ""); // } else { // theBottom = // StringUtils.replace(theBottom, "{organizationName}", project.getOrganization().getName()); // } // } else { // theBottom = StringUtils.replace(theBottom, " {organizationName}", ""); // } // } // // return theBottom; // } // /** // * Method to get the stylesheet path file to be used by the Javadoc Tool. // *
// * If the {@link #stylesheetfile} is empty, return the file as String definded by {@link #stylesheet} value. // *
// * If the {@link #stylesheetfile} is defined, return the file as String. // *
// * Note: since 2.6, the {@link #stylesheetfile} could be a path from a resource in the project source // * directories (i.e. src/main/java, src/main/resources or src/main/javadoc) // * or from a resource in the Javadoc plugin dependencies. // * // * @param javadocOutputDirectory the output directory // * @return the stylesheet file absolute path as String. // * @see #getResource(List, String) // */ // private String getStylesheetFile(final File javadocOutputDirectory) { // if (StringUtils.isEmpty(stylesheetfile)) { // if ("java".equalsIgnoreCase(stylesheet)) { // // use the default Javadoc tool stylesheet // return null; // } // // // maven, see #copyDefaultStylesheet(File) // return new File(javadocOutputDirectory, DEFAULT_CSS_NAME).getAbsolutePath(); // } // // if (new File(stylesheetfile).exists()) { // return new File(stylesheetfile).getAbsolutePath(); // } // // return getResource(new File(javadocOutputDirectory, DEFAULT_CSS_NAME), stylesheetfile); // } // /** // * Method to get the help file to be used by the Javadoc Tool. // *
// * Since 2.6, the {@link #helpfile} could be a path from a resource in the project source // * directories (i.e. src/main/java, src/main/resources or src/main/javadoc) // * or from a resource in the Javadoc plugin dependencies. // * // * @param javadocOutputDirectory the output directory. // * @return the help file absolute path as String. // * @since 2.6 // * @see #getResource(File, String) // */ // private String getHelpFile(final File javadocOutputDirectory) { // if (StringUtils.isEmpty(helpfile)) { // return null; // } // // if (new File(helpfile).exists()) { // return new File(helpfile).getAbsolutePath(); // } // // return getResource(new File(javadocOutputDirectory, "help-doc.html"), helpfile); // } // /** // * Method to get the access level for the classes and members to be shown in the generated javadoc. // * If the specified access level is not public, protected, package or private, the access level // * is set to protected. // * // * @return the access level // */ // private String getAccessLevel() { // String accessLevel; // if ("public".equalsIgnoreCase(show) || "protected".equalsIgnoreCase(show) // || "package".equalsIgnoreCase(show) || "private".equalsIgnoreCase(show)) { // accessLevel = "-" + show; // } else { // if (getLog().isErrorEnabled()) { // getLog().error("Unrecognized access level to show '" + show + "'. Defaulting to protected."); // } // accessLevel = "-protected"; // } // // return accessLevel; // } /** * Method to get the path of the bootclass artifacts used in the -bootclasspath option. * * @return a string that contains bootclass path, separated by the System pathSeparator string * (colon (:) on Solaris or semi-colon (;) on Windows). * @throws MavenReportException if any * @see File#pathSeparator */ private String getBootclassPath() throws MavenReportException { Set bootclasspathArtifacts = collectBootClasspathArtifacts(); List bootclassPath = new ArrayList(); for (BootclasspathArtifact aBootclasspathArtifact : bootclasspathArtifacts) { if ((StringUtils.isNotEmpty(aBootclasspathArtifact.getGroupId())) && (StringUtils.isNotEmpty(aBootclasspathArtifact.getArtifactId())) && (StringUtils.isNotEmpty(aBootclasspathArtifact.getVersion()))) { bootclassPath.addAll(getArtifactsAbsolutePath(aBootclasspathArtifact)); } } bootclassPath = pruneFiles(bootclassPath); StringBuilder path = new StringBuilder(); path.append(StringUtils.join(bootclassPath.iterator(), File.pathSeparator)); // if (StringUtils.isNotEmpty(bootclasspath)) { // path.append(unifyPathSeparator(bootclasspath)); // } return path.toString(); } /** * Method to get the path of the doclet artifacts used in the -docletpath option. * * Either docletArtifact or doclectArtifacts can be defined and used, not both, docletArtifact * takes precedence over doclectArtifacts. docletPath is always appended to any result path * definition. * * @return a string that contains doclet path, separated by the System pathSeparator string * (colon (:) on Solaris or semi-colon (;) on Windows). * @throws MavenReportException if any * @see File#pathSeparator */ private String getDocletPath() throws MavenReportException { Set docletArtifacts = collectDocletArtifacts(); List pathParts = new ArrayList(); for (DocletArtifact docletArtifact : docletArtifacts) { if (!isDocletArtifactEmpty(docletArtifact)) { pathParts.addAll(getArtifactsAbsolutePath(docletArtifact)); } } StringBuilder path = new StringBuilder(); path.append(StringUtils.join(pathParts.iterator(), File.pathSeparator)); // if (!StringUtils.isEmpty(docletPath)) { // path.append(JavadocUtil.unifyPathSeparator(docletPath)); // } if (StringUtils.isEmpty(path.toString()) && getLog().isWarnEnabled()) { getLog().warn( "No docletpath option was found. Please review or " + " or ."); } return path.toString(); } /** * Verify if a doclet artifact is empty or not * * @param aDocletArtifact could be null * @return true if aDocletArtifact or the groupId/artifactId/version of the doclet artifact is null, * false otherwise. */ private boolean isDocletArtifactEmpty(DocletArtifact aDocletArtifact) { if (aDocletArtifact == null) { return true; } return StringUtils.isEmpty(aDocletArtifact.getGroupId()) && StringUtils.isEmpty(aDocletArtifact.getArtifactId()) && StringUtils.isEmpty(aDocletArtifact.getVersion()); } // /** // * Method to get the path of the taglet artifacts used in the -tagletpath option. // * // * @return a string that contains taglet path, separated by the System pathSeparator string // * (colon (:) on Solaris or semi-colon (;) on Windows). // * @throws MavenReportException if any // * @see File#pathSeparator // */ // private String getTagletPath() // throws MavenReportException { // Set tArtifacts = collectTagletArtifacts(); // List pathParts = new ArrayList(); // // for (TagletArtifact tagletArtifact : tArtifacts) { // if ((tagletArtifact != null) && (StringUtils.isNotEmpty(tagletArtifact.getGroupId())) // && (StringUtils.isNotEmpty(tagletArtifact.getArtifactId())) // && (StringUtils.isNotEmpty(tagletArtifact.getVersion()))) { // pathParts.addAll(getArtifactsAbsolutePath(tagletArtifact)); // } // } // // // Set taglets = collectTaglets(); // for (Taglet taglet : taglets) { // if (taglet == null) { // continue; // } // // if ((taglet.getTagletArtifact() != null) // && (StringUtils.isNotEmpty(taglet.getTagletArtifact().getGroupId())) // && (StringUtils.isNotEmpty(taglet.getTagletArtifact().getArtifactId())) // && (StringUtils.isNotEmpty(taglet.getTagletArtifact().getVersion()))) { // pathParts.addAll(getArtifactsAbsolutePath(taglet.getTagletArtifact())); // // pathParts = JavadocUtil.pruneFiles(pathParts); // } else if (StringUtils.isNotEmpty(taglet.getTagletpath())) { // pathParts.add(taglet.getTagletpath()); // // pathParts = JavadocUtil.pruneDirs(project, pathParts); // } // } // // StringBuilder path = new StringBuilder(); // path.append(StringUtils.join(pathParts.iterator(), File.pathSeparator)); // // if (StringUtils.isNotEmpty(tagletpath)) { // path.append(JavadocUtil.unifyPathSeparator(tagletpath)); // } // // return path.toString(); // } // private Set collectLinks() // throws MavenReportException { // Set links = new LinkedHashSet(); // // if (includeDependencySources) { // try { // resolveDependencyBundles(); // } catch (IOException e) { // throw new MavenReportException("Failed to resolve javadoc bundles from dependencies: " + e.getMessage(), e); // } // // if (isNotEmpty(dependencyJavadocBundles)) { // for (JavadocBundle bundle : dependencyJavadocBundles) { // JavadocOptions options = bundle.getOptions(); // if (options != null && isNotEmpty(options.getLinks())) { // links.addAll(options.getLinks()); // } // } // } // } // // if (isNotEmpty(this.links)) { // links.addAll(this.links); // } // // links.addAll(getDependenciesLinks()); // // return links; // } // private Set collectGroups() // throws MavenReportException { // Set groups = new LinkedHashSet(); // // if (includeDependencySources) { // try { // resolveDependencyBundles(); // } catch (IOException e) { // throw new MavenReportException("Failed to resolve javadoc bundles from dependencies: " + e.getMessage(), e); // } // // if (isNotEmpty(dependencyJavadocBundles)) { // for (JavadocBundle bundle : dependencyJavadocBundles) { // JavadocOptions options = bundle.getOptions(); // if (options != null && isNotEmpty(options.getGroups())) { // groups.addAll(options.getGroups()); // } // } // } // } // // if (this.groups != null && this.groups.length > 0) { // groups.addAll(Arrays.asList(this.groups)); // } // // return groups; // } // private Set collectResourcesArtifacts() // throws MavenReportException { // Set result = new LinkedHashSet(); // // if (includeDependencySources) { // try { // resolveDependencyBundles(); // } catch (IOException e) { // throw new MavenReportException("Failed to resolve javadoc bundles from dependencies: " // + e.getMessage(), e); // } // // if (isNotEmpty(dependencyJavadocBundles)) { // for (JavadocBundle bundle : dependencyJavadocBundles) { // JavadocOptions options = bundle.getOptions(); // if (options != null && isNotEmpty(options.getResourcesArtifacts())) { // result.addAll(options.getResourcesArtifacts()); // } // } // } // } // // if (this.resourcesArtifacts != null && this.resourcesArtifacts.length > 0) { // result.addAll(Arrays.asList(this.resourcesArtifacts)); // } // // return result; // } private Set collectBootClasspathArtifacts() throws MavenReportException { Set result = new LinkedHashSet(); // if (includeDependencySources) { // try { // resolveDependencyBundles(); // } catch (IOException e) { // throw new MavenReportException("Failed to resolve javadoc bundles from dependencies: " // + e.getMessage(), e); // } // // if (isNotEmpty(dependencyJavadocBundles)) { // for (JavadocBundle bundle : dependencyJavadocBundles) { // JavadocOptions options = bundle.getOptions(); // if (options != null && isNotEmpty(options.getBootclasspathArtifacts())) { // result.addAll(options.getBootclasspathArtifacts()); // } // } // } // } // if (this.bootclasspathArtifacts != null && this.bootclasspathArtifacts.length > 0) { // result.addAll(Arrays.asList(this.bootclasspathArtifacts)); // } return result; } // private Set collectOfflineLinks() // throws MavenReportException { // Set result = new LinkedHashSet(); // // OfflineLink javaApiLink = getDefaultJavadocApiLink(); // if (javaApiLink != null) { // result.add(javaApiLink); // } // // if (includeDependencySources) { // try { // resolveDependencyBundles(); // } catch (IOException e) { // throw new MavenReportException("Failed to resolve javadoc bundles from dependencies: " // + e.getMessage(), e); // } // // if (isNotEmpty(dependencyJavadocBundles)) { // for (JavadocBundle bundle : dependencyJavadocBundles) { // JavadocOptions options = bundle.getOptions(); // if (options != null && isNotEmpty(options.getOfflineLinks())) { // result.addAll(options.getOfflineLinks()); // } // } // } // } // // if (this.offlineLinks != null && this.offlineLinks.length > 0) { // result.addAll(Arrays.asList(this.offlineLinks)); // } // // return result; // } // private Set collectTags() // throws MavenReportException { // Set tags = new LinkedHashSet(); // // if (includeDependencySources) { // try { // resolveDependencyBundles(); // } catch (IOException e) { // throw new MavenReportException("Failed to resolve javadoc bundles from dependencies: " // + e.getMessage(), e); // } // // if (isNotEmpty(dependencyJavadocBundles)) { // for (JavadocBundle bundle : dependencyJavadocBundles) { // JavadocOptions options = bundle.getOptions(); // if (options != null && isNotEmpty(options.getTags())) { // tags.addAll(options.getTags()); // } // } // } // } // // if (this.tags != null && this.tags.length > 0) { // tags.addAll(Arrays.asList(this.tags)); // } // // return tags; // } // private Set collectTagletArtifacts() // throws MavenReportException { // Set tArtifacts = new LinkedHashSet(); // // if (includeDependencySources) { // try { // resolveDependencyBundles(); // } catch (IOException e) { // throw new MavenReportException("Failed to resolve javadoc bundles from dependencies: " + e.getMessage(), e); // } // // if (isNotEmpty(dependencyJavadocBundles)) { // for (JavadocBundle bundle : dependencyJavadocBundles) { // JavadocOptions options = bundle.getOptions(); // if (options != null && isNotEmpty(options.getTagletArtifacts())) { // tArtifacts.addAll(options.getTagletArtifacts()); // } // } // } // } // // if (tagletArtifact != null) { // tArtifacts.add(tagletArtifact); // } // // if (tagletArtifacts != null && tagletArtifacts.length > 0) { // tArtifacts.addAll(Arrays.asList(tagletArtifacts)); // } // // return tArtifacts; // } private Set collectDocletArtifacts() throws MavenReportException { Set dArtifacts = new LinkedHashSet(); // if (includeDependencySources) { // try { // resolveDependencyBundles(); // } catch (IOException e) { // throw new MavenReportException("Failed to resolve javadoc bundles from dependencies: " // + e.getMessage(), e); // } // // if (isNotEmpty(dependencyJavadocBundles)) { // for (JavadocBundle bundle : dependencyJavadocBundles) { // JavadocOptions options = bundle.getOptions(); // if (options != null && isNotEmpty(options.getDocletArtifacts())) { // dArtifacts.addAll(options.getDocletArtifacts()); // } // } // } // } // add the tld generator jar DocletArtifact tldArtifact = new DocletArtifact(); tldArtifact.setGroupId("com.squeakysand"); tldArtifact.setArtifactId("squeakysand-jsp-tldgenerator"); tldArtifact.setVersion("0.1.0-SNAPSHOT"); dArtifacts.add(tldArtifact); // add an SLF4J implementation DocletArtifact slf4jArtifact = new DocletArtifact(); slf4jArtifact.setGroupId("org.slf4j"); slf4jArtifact.setArtifactId("slf4j-simple"); slf4jArtifact.setVersion("1.6.4"); dArtifacts.add(slf4jArtifact); // if (docletArtifact != null) { // dArtifacts.add(tldArtifact); // } // if (docletArtifacts != null && docletArtifacts.length > 0) { // dArtifacts.addAll(Arrays.asList(docletArtifacts)); // } return dArtifacts; } // private Set collectTaglets() // throws MavenReportException { // Set result = new LinkedHashSet(); // // if (includeDependencySources) { // try { // resolveDependencyBundles(); // } catch (IOException e) { // throw new MavenReportException("Failed to resolve javadoc bundles from dependencies: " // + e.getMessage(), e); // } // // if (isNotEmpty(dependencyJavadocBundles)) { // for (JavadocBundle bundle : dependencyJavadocBundles) { // JavadocOptions options = bundle.getOptions(); // if (options != null && isNotEmpty(options.getTaglets())) { // result.addAll(options.getTaglets()); // } // } // } // } // // if (taglets != null && taglets.length > 0) { // result.addAll(Arrays.asList(taglets)); // } // // return result; // } /** * Return the Javadoc artifact path and its transitive dependencies path from the local repository * * @param javadocArtifact not null * @return a list of locale artifacts absolute path * @throws MavenReportException if any */ private List getArtifactsAbsolutePath(JavadocPathArtifact javadocArtifact) throws MavenReportException { if ((StringUtils.isEmpty(javadocArtifact.getGroupId())) && (StringUtils.isEmpty(javadocArtifact.getArtifactId())) && (StringUtils.isEmpty(javadocArtifact.getVersion()))) { return Collections.emptyList(); } List path = new ArrayList(); try { Artifact artifact = createAndResolveArtifact(javadocArtifact); path.add(artifact.getFile().getAbsolutePath()); // Find its transitive dependencies in the local repo MavenProject artifactProject = mavenProjectBuilder.buildFromRepository(artifact, remoteRepositories, localRepository); Set dependencyArtifacts = artifactProject.createArtifacts(artifactFactory, null, null); if (!dependencyArtifacts.isEmpty()) { ArtifactResolutionResult result = artifactResolver.resolveTransitively(dependencyArtifacts, artifactProject.getArtifact(), artifactProject.getRemoteArtifactRepositories(), localRepository, artifactMetadataSource); Set artifacts = result.getArtifacts(); Map compileArtifactMap = new HashMap(); populateCompileArtifactMap(compileArtifactMap, artifacts); for (Artifact a : compileArtifactMap.values()) { path.add(a.getFile().getAbsolutePath()); } } return path; } catch (ArtifactResolutionException e) { throw new MavenReportException("Unable to resolve artifact:" + javadocArtifact, e); } catch (ArtifactNotFoundException e) { throw new MavenReportException("Unable to find artifact:" + javadocArtifact, e); } catch (ProjectBuildingException e) { throw new MavenReportException("Unable to build the Maven project for the artifact:" + javadocArtifact, e); // } catch (InvalidDependencyVersionException e) { // throw new MavenReportException("Unable to resolve artifact:" + javadocArtifact, e); } } /** * creates an {@link Artifact} representing the configured {@link JavadocPathArtifact} and resolves it. * * @param javadocArtifact the {@link JavadocPathArtifact} to resolve * @return a resolved {@link Artifact} * @throws ArtifactResolutionException if the resolution of the artifact failed. * @throws ArtifactNotFoundException if the artifact hasn't been found. * @throws ProjectBuildingException if the artifact POM could not be build. */ private Artifact createAndResolveArtifact(JavadocPathArtifact javadocArtifact) throws ArtifactResolutionException, ArtifactNotFoundException, ProjectBuildingException { Artifact artifact = artifactFactory.createProjectArtifact(javadocArtifact.getGroupId(), javadocArtifact.getArtifactId(), javadocArtifact.getVersion(), Artifact.SCOPE_COMPILE); if (artifact.getFile() == null) { MavenProject pluginProject = mavenProjectBuilder.buildFromRepository(artifact, remoteRepositories, localRepository); artifact = pluginProject.getArtifact(); artifactResolver.resolve(artifact, remoteRepositories, localRepository); } return artifact; } /** * Is the Javadoc version at least the requested version. * * @param requiredVersion the required version, for example 1.5f * @return true if the javadoc version is equal or greater than the * required version */ private boolean isJavaDocVersionAtLeast(float requiredVersion) { return fJavadocVersion >= requiredVersion; } /** * Convenience method to add an argument to the command line * conditionally based on the given flag. * * @param arguments a list of arguments, not null * @param b the flag which controls if the argument is added or not. * @param value the argument value to be added. */ private void addArgIf(List arguments, boolean b, String value) { if (b) { arguments.add(value); } } // /** // * Convenience method to add an argument to the command line // * regarding the requested Java version. // * // * @param arguments a list of arguments, not null // * @param b the flag which controls if the argument is added or not. // * @param value the argument value to be added. // * @param requiredJavaVersion the required Java version, for example 1.31f or 1.4f // * @see #addArgIf(java.util.List,boolean,String) // * @see #isJavaDocVersionAtLeast(float) // */ // private void addArgIf(List arguments, boolean b, String value, float requiredJavaVersion) { // if (b) { // if (isJavaDocVersionAtLeast(requiredJavaVersion)) { // addArgIf(arguments, b, value); // } else { // if (getLog().isWarnEnabled()) { // getLog().warn( // value + " option is not supported on Java version < " + requiredJavaVersion // + ". Ignore this option."); // } // } // } // } /** * Convenience method to add an argument to the command line * if the the value is not null or empty. *

* Moreover, the value could be comma separated. * * @param arguments a list of arguments, not null * @param key the argument name. * @param value the argument value to be added. * @see #addArgIfNotEmpty(java.util.List,String,String,boolean) */ private void addArgIfNotEmpty(List arguments, String key, String value) { addArgIfNotEmpty(arguments, key, value, false); } // /** // * Convenience method to add an argument to the command line // * if the the value is not null or empty. // *

// * Moreover, the value could be comma separated. // * // * @param arguments a list of arguments, not null // * @param key the argument name. // * @param value the argument value to be added. // * @param repeatKey repeat or not the key in the command line // * @param splitValue if true given value will be tokenized by comma // * @param requiredJavaVersion the required Java version, for example 1.31f or 1.4f // * @see #addArgIfNotEmpty(List, String, String, boolean, boolean) // * @see #isJavaDocVersionAtLeast(float) // */ // private void addArgIfNotEmpty(List arguments, String key, String value, boolean repeatKey, // boolean splitValue, float requiredJavaVersion) { // if (StringUtils.isNotEmpty(value)) { // if (isJavaDocVersionAtLeast(requiredJavaVersion)) { // addArgIfNotEmpty(arguments, key, value, repeatKey, splitValue); // } else { // if (getLog().isWarnEnabled()) { // getLog().warn( // key + " option is not supported on Java version < " + requiredJavaVersion // + ". Ignore this option."); // } // } // } // } /** * Convenience method to add an argument to the command line * if the the value is not null or empty. *

* Moreover, the value could be comma separated. * * @param arguments a list of arguments, not null * @param key the argument name. * @param value the argument value to be added. * @param repeatKey repeat or not the key in the command line * @param splitValue if true given value will be tokenized by comma */ private void addArgIfNotEmpty(List arguments, String key, String value, boolean repeatKey, boolean splitValue) { if (StringUtils.isNotEmpty(value)) { if (StringUtils.isNotEmpty(key)) { arguments.add(key); } if (splitValue) { StringTokenizer token = new StringTokenizer(value, ","); while (token.hasMoreTokens()) { String current = token.nextToken().trim(); if (StringUtils.isNotEmpty(current)) { arguments.add(current); if (token.hasMoreTokens() && repeatKey) { arguments.add(key); } } } } else { arguments.add(value); } } } /** * Convenience method to add an argument to the command line * if the the value is not null or empty. *

* Moreover, the value could be comma separated. * * @param arguments a list of arguments, not null * @param key the argument name. * @param value the argument value to be added. * @param repeatKey repeat or not the key in the command line */ private void addArgIfNotEmpty(List arguments, String key, String value, boolean repeatKey) { addArgIfNotEmpty(arguments, key, value, repeatKey, true); } /** * Convenience method to add an argument to the command line * regarding the requested Java version. * * @param arguments a list of arguments, not null * @param key the argument name. * @param value the argument value to be added. * @param requiredJavaVersion the required Java version, for example 1.31f or 1.4f * @see #addArgIfNotEmpty(java.util.List, String, String, float, boolean) */ private void addArgIfNotEmpty(List arguments, String key, String value, float requiredJavaVersion) { addArgIfNotEmpty(arguments, key, value, requiredJavaVersion, false); } /** * Convenience method to add an argument to the command line * regarding the requested Java version. * * @param arguments a list of arguments, not null * @param key the argument name. * @param value the argument value to be added. * @param requiredJavaVersion the required Java version, for example 1.31f or 1.4f * @param repeatKey repeat or not the key in the command line * @see #addArgIfNotEmpty(java.util.List,String,String) * @see #isJavaDocVersionAtLeast(float) */ private void addArgIfNotEmpty(List arguments, String key, String value, float requiredJavaVersion, boolean repeatKey) { if (StringUtils.isNotEmpty(value)) { if (isJavaDocVersionAtLeast(requiredJavaVersion)) { addArgIfNotEmpty(arguments, key, value, repeatKey); } else { if (getLog().isWarnEnabled()) { getLog().warn(key + " option is not supported on Java version < " + requiredJavaVersion); } } } } // /** // * Convenience method to process {@link #offlineLinks} values as individual -linkoffline // * javadoc options. // *
// * If {@link #detectOfflineLinks}, try to add javadoc apidocs according Maven conventions for all modules given // * in the project. // * // * @param arguments a list of arguments, not null // * @throws MavenReportException if any // * @see #offlineLinks // * @see #getModulesLinks() // * @see package-list spec // */ // private void addLinkofflineArguments(List arguments) // throws MavenReportException { // Set offlineLinksList = collectOfflineLinks(); // // offlineLinksList.addAll(getModulesLinks()); // // for (OfflineLink offlineLink : offlineLinksList) { // String url = offlineLink.getUrl(); // if (StringUtils.isEmpty(url)) { // continue; // } // url = cleanUrl(url); // // String location = offlineLink.getLocation(); // if (StringUtils.isEmpty(location)) { // continue; // } // if (isValidJavadocLink(location)) { // addArgIfNotEmpty(arguments, "-linkoffline", JavadocUtil.quotedPathArgument(url) + " " // + JavadocUtil.quotedPathArgument(location), true); // } // } // } // /** // * Convenience method to process {@link #links} values as individual -link javadoc options. // * If {@link #detectLinks}, try to add javadoc apidocs according Maven conventions for all dependencies given // * in the project. // *
// * According the Javadoc documentation, all defined link should have ${link}/package-list fetchable. // *
// * Note: when a link is not fetchable: // *

    // *
  • Javadoc 1.4 and less throw an exception
  • // *
  • Javadoc 1.5 and more display a warning
  • // *
// * // * @param arguments a list of arguments, not null // * @throws MavenReportException // * @see #detectLinks // * @see #getDependenciesLinks() // * @see package-list spec // */ // private void addLinkArguments(List arguments) // throws MavenReportException { // Set links = collectLinks(); // // for (String link : links) { // if (StringUtils.isEmpty(link)) { // continue; // } // // while (link.endsWith("/")) { // link = link.substring(0, link.lastIndexOf("/")); // } // // addArgIfNotEmpty(arguments, "-link", JavadocUtil.quotedPathArgument(link), true); // } // } // /** // * Copies the {@link #DEFAULT_CSS_NAME} css file from the current class // * loader to the outputDirectory only if {@link #stylesheetfile} is empty and // * {@link #stylesheet} is equals to maven. // * // * @param anOutputDirectory the output directory // * @throws java.io.IOException if any // * @see #DEFAULT_CSS_NAME // * @see JavadocUtil#copyResource(File, URL) // */ // private void copyDefaultStylesheet(File anOutputDirectory) // throws IOException { // if (StringUtils.isNotEmpty(stylesheetfile)) { // return; // } // // if (!stylesheet.equalsIgnoreCase("maven")) { // return; // } // // URL url = getClass().getClassLoader().getResource(RESOURCE_CSS_DIR + "/" + DEFAULT_CSS_NAME); // File outFile = new File(anOutputDirectory, DEFAULT_CSS_NAME); // JavadocUtil.copyResource(url, outFile); // } // /** // * Method that copy all doc-files directories from javadocDirectory of // * the current projet or of the projects in the reactor to the outputDirectory. // * // * @see Reference // * Guide, Copies new "doc-files" directory for holding images and examples // * @see #docfilessubdirs // * // * @param anOutputDirectory the output directory // * @throws java.io.IOException if any // */ // private void copyJavadocResources(File anOutputDirectory) // throws IOException { // if (anOutputDirectory == null || !anOutputDirectory.exists()) { // throw new IOException("The outputDirectory " + anOutputDirectory + " doesn't exists."); // } // // if (includeDependencySources) { // resolveDependencyBundles(); // if (isNotEmpty(dependencyJavadocBundles)) { // for (JavadocBundle bundle : dependencyJavadocBundles) { // File dir = bundle.getResourcesDirectory(); // JavadocOptions options = bundle.getOptions(); // if (dir != null && dir.isDirectory()) { // JavadocUtil.copyJavadocResources(anOutputDirectory, dir, options == null ? null // : options.getExcludedDocfilesSubdirs()); // } // } // } // } // // if (getJavadocDirectory() != null) { // JavadocUtil.copyJavadocResources(anOutputDirectory, getJavadocDirectory(), excludedocfilessubdir); // } // // if (isAggregator() && project.isExecutionRoot()) { // for (MavenProject subProject : reactorProjects) { // if (subProject != project) { // String javadocDirRelative = // PathUtils.toRelative(project.getBasedir(), getJavadocDirectory().getAbsolutePath()); // File javadocDir = new File(subProject.getBasedir(), javadocDirRelative); // JavadocUtil.copyJavadocResources(anOutputDirectory, javadocDir, excludedocfilessubdir); // } // } // } // } // private synchronized void resolveDependencyBundles() // throws IOException { // if (dependencyJavadocBundles == null) { // dependencyJavadocBundles = ResourceResolver.resolveDependencyJavadocBundles(getDependencySourceResolverConfig()); // if (dependencyJavadocBundles == null) { // dependencyJavadocBundles = new ArrayList(); // } // } // } // /** // * Method that copy additional Javadoc resources from given artifacts. // * // * @see #resourcesArtifacts // * @param anOutputDirectory the output directory // * @throws MavenReportException if any // */ // private void copyAdditionalJavadocResources(File anOutputDirectory) // throws MavenReportException { // Set resourcesArtifacts = collectResourcesArtifacts(); // if (isEmpty(resourcesArtifacts)) { // return; // } // // UnArchiver unArchiver; // try { // unArchiver = archiverManager.getUnArchiver("jar"); // } catch (NoSuchArchiverException e) { // throw new MavenReportException("Unable to extract resources artifact. " // + "No archiver for 'jar' available.", e); // } // // for (ResourcesArtifact item : resourcesArtifacts) { // Artifact artifact; // try { // artifact = createAndResolveArtifact(item); // } catch (ArtifactResolutionException e) { // throw new MavenReportException("Unable to resolve artifact:" + item, e); // } catch (ArtifactNotFoundException e) { // throw new MavenReportException("Unable to find artifact:" + item, e); // } catch (ProjectBuildingException e) { // throw new MavenReportException("Unable to build the Maven project for the artifact:" + item, // e); // } // // unArchiver.setSourceFile(artifact.getFile()); // unArchiver.setDestDirectory(anOutputDirectory); // // remove the META-INF directory from resource artifact // IncludeExcludeFileSelector[] selectors = // new IncludeExcludeFileSelector[]{new IncludeExcludeFileSelector()}; // selectors[0].setExcludes(new String[]{"META-INF/**"}); // unArchiver.setFileSelectors(selectors); // // getLog().info("Extracting contents of resources artifact: " + artifact.getArtifactId()); // try { // unArchiver.extract(); // } catch (ArchiverException e) { // throw new MavenReportException("Extraction of resources failed. Artifact that failed was: " // + artifact.getArtifactId(), e); // } // } // } /** * @param sourcePaths not null, containing absolute and relative paths * @param files not null, containing list of quoted files * @param onlyPackageName boolean for only package name * @return a list of package names or files with unnamed package names, depending the value of the unnamed flag * @see #getFiles(List) * @see #getSourcePaths() */ private List getPackageNamesOrFilesWithUnnamedPackages(List sourcePaths, List files, boolean onlyPackageName) { List returnList = new ArrayList(); if (!StringUtils.isEmpty(sourcepath)) { return returnList; } for (String currentFile : files) { currentFile = currentFile.replace('\\', '/'); for (String currentSourcePath : sourcePaths) { currentSourcePath = currentSourcePath.replace('\\', '/'); if (!currentSourcePath.endsWith("/")) { currentSourcePath += "/"; } if (currentFile.indexOf(currentSourcePath) != -1) { String packagename = currentFile.substring(currentSourcePath.length() + 1); /* * Remove the miscellaneous files * http://download.oracle.com/javase/1.4.2/docs/tooldocs/solaris/javadoc.html#unprocessed */ if (packagename.indexOf("doc-files") != -1) { continue; } if (onlyPackageName && packagename.lastIndexOf("/") != -1) { packagename = packagename.substring(0, packagename.lastIndexOf("/")); packagename = packagename.replace('/', '.'); if (!returnList.contains(packagename)) { returnList.add(packagename); } } if (!onlyPackageName && packagename.lastIndexOf("/") == -1) { returnList.add(currentFile); } } } } return returnList; } /** * Generate a file called argfile (or files, depending the JDK) to hold files and add * the @argfile (or @file, depending the JDK) in the command line. * * @see * Reference Guide, Command line argument files * * @see * What s New in Javadoc 1.4 * * * @param cmd not null * @param javadocOutputDirectory not null * @param files not null * @throws MavenReportException if any * @see #isJavaDocVersionAtLeast(float) * @see #ARGFILE_FILE_NAME * @see #FILES_FILE_NAME */ private void addCommandLineArgFile(Commandline cmd, File javadocOutputDirectory, List files) throws MavenReportException { File argfileFile; if (isJavaDocVersionAtLeast(SINCE_JAVADOC_1_4)) { argfileFile = new File(javadocOutputDirectory, ARGFILE_FILE_NAME); } else { argfileFile = new File(javadocOutputDirectory, FILES_FILE_NAME); } try { FileUtils.fileWrite(argfileFile.getAbsolutePath(), StringUtils.join(files.iterator(), SystemUtils.LINE_SEPARATOR)); } catch (IOException e) { throw new MavenReportException("Unable to write '" + argfileFile.getName() + "' temporary file for command execution", e); } if (isJavaDocVersionAtLeast(SINCE_JAVADOC_1_4)) { cmd.createArg().setValue("@" + ARGFILE_FILE_NAME); } else { cmd.createArg().setValue("@" + FILES_FILE_NAME); } } /** * Checks for the validity of the Javadoc options used by the user. * * @throws MavenReportException if error */ private void validateJavadocOptions() throws MavenReportException { // encoding if (StringUtils.isNotEmpty(getEncoding()) && !validateEncoding(getEncoding())) { throw new MavenReportException("Unsupported option '" + getEncoding() + "'"); } // // locale // if (StringUtils.isNotEmpty(this.locale)) { // StringTokenizer tokenizer = new StringTokenizer(this.locale, "_"); // final int maxTokens = 3; // if (tokenizer.countTokens() > maxTokens) { // throw new MavenReportException("Unsupported option '" + this.locale // + "', should be language_country_variant."); // } // // Locale localeObject = null; // if (tokenizer.hasMoreTokens()) { // String language = tokenizer.nextToken().toLowerCase(Locale.ENGLISH); // if (!Arrays.asList(Locale.getISOLanguages()).contains(language)) { // throw new MavenReportException("Unsupported language '" + language // + "' in option '" + this.locale + "'"); // } // localeObject = new Locale(language); // // if (tokenizer.hasMoreTokens()) { // String country = tokenizer.nextToken().toUpperCase(Locale.ENGLISH); // if (!Arrays.asList(Locale.getISOCountries()).contains(country)) { // throw new MavenReportException("Unsupported country '" + country // + "' in option '" + this.locale + "'"); // } // localeObject = new Locale(language, country); // // if (tokenizer.hasMoreTokens()) { // String variant = tokenizer.nextToken(); // localeObject = new Locale(language, country, variant); // } // } // } // // if (localeObject == null) { // throw new MavenReportException("Unsupported option '" + this.locale // + "', should be language_country_variant."); // } // // this.locale = localeObject.toString(); // final List availableLocalesList = Arrays.asList(Locale.getAvailableLocales()); // if (StringUtils.isNotEmpty(localeObject.getVariant()) // && !availableLocalesList.contains(localeObject)) { // StringBuilder sb = new StringBuilder(); // sb.append("Unsupported option with variant '").append(this.locale); // sb.append("'"); // // localeObject = new Locale(localeObject.getLanguage(), localeObject.getCountry()); // this.locale = localeObject.toString(); // // sb.append(", trying to use without variant, i.e. '").append(this.locale).append("'"); // if (getLog().isWarnEnabled()) { // getLog().warn(sb.toString()); // } // } // // if (!availableLocalesList.contains(localeObject)) { // throw new MavenReportException("Unsupported option '" + this.locale + "'"); // } // } } // /** // * Checks for the validity of the Standard Doclet options. // *
// * For example, throw an exception if <nohelp/> and <helpfile/> options are used together. // * // * @throws MavenReportException if error or conflict found // */ // private void validateStandardDocletOptions() // throws MavenReportException { // // docencoding // if (StringUtils.isNotEmpty(getDocencoding()) && !validateEncoding(getDocencoding())) { // throw new MavenReportException("Unsupported option '" + getDocencoding() + "'"); // } // // // charset // if (StringUtils.isNotEmpty(getCharset()) && !JavadocUtil.validateEncoding(getCharset())) { // throw new MavenReportException("Unsupported option '" + getCharset() + "'"); // } // // // helpfile // if (StringUtils.isNotEmpty(helpfile) && nohelp) { // throw new MavenReportException("Option conflicts with "); // } // // // overview // if ((getOverview() != null) && nooverview) { // throw new MavenReportException("Option conflicts with "); // } // // // index // if (splitindex && noindex) { // throw new MavenReportException("Option conflicts with "); // } // // // stylesheet // if (StringUtils.isNotEmpty(stylesheet) // && !(stylesheet.equalsIgnoreCase("maven") || stylesheet.equalsIgnoreCase("java"))) { // throw new MavenReportException("Option supports only \"maven\" or \"java\" value."); // } // // // default java api links // if (javaApiLinks == null || javaApiLinks.size() == 0) { // javaApiLinks = DEFAULT_JAVA_API_LINKS; // } // } /** * This method is checking to see if the artifacts that can't be resolved are all * part of this reactor. This is done to prevent a chicken or egg scenario with * fresh projects. See MJAVADOC-116 for more info. * * @param dependencyArtifacts the sibling projects in the reactor * @param missing the artifacts that can't be found * @return true if ALL missing artifacts are found in the reactor. * @see DefaultPluginManager#checkRequiredMavenVersion( plugin, localRepository, remoteRepositories ) */ private boolean checkMissingArtifactsInReactor(Collection dependencyArtifacts, Collection missing) { Set foundInReactor = new HashSet(); for (Artifact mArtifact : missing) { for (MavenProject p : reactorProjects) { if (p.getArtifactId().equals(mArtifact.getArtifactId()) && p.getGroupId().equals(mArtifact.getGroupId()) && p.getVersion().equals(mArtifact.getVersion())) { getLog().warn( "The dependency: [" + p.getId() + "] can't be resolved but has been found in the reactor (probably snapshots).\n" + "This dependency has been excluded from the Javadoc classpath. " + "You should rerun javadoc after executing mvn install."); // found it, move on. foundInReactor.add(p); break; } } } // if all of them have been found, we can continue. return foundInReactor.size() == missing.size(); } // /** // * Add groups parameter to arguments. // * // * @param arguments not null // * @throws MavenReportException // */ // private void addGroups(List arguments) // throws MavenReportException { // Set groups = collectGroups(); // if (isEmpty(groups)) { // return; // } // // for (Group group : groups) { // if (group == null || StringUtils.isEmpty(group.getTitle()) // || StringUtils.isEmpty(group.getPackages())) { // if (getLog().isWarnEnabled()) { // getLog().warn("A group option is empty. Ignore this option."); // } // } else { // String groupTitle = StringUtils.replace(group.getTitle(), ",", ","); // addArgIfNotEmpty(arguments, "-group", JavadocUtil.quotedArgument(groupTitle) + " " // + JavadocUtil.quotedArgument(group.getPackages()), true); // } // } // } // /** // * Add tags parameter to arguments. // * // * @param arguments not null // * @throws MavenReportException // */ // private void addTags(List arguments) // throws MavenReportException { // Set tags = collectTags(); // // if (isEmpty(tags)) { // return; // } // // for (Tag tag : tags) { // if (StringUtils.isEmpty(tag.getName())) { // if (getLog().isWarnEnabled()) { // getLog().warn("A tag name is empty. Ignore this option."); // } // } else { // String value = "\"" + tag.getName(); // if (StringUtils.isNotEmpty(tag.getPlacement())) { // value += ":" + tag.getPlacement(); // if (StringUtils.isNotEmpty(tag.getHead())) { // value += ":" + tag.getHead(); // } // } // value += "\""; // addArgIfNotEmpty(arguments, "-tag", value, SINCE_JAVADOC_1_4); // } // } // } // /** // * Add taglets parameter to arguments. // * // * @param arguments not null // */ // private void addTaglets(List arguments) { // if (taglets == null) { // return; // } // // for (int i = 0; i < taglets.length; i++) { // if ((taglets[i] == null) || (StringUtils.isEmpty(taglets[i].getTagletClass()))) { // if (getLog().isWarnEnabled()) { // getLog().warn("A taglet option is empty. Ignore this option."); // } // } else { // addArgIfNotEmpty(arguments, "-taglet", JavadocUtil.quotedArgument(taglets[i].getTagletClass()), // SINCE_JAVADOC_1_4); // } // } // } // /** // * Auto-detect taglets class name from tagletArtifacts and add them to arguments. // * // * @param arguments not null // * @throws MavenReportException if any // * @see JavadocUtil#getTagletClassNames(File) // */ // private void addTagletsFromTagletArtifacts(List arguments) // throws MavenReportException { // Set tArtifacts = new LinkedHashSet(); // if (tagletArtifacts != null && tagletArtifacts.length > 0) { // tArtifacts.addAll(Arrays.asList(tagletArtifacts)); // } // // if (includeDependencySources) { // try { // resolveDependencyBundles(); // } catch (IOException e) { // throw new MavenReportException("Failed to resolve javadoc bundles from dependencies: " + e.getMessage(), e); // } // // if (isNotEmpty(dependencyJavadocBundles)) { // for (JavadocBundle bundle : dependencyJavadocBundles) { // JavadocOptions options = bundle.getOptions(); // if (options != null && isNotEmpty(options.getTagletArtifacts())) { // tArtifacts.addAll(options.getTagletArtifacts()); // } // } // } // } // // if (isEmpty(tArtifacts)) { // return; // } // // List tagletsPath = new ArrayList(); // // for (TagletArtifact aTagletArtifact : tArtifacts) { // if ((StringUtils.isNotEmpty(aTagletArtifact.getGroupId())) // && (StringUtils.isNotEmpty(aTagletArtifact.getArtifactId())) // && (StringUtils.isNotEmpty(aTagletArtifact.getVersion()))) { // Artifact artifact; // try { // artifact = createAndResolveArtifact(aTagletArtifact); // } catch (ArtifactResolutionException e) { // throw new MavenReportException("Unable to resolve artifact:" + aTagletArtifact, e); // } catch (ArtifactNotFoundException e) { // throw new MavenReportException("Unable to find artifact:" + aTagletArtifact, e); // } catch (ProjectBuildingException e) { // throw new MavenReportException("Unable to build the Maven project for the artifact:" // + aTagletArtifact, e); // } // // tagletsPath.add(artifact.getFile().getAbsolutePath()); // } // } // // tagletsPath = JavadocUtil.pruneFiles(tagletsPath); // // for (String tagletJar : tagletsPath) { // if (!tagletJar.toLowerCase(Locale.ENGLISH).endsWith(".jar")) { // continue; // } // // List tagletClasses; // try { // tagletClasses = JavadocUtil.getTagletClassNames(new File(tagletJar)); // } catch (IOException e) { // if (getLog().isWarnEnabled()) { // getLog().warn( // "Unable to auto-detect Taglet class names from '" + tagletJar // + "'. Try to specify them with ."); // } // if (getLog().isDebugEnabled()) { // getLog().debug("IOException: " + e.getMessage(), e); // } // continue; // } catch (ClassNotFoundException e) { // if (getLog().isWarnEnabled()) { // getLog().warn( // "Unable to auto-detect Taglet class names from '" + tagletJar // + "'. Try to specify them with ."); // } // if (getLog().isDebugEnabled()) { // getLog().debug("ClassNotFoundException: " + e.getMessage(), e); // } // continue; // } catch (NoClassDefFoundError e) { // if (getLog().isWarnEnabled()) { // getLog().warn( // "Unable to auto-detect Taglet class names from '" + tagletJar // + "'. Try to specify them with ."); // } // if (getLog().isDebugEnabled()) { // getLog().debug("NoClassDefFoundError: " + e.getMessage(), e); // } // continue; // } // // if (tagletClasses != null && !tagletClasses.isEmpty()) { // for (String tagletClass : tagletClasses) { // addArgIfNotEmpty(arguments, "-taglet", JavadocUtil.quotedArgument(tagletClass), // SINCE_JAVADOC_1_4); // } // } // } // } /** * Execute the Javadoc command line * * @param cmd not null * @param javadocOutputDirectory not null * @throws MavenReportException if any errors occur */ private void executeJavadocCommandLine(Commandline cmd, File javadocOutputDirectory) throws MavenReportException { // if (getLog().isDebugEnabled()) { // // no quoted arguments // getLog().debug(CommandLineUtils.toString(cmd.getCommandline()).replaceAll("'", "")); // } String cmdLine = null; // if (debug) { // cmdLine = CommandLineUtils.toString(cmd.getCommandline()).replaceAll("'", ""); // cmdLine = hideProxyPassword(cmdLine, settings); // // writeDebugJavadocScript(cmdLine, javadocOutputDirectory); // } CommandLineUtils.StringStreamConsumer err = new CommandLineUtils.StringStreamConsumer(); CommandLineUtils.StringStreamConsumer out = new CommandLineUtils.StringStreamConsumer(); try { int exitCode = CommandLineUtils.executeCommandLine(cmd, out, err); String output = (StringUtils.isEmpty(out.getOutput()) ? null : '\n' + out.getOutput().trim()); if (exitCode != 0) { if (cmdLine == null) { cmdLine = CommandLineUtils.toString(cmd.getCommandline()).replaceAll("'", ""); cmdLine = hideProxyPassword(cmdLine, settings); } writeDebugJavadocScript(cmdLine, javadocOutputDirectory); if (StringUtils.isNotEmpty(output) && StringUtils.isEmpty(err.getOutput()) && isJavadocVMInitError(output)) { StringBuilder msg = new StringBuilder(); msg.append(output); msg.append('\n').append('\n'); msg.append(ERROR_INIT_VM).append('\n'); msg.append("Or, try to reduce the Java heap size for the Javadoc goal using "); msg.append("-Dminmemory= and -Dmaxmemory=.").append('\n').append('\n'); msg.append("Command line was: ").append(cmdLine).append('\n').append('\n'); msg.append("Refer to the generated Javadoc files in '").append(javadocOutputDirectory).append("' dir.\n"); throw new MavenReportException(msg.toString()); } if (StringUtils.isNotEmpty(output)) { getLog().info(output); } StringBuilder msg = new StringBuilder("\nExit code: "); msg.append(exitCode); if (StringUtils.isNotEmpty(err.getOutput())) { msg.append(" - ").append(err.getOutput()); } msg.append('\n'); msg.append("Command line was: ").append(cmdLine).append('\n').append('\n'); msg.append("Refer to the generated Javadoc files in '").append(javadocOutputDirectory).append("' dir.\n"); throw new MavenReportException(msg.toString()); } if (StringUtils.isNotEmpty(output)) { getLog().info(output); } } catch (CommandLineException e) { throw new MavenReportException("Unable to execute javadoc command: " + e.getMessage(), e); } // ---------------------------------------------------------------------- // Handle Javadoc warnings // ---------------------------------------------------------------------- if (StringUtils.isNotEmpty(err.getOutput()) && getLog().isWarnEnabled()) { getLog().warn("Javadoc Warnings"); StringTokenizer token = new StringTokenizer(err.getOutput(), "\n"); while (token.hasMoreTokens()) { String current = token.nextToken().trim(); getLog().warn(current); } } } // /** // * @param outputFile not nul // * @param inputResourceName a not null resource in src/main/java, src/main/resources or src/main/javadoc // * or in the Javadoc plugin dependencies. // * @return the resource file absolute path as String // * @since 2.6 // */ // private String getResource(File outputFile, String inputResourceName) { // if (inputResourceName.startsWith("/")) { // inputResourceName = inputResourceName.replaceFirst("//*", ""); // } // // List classPath = new ArrayList(); // classPath.add(project.getBuild().getSourceDirectory()); // // URL resourceURL = getResource(classPath, inputResourceName); // if (resourceURL != null) { // getLog().debug(inputResourceName + " found in the main src directory of the project."); // return FileUtils.toFile(resourceURL).getAbsolutePath(); // } // // classPath.clear(); // List resources = project.getBuild().getResources(); // for (Resource resource : resources) { // classPath.add(resource.getDirectory()); // } // resourceURL = getResource(classPath, inputResourceName); // if (resourceURL != null) { // getLog().debug(inputResourceName + " found in the main resources directories of the project."); // return FileUtils.toFile(resourceURL).getAbsolutePath(); // } // // if (javadocDirectory.exists()) { // classPath.clear(); // classPath.add(javadocDirectory.getAbsolutePath()); // resourceURL = getResource(classPath, inputResourceName); // if (resourceURL != null) { // getLog().debug(inputResourceName + " found in the main javadoc directory of the project."); // return FileUtils.toFile(resourceURL).getAbsolutePath(); // } // } // // classPath.clear(); // final String pluginId = "org.apache.maven.plugins:maven-javadoc-plugin"; // Plugin javadocPlugin = getPlugin(project, pluginId); // if (javadocPlugin != null && javadocPlugin.getDependencies() != null) { // List dependencies = javadocPlugin.getDependencies(); // for (Dependency dependency : dependencies) { // JavadocPathArtifact javadocPathArtifact = new JavadocPathArtifact(); // javadocPathArtifact.setGroupId(dependency.getGroupId()); // javadocPathArtifact.setArtifactId(dependency.getArtifactId()); // javadocPathArtifact.setVersion(dependency.getVersion()); // Artifact artifact = null; // try { // artifact = createAndResolveArtifact(javadocPathArtifact); // } catch (Exception e) { // logError("Unable to retrieve the dependency: " + dependency + ". Ignored.", e); // } // // if (artifact != null && artifact.getFile().exists()) { // classPath.add(artifact.getFile().getAbsolutePath()); // } // } // resourceURL = getResource(classPath, inputResourceName); // if (resourceURL != null) { // getLog().debug(inputResourceName + " found in javadoc plugin dependencies."); // try { // copyResource(resourceURL, outputFile); // // return outputFile.getAbsolutePath(); // } catch (IOException e) { // logError("IOException: " + e.getMessage(), e); // } // } // } // // getLog().warn("Unable to find the resource '" + inputResourceName + "'. Using default Javadoc resources."); // // return null; // } /** * @param classPath a not null String list of files where resource will be look up. * @param resource a not null ressource to find in the class path. * @return the resource from the given classpath or null if not found * @see ClassLoader#getResource(String) * @since 2.6 */ private URL getResource(final List classPath, final String resource) { List urls = new ArrayList(classPath.size()); for (String filename : classPath) { try { urls.add(new File(filename).toURL()); } catch (MalformedURLException e) { getLog().error("MalformedURLException: " + e.getMessage()); } } ClassLoader javadocClassLoader = new URLClassLoader((URL[]) urls.toArray(new URL[urls.size()]), null); return javadocClassLoader.getResource(resource); } // /** // * Get the full javadoc goal. Loads the plugin's pom.properties to get the current plugin version. // * // * @return org.apache.maven.plugins:maven-javadoc-plugin:CURRENT_VERSION:[test-]javadoc // */ // private String getFullJavadocGoal() { // String javadocPluginVersion = null; // InputStream resourceAsStream = null; // try { // String resource = // "META-INF/maven/org.apache.maven.plugins/maven-javadoc-plugin/pom.properties"; // resourceAsStream = TldGeneratorMojo.class.getClassLoader().getResourceAsStream(resource); // // if (resourceAsStream != null) { // Properties properties = new Properties(); // properties.load(resourceAsStream); // // if (StringUtils.isNotEmpty(properties.getProperty("version"))) { // javadocPluginVersion = properties.getProperty("version"); // } // } // } catch (IOException e) { // // nop // } finally { // IOUtil.close(resourceAsStream); // } // // StringBuilder sb = new StringBuilder(); // // sb.append("org.apache.maven.plugins:maven-javadoc-plugin:"); // if (StringUtils.isNotEmpty(javadocPluginVersion)) { // sb.append(javadocPluginVersion).append(":"); // } // // if (this instanceof TestJavadocReport) { // sb.append("test-javadoc"); // } else { // sb.append("javadoc"); // } // // return sb.toString(); // } // /** // * Using Maven, a Javadoc link is given by ${project.url}/apidocs. // * // * @return the detected Javadoc links using the Maven conventions for all modules defined in the current project // * or an empty list. // * @throws MavenReportException if any // * @see #detectOfflineLinks // * @see #reactorProjects // * @since 2.6 // */ // private List getModulesLinks() // throws MavenReportException { // if (!detectOfflineLinks || isAggregator() || reactorProjects == null) { // return Collections.emptyList(); // } // // getLog().debug("Trying to add links for modules..."); // // Set dependencyArtifactIds = new HashSet(); // final Set dependencyArtifacts = project.getDependencyArtifacts(); // for (Artifact artifact : dependencyArtifacts) { // dependencyArtifactIds.add(artifact.getId()); // } // // List modulesLinks = new ArrayList(); // String javadocDirRelative = PathUtils.toRelative(project.getBasedir(), getOutputDirectory()); // for (MavenProject p : reactorProjects) { // if (!dependencyArtifactIds.contains(p.getArtifact().getId()) || (p.getUrl() == null)) { // continue; // } // // File location = new File(p.getBasedir(), javadocDirRelative); // // if (!location.exists()) { // if (getLog().isDebugEnabled()) { // getLog().debug("Javadoc directory not found: " + location); // } // // String javadocGoal = getFullJavadocGoal(); // getLog().info("The goal '" + javadocGoal + "' has not been previously called for the module: '" // + p.getId() + "'. Trying to invoke it..."); // // File invokerDir = new File(project.getBuild().getDirectory(), "invoker"); // invokerDir.mkdirs(); // File invokerLogFile = FileUtils.createTempFile("maven-javadoc-plugin", ".txt", invokerDir); // try { // JavadocUtil.invokeMaven(getLog(), new File(localRepository.getBasedir()), p.getFile(), // Collections.singletonList(javadocGoal), null, invokerLogFile); // } catch (MavenInvocationException e) { // logError("MavenInvocationException: " + e.getMessage(), e); // // String invokerLogContent = JavadocUtil.readFile(invokerLogFile, "UTF-8"); // // // TODO: Why are we only interested in cases where the JVM won't start? // // [MJAVADOC-275][jdcasey] I changed the logic here to only throw an error WHEN // // the JVM won't start (opposite of what it was). // if (invokerLogContent != null && invokerLogContent.contains(JavadocUtil.ERROR_INIT_VM)) { // throw new MavenReportException(e.getMessage(), e); // } // } finally { // // just create the directory to prevent repeated invocations.. // if (!location.exists()) { // getLog().warn("Creating fake javadoc directory to prevent repeated invocations: " + location); // location.mkdirs(); // } // } // } // // if (location.exists()) { // String url = getJavadocLink(p); // // OfflineLink ol = new OfflineLink(); // ol.setUrl(url); // ol.setLocation(location.getAbsolutePath()); // // if (getLog().isDebugEnabled()) { // getLog().debug("Added Javadoc offline link: " + url + " for the module: " + p.getId()); // } // // modulesLinks.add(ol); // } // } // // return modulesLinks; // } // /** // * Using Maven, a Javadoc link is given by ${project.url}/apidocs. // * // * @return the detected Javadoc links using the Maven conventions for all dependencies defined in the current // * project or an empty list. // * @see #detectLinks // * @see #isValidJavadocLink(String) // * @since 2.6 // */ // private List getDependenciesLinks() { // if (!detectLinks) { // return Collections.emptyList(); // } // // getLog().debug("Trying to add links for dependencies..."); // // List dependenciesLinks = new ArrayList(); // // final Set dependencies = project.getDependencyArtifacts(); // for (Artifact artifact : dependencies) { // if (artifact.getFile() == null || !artifact.getFile().exists()) { // continue; // } // // try { // MavenProject artifactProject = // mavenProjectBuilder.buildFromRepository(artifact, remoteRepositories, localRepository); // // if (StringUtils.isNotEmpty(artifactProject.getUrl())) { // String url = getJavadocLink(artifactProject); // // if (isValidJavadocLink(url)) { // getLog().debug("Added Javadoc link: " + url + " for " + artifactProject.getId()); // // dependenciesLinks.add(url); // } // } // } catch (ProjectBuildingException e) { // logError("ProjectBuildingException for " + artifact.toString() + ": " + e.getMessage(), e); // } // } // // return dependenciesLinks; // } // /** // * @return if {@link #detectJavaApiLink}, the Java API link based on the {@link #javaApiLinks} properties and the // * value of the source parameter in the org.apache.maven.plugins:maven-compiler-plugin // * defined in ${project.build.plugins} or in ${project.build.pluginManagement}, // * or the {@link #fJavadocVersion}, or null if not defined. // * @since 2.6 // * @see #detectJavaApiLink // * @see #javaApiLinks // * @see #DEFAULT_JAVA_API_LINKS // * @see source parameter // */ // private OfflineLink getDefaultJavadocApiLink() { // if (!detectJavaApiLink) { // return null; // } // // final String pluginId = "org.apache.maven.plugins:maven-compiler-plugin"; // float sourceVersion = fJavadocVersion; // String sourceConfigured = getPluginParameter(project, pluginId, "source"); // if (sourceConfigured != null) { // try { // sourceVersion = Float.parseFloat(sourceConfigured); // } catch (NumberFormatException e) { // getLog().debug("NumberFormatException for the source parameter in the maven-compiler-plugin. " // + "Ignored it", e); // } // } else { // getLog().debug("No maven-compiler-plugin defined in ${build.plugins} or in " // + "${project.build.pluginManagement} for the " + project.getId() // + ". Added Javadoc API link according the javadoc executable version i.e.: " // + fJavadocVersion); // } // // String apiVersion = null; // if (sourceVersion >= 1.3f && sourceVersion < 1.4f) { // apiVersion = "1.3"; // } else if (sourceVersion >= 1.4f && sourceVersion < 1.5f) { // apiVersion = "1.4"; // } else if (sourceVersion >= 1.5f && sourceVersion < 1.6f) { // apiVersion = "1.5"; // } else if (sourceVersion >= 1.6f) { // apiVersion = "1.6"; // } // String javaApiLink = javaApiLinks.getProperty("api_" + apiVersion, null); // // if (getLog().isDebugEnabled()) { // if (StringUtils.isNotEmpty(javaApiLink)) { // getLog().debug("Found Java API link: " + javaApiLink); // } else { // getLog().debug("No Java API link found."); // } // } // // if (javaApiLink == null) { // return null; // } // // File javaApiPackageListFile = new File(getJavadocOptionsFile().getParentFile(), "package-list"); // // OfflineLink link = new OfflineLink(); // link.setLocation(javaApiPackageListFile.getParentFile().getAbsolutePath()); // link.setUrl(javaApiLink); // // InputStream in = this.getClass().getResourceAsStream("java-api-package-list-" + apiVersion); // OutputStream out = null; // try { // out = new FileOutputStream(javaApiPackageListFile); // IOUtil.copy(in, out); // } catch (IOException ioe) { // logError("Can't get java-api-package-list-" + apiVersion + ": " + ioe.getMessage(), ioe); // return null; // } finally { // IOUtil.close(in); // IOUtil.close(out); // } // // return link; // } // /** // * @param link not null // * @return true if the link has a /package-list, false otherwise. // * @since 2.6 // * @see // * package-list spec // */ // private boolean isValidJavadocLink(String link) { // try { // URI linkUri; // if (link.trim().toLowerCase(Locale.ENGLISH).startsWith("http:") // || link.trim().toLowerCase(Locale.ENGLISH).startsWith("https:") // || link.trim().toLowerCase(Locale.ENGLISH).startsWith("ftp:") // || link.trim().toLowerCase(Locale.ENGLISH).startsWith("file:")) { // linkUri = new URI(link + "/package-list"); // } else { // // links can be relative paths or files // File dir = new File(link); // if (!dir.isAbsolute()) { // dir = new File(getOutputDirectory(), link); // } // if (!dir.isDirectory()) { // getLog().error("The given File link: " + dir + " is not a dir."); // } // linkUri = new File(dir, "package-list").toURI(); // } // // if (!isValidPackageList(linkUri.toURL(), settings, validateLinks)) { // if (getLog().isErrorEnabled()) { // getLog().error("Invalid link: " + link + "/package-list. Ignored it."); // } // // return false; // } // // return true; // } catch (URISyntaxException e) { // if (getLog().isErrorEnabled()) { // getLog().error("Malformed link: " + link + "/package-list. Ignored it."); // } // return false; // } catch (IOException e) { // if (getLog().isErrorEnabled()) { // getLog().error("Error fetching link: " + link + "/package-list. Ignored it."); // } // return false; // } // } /** * Write a debug javadoc script in case of command line error or in debug mode. * * @param cmdLine the current command line as string, not null. * @param javadocOutputDirectory the output dir, not null. * @see #executeJavadocCommandLine(Commandline, File) * @since 2.6 */ private void writeDebugJavadocScript(String cmdLine, File javadocOutputDirectory) { File commandLineFile = new File(javadocOutputDirectory, DEBUG_JAVADOC_SCRIPT_NAME); commandLineFile.getParentFile().mkdirs(); try { FileUtils.fileWrite(commandLineFile.getAbsolutePath(), "UTF-8", cmdLine); if (!SystemUtils.IS_OS_WINDOWS) { Runtime.getRuntime().exec(new String[]{"chmod", "a+x", commandLineFile.getAbsolutePath()}); } } catch (IOException e) { logError("Unable to write '" + commandLineFile.getName() + "' debug script file", e); } } /** * Check if the Javadoc JVM is correctly started or not. * * @param output the command line output, not null. * @return true if Javadoc output command line contains Javadoc word, false otherwise. * @see #executeJavadocCommandLine(Commandline, File) * @since 2.6.1 */ private boolean isJavadocVMInitError(String output) { /* * see main.usage and main.Building_tree keys from * com.sun.tools.javadoc.resources.javadoc bundle in tools.jar */ return !(output.contains("Javadoc") || output.contains("javadoc")); } // ---------------------------------------------------------------------- // Static methods // ---------------------------------------------------------------------- // /** // * @param p not null // * @return the javadoc link based on the project url i.e. ${project.url}/${destDir} where // * destDir is configued in the Javadoc plugin configuration (apidocs by default). // * @since 2.6 // */ // private String getJavadocLink(MavenProject p) { // if (p.getUrl() == null) { // return null; // } // // String url = cleanUrl(p.getUrl()); // String destDir = "apidocs"; // see JavadocReport#destDir // // final String pluginId = "org.apache.maven.plugins:maven-javadoc-plugin"; // String destDirConfigured = getPluginParameter(p, pluginId, "destDir"); // if (destDirConfigured != null) { // destDir = destDirConfigured; // } // // return url + "/" + destDir; // } /** * @param url could be null. * @return the url cleaned or empty if url was null. * @since 2.6 */ private String cleanUrl(String url) { if (url == null) { return ""; } url = url.trim(); while (url.endsWith("/")) { url = url.substring(0, url.lastIndexOf("/")); } return url; } /** * @param p not null * @param pluginId not null key of the plugin defined in {@link org.apache.maven.model.Build#getPluginsAsMap()} * or in {@link org.apache.maven.model.PluginManagement#getPluginsAsMap()} * @return the Maven plugin defined in ${project.build.plugins} or in * ${project.build.pluginManagement}, or null if not defined. * @since 2.6 */ private Plugin getPlugin(MavenProject p, String pluginId) { if ((p.getBuild() == null) || (p.getBuild().getPluginsAsMap() == null)) { return null; } Plugin plugin = (Plugin) p.getBuild().getPluginsAsMap().get(pluginId); if ((plugin == null) && (p.getBuild().getPluginManagement() != null) && (p.getBuild().getPluginManagement().getPluginsAsMap() != null)) { plugin = (Plugin) p.getBuild().getPluginManagement().getPluginsAsMap().get(pluginId); } return plugin; } /** * @param p not null * @param pluginId not null * @param param not null * @return the simple parameter as String defined in the plugin configuration by param key * or null if not found. * @since 2.6 */ private String getPluginParameter(MavenProject p, String pluginId, String param) { // p.getGoalConfiguration( pluginGroupId, pluginArtifactId, executionId, goalId ); Plugin plugin = getPlugin(p, pluginId); if (plugin != null) { Xpp3Dom xpp3Dom = (Xpp3Dom) plugin.getConfiguration(); if (xpp3Dom != null && xpp3Dom.getChild(param) != null && StringUtils.isNotEmpty(xpp3Dom.getChild(param).getValue())) { return xpp3Dom.getChild(param).getValue(); } } return null; } // /** // * Construct the output file for the generated javadoc-options XML file, after creating the // * javadocOptionsDir if necessary. This method does NOT write to the file in question. // * // * @since 2.7 // */ // private File getJavadocOptionsFile() { // if (javadocOptionsDir != null && !javadocOptionsDir.exists()) { // javadocOptionsDir.mkdirs(); // } // // return new File(javadocOptionsDir, "javadoc-options-" + getAttachmentClassifier() + ".xml"); // // } // /** // * Override this if you need to provide a bundle attachment classifier, as in the case of test // * javadocs. // */ // protected String getAttachmentClassifier() { // return JAVADOC_RESOURCES_ATTACHMENT_CLASSIFIER; // } /** * Logs an error with throwable content only if in debug. * * @param message * @param t */ private void logError(String message, Throwable t) { if (getLog().isDebugEnabled()) { getLog().error(message, t); } else { getLog().error(message); } } /** The default timeout used when fetching url, i.e. 2000. */ private static final int DEFAULT_TIMEOUT = 2000; /** Error message when VM could not be started using invoker. */ private static final String ERROR_INIT_VM = "Error occurred during initialization of VM, try to reduce the Java heap size for the MAVEN_OPTS " + "environnement variable using -Xms: and -Xmx:."; /** * Method that removes the invalid directories in the specified directories. * Note: All elements in dirs could be an absolute or relative against the project's base * directory String path. * * @param project the current Maven project not null * @param dirs the list of String directories path that will be validated. * @return a List of valid String directories absolute paths. */ private List pruneDirs(MavenProject project, List dirs) { List pruned = new ArrayList(dirs.size()); for (String dir : dirs) { if (dir == null) { continue; } File directory = new File(dir); if (!directory.isAbsolute()) { directory = new File(project.getBasedir(), directory.getPath()); } if (directory.isDirectory() && !pruned.contains(directory.getAbsolutePath())) { pruned.add(directory.getAbsolutePath()); } } return pruned; } /** * Method that removes the invalid files in the specified files. * Note: All elements in files should be an absolute String path. * * @param files the list of String files paths that will be validated. * @return a List of valid File objects. */ private List pruneFiles(List files) { List pruned = new ArrayList(files.size()); for (String f : files) { if (!shouldPruneFile(f, pruned)) { pruned.add(f); } } return pruned; } /** * Determine whether a file should be excluded from the provided list of paths, based on whether * it exists and is already present in the list. */ private boolean shouldPruneFile(String f, List pruned) { if (f != null) { File file = new File(f); if (file.isFile() && (isEmpty(pruned) || !pruned.contains(f))) { return false; } } return true; } /** * Method that gets all the source files to be excluded from the javadoc on the given * source paths. * * @param sourcePaths the path to the source files * @param subpackagesList list of subpackages to be included in the javadoc * @param excludedPackages the package names to be excluded in the javadoc * @return a List of the source files to be excluded in the generated javadoc */ private List getExcludedNames(List sourcePaths, String[] subpackagesList, String[] excludedPackages) { List excludedNames = new ArrayList(); for (String path : sourcePaths) { for (int j = 0; j < subpackagesList.length; j++) { List excludes = getExcludedPackages(path, excludedPackages); excludedNames.addAll(excludes); } } return excludedNames; } // /** // * Copy from {@link org.apache.maven.project.MavenProject#getCompileArtifacts()} // * @param artifacts not null // * @return list of compile artifacts with compile scope // * @deprecated since 2.5, using {@link #getCompileArtifacts(Set, boolean)} instead of. // */ // private List getCompileArtifacts(Set artifacts) { // return getCompileArtifacts(artifacts, false); // } /** * Copy from {@link org.apache.maven.project.MavenProject#getCompileArtifacts()} * @param artifacts not null * @param withTestScope flag to include or not the artifacts with test scope * @return list of compile artifacts with or without test scope. */ private List getCompileArtifacts(Set artifacts, boolean withTestScope) { List list = new ArrayList(artifacts.size()); for (Artifact a : artifacts) { // TODO: classpath check doesn't belong here - that's the other method if (a.getArtifactHandler().isAddedToClasspath()) { // TODO: let the scope handler deal with this if (withTestScope) { if (Artifact.SCOPE_COMPILE.equals(a.getScope()) || Artifact.SCOPE_PROVIDED.equals(a.getScope()) || Artifact.SCOPE_SYSTEM.equals(a.getScope()) || Artifact.SCOPE_TEST.equals(a.getScope())) { list.add(a); } } else { if (Artifact.SCOPE_COMPILE.equals(a.getScope()) || Artifact.SCOPE_PROVIDED.equals(a.getScope()) || Artifact.SCOPE_SYSTEM.equals(a.getScope())) { list.add(a); } } } } return list; } /** * Convenience method to wrap an argument value in single quotes (i.e. '). Intended for values * which may contain whitespaces. *
* To prevent javadoc error, the line separator (i.e. \n) are skipped. * * @param value the argument value. * @return argument with quote */ private String quotedArgument(String value) { String arg = value; if (StringUtils.isNotEmpty(arg)) { if (arg.indexOf("'") != -1) { arg = StringUtils.replace(arg, "'", "\\'"); } arg = "'" + arg + "'"; // To prevent javadoc error arg = StringUtils.replace(arg, "\n", " "); } return arg; } /** * Convenience method to format a path argument so that it is properly interpreted by the javadoc tool. Intended * for path values which may contain whitespaces. * * @param value the argument value. * @return path argument with quote */ private String quotedPathArgument(String value) { String path = value; if (StringUtils.isNotEmpty(path)) { path = path.replace('\\', '/'); if (path.indexOf("\'") != -1) { String split[] = path.split("\'"); path = ""; for (int i = 0; i < split.length; i++) { if (i != split.length - 1) { path = path + split[i] + "\\'"; } else { path = path + split[i]; } } } path = "'" + path + "'"; } return path; } // /** // * Convenience method that copy all doc-files directories from javadocDir // * to the outputDirectory. // * // * @param outputDirectory the output directory // * @param javadocDir the javadoc directory // * @throws IOException if any // * @deprecated since 2.5, using {@link #copyJavadocResources(File, File, String)} instead of. // */ // private void copyJavadocResources(File outputDirectory, File javadocDir) // throws IOException { // copyJavadocResources(outputDirectory, javadocDir, null); // } // /** // * Convenience method that copy all doc-files directories from javadocDir // * to the outputDirectory. // * // * @param outputDirectory the output directory // * @param javadocDir the javadoc directory // * @param excludedocfilessubdir the excludedocfilessubdir parameter // * @throws IOException if any // * @since 2.5 // */ // private void copyJavadocResources(File outputDirectory, File javadocDir, String excludedocfilessubdir) // throws IOException { // if (!javadocDir.isDirectory()) { // return; // } // // List excludes = new ArrayList(); // excludes.addAll(Arrays.asList(FileUtils.getDefaultExcludes())); // // if (StringUtils.isNotEmpty(excludedocfilessubdir)) { // StringTokenizer st = new StringTokenizer(excludedocfilessubdir, ":"); // String current; // while (st.hasMoreTokens()) { // current = st.nextToken(); // excludes.add("**/" + current + "/**"); // } // } // // List docFiles = // FileUtils.getDirectoryNames(javadocDir, "resources,**/doc-files", // StringUtils.join(excludes.iterator(), ","), false, true); // for (String docFile : docFiles) { // File docFileOutput = new File(outputDirectory, docFile); // FileUtils.mkdir(docFileOutput.getAbsolutePath()); // FileUtils.copyDirectoryStructure(new File(javadocDir, docFile), docFileOutput); // List files = // FileUtils.getFileAndDirectoryNames(docFileOutput, StringUtils.join(excludes.iterator(), ","), // null, true, true, true, true); // for (String filename : files) { // File file = new File(filename); // // if (file.isDirectory()) { // FileUtils.deleteDirectory(file); // } else { // file.delete(); // } // } // } // } /** * Method that gets the files or classes that would be included in the javadocs using the subpackages * parameter. * * @param sourceDirectory the directory where the source files are located * @param fileList the list of all files found in the sourceDirectory * @param excludePackages package names to be excluded in the javadoc * @return a StringBuffer that contains the appended file names of the files to be included in the javadoc */ private List getIncludedFiles(File sourceDirectory, String[] fileList, String[] excludePackages) { List files = new ArrayList(); for (int j = 0; j < fileList.length; j++) { boolean include = true; for (int k = 0; k < excludePackages.length && include; k++) { // handle wildcards (*) in the excludePackageNames String[] excludeName = excludePackages[k].split("[*]"); if (excludeName.length == 0) { continue; } if (excludeName.length > 1) { int u = 0; while (include && u < excludeName.length) { if (!"".equals(excludeName[u].trim()) && fileList[j].indexOf(excludeName[u]) != -1) { include = false; } u++; } } else { if (fileList[j].startsWith(sourceDirectory.toString() + File.separatorChar + excludeName[0])) { if (excludeName[0].endsWith(String.valueOf(File.separatorChar))) { int i = fileList[j].lastIndexOf(File.separatorChar); String packageName = fileList[j].substring(0, i + 1); File currentPackage = new File(packageName); File excludedPackage = new File(sourceDirectory, excludeName[0]); if (currentPackage.equals(excludedPackage) && fileList[j].substring(i).indexOf(".java") != -1) { include = true; } else { include = false; } } else { include = false; } } } } if (include) { files.add(quotedPathArgument(fileList[j])); } } return files; } /** * Method that gets the complete package names (including subpackages) of the packages that were defined * in the excludePackageNames parameter. * * @param sourceDirectory the directory where the source files are located * @param excludePackagenames package names to be excluded in the javadoc * @return a List of the packagenames to be excluded */ private List getExcludedPackages(String sourceDirectory, String[] excludePackagenames) { List files = new ArrayList(); for (int i = 0; i < excludePackagenames.length; i++) { String[] fileList = FileUtils.getFilesFromExtension(sourceDirectory, new String[]{"java"}); for (int j = 0; j < fileList.length; j++) { String[] excludeName = excludePackagenames[i].split("[*]"); int u = 0; while (u < excludeName.length) { if (!"".equals(excludeName[u].trim()) && fileList[j].indexOf(excludeName[u]) != -1 && sourceDirectory.indexOf(excludeName[u]) == -1) { files.add(fileList[j]); } u++; } } } List excluded = new ArrayList(); for (String file : files) { int idx = file.lastIndexOf(File.separatorChar); String tmpStr = file.substring(0, idx); tmpStr = tmpStr.replace('\\', '/'); String[] srcSplit = tmpStr.split(sourceDirectory.replace('\\', '/') + '/'); String excludedPackage = srcSplit[1].replace('/', '.'); if (!excluded.contains(excludedPackage)) { excluded.add(excludedPackage); } } return excluded; } /** * Convenience method that gets the files to be included in the javadoc. * * @param sourceDirectory the directory where the source files are located * @param files the variable that contains the appended filenames of the files to be included in the javadoc * @param excludePackages the packages to be excluded in the javadocs */ private void addFilesFromSource(List files, File sourceDirectory, String[] excludePackages) { String[] fileList = FileUtils.getFilesFromExtension(sourceDirectory.getPath(), new String[]{"java"}); if (fileList != null && fileList.length != 0) { List tmpFiles = getIncludedFiles(sourceDirectory, fileList, excludePackages); files.addAll(tmpFiles); } } /** * Call the Javadoc tool and parse its output to find its version, i.e.: *
     * javadoc.exe(or .sh) -J-version
     * 
* * @param javadocExe not null file * @return the javadoc version as float * @throws IOException if javadocExe is null, doesn't exist or is not a file * @throws CommandLineException if any * @throws IllegalArgumentException if no output was found in the command line * @throws PatternSyntaxException if the output contains a syntax error in the regular-expression pattern. * @see #parseJavadocVersion(String) */ private float getJavadocVersion(File javadocExe) throws IOException, CommandLineException, IllegalArgumentException, PatternSyntaxException { if ((javadocExe == null) || (!javadocExe.exists()) || (!javadocExe.isFile())) { throw new IOException("The javadoc executable '" + javadocExe + "' doesn't exist or is not a file. "); } Commandline cmd = new Commandline(); cmd.setExecutable(javadocExe.getAbsolutePath()); cmd.setWorkingDirectory(javadocExe.getParentFile()); cmd.createArg().setValue("-J-version"); CommandLineUtils.StringStreamConsumer out = new CommandLineUtils.StringStreamConsumer(); CommandLineUtils.StringStreamConsumer err = new CommandLineUtils.StringStreamConsumer(); int exitCode = CommandLineUtils.executeCommandLine(cmd, out, err); if (exitCode != 0) { StringBuffer msg = new StringBuffer("Exit code: " + exitCode + " - " + err.getOutput()); msg.append('\n'); msg.append("Command line was:" + CommandLineUtils.toString(cmd.getCommandline())); throw new CommandLineException(msg.toString()); } if (StringUtils.isNotEmpty(err.getOutput())) { return parseJavadocVersion(err.getOutput()); } else if (StringUtils.isNotEmpty(out.getOutput())) { return parseJavadocVersion(out.getOutput()); } throw new IllegalArgumentException("No output found from the command line 'javadoc -J-version'"); } /** * Parse the output for 'javadoc -J-version' and return the javadoc version recognized. *
* Here are some output for 'javadoc -J-version' depending the JDK used: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
JDKOutput for 'javadoc -J-version'
Sun 1.4java full version "1.4.2_12-b03"
Sun 1.5java full version "1.5.0_07-164"
IBM 1.4javadoc full version "J2RE 1.4.2 IBM Windows 32 build cn1420-20040626"
IBM 1.5 (French JVM)javadoc version complète de "J2RE 1.5.0 IBM Windows 32 build pwi32pdev-20070426a"
FreeBSD 1.5java full version "diablo-1.5.0-b01"
BEA jrockit 1.5java full version "1.5.0_11-b03"
* * @param output for 'javadoc -J-version' * @return the version of the javadoc for the output. * @throws PatternSyntaxException if the output doesn't match with the output pattern * (?s).*?([0-9]+\\.[0-9]+)(\\.([0-9]+))?.*. * @throws IllegalArgumentException if the output is null */ private float parseJavadocVersion(String output) throws IllegalArgumentException, PatternSyntaxException { if (StringUtils.isEmpty(output)) { throw new IllegalArgumentException("The output could not be null."); } Pattern pattern = Pattern.compile("(?s).*?([0-9]+\\.[0-9]+)(\\.([0-9]+))?.*"); Matcher matcher = pattern.matcher(output); if (!matcher.matches()) { throw new PatternSyntaxException("Unrecognized version of Javadoc: '" + output + "'", pattern.pattern(), pattern.toString().length() - 1); } String version = matcher.group(3); if (version == null) { version = matcher.group(1); } else { version = matcher.group(1) + version; } return Float.parseFloat(version); } /** * Parse a memory string which be used in the JVM arguments -Xms or -Xmx. *
* Here are some supported memory string depending the JDK used: * * * * * * * * * * * * * * * * * *
JDKMemory argument support for -Xms or -Xmx
SUN1024k | 128m | 1g | 1t
IBM1024k | 1024b | 128m | 128mb | 1g | 1gb
BEA1024k | 1024kb | 128m | 128mb | 1g | 1gb
* * @param memory the memory to be parsed, not null. * @return the memory parsed with a supported unit. If no unit specified in the memory parameter, * the default unit is m. The units g | gb or t | tb will be converted * in m. * @throws IllegalArgumentException if the memory parameter is null or doesn't match any pattern. */ private String parseJavadocMemory(String memory) throws IllegalArgumentException { if (StringUtils.isEmpty(memory)) { throw new IllegalArgumentException("The memory could not be null."); } Pattern p = Pattern.compile("^\\s*(\\d+)\\s*?\\s*$"); Matcher m = p.matcher(memory); if (m.matches()) { return m.group(1) + "m"; } p = Pattern.compile("^\\s*(\\d+)\\s*k(b)?\\s*$", Pattern.CASE_INSENSITIVE); m = p.matcher(memory); if (m.matches()) { return m.group(1) + "k"; } p = Pattern.compile("^\\s*(\\d+)\\s*m(b)?\\s*$", Pattern.CASE_INSENSITIVE); m = p.matcher(memory); if (m.matches()) { return m.group(1) + "m"; } p = Pattern.compile("^\\s*(\\d+)\\s*g(b)?\\s*$", Pattern.CASE_INSENSITIVE); m = p.matcher(memory); if (m.matches()) { return (Integer.parseInt(m.group(1)) * 1024) + "m"; } p = Pattern.compile("^\\s*(\\d+)\\s*t(b)?\\s*$", Pattern.CASE_INSENSITIVE); m = p.matcher(memory); if (m.matches()) { return (Integer.parseInt(m.group(1)) * 1024 * 1024) + "m"; } throw new IllegalArgumentException("Could convert not to a memory size: " + memory); } /** * Validate if a charset is supported on this platform. * * @param charsetName the charsetName to be check. * @return true if the given charset is supported by the JVM, false otherwise. */ private boolean validateEncoding(String charsetName) { if (StringUtils.isEmpty(charsetName)) { return false; } OutputStream ost = new ByteArrayOutputStream(); OutputStreamWriter osw = null; try { osw = new OutputStreamWriter(ost, charsetName); } catch (UnsupportedEncodingException exc) { return false; } finally { IOUtil.close(osw); } return true; } /** * For security reasons, if an active proxy is defined and needs an authentication by * username/password, hide the proxy password in the command line. * * @param cmdLine a command line, not null * @param settings the user settings * @return the cmdline with '*' for the http.proxyPassword JVM property */ private String hideProxyPassword(String cmdLine, Settings settings) { if (cmdLine == null) { throw new IllegalArgumentException("cmdLine could not be null"); } if (settings == null) { return cmdLine; } Proxy activeProxy = settings.getActiveProxy(); if (activeProxy != null && StringUtils.isNotEmpty(activeProxy.getHost()) && StringUtils.isNotEmpty(activeProxy.getUsername()) && StringUtils.isNotEmpty(activeProxy.getPassword())) { String pass = "-J-Dhttp.proxyPassword=\"" + activeProxy.getPassword() + "\""; String hidepass = "-J-Dhttp.proxyPassword=\"" + StringUtils.repeat("*", activeProxy.getPassword().length()) + "\""; return StringUtils.replace(cmdLine, pass, hidepass); } return cmdLine; } // /** // * Auto-detect the class names of the implementation of com.sun.tools.doclets.Taglet class from a // * given jar file. // *
// * Note: JAVA_HOME/lib/tools.jar is a requirement to find // * com.sun.tools.doclets.Taglet class. // * // * @param jarFile not null // * @return the list of com.sun.tools.doclets.Taglet class names from a given jarFile. // * @throws IOException if jarFile is invalid or not found, or if the JAVA_HOME/lib/tools.jar // * is not found. // * @throws ClassNotFoundException if any // * @throws NoClassDefFoundError if any // */ // private List getTagletClassNames(File jarFile) // throws IOException, ClassNotFoundException, NoClassDefFoundError { // List classes = getClassNamesFromJar(jarFile); // ClassLoader cl; // // // Needed to find com.sun.tools.doclets.Taglet class // File tools = new File(System.getProperty("java.home"), "../lib/tools.jar"); // if (tools.exists() && tools.isFile()) { // cl = new URLClassLoader(new URL[]{jarFile.toURI().toURL(), tools.toURI().toURL()}, null); // } else { // cl = new URLClassLoader(new URL[]{jarFile.toURI().toURL()}, null); // } // // List tagletClasses = new ArrayList(); // // Class tagletClass = cl.loadClass("com.sun.tools.doclets.Taglet"); // for (String s : classes) { // Class c = cl.loadClass(s); // // if (tagletClass.isAssignableFrom(c) && !Modifier.isAbstract(c.getModifiers())) { // tagletClasses.add(c.getName()); // } // } // // return tagletClasses; // } /** * Copy the given url to the given file. * * @param url not null url * @param file not null file where the url will be created * @throws IOException if any * @since 2.6 */ private void copyResource(URL url, File file) throws IOException { if (file == null) { throw new IOException("The file " + file + " can't be null."); } if (url == null) { throw new IOException("The url " + url + " could not be null."); } InputStream is = url.openStream(); if (is == null) { throw new IOException("The resource " + url + " doesn't exists."); } if (!file.getParentFile().exists()) { file.getParentFile().mkdirs(); } FileOutputStream os = null; try { os = new FileOutputStream(file); IOUtil.copy(is, os); } finally { IOUtil.close(is); IOUtil.close(os); } } // /** // * Invoke Maven for the given project file with a list of goals and properties, the output will be in the // * invokerlog file. // *
// * Note: the Maven Home should be defined in the maven.home Java system property or defined in // * M2_HOME system env variables. // * // * @param log a logger could be null. // * @param localRepositoryDir the localRepository not null. // * @param projectFile a not null project file. // * @param goals a not null goals list. // * @param properties the properties for the goals, could be null. // * @param invokerLog the log file where the invoker will be written, if null using System.out. // * @throws MavenInvocationException if any // * @since 2.6 // */ // private void invokeMaven(Log log, File localRepositoryDir, File projectFile, List goals, // Properties properties, File invokerLog) // throws MavenInvocationException { // if (projectFile == null) { // throw new IllegalArgumentException("projectFile should be not null."); // } // if (!projectFile.isFile()) { // throw new IllegalArgumentException(projectFile.getAbsolutePath() + " is not a file."); // } // if (goals == null || goals.size() == 0) { // throw new IllegalArgumentException("goals should be not empty."); // } // if (localRepositoryDir == null || !localRepositoryDir.isDirectory()) { // throw new IllegalArgumentException("localRepositoryDir '" + localRepositoryDir // + "' should be a directory."); // } // // String mavenHome = getMavenHome(log); // if (StringUtils.isEmpty(mavenHome)) { // String msg = // "Could NOT invoke Maven because no Maven Home is defined. You need to have set the M2_HOME " // + "system env variable or a maven.home Java system properties."; // if (log != null) { // log.error(msg); // } else { // System.err.println(msg); // } // return; // } // // Invoker invoker = new DefaultInvoker(); // invoker.setMavenHome(new File(mavenHome)); // invoker.setLocalRepositoryDirectory(localRepositoryDir); // // InvocationRequest request = new DefaultInvocationRequest(); // request.setBaseDirectory(projectFile.getParentFile()); // request.setPomFile(projectFile); // if (log != null) { // request.setDebug(log.isDebugEnabled()); // } else { // request.setDebug(true); // } // request.setGoals(goals); // if (properties != null) { // request.setProperties(properties); // } // File javaHome = getJavaHome(log); // if (javaHome != null) { // request.setJavaHome(javaHome); // } // // if (log != null && log.isDebugEnabled()) { // log.debug("Invoking Maven for the goals: " + goals + " with " // + (properties == null ? "no properties" : "properties=" + properties)); // } // InvocationResult result = invoke(log, invoker, request, invokerLog, goals, properties, null); // // if (result.getExitCode() != 0) { // String invokerLogContent = readFile(invokerLog, "UTF-8"); // // // see DefaultMaven // if (invokerLogContent != null && (invokerLogContent.indexOf("Scanning for projects...") == -1 // || invokerLogContent.indexOf(OutOfMemoryError.class.getName()) != -1)) { // if (log != null) { // log.error("Error occurred during initialization of VM, trying to use an empty MAVEN_OPTS..."); // // if (log.isDebugEnabled()) { // log.debug("Reinvoking Maven for the goals: " + goals + " with an empty MAVEN_OPTS..."); // } // } // result = invoke(log, invoker, request, invokerLog, goals, properties, ""); // } // } // // if (result.getExitCode() != 0) { // String invokerLogContent = readFile(invokerLog, "UTF-8"); // // // see DefaultMaven // if (invokerLogContent != null && (invokerLogContent.indexOf("Scanning for projects...") == -1 // || invokerLogContent.indexOf(OutOfMemoryError.class.getName()) != -1)) { // throw new MavenInvocationException(ERROR_INIT_VM); // } // // throw new MavenInvocationException("Error when invoking Maven, consult the invoker log file: " // + invokerLog.getAbsolutePath()); // } // } // /** // * Read the given file and return the content or null if an IOException occurs. // * // * @param javaFile not null // * @param encoding could be null // * @return the content with unified line separator of the given javaFile using the given encoding. // * @see FileUtils#fileRead(File, String) // * @since 2.6.1 // */ // private String readFile(final File javaFile, final String encoding) { // try { // return FileUtils.fileRead(javaFile, encoding); // } catch (IOException e) { // return null; // } // } /** * Split the given path with colon and semi-colon, to support Solaris and Windows path. * Examples: *
     * splitPath( "/home:/tmp" )     = ["/home", "/tmp"]
     * splitPath( "/home;/tmp" )     = ["/home", "/tmp"]
     * splitPath( "C:/home:C:/tmp" ) = ["C:/home", "C:/tmp"]
     * splitPath( "C:/home;C:/tmp" ) = ["C:/home", "C:/tmp"]
     * 
* * @param path which can contain multiple paths separated with a colon (:) or a * semi-colon (;), platform independent. Could be null. * @return the path splitted by colon or semi-colon or null if path was null. * @since 2.6.1 */ private String[] splitPath(final String path) { if (path == null) { return null; } List subpaths = new ArrayList(); PathTokenizer pathTokenizer = new PathTokenizer(path); while (pathTokenizer.hasMoreTokens()) { subpaths.add(pathTokenizer.nextToken()); } return subpaths.toArray(new String[subpaths.size()]); } /** * Unify the given path with the current System path separator, to be platform independent. * Examples: *
     * unifyPathSeparator( "/home:/tmp" ) = "/home:/tmp" (Solaris box)
     * unifyPathSeparator( "/home:/tmp" ) = "/home;/tmp" (Windows box)
     * 
* * @param path which can contain multiple paths by separating them with a colon (:) or a * semi-colon (;), platform independent. Could be null. * @return the same path but separated with the current System path separator or null if path was * null. * @since 2.6.1 * @see #splitPath(String) * @see File#pathSeparator */ private String unifyPathSeparator(final String path) { if (path == null) { return null; } return StringUtils.join(splitPath(path), File.pathSeparator); } // ---------------------------------------------------------------------- // private methods // ---------------------------------------------------------------------- /** * @param jarFile not null * @return all class names from the given jar file. * @throws IOException if any or if the jarFile is null or doesn't exist. */ private List getClassNamesFromJar(File jarFile) throws IOException { if (jarFile == null || !jarFile.exists() || !jarFile.isFile()) { throw new IOException("The jar '" + jarFile + "' doesn't exist or is not a file."); } List classes = new ArrayList(); JarInputStream jarStream = null; try { jarStream = new JarInputStream(new FileInputStream(jarFile)); JarEntry jarEntry = jarStream.getNextJarEntry(); while (jarEntry != null) { if (jarEntry.getName().toLowerCase(Locale.ENGLISH).endsWith(".class")) { String name = jarEntry.getName().substring(0, jarEntry.getName().indexOf(".")); classes.add(name.replaceAll("/", "\\.")); } jarStream.closeEntry(); jarEntry = jarStream.getNextJarEntry(); } } finally { IOUtil.close(jarStream); } return classes; } // /** // * @param log could be null // * @param invoker not null // * @param request not null // * @param invokerLog not null // * @param goals not null // * @param properties could be null // * @param mavenOpts could be null // * @return the invocation result // * @throws MavenInvocationException if any // * @since 2.6 // */ // private InvocationResult invoke(Log log, Invoker invoker, InvocationRequest request, File invokerLog, // List goals, Properties properties, String mavenOpts) // throws MavenInvocationException { // PrintStream ps; // OutputStream os = null; // if (invokerLog != null) { // if (log != null && log.isDebugEnabled()) { // log.debug("Using " + invokerLog.getAbsolutePath() + " to log the invoker"); // } // // try { // if (!invokerLog.exists()) { // invokerLog.getParentFile().mkdirs(); // } // os = new FileOutputStream(invokerLog); // ps = new PrintStream(os, true, "UTF-8"); // } catch (FileNotFoundException e) { // if (log != null && log.isErrorEnabled()) { // log.error("FileNotFoundException: " + e.getMessage() + ". Using System.out to log the invoker."); // } // ps = System.out; // } catch (UnsupportedEncodingException e) { // if (log != null && log.isErrorEnabled()) { // log.error("UnsupportedEncodingException: " + e.getMessage() // + ". Using System.out to log the invoker."); // } // ps = System.out; // } // } else { // if (log != null && log.isDebugEnabled()) { // log.debug("Using System.out to log the invoker."); // } // // ps = System.out; // } // // if (mavenOpts != null) { // request.setMavenOpts(mavenOpts); // } // // InvocationOutputHandler outputHandler = new PrintStreamHandler(ps, false); // request.setOutputHandler(outputHandler); // // outputHandler.consumeLine("Invoking Maven for the goals: " + goals + " with " // + (properties == null ? "no properties" : "properties=" + properties)); // outputHandler.consumeLine(""); // outputHandler.consumeLine("M2_HOME=" + getMavenHome(log)); // outputHandler.consumeLine("MAVEN_OPTS=" + getMavenOpts(log)); // outputHandler.consumeLine("JAVA_HOME=" + getJavaHome(log)); // outputHandler.consumeLine("JAVA_OPTS=" + getJavaOpts(log)); // outputHandler.consumeLine(""); // // try { // return invoker.execute(request); // } finally { // IOUtil.close(os); // ps = null; // } // } // /** // * @param log a logger could be null // * @return the Maven home defined in the maven.home system property or defined // * in M2_HOME system env variables or null if never set. // * @since 2.6 // */ // private String getMavenHome(Log log) { // String mavenHome = System.getProperty("maven.home"); // if (mavenHome == null) { // try { // mavenHome = CommandLineUtils.getSystemEnvVars().getProperty("M2_HOME"); // } catch (IOException e) { // if (log != null && log.isDebugEnabled()) { // log.debug("IOException: " + e.getMessage()); // } // } // } // // File m2Home = new File(mavenHome); // if (!m2Home.exists()) { // if (log != null && log.isErrorEnabled()) { // log.error("Cannot find Maven application directory. Either specify \'maven.home\' system property, or " // + "M2_HOME environment variable."); // } // } // // return mavenHome; // } // /** // * @param log a logger could be null // * @return the MAVEN_OPTS env variable value // * @since 2.6 // */ // private String getMavenOpts(Log log) { // String mavenOpts = null; // try { // mavenOpts = CommandLineUtils.getSystemEnvVars().getProperty("MAVEN_OPTS"); // } catch (IOException e) { // if (log != null && log.isDebugEnabled()) { // log.debug("IOException: " + e.getMessage()); // } // } // // return mavenOpts; // } // /** // * @param log a logger could be null // * @return the JAVA_HOME from System.getProperty( "java.home" ) // * By default, System.getProperty( "java.home" ) = JRE_HOME and JRE_HOME // * should be in the JDK_HOME // * @since 2.6 // */ // private File getJavaHome(Log log) { // File javaHome; // if (SystemUtils.IS_OS_MAC_OSX) { // javaHome = SystemUtils.getJavaHome(); // } else { // javaHome = new File(SystemUtils.getJavaHome(), ".."); // } // // if (javaHome == null || !javaHome.exists()) { // try { // javaHome = new File(CommandLineUtils.getSystemEnvVars().getProperty("JAVA_HOME")); // } catch (IOException e) { // if (log != null && log.isDebugEnabled()) { // log.debug("IOException: " + e.getMessage()); // } // } // } // // if (javaHome == null || !javaHome.exists()) { // if (log != null && log.isErrorEnabled()) { // log.error("Cannot find Java application directory. Either specify \'java.home\' system property, or " // + "JAVA_HOME environment variable."); // } // } // // return javaHome; // } // /** // * @param log a logger could be null // * @return the JAVA_OPTS env variable value // * @since 2.6 // */ // private String getJavaOpts(Log log) { // String javaOpts = null; // try { // javaOpts = CommandLineUtils.getSystemEnvVars().getProperty("JAVA_OPTS"); // } catch (IOException e) { // if (log != null && log.isDebugEnabled()) { // log.debug("IOException: " + e.getMessage()); // } // } // // return javaOpts; // } /** * A Path tokenizer takes a path and returns the components that make up * that path. * * The path can use path separators of either ':' or ';' and file separators * of either '/' or '\'. * * @version revision 439418 taken on 2009-09-12 from Ant Project * (see http://svn.apache.org/repos/asf/ant/core/trunk/src/main/org/apache/tools/ant/PathTokenizer.java) */ private static class PathTokenizer { /** * A tokenizer to break the string up based on the ':' or ';' separators. */ private StringTokenizer tokenizer; /** * A String which stores any path components which have been read ahead * due to DOS filesystem compensation. */ private String lookahead = null; /** * A boolean that determines if we are running on Novell NetWare, which * exhibits slightly different path name characteristics (multi-character * volume / drive names) */ private boolean onNetWare = Os.isFamily("netware"); /** * Flag to indicate whether or not we are running on a platform with a * DOS style filesystem */ private boolean dosStyleFilesystem; /** * Constructs a path tokenizer for the specified path. * * @param path The path to tokenize. Must not be null. */ public PathTokenizer(String path) { if (onNetWare) { // For NetWare, use the boolean=true mode, so we can use delimiter // information to make a better decision later. tokenizer = new StringTokenizer(path, ":;", true); } else { // on Windows and Unix, we can ignore delimiters and still have // enough information to tokenize correctly. tokenizer = new StringTokenizer(path, ":;", false); } dosStyleFilesystem = File.pathSeparatorChar == ';'; } /** * Tests if there are more path elements available from this tokenizer's * path. If this method returns true, then a subsequent call * to nextToken will successfully return a token. * * @return true if and only if there is at least one token * in the string after the current position; false otherwise. */ public boolean hasMoreTokens() { if (lookahead != null) { return true; } return tokenizer.hasMoreTokens(); } /** * Returns the next path element from this tokenizer. * * @return the next path element from this tokenizer. * * @exception NoSuchElementException if there are no more elements in this * tokenizer's path. */ public String nextToken() throws NoSuchElementException { String token = null; if (lookahead != null) { token = lookahead; lookahead = null; } else { token = tokenizer.nextToken().trim(); } if (!onNetWare) { if (token.length() == 1 && Character.isLetter(token.charAt(0)) && dosStyleFilesystem && tokenizer.hasMoreTokens()) { // we are on a dos style system so this path could be a drive // spec. We look at the next token String nextToken = tokenizer.nextToken().trim(); if (nextToken.startsWith("\\") || nextToken.startsWith("/")) { // we know we are on a DOS style platform and the next path // starts with a slash or backslash, so we know this is a // drive spec token += ":" + nextToken; } else { // store the token just read for next time lookahead = nextToken; } } } else { // we are on NetWare, tokenizing is handled a little differently, // due to the fact that NetWare has multiple-character volume names. if (token.equals(File.pathSeparator) || token.equals(":")) { // ignore ";" and get the next token token = tokenizer.nextToken().trim(); } if (tokenizer.hasMoreTokens()) { // this path could be a drive spec, so look at the next token String nextToken = tokenizer.nextToken().trim(); // make sure we aren't going to get the path separator next if (!nextToken.equals(File.pathSeparator)) { if (nextToken.equals(":")) { if (!token.startsWith("/") && !token.startsWith("\\") && !token.startsWith(".") && !token.startsWith("..")) { // it indeed is a drive spec, get the next bit String oneMore = tokenizer.nextToken().trim(); if (!oneMore.equals(File.pathSeparator)) { token += ":" + oneMore; } else { token += ":"; lookahead = oneMore; } } // implicit else: ignore the ':' since we have either a // UNIX or a relative path } else { // store the token just read for next time lookahead = nextToken; } } } } return token; } } private List toList(String src) { return toList(src, null, null); } private List toList(String src, String elementPrefix, String elementSuffix) { if (StringUtils.isEmpty(src)) { return null; } List result = new ArrayList(); StringTokenizer st = new StringTokenizer(src, "[,:;]"); StringBuilder sb = new StringBuilder(256); while (st.hasMoreTokens()) { sb.setLength(0); if (StringUtils.isNotEmpty(elementPrefix)) { sb.append(elementPrefix); } sb.append(st.nextToken()); if (StringUtils.isNotEmpty(elementSuffix)) { sb.append(elementSuffix); } result.add(sb.toString()); } return result; } private List toList(T[] multiple) { return toList(null, multiple); } private List toList(T single, T[] multiple) { if (single == null && (multiple == null || multiple.length < 1)) { return null; } List result = new ArrayList(); if (single != null) { result.add(single); } if (multiple != null && multiple.length > 0) { result.addAll(Arrays.asList(multiple)); } return result; } // // TODO: move to plexus-utils or use something appropriate from there // private String toRelative(File basedir, String absolutePath) { // String relative; // // absolutePath = absolutePath.replace('\\', '/'); // String basedirPath = basedir.getAbsolutePath().replace('\\', '/'); // // if (absolutePath.startsWith(basedirPath)) { // relative = absolutePath.substring(basedirPath.length()); // if (relative.startsWith("/")) { // relative = relative.substring(1); // } // if (relative.length() <= 0) { // relative = "."; // } // } else { // relative = absolutePath; // } // // return relative; // } /** * Convenience method to determine that a collection is not empty or null. */ private boolean isNotEmpty(final Collection collection) { return collection != null && !collection.isEmpty(); } /** * Convenience method to determine that a collection is empty or null. */ private boolean isEmpty(final Collection collection) { return collection == null || collection.isEmpty(); } // /** // * Validates an URL to point to a valid package-list resource. // * // * @param url The URL to validate. // * @param settings The user settings used to configure the connection to the URL or {@code null}. // * @param validateContent true to validate the content of the package-list resource; // * false to only check the existence of the package-list resource. // * // * @return true if url points to a valid package-list resource; // * false else. // * // * @throws IOException if reading the resource fails. // * // * @see #createHttpClient(org.apache.maven.settings.Settings, java.net.URL) // * // * @since 2.8 // */ // private boolean isValidPackageList(URL url, Settings settings, boolean validateContent) // throws IOException { // if (url == null) { // throw new IllegalArgumentException("The url is null"); // } // // BufferedReader reader = null; // GetMethod httpMethod = null; // // try { // if ("file".equals(url.getProtocol())) { // // Intentionally using the platform default encoding here since this is what Javadoc uses internally. // reader = new BufferedReader(new InputStreamReader(url.openStream())); // } else { // // http, https... // HttpClient httpClient = createHttpClient(settings, url); // // httpMethod = new GetMethod(url.toString()); // int status; // try { // status = httpClient.executeMethod(httpMethod); // } catch (SocketTimeoutException e) { // // could be a sporadic failure, one more retry before we give up // status = httpClient.executeMethod(httpMethod); // } // // if (status != HttpStatus.SC_OK) { // throw new FileNotFoundException( // "Unexpected HTTP status code " + status + " getting resource " + url.toExternalForm() + "."); // // } // // // Intentionally using the platform default encoding here since this is what Javadoc uses internally. // reader = new BufferedReader(new InputStreamReader(httpMethod.getResponseBodyAsStream())); // } // // if (validateContent) { // String line; // while ((line = reader.readLine()) != null) { // if (!isValidPackageName(line)) { // return false; // } // } // } // // return true; // } finally { // IOUtil.close(reader); // // if (httpMethod != null) { // httpMethod.releaseConnection(); // } // } // } // private static boolean isValidPackageName(String str) { // if (StringUtils.isEmpty(str)) { // return false; // } // // int idx; // while ((idx = str.indexOf('.')) != -1) { // if (!isValidClassName(str.substring(0, idx))) { // return false; // } // // str = str.substring(idx + 1); // } // // return isValidClassName(str); // } // private static boolean isValidClassName(String str) { // if (StringUtils.isEmpty(str) || !Character.isJavaIdentifierStart(str.charAt(0))) { // return false; // } // // for (int i = str.length() - 1; i > 0; i--) { // if (!Character.isJavaIdentifierPart(str.charAt(i))) { // return false; // } // } // // return true; // } // /** // * Creates a new {@code HttpClient} instance. // * // * @param settings The settings to use for setting up the client or {@code null}. // * @param url The {@code URL} to use for setting up the client or {@code null}. // * // * @return A new {@code HttpClient} instance. // * // * @see #DEFAULT_TIMEOUT // * @since 2.8 // */ // private HttpClient createHttpClient(Settings settings, URL url) { // HttpClient httpClient = new HttpClient(new MultiThreadedHttpConnectionManager()); // httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(DEFAULT_TIMEOUT); // httpClient.getHttpConnectionManager().getParams().setSoTimeout(DEFAULT_TIMEOUT); // httpClient.getParams().setBooleanParameter(HttpClientParams.ALLOW_CIRCULAR_REDIRECTS, true); // // // Some web servers don't allow the default user-agent sent by httpClient // httpClient.getParams().setParameter(HttpMethodParams.USER_AGENT, // "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"); // // if (settings != null && settings.getActiveProxy() != null) { // Proxy activeProxy = settings.getActiveProxy(); // // ProxyInfo proxyInfo = new ProxyInfo(); // proxyInfo.setNonProxyHosts(activeProxy.getNonProxyHosts()); // // if (StringUtils.isNotEmpty(activeProxy.getHost()) // && (url == null || !ProxyUtils.validateNonProxyHosts(proxyInfo, url.getHost()))) { // httpClient.getHostConfiguration().setProxy(activeProxy.getHost(), activeProxy.getPort()); // // if (StringUtils.isNotEmpty(activeProxy.getUsername()) && activeProxy.getPassword() != null) { // Credentials credentials = // new UsernamePasswordCredentials(activeProxy.getUsername(), activeProxy.getPassword()); // // httpClient.getState().setProxyCredentials(AuthScope.ANY, credentials); // } // } // } // // return httpClient; // } // private boolean equalsIgnoreCase(String value, String... strings) { // for (String s : strings) { // if (s.equalsIgnoreCase(value)) { // return true; // } // } // return false; // } // // private boolean equals(String value, String... strings) { // for (String s : strings) { // if (s.equals(value)) { // return true; // } // } // return false; // } // protected boolean isAggregator() { // // only here for backward compatibility, this flag does not work reliably // return aggregate; // } }