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

org.eclipse.tycho.extras.docbundle.JavadocMojo Maven / Gradle / Ivy

There is a newer version: 3.0.5
Show newest version
/*******************************************************************************
 * Copyright (c) 2013, 2015 IBH SYSTEMS GmbH and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBH SYSTEMS GmbH - initial API and implementation
 *******************************************************************************/
package org.eclipse.tycho.extras.docbundle;

import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.maven.execution.MavenSession;
import org.apache.maven.model.Dependency;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.project.MavenProject;
import org.apache.maven.toolchain.ToolchainManager;
import org.codehaus.plexus.util.FileUtils;
import org.eclipse.tycho.core.osgitools.BundleReader;

/**
 * Create the javadoc based API reference for this bundle 
* This mojo creates the javadoc documentation by calling the javadoc application from the command * line. In addition it creates a ready to include toc-xml file for the Eclipse Help system.
* The sources for creating the javadoc are generated automatically based on the dependency that * this project has. As dependency you can specify any other maven project, for example the feature * project that references you other bundles. Included features will be added to the list. * * @since 0.20.0 */ @Mojo(name = "javadoc", defaultPhase = LifecyclePhase.PROCESS_CLASSES, requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME, threadSafe = false) public class JavadocMojo extends AbstractMojo { /** * The directory where the javadoc content will be generated * */ @Parameter(property = "outputDirectory", defaultValue = "${project.build.directory}/reference/api", required = true) private File outputDirectory; /** * The base output directory */ @Parameter(property = "basedir", required = true, readonly = true) private File basedir; /** * The build directory where temporary build files will be placed */ @Parameter(property = "project.build.directory", required = true) private File buildDirectory; /** * An option to clean out the whole outputDirectory first. */ @Parameter(property = "cleanFirst", defaultValue = "true") private boolean cleanFirst; @Component private ToolchainManager toolchainManager; @Parameter(property = "session", required = true, readonly = true) private MavenSession session; @Parameter(property = "reactorProjects", required = true, readonly = true) protected List reactorProjects; /** * The scopes that the dependencies must have in order to be included */ @Parameter(property = "scopes", defaultValue = "compile,provided") private Set scopes = new HashSet<>(); /** * Maven module types that will be used to include the source */ @Parameter(property = "sourceTypes", defaultValue = "eclipse-plugin") private Set sourceTypes = new HashSet<>(); /** * Options for calling the javadoc application. Possible options are (all options are optional): *
    *
  • ignoreError, specifies if errors calling javadoc should be ignored
  • *
  • doclet, used as javadoc -doclet parameter
  • *
  • docletArtifacts, dependencies will be resovled and added as -docletpath * parameter
  • *
  • encoding, used as javadoc -encoding parameter (default: * ${project.build.sourceEncoding}
  • *
  • additionalArguments, a list of additional arguments passed to javadoc
  • *
  • includes/excludes, the list of names of packages to be included in or * excluded from JavaDoc processing; use '*' character as wildcard
  • *
* Example configuration: * *
     * <configuration>
     *    <javadocOptions>
     *       <ignoreError>false</ignoreError>
     *       <encoding>UTF-8</encoding>
     *       <doclet>foo.bar.MyDoclet</doclet>
     *       <docletArtifacts>
     *          <docletArtifact>
     *             <groupId>foo.bar</groupId>
     *             <artifactId>foo.bar.mydocletartifact</artifactId>
     *             <version>1.0</version>
     *          </docletArtifact>
     *       </docletArtifacts>
     *       <includes>
     *          <include>com.example.*</include>
     *       </includes>
     *       <excludes>
     *          <exclude>com.example.internal.*</exclude>
     *       </excludes>   
     *       <additionalArguments>
     *          <additionalArgument>-windowtitle "The Window Title"</additionalArgument>
     *          <additionalArgument>-nosince</additionalArgument>
     *       </additionalArguments>
     *    </javadocOptions>
     * </configuration>
     * 
*/ @Parameter(property = "javadocOptions") private JavadocOptions javadocOptions = new JavadocOptions(); /** * Options for creating the toc files. *
    *
  • mainLabel, specifies the main label of the toc file (default: "API Reference") *
  • *
  • mainFilename, specifies the filename of the TOC file (default: * "overview-summary.html") *
* Example configuration: * *
     * <configuration>
     *    <tocOptions>
     *       <mainLabel>My own label</mainLabel>
     *       <mainFilename>myOverviewSummary.html</mainFilename>
     *    </tocOptions>
     * </configuration>
     * 
*/ @Parameter(property = "tocOptions") private TocOptions tocOptions = new TocOptions(); /** * Set this property to true to skip the generation of the Eclipse TOC files. */ @Parameter(property = "skipTocGen", defaultValue = "false") private boolean skipTocGen = false; /** * The output location of the toc file.
* This file will be overwritten. */ @Parameter(property = "tocFile", defaultValue = "${project.build.directory}/tocjavadoc.xml") private File tocFile; @Parameter(property = "project.build.sourceEncoding", readonly = true) private String projectBuildSourceEncoding; @Component private BundleReader bundleReader; @Component private DocletArtifactsResolver docletArtifactsResolver; public void setTocOptions(TocOptions tocOptions) { this.tocOptions = tocOptions; } public void setSourceTypes(final Set sourceTypes) { this.sourceTypes = sourceTypes; } public void setScopes(final Set scopes) { this.scopes = scopes; } public void setJavadocOptions(final JavadocOptions javadocOptions) { this.javadocOptions = javadocOptions; } public void execute() throws MojoExecutionException { getLog().info("Scopes: " + this.scopes); getLog().info("Output directory: " + this.outputDirectory); getLog().info("BaseDir: " + this.basedir); if (this.cleanFirst) { getLog().info("Cleaning up first"); cleanUp(); } // if no encoding is set, fall back to ${project.build.sourceEncoding} if (javadocOptions.getEncoding() == null) { javadocOptions.setEncoding(projectBuildSourceEncoding); } final JavadocRunner runner = new JavadocRunner(); runner.setLog(getLog()); runner.setOutput(this.outputDirectory); runner.setBuildDirectory(this.buildDirectory); runner.setToolchainManager(this.toolchainManager); runner.setSession(this.session); runner.setDocletArtifactsResolver(docletArtifactsResolver); final GatherManifestVisitor gmv = new GatherManifestVisitor(); visitProjects(this.session.getCurrentProject().getDependencies(), this.scopes, gmv); final GatherSourcesVisitor gsv = new GatherSourcesVisitor(); visitProjects(this.session.getCurrentProject().getDependencies(), this.scopes, gsv); getLog().info(String.format("%s source folders", gsv.getSourceFolders().size())); for (final File file : gsv.getSourceFolders()) { getLog().info("Source folder: " + file); } // TODO: use tycho's approach of gathering the classpath final GatherClasspathVisitor gcv = new GatherClasspathVisitor(); visitProjects(this.session.getCurrentProject().getDependencies(), this.scopes, gcv); final Collection cp = gcv.getClassPath(); getLog().info(String.format("%s classpath deps", cp.size())); for (final String ele : cp) { getLog().info("CP: " + ele); } runner.setBundleReader(this.bundleReader); runner.setOptions(this.javadocOptions); runner.setManifestFiles(gmv.getManifestFiles()); runner.setSourceFolders(gsv.getSourceFolders()); runner.setClassPath(cp); // Setup toc writer final TocWriter tocWriter = new TocWriter(); tocWriter.setOptions(this.tocOptions); tocWriter.setJavadocDir(this.outputDirectory); tocWriter.setBasedir(this.basedir); tocWriter.setLog(getLog()); try { runner.run(); if (!skipTocGen) { tocWriter.writeTo(this.tocFile); } } catch (final Exception e) { throw new MojoExecutionException("Failed to run javadoc", e); } } private void cleanUp() throws MojoExecutionException { if (!this.outputDirectory.exists()) { return; } try { FileUtils.deleteDirectory(this.outputDirectory); } catch (final IOException e) { throw new MojoExecutionException("Failed to clean output directory", e); } } @SuppressWarnings("unchecked") private void visitProjects(final List dependencies, final Set scopes, final ProjectVisitor visitor) throws MojoExecutionException { for (final Dependency dep : (List) dependencies) { getLog().debug("Dependency: " + dep + " / scope=" + dep.getScope()); final String scope = dep.getScope(); if (scopes.contains(scope)) { visitDeps(dep, visitor, scopes); } } } private interface ProjectVisitor { public void visit(MavenProject project) throws MojoExecutionException; } private class GatherSourcesVisitor implements ProjectVisitor { private final Set sourceFolders = new HashSet<>(); public void visit(final MavenProject project) { if (JavadocMojo.this.sourceTypes.contains(project.getPackaging())) { for (final String root : (Collection) project.getCompileSourceRoots()) { getLog().debug("\tAdding source root: " + root); final File rootFile = new File(root); if (rootFile.isDirectory()) { this.sourceFolders.add(rootFile); } } } } public Set getSourceFolders() { return this.sourceFolders; } } private class GatherManifestVisitor implements ProjectVisitor { private final Set manifestFiles = new HashSet<>(); public void visit(final MavenProject project) { if (JavadocMojo.this.sourceTypes.contains(project.getPackaging())) { this.manifestFiles.add(new File(project.getBasedir(), "META-INF/MANIFEST.MF")); } } public Set getManifestFiles() { return manifestFiles; } } private class GatherClasspathVisitor implements ProjectVisitor { private final Set classPath = new HashSet<>(); public void visit(final MavenProject project) throws MojoExecutionException { for (final Dependency dep : (List) project.getDependencies()) { if (dep.getSystemPath() != null) { this.classPath.add(dep.getSystemPath()); } } } public Set getClassPath() { return this.classPath; } } private void visitDeps(final Dependency dep, final ProjectVisitor visitor, final Set scopes) throws MojoExecutionException { final MavenProject project = findProject(dep.getGroupId(), dep.getArtifactId()); if (project == null) { getLog().info(String.format("Did not find project %s in reactor", dep)); return; } getLog().debug("Adding sources from: " + project); visitor.visit(project); getLog().debug("Scanning dependencies: " + project.getDependencies().size()); visitProjects(project.getDependencies(), scopes, visitor); getLog().debug("Done processing: " + project); } private MavenProject findProject(final String groupId, final String artifactId) { getLog().debug(String.format("findProject - groupId: %s, artifactId: %s", groupId, artifactId)); for (final MavenProject p : this.reactorProjects) { if (!p.getGroupId().equals(groupId)) { continue; } if (!p.getArtifactId().equals(artifactId)) { continue; } return p; } return null; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy