org.codehaus.mojo.gwt.AbstractGwtMojo.java Source code

Java tutorial

Introduction

Here is the source code for org.codehaus.mojo.gwt.AbstractGwtMojo.java

Source

package org.codehaus.mojo.gwt;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

import static org.apache.maven.artifact.Artifact.SCOPE_COMPILE;
import static org.apache.maven.artifact.Artifact.SCOPE_RUNTIME;

import org.apache.commons.io.IOUtils;
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.model.Dependency;
import org.apache.maven.model.Resource;
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.Parameter;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.MavenProjectBuilder;
import org.apache.maven.project.artifact.MavenMetadataSource;
import org.codehaus.plexus.util.StringUtils;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

/**
 * Abstract Support class for all GWT-related operations.
 * <p>
 * Provide methods to build classpath for GWT SDK tools.
 *
 * @author <a href="mailto:nicolas@apache.org">Nicolas De Loof</a>
 * @version $Id$
 */
public abstract class AbstractGwtMojo extends AbstractMojo {
    private static final String GWT_USER = "com.google.gwt:gwt-user";

    private static final String GWT_DEV = "com.google.gwt:gwt-dev";

    /** GWT artifacts groupId */
    public static final String GWT_GROUP_ID = "com.google.gwt";

    // --- Some Maven tools ----------------------------------------------------

    @Parameter(defaultValue = "${plugin.artifactMap}", required = true, readonly = true)
    private Map<String, Artifact> pluginArtifactMap;

    @Component
    private MavenProjectBuilder projectBuilder;

    @Component
    protected ArtifactResolver resolver;

    @Component
    protected ArtifactFactory artifactFactory;

    @Component
    protected ClasspathBuilder classpathBuilder;

    // --- Some MavenSession related structures --------------------------------

    @Parameter(defaultValue = "${localRepository}", required = true, readonly = true)
    protected ArtifactRepository localRepository;

    @Parameter(defaultValue = "${project.pluginArtifactRepositories}", required = true, readonly = true)
    protected List<ArtifactRepository> remoteRepositories;

    @Component
    protected ArtifactMetadataSource artifactMetadataSource;

    /**
     * The maven project descriptor
     */
    @Parameter(defaultValue = "${project}", required = true, readonly = true)
    private MavenProject project;

    // --- Plugin parameters ---------------------------------------------------

    /**
     * Folder where generated-source will be created (automatically added to compile classpath).
     */
    @Parameter(defaultValue = "${project.build.directory}/generated-sources/gwt", required = true)
    private File generateDirectory;

    /**
     * Location on filesystem where GWT will write output files (-out option to GWTCompiler).
     */
    @Parameter(property = "gwt.war", defaultValue = "${project.build.directory}/${project.build.finalName}", alias = "outputDirectory")
    private File webappDirectory;

    /**
     * Prefix to prepend to module names inside {@code webappDirectory} or in URLs in DevMode.
     * <p>
     * Could also be seen as a suffix to {@code webappDirectory}.
     */
    @Parameter(property = "gwt.modulePathPrefix")
    protected String modulePathPrefix;

    /**
     * Location of the web application static resources (same as maven-war-plugin parameter)
     */
    @Parameter(defaultValue = "${basedir}/src/main/webapp")
    protected File warSourceDirectory;

    /**
     * Select the place where GWT application is built. In <code>inplace</code> mode, the warSourceDirectory is used to
     * match the same use case of the {@link war:inplace
     * http://maven.apache.org/plugins/maven-war-plugin/inplace-mojo.html} goal.
     */
    @Parameter(defaultValue = "false", property = "gwt.inplace")
    private boolean inplace;

    /**
     * The forked command line will use gwt sdk jars first in classpath.
     * see issue http://code.google.com/p/google-web-toolkit/issues/detail?id=5290
     *
     * @since 2.1.0-1
     * @deprecated tweak your dependencies and/or split your project with a client-only module
     */
    @Deprecated
    @Parameter(defaultValue = "false", property = "gwt.gwtSdkFirstInClasspath")
    protected boolean gwtSdkFirstInClasspath;

    public File getOutputDirectory() {
        File out = inplace ? warSourceDirectory : webappDirectory;
        if (!StringUtils.isBlank(modulePathPrefix)) {
            out = new File(out, modulePathPrefix);
        }
        return out;
    }

    /**
     * Add classpath elements to a classpath URL set
     *
     * @param elements the initial URL set
     * @param urls the urls to add
     * @param startPosition the position to insert URLS
     * @return full classpath URL set
     * @throws MojoExecutionException some error occured
     */
    protected int addClasspathElements(Collection<?> elements, URL[] urls, int startPosition)
            throws MojoExecutionException {
        for (Object object : elements) {
            try {
                if (object instanceof Artifact) {
                    urls[startPosition] = ((Artifact) object).getFile().toURI().toURL();
                } else if (object instanceof Resource) {
                    urls[startPosition] = new File(((Resource) object).getDirectory()).toURI().toURL();
                } else {
                    urls[startPosition] = new File((String) object).toURI().toURL();
                }
            } catch (MalformedURLException e) {
                throw new MojoExecutionException(
                        "Failed to convert original classpath element " + object + " to URL.", e);
            }
            startPosition++;
        }
        return startPosition;
    }

    /**
     * Build the GWT classpath for the specified scope
     *
     * @param scope Artifact.SCOPE_COMPILE or Artifact.SCOPE_TEST
     * @return a collection of dependencies as Files for the specified scope.
     * @throws MojoExecutionException if classPath building failed
     */
    public Collection<File> getClasspath(String scope) throws MojoExecutionException {
        try {
            Collection<File> files = classpathBuilder.buildClasspathList(getProject(), scope, getProjectArtifacts(),
                    isGenerator());

            if (getLog().isDebugEnabled()) {
                getLog().debug("GWT SDK execution classpath :");
                for (File f : files) {
                    getLog().debug("   " + f.getAbsolutePath());
                }
            }
            return files;
        } catch (ClasspathBuilderException e) {
            throw new MojoExecutionException(e.getMessage(), e);
        }
    }

    /**
     * Whether to use processed resources and compiled classes ({@code false}), or raw resources ({@code true }).
     */
    protected boolean isGenerator() {
        return false;
    }

    protected Collection<File> getGwtDevJar() throws MojoExecutionException {
        return getJarFiles(GWT_DEV);
    }

    protected Collection<File> getGwtUserJar() throws MojoExecutionException {
        return getJarFiles(GWT_USER);
    }

    private Collection<File> getJarFiles(String artifactId) throws MojoExecutionException {
        checkGwtUserVersion();
        Artifact rootArtifact = pluginArtifactMap.get(artifactId);

        ArtifactResolutionResult result;
        try {
            // Code shamelessly copied from exec-maven-plugin.
            MavenProject rootProject = this.projectBuilder.buildFromRepository(rootArtifact,
                    this.remoteRepositories, this.localRepository);
            List<Dependency> dependencies = rootProject.getDependencies();
            Set<Artifact> dependencyArtifacts = MavenMetadataSource.createArtifacts(artifactFactory, dependencies,
                    null, null, null);
            dependencyArtifacts.add(rootProject.getArtifact());
            result = resolver.resolveTransitively(dependencyArtifacts, rootArtifact, Collections.EMPTY_MAP,
                    localRepository, remoteRepositories, artifactMetadataSource, null, Collections.EMPTY_LIST);
        } catch (Exception e) {
            throw new MojoExecutionException("Failed to resolve artifact", e);
        }

        Collection<Artifact> resolved = result.getArtifacts();
        Collection<File> files = new ArrayList<File>(resolved.size() + 1);
        files.add(rootArtifact.getFile());
        for (Artifact artifact : resolved) {
            files.add(artifact.getFile());
        }

        return files;
    }

    /**
     * Check gwt-user dependency matches plugin version
     */
    private void checkGwtUserVersion() throws MojoExecutionException {
        InputStream inputStream = Thread.currentThread().getContextClassLoader()
                .getResourceAsStream("org/codehaus/mojo/gwt/mojoGwtVersion.properties");
        Properties properties = new Properties();
        try {
            properties.load(inputStream);

        } catch (IOException e) {
            throw new MojoExecutionException("Failed to load plugin properties", e);
        } finally {
            IOUtils.closeQuietly(inputStream);
        }

        Artifact gwtUser = project.getArtifactMap().get(GWT_USER);
        if (gwtUser != null) {
            String mojoGwtVersion = properties.getProperty("gwt.version");
            //ComparableVersion with an up2date maven version
            ArtifactVersion mojoGwtArtifactVersion = new DefaultArtifactVersion(mojoGwtVersion);
            ArtifactVersion userGwtArtifactVersion = new DefaultArtifactVersion(gwtUser.getVersion());
            if (userGwtArtifactVersion.compareTo(mojoGwtArtifactVersion) < 0) {
                getLog().warn("Your project declares dependency on gwt-user " + gwtUser.getVersion()
                        + ". This plugin is designed for at least gwt version " + mojoGwtVersion);
            }
        }
    }

    protected Artifact resolve(String groupId, String artifactId, String version, String type, String classifier)
            throws MojoExecutionException {
        // return project.getArtifactMap().get( groupId + ":" + artifactId );

        Artifact artifact = artifactFactory.createArtifactWithClassifier(groupId, artifactId, version, type,
                classifier);
        try {
            resolver.resolve(artifact, remoteRepositories, localRepository);
        } catch (ArtifactNotFoundException e) {
            throw new MojoExecutionException("artifact not found - " + e.getMessage(), e);
        } catch (ArtifactResolutionException e) {
            throw new MojoExecutionException("artifact resolver problem - " + e.getMessage(), e);
        }
        return artifact;
    }

    /**
     * @param path file to add to the project compile directories
     */
    protected void addCompileSourceRoot(File path) {
        getProject().addCompileSourceRoot(path.getAbsolutePath());
    }

    /**
     * @return the project
     */
    public MavenProject getProject() {
        return project;
    }

    public ArtifactRepository getLocalRepository() {
        return this.localRepository;
    }

    public List<ArtifactRepository> getRemoteRepositories() {
        return this.remoteRepositories;
    }

    protected File setupGenerateDirectory() {
        if (!generateDirectory.exists()) {
            getLog().debug("Creating target directory " + generateDirectory.getAbsolutePath());
            generateDirectory.mkdirs();
        }
        getLog().debug("Add compile source root " + generateDirectory.getAbsolutePath());
        addCompileSourceRoot(generateDirectory);
        return generateDirectory;
    }

    public File getGenerateDirectory() {
        if (!generateDirectory.exists()) {
            getLog().debug("Creating target directory " + generateDirectory.getAbsolutePath());
            generateDirectory.mkdirs();
        }
        return generateDirectory;
    }

    public Set<Artifact> getProjectArtifacts() {
        return project.getArtifacts();
    }

    public Set<Artifact> getProjectRuntimeArtifacts() {
        Set<Artifact> artifacts = new HashSet<Artifact>();
        for (Artifact projectArtifact : project.getArtifacts()) {
            String scope = projectArtifact.getScope();
            if (SCOPE_RUNTIME.equals(scope) || SCOPE_COMPILE.equals(scope)) {
                artifacts.add(projectArtifact);
            }

        }
        return artifacts;
    }

}