com.google.gdt.eclipse.maven.configurators.MavenProjectConfigurator.java Source code

Java tutorial

Introduction

Here is the source code for com.google.gdt.eclipse.maven.configurators.MavenProjectConfigurator.java

Source

/*******************************************************************************
 * Copyright 2011 Google Inc. All Rights Reserved.
 *
 * 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
 *
 * 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.google.gdt.eclipse.maven.configurators;

import com.google.gdt.eclipse.core.StringUtilities;
import com.google.gdt.eclipse.core.properties.WebAppProjectProperties;
import com.google.gdt.eclipse.maven.Activator;
import com.google.gdt.eclipse.maven.sdk.GWTMavenRuntime;
import com.google.gwt.eclipse.core.nature.GWTNature;

import org.apache.maven.model.Dependency;
import org.apache.maven.model.Plugin;
import org.apache.maven.plugin.MojoExecution;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.util.xml.Xpp3Dom;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.m2e.core.lifecyclemapping.model.IPluginExecutionMetadata;
import org.eclipse.m2e.core.project.IMavenProjectFacade;
import org.eclipse.m2e.core.project.MavenProjectChangedEvent;
import org.eclipse.m2e.core.project.configurator.AbstractBuildParticipant;
import org.eclipse.m2e.core.project.configurator.ProjectConfigurationRequest;
import org.osgi.service.prefs.BackingStoreException;

import java.util.List;

/**
 * M2Eclipse project configuration extension that configures a project to get the Google GWT project nature.
 * <p>
 * NOTE: Do not access this class from outside of the configurators package. All classes in the configurators package
 * have dependencies on plugins that may or may not be present in the user's installation. As long as these classes are
 * only invoked through m2Eclipe's extension points, other parts of this plug-in can be used without requiring the
 * m2Eclipse dependencies.
 */
public class MavenProjectConfigurator extends AbstracMavenProjectConfigurator {

    /**
     * These properties may be pulled from the gwt-maven-plugin configuration of the pom to be used in configuring the
     * Google Web Application settings for the Eclipse project. If not present, defaults are used.
     */
    private static final String ECLIPSE_LAUNCH_SRC_DIR_PROPERTY_KEY = "eclipseLaunchFromWarDir";
    private static final boolean ECLIPSE_LAUNCH_SRC_DIR_DEFAULT = false;
    private static final String WAR_SRC_DIR_PROPERTY_KEY = "warSourceDirectory";
    private static final String WEB_APP_DIRECTORY = "webappDirectory";
    private static final String HOSTED_WEB_APP_DIRECTORY = "hostedWebapp"; // GWT Maven Plugin 1 only
    private static final String GWT_MAVEN_MODULENAME = "moduleName";
    private static final String GWT_MAVEN_MODULESHORTNAME = "moduleShortName";

    private static final String WAR_SRC_DIR_DEFAULT = "src/main/webapp";

    @Override
    public AbstractBuildParticipant getBuildParticipant(final IMavenProjectFacade projectFacade,
            MojoExecution execution, IPluginExecutionMetadata executionMetadata) {
        Activator.log("MavenProjectConfigurator.getBuildParticipant for Maven invoked");
        return super.getBuildParticipant(projectFacade, execution, executionMetadata);
    }

    @Override
    public void mavenProjectChanged(MavenProjectChangedEvent event, IProgressMonitor monitor) throws CoreException {
        super.mavenProjectChanged(event, monitor);
    }

    @Override
    public void configure(ProjectConfigurationRequest request, IProgressMonitor monitor) throws CoreException {
        Activator.log("MavenProjectConfigurator.configure invoked");
        super.configure(request, monitor);
    }

    @Override
    protected void doConfigure(final MavenProject mavenProject, IProject project,
            ProjectConfigurationRequest unused, final IProgressMonitor monitor) throws CoreException {
        Activator.log("MavenProjectConfigurator.doConfigure invoked");
        // configure the GWT Nature
        boolean hasGwtNature = configureNature(project, mavenProject, GWTNature.NATURE_ID, true,
                new NatureCallback() {
                    @Override
                    protected void beforeAddingNature() {
                        configureGwtProject(mavenProject, monitor);
                    }
                }, monitor);

        // retrieve gwt-maven-plugin configuration if it exists
        Plugin gwtMavenPlugin = getGwtMavenPlugin(mavenProject);
        Xpp3Dom mavenConfig = gwtMavenPlugin == null ? null : (Xpp3Dom) gwtMavenPlugin.getConfiguration();

        // Persist GWT nature settings
        if (!hasGwtNature) {
            Activator.log(
                    "MavenProjectConfigurator: Skipping Maven configuration because GWT nature is false. hasGWTNature="
                            + hasGwtNature);
            // Exit no maven plugin found
            return;
        }

        try {
            persistGwtNatureSettings(project, mavenProject, mavenConfig);
        } catch (BackingStoreException exception) {
            Activator.logError("MavenProjectConfigurator: Problem configuring maven project.", exception);
        }
    }

    /**
     * Save the settings for the GWT nature in the application GWT preferences.
     *
     * @param project
     * @param mavenProject
     * @param mavenConfig
     * @throws BackingStoreException
     */
    private void persistGwtNatureSettings(IProject project, MavenProject mavenProject, Xpp3Dom mavenConfig)
            throws BackingStoreException {
        IPath warOutDir = getWarOutDir(project, mavenProject);

        WebAppProjectProperties.setWarSrcDir(project, getWarSrcDir(mavenProject, mavenConfig)); // src/main/webapp
        WebAppProjectProperties.setWarSrcDirIsOutput(project, getLaunchFromHere(mavenConfig)); // false

        // TODO the extension should be used, from WarArgProcessor
        WebAppProjectProperties.setLastUsedWarOutLocation(project, warOutDir);

        WebAppProjectProperties.setGwtMavenModuleName(project, getGwtModuleName(mavenProject));
        WebAppProjectProperties.setGwtMavenModuleShortName(project, getGwtModuleShortName(mavenProject));

        String message = "MavenProjectConfiguratior Maven: Success with setting up GWT Nature\n";
        message += "\tartifactId=" + mavenProject.getArtifactId() + "\n";
        message += "\tversion=" + mavenProject.getVersion() + "\n";
        message += "\twarOutDir=" + warOutDir;
        Activator.log(message);
    }

    /**
     * Get the GWT Maven plugin 2 <moduleName/>.
     *
     * @param mavenProject
     * @return the moduleName from configuration
     */
    private String getGwtModuleName(MavenProject mavenProject) {
        if (!isGwtMavenPlugin2(mavenProject)) {
            return null;
        }

        Plugin gwtPlugin2 = getGwtMavenPlugin2(mavenProject);
        if (gwtPlugin2 == null) {
            return null;
        }

        Xpp3Dom gwtPluginConfig = (Xpp3Dom) gwtPlugin2.getConfiguration();
        if (gwtPluginConfig == null) {
            return null;
        }

        String moduleName = null;
        for (Xpp3Dom child : gwtPluginConfig.getChildren()) {
            if (child != null && GWT_MAVEN_MODULENAME.equals(child.getName())) {
                moduleName = child.getValue().trim();
            }
        }
        return moduleName;
    }

    /**
     * Get the GWT Maven plugin 2 <moduleShort=Name/>.
     *
     * @param mavenProject
     * @return the moduleName from configuration
     */
    private String getGwtModuleShortName(MavenProject mavenProject) {
        if (!isGwtMavenPlugin2(mavenProject)) {
            return null;
        }

        Plugin gwtPlugin2 = getGwtMavenPlugin2(mavenProject);
        if (gwtPlugin2 == null) {
            return null;
        }

        Xpp3Dom gwtPluginConfig = (Xpp3Dom) gwtPlugin2.getConfiguration();
        if (gwtPluginConfig == null) {
            return null;
        }

        String moduleName = null;
        for (Xpp3Dom child : gwtPluginConfig.getChildren()) {
            if (child != null && GWT_MAVEN_MODULESHORTNAME.equals(child.getName())) {
                moduleName = child.getValue().trim();
            }
        }
        return moduleName;
    }

    /**
     * Get the war output directory.
     *
     * @param project
     * @param mavenProject
     * @return returns the war output path
     */
    private IPath getWarOutDir(IProject project, MavenProject mavenProject) {
        String artifactId = mavenProject.getArtifactId();
        String version = mavenProject.getVersion();
        IPath locationOfProject = (project.getRawLocation() != null ? project.getRawLocation()
                : project.getLocation());

        IPath warOut = null;

        // Default directory target/artifact-version
        if (locationOfProject != null && artifactId != null && version != null) {
            warOut = locationOfProject.append("target").append(artifactId + "-" + version);
        }

        // Get the GWT Maven plugin 1 <hostedWebapp/> directory
        if (isGwtMavenPlugin1(mavenProject) && getGwtMavenPluginHostedWebAppDirectory(mavenProject) != null) {
            warOut = getGwtMavenPluginHostedWebAppDirectory(mavenProject);
        }

        // Get the Gwt Maven plugin 1 <webappDirectory/>
        if (isGwtMavenPlugin2(mavenProject) && getGwtPlugin2WebAppDirectory(mavenProject) != null) {
            warOut = getGwtPlugin2WebAppDirectory(mavenProject);
        }

        // Get the maven war plugin <webappDirectory/>
        if (getMavenWarPluginWebAppDirectory(mavenProject) != null) {
            warOut = getMavenWarPluginWebAppDirectory(mavenProject);
        }

        // make the directory if it doesn't exist
        if (warOut != null) {
            warOut.toFile().mkdirs();
        }

        return warOut;
    }

    /**
     * Get the GWT Maven <hostedWebapp/> directory.
     *
     * @param mavenProject
     * @return the webapp directory
     */
    private IPath getGwtMavenPluginHostedWebAppDirectory(MavenProject mavenProject) {
        Plugin warPlugin = getGwtMavenPlugin(mavenProject);
        if (warPlugin == null) {
            return null;
        }

        Xpp3Dom warPluginConfig = (Xpp3Dom) warPlugin.getConfiguration();
        if (warPluginConfig == null) {
            return null;
        }

        IPath warOut = null;
        for (Xpp3Dom child : warPluginConfig.getChildren()) {
            if (child != null && HOSTED_WEB_APP_DIRECTORY.equals(child.getName())) {
                String path = child.getValue().trim();
                if (!path.isEmpty()) {
                    warOut = new Path(path);
                }
            }
        }

        return warOut;
    }

    /**
     * Return the war out directory via the Maven war plugin <webappDirectory/>.
     *
     * @param mavenProject
     * @return path to web app direcotry
     */
    protected IPath getMavenWarPluginWebAppDirectory(MavenProject mavenProject) {
        Plugin warPlugin = getWarPlugin(mavenProject);
        if (warPlugin == null) {
            return null;
        }

        Xpp3Dom warPluginConfig = (Xpp3Dom) warPlugin.getConfiguration();
        if (warPluginConfig == null) {
            return null;
        }

        IPath warOut = null;
        for (Xpp3Dom child : warPluginConfig.getChildren()) {
            if (child != null && WEB_APP_DIRECTORY.equals(child.getName())) {
                String path = child.getValue().trim();
                if (!path.isEmpty()) {
                    warOut = new Path(path);
                }
            }
        }

        return warOut;
    }

    /**
     * Returns the Gwt Maven Plugin 2 web app directory <webappDirectory/>.
     *
     * @param mavenProject
     * @return path to web app direcotry
     */
    protected IPath getGwtPlugin2WebAppDirectory(MavenProject mavenProject) {
        Plugin warPlugin = getGwtMavenPlugin2(mavenProject);
        if (warPlugin == null) {
            return null;
        }

        Xpp3Dom warPluginConfig = (Xpp3Dom) warPlugin.getConfiguration();
        if (warPluginConfig == null) {
            return null;
        }

        IPath warOut = null;
        for (Xpp3Dom child : warPluginConfig.getChildren()) {
            if (child != null && WEB_APP_DIRECTORY.equals(child.getName())) {
                String path = child.getValue().trim();
                if (!path.isEmpty()) {
                    warOut = new Path(path);
                }
            }
        }

        return warOut;
    }

    /**
     * Configure the GWT Nature.
     *
     * @param mavenProject
     * @param monitor
     */
    protected void configureGwtProject(MavenProject mavenProject, IProgressMonitor monitor) {
        // Get the GWT version from the project pom
        String gwtVersion = null;
        List<Dependency> dependencies = mavenProject.getDependencies();
        for (Dependency dependency : dependencies) {
            boolean hasGwtGroupId = GWTMavenRuntime.MAVEN_GWT_GROUP_ID.equals(dependency.getGroupId());
            boolean hasGwtUserArtivactId = GWTMavenRuntime.MAVEN_GWT_USER_ARTIFACT_ID
                    .equals(dependency.getArtifactId());
            boolean hasGwtUserServletId = GWTMavenRuntime.MAVEN_GWT_SERVLET_ARTIFACT_ID
                    .equals(dependency.getArtifactId());
            if (hasGwtGroupId && (hasGwtUserArtivactId || hasGwtUserServletId)) {
                gwtVersion = dependency.getVersion();
                Activator.log("MavenProjectConfigurator, Maven: Setting up Gwt Project. hasGwtGroupId="
                        + hasGwtGroupId + " hasGwtUser=" + hasGwtUserArtivactId + " hasGwtUserServletId="
                        + hasGwtUserServletId);
                break;
            }
        }

        Activator.log("MavenProjectConfigurator, Maven: gwtVersion=" + gwtVersion);

        resolveGwtDevJar(mavenProject, monitor, gwtVersion);
    }

    private void resolveGwtDevJar(MavenProject mavenProject, IProgressMonitor monitor, String gwtVersion) {
        // Check that the pom.xml has GWT dependencies
        if (gwtVersion != null && !StringUtilities.isEmpty(gwtVersion)) {
            try {
                // Download and install the gwt-dev.jar into the local repository.
                maven.resolve(GWTMavenRuntime.MAVEN_GWT_GROUP_ID, GWTMavenRuntime.MAVEN_GWT_DEV_JAR_ARTIFACT_ID,
                        gwtVersion, "jar", null, mavenProject.getRemoteArtifactRepositories(), monitor);
            } catch (CoreException exception) {
                Activator.logError(
                        "MavenProjectConfigurator: Problem configuring the maven project because it could not download the "
                                + "gwt-dev.jar which is used to determine the version.",
                        exception);
            }
        }
    }

    /**
     * Returns the war source directory such as src/main/webapp
     *
     * @param mavenProject
     *
     * @param config
     *          gwt-maven-maven config DOM
     * @return the {@link #WAR_SRC_DIR_PROPERTY_KEY} value from the config if it exists, {@link #WAR_SRC_DIR_DEFAULT}
     *         otherwise or if config is null
     */
    private static final IPath getWarSrcDir(MavenProject mavenProject, Xpp3Dom config) {
        String spath = WAR_SRC_DIR_DEFAULT;

        if (config != null) {
            for (Xpp3Dom child : config.getChildren()) {
                if (child != null && WAR_SRC_DIR_PROPERTY_KEY.equals(child.getName())) {
                    spath = child.getValue() == null ? WAR_SRC_DIR_DEFAULT : child.getValue().trim();
                }
            }
        }

        IPath path = null;
        if (spath != null) {
            path = new Path(spath);

            String basePath = mavenProject.getBasedir().toPath().toAbsolutePath().toString();
            String fullPath = basePath + "/" + spath;
            java.io.File fullPathFile = new java.io.File(fullPath);
            if (!fullPathFile.exists()) {
                path = null;
            }
        }

        return path;
    }

    /**
     * Get the project launch locaiton
     *
     * @param config
     *          gwt-maven-maven config DOM
     * @return the {@link #ECLIPSE_LAUNCH_SRC_DIR_PROPERTY_KEY} value from the config if it exists,
     *         {@link #ECLIPSE_LAUNCH_SRC_DIR_DEFAULT} otherwise or if config is null
     */
    private final boolean getLaunchFromHere(Xpp3Dom config) {
        if (config == null) {
            return ECLIPSE_LAUNCH_SRC_DIR_DEFAULT;
        }
        for (Xpp3Dom child : config.getChildren()) {
            if (child != null && ECLIPSE_LAUNCH_SRC_DIR_PROPERTY_KEY.equals(child.getName())) {
                return child.getValue() == null ? ECLIPSE_LAUNCH_SRC_DIR_DEFAULT
                        : Boolean.parseBoolean(child.getValue().trim());
            }
        }
        return ECLIPSE_LAUNCH_SRC_DIR_DEFAULT;
    }

}