com.liferay.ide.maven.core.LiferayMavenProjectConfigurator.java Source code

Java tutorial

Introduction

Here is the source code for com.liferay.ide.maven.core.LiferayMavenProjectConfigurator.java

Source

/*******************************************************************************
 * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation; either version 2.1 of the License, or (at your option)
 * any later version.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 * details.
 *
 *******************************************************************************/
package com.liferay.ide.maven.core;

import com.liferay.ide.core.ILiferayConstants;
import com.liferay.ide.core.IWebProject;
import com.liferay.ide.core.LiferayCore;
import com.liferay.ide.core.LiferayNature;
import com.liferay.ide.core.util.CoreUtil;
import com.liferay.ide.hook.core.dd.HookDescriptorHelper;
import com.liferay.ide.hook.core.util.HookUtil;
import com.liferay.ide.project.core.facet.IPluginFacetConstants;
import com.liferay.ide.project.core.util.ProjectUtil;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.maven.model.Plugin;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.util.DirectoryScanner;
import org.codehaus.plexus.util.xml.Xpp3Dom;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IMarker;
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.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.m2e.core.internal.IMavenConstants;
import org.eclipse.m2e.core.internal.MavenPluginActivator;
import org.eclipse.m2e.core.internal.markers.IMavenMarkerManager;
import org.eclipse.m2e.core.internal.markers.MavenProblemInfo;
import org.eclipse.m2e.core.internal.markers.SourceLocation;
import org.eclipse.m2e.core.internal.markers.SourceLocationHelper;
import org.eclipse.m2e.core.project.IMavenProjectFacade;
import org.eclipse.m2e.core.project.configurator.AbstractProjectConfigurator;
import org.eclipse.m2e.core.project.configurator.ProjectConfigurationRequest;
import org.eclipse.m2e.jdt.IClasspathDescriptor;
import org.eclipse.m2e.jdt.IJavaProjectConfigurator;
import org.eclipse.m2e.wtp.WTPProjectsUtil;
import org.eclipse.m2e.wtp.WarPluginConfiguration;
import org.eclipse.osgi.util.NLS;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.internal.StructureEdit;
import org.eclipse.wst.common.componentcore.internal.WorkbenchComponent;
import org.eclipse.wst.common.componentcore.internal.util.ComponentUtilities;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.frameworks.datamodel.DataModelFactory;
import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
import org.eclipse.wst.common.frameworks.datamodel.IDataModelProvider;
import org.eclipse.wst.common.project.facet.core.IFacetedProject;
import org.eclipse.wst.common.project.facet.core.IFacetedProject.Action;
import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
import org.osgi.framework.Version;

/**
 * @author Gregory Amerson
 * @author Simon Jiang
 * @author Kuo Zhang
 * @author Kamesh Sampath
 */
@SuppressWarnings("restriction")
public class LiferayMavenProjectConfigurator extends AbstractProjectConfigurator
        implements IJavaProjectConfigurator {

    private static final IPath ROOT_PATH = new Path("/"); //$NON-NLS-1$
    private static final String MAVEN_WAR_PLUGIN_KEY = "org.apache.maven.plugins:maven-war-plugin";
    private static final String WAR_SOURCE_FOLDER = "/src/main/webapp"; //$NON-NLS-1$

    private IMavenMarkerManager mavenMarkerManager;

    public LiferayMavenProjectConfigurator() {
        super();

        this.mavenMarkerManager = MavenPluginActivator.getDefault().getMavenMarkerManager();
    }

    private MavenProblemInfo checkValidConfigDir(Plugin liferayMavenPlugin, Xpp3Dom config, String configParam) {
        MavenProblemInfo retval = null;
        String message = null;
        String value = null;

        if (configParam != null) {
            if (config == null) {
                message = NLS.bind(Msgs.missingConfigValue, configParam);
            } else {
                final Xpp3Dom dirNode = config.getChild(configParam);

                if (dirNode == null) {
                    message = NLS.bind(Msgs.missingConfigValue, configParam);
                } else {
                    value = dirNode.getValue();

                    if (CoreUtil.isNullOrEmpty(value)) {
                        message = NLS.bind(Msgs.emptyConfigValue, configParam);
                    } else {
                        final File configDir = new File(value);

                        if ((!configDir.exists()) || (!configDir.isDirectory())) {
                            message = NLS.bind(Msgs.unusableConfigValue, configParam, value);
                        }
                    }
                }
            }
        }

        if (message != null) {
            final SourceLocation location = SourceLocationHelper.findLocation(liferayMavenPlugin,
                    SourceLocationHelper.CONFIGURATION);

            retval = new MavenProblemInfo(message, IMarker.SEVERITY_WARNING, location);
        }

        return retval;
    }

    private MavenProblemInfo checkValidVersion(Plugin plugin, Xpp3Dom config, String versionNodeName) {
        MavenProblemInfo retval = null;
        Version liferayVersion = null;
        String version = null;

        if (config != null) {
            // check for version config node
            final Xpp3Dom versionNode = config.getChild(versionNodeName);

            if (versionNode != null) {
                version = versionNode.getValue();

                try {
                    liferayVersion = new Version(MavenUtil.getVersion(version));
                } catch (IllegalArgumentException e) {
                    // bad version
                }
            }
        }

        if (liferayVersion == null || liferayVersion.equals(ILiferayConstants.EMPTY_VERSION)) {
            // could not get valid liferayVersion
            final SourceLocation location = SourceLocationHelper.findLocation(plugin,
                    SourceLocationHelper.CONFIGURATION);
            final String problemMsg = NLS.bind(Msgs.unusableConfigValue, versionNodeName, version);
            retval = new MavenProblemInfo(problemMsg, IMarker.SEVERITY_WARNING, location);
        }

        return retval;
    }

    @Override
    public void configure(ProjectConfigurationRequest request, IProgressMonitor monitor) throws CoreException {
        if (monitor == null) {
            monitor = new NullProgressMonitor();
        }

        monitor.beginTask(NLS.bind(Msgs.configuringLiferayProject, request.getProject()), 100);

        final Plugin liferayMavenPlugin = MavenUtil.getPlugin(request.getMavenProjectFacade(),
                ILiferayMavenConstants.LIFERAY_MAVEN_PLUGIN_KEY, monitor);

        if (!shouldConfigure(liferayMavenPlugin, request)) {
            monitor.done();
            return;
        }

        final IProject project = request.getProject();
        final IFile pomFile = project.getFile(IMavenConstants.POM_FILE_NAME);
        final IFacetedProject facetedProject = ProjectFacetsManager.create(project, false, monitor);

        removeLiferayMavenMarkers(project);

        monitor.worked(25);

        final MavenProject mavenProject = request.getMavenProject();
        final List<MavenProblemInfo> errors = findLiferayMavenPluginProblems(project, request, monitor);

        if (errors.size() > 0) {
            try {
                this.markerManager.addErrorMarkers(pomFile,
                        ILiferayMavenConstants.LIFERAY_MAVEN_MARKER_CONFIGURATION_WARNING_ID, errors);
            } catch (CoreException e) {
                // no need to log this error its just best effort
            }
        }

        monitor.worked(25);

        MavenProblemInfo installProblem = null;

        if (shouldInstallNewLiferayFacet(mavenProject, facetedProject)) {
            installProblem = installNewLiferayFacet(facetedProject, request, monitor);
        }

        if (shouldAddLiferayNature(mavenProject, facetedProject)) {
            LiferayNature.addLiferayNature(project, monitor);
        }

        monitor.worked(25);

        if (installProblem != null) {
            this.markerManager.addMarker(pomFile,
                    ILiferayMavenConstants.LIFERAY_MAVEN_MARKER_CONFIGURATION_WARNING_ID,
                    installProblem.getMessage(), installProblem.getLocation().getLineNumber(),
                    IMarker.SEVERITY_WARNING);
        } else {
            String pluginType = MavenUtil.getLiferayMavenPluginType(mavenProject);

            // IDE-817 we need to mak sure that on deployment it will have the correct suffix for project name
            final IVirtualComponent projectComponent = ComponentCore.createComponent(project);

            try {
                if (projectComponent != null) {
                    String deployedName = projectComponent.getDeployedName();

                    Pattern VERSION_PATTERN = Pattern.compile("^(.*)-([0-9]\\.[0-9]\\.[0-9])(?:-SNAPSHOT)?$");

                    Matcher m = VERSION_PATTERN.matcher(deployedName);

                    if (m.matches()) {
                        deployedName = m.group(1);
                        configureDeployedName(project, deployedName);
                    }

                    if (pluginType != null) {
                        final String pluginTypeSuffix = "-" + pluginType;

                        final String deployedFileName = project.getName() + pluginTypeSuffix;

                        if (deployedName == null
                                || (deployedName != null && !deployedName.endsWith(pluginTypeSuffix))) {
                            configureDeployedName(project, deployedFileName);
                        }

                        final String oldContextRoot = ComponentUtilities.getServerContextRoot(project);

                        if (oldContextRoot == null
                                || (oldContextRoot != null && !oldContextRoot.endsWith(pluginTypeSuffix))) {

                            final IEclipsePreferences prefs = InstanceScope.INSTANCE
                                    .getNode(LiferayMavenCore.PLUGIN_ID);

                            boolean setMavenPluginSuffix = prefs
                                    .getBoolean(LiferayMavenCore.PREF_ADD_MAVEN_PLUGIN_SUFFIX, false);

                            if (setMavenPluginSuffix) {
                                ComponentUtilities.setServerContextRoot(project, deployedFileName);
                            }
                        }
                    }
                }
            } catch (Exception e) {
                LiferayMavenCore.logError("Unable to configure deployed name for project " + project.getName(), e);
            }

            if (ILiferayMavenConstants.THEME_PLUGIN_TYPE.equals(pluginType)) {
                final IVirtualComponent component = ComponentCore.createComponent(project, true);

                if (component != null) {
                    // make sure to update the main deployment folder
                    WarPluginConfiguration config = new WarPluginConfiguration(mavenProject, project);
                    String warSourceDirectory = config.getWarSourceDirectory();
                    IFolder contentFolder = project.getFolder(warSourceDirectory);
                    IPath warPath = ROOT_PATH.append(contentFolder.getProjectRelativePath());
                    IPath themeFolder = ROOT_PATH.append(getThemeTargetFolder(mavenProject, project));

                    // add a link to our m2e-liferay/theme-resources folder into deployment assembly
                    WTPProjectsUtil.insertLinkBefore(project, themeFolder, warPath, ROOT_PATH, monitor);
                }
            }
        }

        if (project != null && ProjectUtil.isHookProject(project)) {
            final HookDescriptorHelper hookDescriptor = new HookDescriptorHelper(project);
            final String customJSPFolder = hookDescriptor.getCustomJSPFolder(null);

            if (customJSPFolder != null) {
                final IWebProject webproject = LiferayCore.create(IWebProject.class, project);

                if (webproject != null && webproject.getDefaultDocrootFolder() != null) {
                    final IFolder docFolder = webproject.getDefaultDocrootFolder();
                    final IPath newPath = Path.fromOSString(customJSPFolder);
                    final IPath pathValue = docFolder.getFullPath().append(newPath);

                    final boolean disableCustomJspValidation = LiferayMavenCore
                            .getPreferenceBoolean(LiferayMavenCore.PREF_DISABLE_CUSTOM_JSP_VALIDATION);

                    if (disableCustomJspValidation) {
                        HookUtil.configureJSPSyntaxValidationExclude(project,
                                project.getFolder(pathValue.makeRelativeTo(project.getFullPath())), true);
                    }
                }
            }
        }

        monitor.worked(25);
        monitor.done();
    }

    private boolean shouldAddLiferayNature(MavenProject mavenProject, IFacetedProject facetedProject) {
        return mavenProject.getPlugin(ILiferayMavenConstants.BND_MAVEN_PLUGIN_KEY) != null
                || mavenProject.getPlugin(ILiferayMavenConstants.MAVEN_BUNDLE_PLUGIN_KEY) != null
                || mavenProject.getPlugin(ILiferayMavenConstants.LIFERAY_THEME_BUILDER_PLUGIN_KEY) != null;
    }

    public static IPath getThemeTargetFolder(MavenProject mavenProject, IProject project) {
        return MavenUtil.getM2eLiferayFolder(mavenProject, project)
                .append(ILiferayMavenConstants.THEME_RESOURCES_FOLDER);
    }

    public void configureClasspath(IMavenProjectFacade facade, IClasspathDescriptor classpath,
            IProgressMonitor monitor) throws CoreException {
    }

    // Copied from org.eclipse.m2e.wtp.AbstractProjectConfiguratorDelegate#configureDeployedName()
    protected void configureDeployedName(IProject project, String deployedFileName) {
        //We need to remove the file extension from deployedFileName
        int extSeparatorPos = deployedFileName.lastIndexOf('.');
        String deployedName = extSeparatorPos > -1 ? deployedFileName.substring(0, extSeparatorPos)
                : deployedFileName;
        //From jerr's patch in MNGECLIPSE-965
        IVirtualComponent projectComponent = ComponentCore.createComponent(project);
        if (projectComponent != null && !deployedName.equals(projectComponent.getDeployedName())) {//MNGECLIPSE-2331 : Seems projectComponent.getDeployedName() can be null
            StructureEdit moduleCore = null;
            try {
                moduleCore = StructureEdit.getStructureEditForWrite(project);
                if (moduleCore != null) {
                    WorkbenchComponent component = moduleCore.getComponent();
                    if (component != null) {
                        component.setName(deployedName);
                        moduleCore.saveIfNecessary(null);
                    }
                }
            } finally {
                if (moduleCore != null) {
                    moduleCore.dispose();
                }
            }
        }
    }

    public void configureRawClasspath(ProjectConfigurationRequest request, IClasspathDescriptor classpath,
            IProgressMonitor monitor) throws CoreException {
    }

    private List<MavenProblemInfo> findLiferayMavenPluginProblems(IProject project,
            ProjectConfigurationRequest request, IProgressMonitor monitor) throws CoreException {
        final List<MavenProblemInfo> warnings = new ArrayList<>();

        // first check to make sure that the AppServer* properties are available and pointed to valid location
        final Plugin liferayMavenPlugin = MavenUtil.getPlugin(request.getMavenProjectFacade(),
                ILiferayMavenConstants.LIFERAY_MAVEN_PLUGIN_KEY, monitor);

        if (liferayMavenPlugin != null) {
            final Xpp3Dom config = (Xpp3Dom) liferayMavenPlugin.getConfiguration();

            final MavenProblemInfo validLiferayProblemInfo = checkValidVersion(liferayMavenPlugin, config,
                    ILiferayMavenConstants.PLUGIN_CONFIG_LIFERAY_VERSION);

            if (validLiferayProblemInfo != null) {
                warnings.add(validLiferayProblemInfo);
            }

            final Version mavenPluginVersion = new Version(MavenUtil.getVersion(liferayMavenPlugin.getVersion()));

            if (mavenPluginVersion == null || mavenPluginVersion.equals(ILiferayConstants.EMPTY_VERSION)) {
                // could not get valid version for liferaymavenPlugin
                final SourceLocation location = SourceLocationHelper.findLocation(liferayMavenPlugin, "version");
                final String problemMsg = NLS.bind(Msgs.invalidVersion, "liferay-maven-plugin",
                        liferayMavenPlugin.getVersion());
                final MavenProblemInfo versionProblem = new MavenProblemInfo(problemMsg, IMarker.SEVERITY_WARNING,
                        location);
                warnings.add(versionProblem);
            }

            final String[] configDirParams = new String[] {
                    ILiferayMavenConstants.PLUGIN_CONFIG_APP_SERVER_PORTAL_DIR, };

            for (final String configParam : configDirParams) {
                final MavenProblemInfo configProblemInfo = checkValidConfigDir(liferayMavenPlugin, config,
                        configParam);

                if (configProblemInfo != null) {
                    warnings.add(configProblemInfo);
                }
            }
        }

        return warnings;
    }

    private IProjectFacetVersion getLiferayProjectFacet(IFacetedProject facetedProject) {
        IProjectFacetVersion retval = null;

        if (facetedProject != null) {
            for (IProjectFacetVersion fv : facetedProject.getProjectFacets()) {
                if (fv.getProjectFacet().getId().contains("liferay.")) //$NON-NLS-1$
                {
                    retval = fv;
                    break;
                }
            }
        }

        return retval;
    }

    private Action getNewLiferayFacetInstallAction(String pluginType) {
        Action retval = null;
        IProjectFacetVersion newFacet = null;
        IDataModelProvider dataModel = null;

        if (ILiferayMavenConstants.PORTLET_PLUGIN_TYPE.equals(pluginType)) {
            newFacet = IPluginFacetConstants.LIFERAY_PORTLET_PROJECT_FACET.getDefaultVersion();
            dataModel = new MavenPortletPluginFacetInstallProvider();
        } else if (ILiferayMavenConstants.HOOK_PLUGIN_TYPE.equals(pluginType)) {
            newFacet = IPluginFacetConstants.LIFERAY_HOOK_PROJECT_FACET.getDefaultVersion();
            dataModel = new MavenHookPluginFacetInstallProvider();
        } else if (ILiferayMavenConstants.EXT_PLUGIN_TYPE.equals(pluginType)) {
            newFacet = IPluginFacetConstants.LIFERAY_EXT_PROJECT_FACET.getDefaultVersion();
            dataModel = new MavenExtPluginFacetInstallProvider();
        } else if (ILiferayMavenConstants.LAYOUTTPL_PLUGIN_TYPE.equals(pluginType)) {
            newFacet = IPluginFacetConstants.LIFERAY_LAYOUTTPL_PROJECT_FACET.getDefaultVersion();
            dataModel = new MavenLayoutTplPluginFacetInstallProvider();
        } else if (ILiferayMavenConstants.THEME_PLUGIN_TYPE.equals(pluginType)) {
            newFacet = IPluginFacetConstants.LIFERAY_THEME_PROJECT_FACET.getDefaultVersion();
            dataModel = new MavenThemePluginFacetInstallProvider();
        } else if (ILiferayMavenConstants.WEB_PLUGIN_TYPE.equals(pluginType)) {
            newFacet = IPluginFacetConstants.LIFERAY_WEB_PROJECT_FACET.getDefaultVersion();
            dataModel = new MavenWebPluginFacetInstallProvider();
        }

        if (newFacet != null) {
            final IDataModel config = DataModelFactory.createDataModel(dataModel);
            retval = new Action(Action.Type.INSTALL, newFacet, config);
        }

        return retval;
    }

    private MavenProblemInfo installNewLiferayFacet(IFacetedProject facetedProject,
            ProjectConfigurationRequest request, IProgressMonitor monitor) throws CoreException {
        MavenProblemInfo retval = null;

        String pluginType = MavenUtil.getLiferayMavenPluginType(request.getMavenProject());

        if (pluginType == null) {
            pluginType = ILiferayMavenConstants.DEFAULT_PLUGIN_TYPE;
        }

        final Plugin liferayMavenPlugin = MavenUtil.getPlugin(request.getMavenProjectFacade(),
                ILiferayMavenConstants.LIFERAY_MAVEN_PLUGIN_KEY, monitor);
        final Action action = getNewLiferayFacetInstallAction(pluginType);

        if (action != null) {
            try {
                facetedProject.modify(Collections.singleton(action), monitor);
            } catch (Exception e) {
                try {
                    final SourceLocation location = SourceLocationHelper.findLocation(liferayMavenPlugin,
                            SourceLocationHelper.CONFIGURATION);
                    final String problemMsg = NLS.bind(Msgs.facetInstallError, pluginType,
                            e.getCause() != null ? e.getCause().getMessage() : e.getMessage());

                    retval = new MavenProblemInfo(location, e);
                    retval.setMessage(problemMsg);
                } catch (Exception e1) {
                }

                LiferayMavenCore.logError("Unable to install liferay facet " + action.getProjectFacetVersion(), //$NON-NLS-1$
                        e.getCause());
            }
        }

        return retval;
    }

    private void removeLiferayMavenMarkers(IProject project) throws CoreException {
        this.mavenMarkerManager.deleteMarkers(project,
                ILiferayMavenConstants.LIFERAY_MAVEN_MARKER_CONFIGURATION_WARNING_ID);
    }

    /*
     * IDE-1489 when no liferay maven plugin is found the project will be scanned for liferay specific files
     */
    private boolean shouldConfigure(Plugin liferayMavenPlugin, ProjectConfigurationRequest request) {
        final IProject project = request.getProject();
        final MavenProject mavenProject = request.getMavenProject();

        boolean configureAsLiferayPlugin = liferayMavenPlugin != null;

        final IFolder warSourceDir = warSourceDirectory(project, mavenProject);

        if (!configureAsLiferayPlugin && warSourceDir != null) {

            final IPath baseDir = warSourceDir.getRawLocation();
            final String[] includes = { "**/liferay*.xml", "**/liferay*.properties" };

            final DirectoryScanner dirScanner = new DirectoryScanner();
            dirScanner.setBasedir(baseDir.toFile());
            dirScanner.setIncludes(includes);
            dirScanner.scan();

            final String[] liferayProjectFiles = dirScanner.getIncludedFiles();
            configureAsLiferayPlugin = liferayProjectFiles != null && liferayProjectFiles.length > 0;
        }

        return configureAsLiferayPlugin;
    }

    private boolean shouldInstallNewLiferayFacet(MavenProject mavenProject, IFacetedProject facetedProject) {
        return getLiferayProjectFacet(facetedProject) == null;
    }

    private IFolder warSourceDirectory(final IProject project, final MavenProject mavenProject) {
        IFolder retval = null;

        final Xpp3Dom warPluginConfiguration = (Xpp3Dom) mavenProject.getPlugin(MAVEN_WAR_PLUGIN_KEY)
                .getConfiguration();

        if (warPluginConfiguration != null) {
            final Xpp3Dom[] warSourceDirs = warPluginConfiguration.getChildren("warSourceDirectory");

            if (warSourceDirs != null && warSourceDirs.length > 0) {
                final String resourceLocation = warSourceDirs[0].getValue();
                retval = project.getFolder(resourceLocation);
            }
        }

        if (retval == null) {
            /*
             * if no explicit warSourceDirectory set we assume the default warSource directory
             * ${basedir}/src/main/webapp refer to http://maven.apache.org/plugins/maven-war-plugin/war-mojo.html
             * for more information
             */
            retval = project.getFolder(WAR_SOURCE_FOLDER);
        }

        return retval;
    }

    private static class Msgs extends NLS {
        public static String configuringLiferayProject;
        public static String emptyConfigValue;
        public static String facetInstallError;
        public static String invalidVersion;
        public static String missingConfigValue;
        public static String unusableConfigValue;

        static {
            initializeMessages(LiferayMavenProjectConfigurator.class.getName(), Msgs.class);
        }
    }

}