| /* |
| * 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. |
| */ |
| package org.apache.sling.ide.eclipse.m2e.internal; |
| |
| import java.io.IOException; |
| import java.util.Arrays; |
| import java.util.LinkedHashSet; |
| import java.util.Optional; |
| import java.util.Set; |
| import java.util.TreeSet; |
| |
| import org.apache.maven.project.MavenProject; |
| import org.apache.sling.ide.eclipse.core.ConfigurationHelper; |
| import org.eclipse.aether.util.StringUtils; |
| import org.eclipse.core.resources.IMarker; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IProjectDescription; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.jst.common.project.facet.core.JavaFacet; |
| import org.eclipse.jst.common.project.facet.core.internal.JavaFacetUtil; |
| import org.eclipse.jst.j2ee.project.facet.IJ2EEFacetConstants; |
| import org.eclipse.jst.j2ee.project.facet.IJ2EEModuleFacetInstallDataModelProperties; |
| import org.eclipse.jst.j2ee.web.project.facet.IWebFacetInstallDataModelProperties; |
| import org.eclipse.jst.j2ee.web.project.facet.WebFacetInstallDataModelProvider; |
| import org.eclipse.jst.j2ee.web.project.facet.WebFacetUtils; |
| import org.eclipse.m2e.core.project.configurator.ProjectConfigurationRequest; |
| import org.eclipse.ui.statushandlers.StatusManager; |
| import org.eclipse.wst.common.frameworks.datamodel.DataModelFactory; |
| import org.eclipse.wst.common.frameworks.datamodel.IDataModel; |
| 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; |
| |
| /** |
| * m2e project configurator that creates the Eclipse project files (e.g .project) from a pom.xml for |
| * the maven packaging type "content-package". The configurator is run automatically |
| * on "Import..." -> "Existing Maven Project" and Right-Click on Project -> "Maven" |
| * -> "Update Project...". |
| * |
| * |
| */ |
| public class ContentPackageProjectConfigurator extends AbstractProjectConfigurator { |
| |
| // Using these maven properties, the to-be-created eclipse project settings can be configured in pom.xml |
| private static final String M2E_ACTIVE = "sling.ide.m2e.contentpackage.active"; |
| private static final String M2E_JAVA_FACET_VERSION = "sling.ide.m2e.contentpackage.javaFacetVersion"; |
| private static final String M2E_WEB_FACET_VERSION = "sling.ide.m2e.contentpackage.webFacetVersion"; |
| |
| @Override |
| public void configure(ProjectConfigurationRequest configRequest, IProgressMonitor progressMonitor) throws CoreException { |
| |
| IProject project = configRequest.getProject(); |
| // delete all previous markers on this pom.xml set by any project configurator |
| deleteMarkers(configRequest.getPom()); |
| |
| if (!getPreferences().isContentPackageProjectConfiguratorEnabled()) { |
| trace("M2E project configurator for packing type 'content-package' was disabled through preference."); |
| return; |
| } |
| |
| MavenProject mavenProject = configRequest.getMavenProject(); |
| boolean active = !"false".equalsIgnoreCase(mavenProject.getProperties().getProperty(M2E_ACTIVE)); |
| if(!active) { |
| trace("M2E project configurator for packing type 'content-package' was disabled with Maven property {0}", M2E_ACTIVE); |
| return; |
| } |
| |
| trace("Configuring {0} with packaging 'content-package'...", mavenProject); |
| |
| // core configuration for sling ide plugin |
| |
| try { |
| Optional<java.nio.file.Path> contentSyncPath = MavenProjectUtils.guessJcrRootFolder(mavenProject); |
| if (contentSyncPath.isPresent()) { |
| // add marker |
| addMarker(configRequest.getPom(), "Could not detect jcr_root path for this content package!", IMarker.SEVERITY_ERROR); |
| } |
| |
| String jcrRootPath = contentSyncPath.toString(); |
| ConfigurationHelper.convertToContentPackageProject(project, progressMonitor, Path.fromOSString(jcrRootPath)); |
| |
| if (getPreferences().isWtpFacetsEnabledInContentPackageProjectConfigurator()) { |
| new WtpProjectConfigurer(configRequest, project, jcrRootPath).configure(progressMonitor); |
| trace("WTP facets for {0} added", mavenProject); |
| } else { |
| trace("WTP facets for packing type 'content-package' are disabled through preferences."); |
| } |
| } catch (IOException e) { |
| Activator.getDefault().getPluginLogger().warn("Could not determine jcr_root for project: " + mavenProject.getBasedir() + ": "+e, e); |
| } |
| |
| trace("Done converting ."); |
| } |
| |
| /** |
| * Adds the given natures to the project |
| * @param project |
| * @param natureIdsToAdd |
| * @param progressMonitor |
| * @throws CoreException |
| * @see <a href="http://help.eclipse.org/neon/index.jsp?topic=%2Forg.eclipse.platform.doc.isv%2Fguide%2FresAdv_natures.htm">Eclipse Help: Project Natures</a> |
| */ |
| private void addNatures(IProject project, String[] natureIdsToAdd, IProgressMonitor progressMonitor, IResource pomResource) |
| throws CoreException { |
| |
| trace("Adding natures {0} to project {1} ", Arrays.toString(natureIdsToAdd), project); |
| |
| IProjectDescription description = project.getDescription(); |
| String[] oldNatureIds = description.getNatureIds(); |
| Set<String> newNatureIdSet = new TreeSet<String>(); |
| newNatureIdSet.addAll(Arrays.asList(oldNatureIds)); |
| // check if there is a nature change really requested |
| if (newNatureIdSet.addAll(Arrays.asList(natureIdsToAdd))) { |
| String[] newNatureIds = newNatureIdSet.toArray(new String[newNatureIdSet.size()]); |
| IStatus status = project.getWorkspace().validateNatureSet(newNatureIds); |
| // check the status and decide what to do |
| if (status.getCode() == IStatus.OK) { |
| trace("Modifiying natures of project {1} to {0}", Arrays.toString(newNatureIds), project); |
| description.setNatureIds(newNatureIds); |
| project.setDescription(description, IResource.KEEP_HISTORY, progressMonitor); |
| } else { |
| StatusManager.getManager().handle(status, StatusManager.LOG|StatusManager.SHOW); |
| // add marker |
| addMarker(pomResource, "Could not add all necessary WTP natures: " + status.getMessage(), IMarker.SEVERITY_ERROR); |
| } |
| } else { |
| trace("Not modifiying natures of project {1} as required natures {0} are already set ", Arrays.toString(natureIdsToAdd), project); |
| } |
| } |
| |
| // Implemented in line with the current m2e-wtp plugin, except that java/web facet version can be configured |
| private class WtpProjectConfigurer { |
| |
| private final ProjectConfigurationRequest configRequest; |
| private final IProject project; |
| private final String jcrRootPath; |
| |
| WtpProjectConfigurer(ProjectConfigurationRequest configRequest, |
| IProject project, String jcrRootPath) { |
| |
| this.configRequest = configRequest; |
| this.project = project; |
| this.jcrRootPath = jcrRootPath; |
| } |
| |
| |
| void configure(IProgressMonitor progressMonitor) throws CoreException { |
| |
| trace("Configuring content-package with WTP facets/natures"); |
| |
| addNatures(project, getDefaultWtpNatures(), progressMonitor, configRequest.getPom()); |
| addWtpFacets(progressMonitor); |
| } |
| |
| void addWtpFacets( IProgressMonitor progressMonitor) throws CoreException { |
| MavenProject mavenProject = configRequest.getMavenProject(); |
| String javaFacetVersion; |
| if ( !StringUtils.isEmpty(mavenProject.getProperties().getProperty(M2E_JAVA_FACET_VERSION))) { |
| javaFacetVersion = mavenProject.getProperties().getProperty(M2E_JAVA_FACET_VERSION); |
| trace("Configured Java facet version {0} from pom property {1}", javaFacetVersion, M2E_JAVA_FACET_VERSION); |
| } else { |
| javaFacetVersion = JavaFacetUtil.getCompilerLevel(project); |
| trace("Configured Java facet version {0} using JavaFacetUtil", javaFacetVersion); |
| } |
| |
| String webFacetVersion; |
| if ( !StringUtils.isEmpty(mavenProject.getProperties().getProperty(M2E_WEB_FACET_VERSION))) { |
| webFacetVersion = mavenProject.getProperties().getProperty(M2E_WEB_FACET_VERSION); |
| trace("Configured Web facet version {0} from pom property {1}", webFacetVersion, M2E_WEB_FACET_VERSION); |
| } else { |
| webFacetVersion = MavenProjectUtils.guessServletApiVersion(mavenProject); |
| trace("Configured Web facet version {0} from project dependencies", webFacetVersion); |
| } |
| |
| // web facets |
| IFacetedProject facetedProject = ProjectFacetsManager.create(project, true, progressMonitor); |
| Set<Action> actions = new LinkedHashSet<Action>(); |
| installJavaFacet(actions, project, facetedProject, javaFacetVersion); |
| |
| IProjectFacetVersion webFv = ProjectFacetsManager.getProjectFacet(IJ2EEFacetConstants.DYNAMIC_WEB).getVersion(webFacetVersion); |
| IDataModel webModelCfg = getWebModelConfig(jcrRootPath); |
| if (!facetedProject.hasProjectFacet(WebFacetUtils.WEB_FACET)) { |
| removeConflictingFacets(facetedProject, webFv, actions); |
| actions.add(new IFacetedProject.Action(IFacetedProject.Action.Type.INSTALL, webFv, webModelCfg)); |
| } else { |
| IProjectFacetVersion projectFacetVersion = facetedProject.getProjectFacetVersion(WebFacetUtils.WEB_FACET); |
| if (webFv.getVersionString() != null && !webFv.getVersionString().equals(projectFacetVersion.getVersionString())) { |
| actions.add(new IFacetedProject.Action(IFacetedProject.Action.Type.VERSION_CHANGE, webFv, webModelCfg)); |
| } |
| } |
| |
| if (!actions.isEmpty()) { |
| try { |
| facetedProject.modify(actions, progressMonitor); |
| } catch (Exception e) { |
| Activator.getDefault().getPluginLogger().warn("Could not add facets to project: "+e, e); |
| } |
| |
| } |
| } |
| |
| private IDataModel getWebModelConfig(String warSourceDirectory) { |
| IDataModel webModelCfg = DataModelFactory.createDataModel(new WebFacetInstallDataModelProvider()); |
| webModelCfg.setProperty(IJ2EEModuleFacetInstallDataModelProperties.CONFIG_FOLDER, warSourceDirectory); |
| webModelCfg.setProperty(IWebFacetInstallDataModelProperties.CONTEXT_ROOT, "/"); |
| webModelCfg.setProperty(IJ2EEModuleFacetInstallDataModelProperties.GENERATE_DD, false); |
| return webModelCfg; |
| } |
| |
| private void installJavaFacet(Set<Action> actions, IProject project, IFacetedProject facetedProject, String javaFacetVersion) { |
| IProjectFacetVersion javaFv = JavaFacet.FACET.getVersion(javaFacetVersion); |
| if (!facetedProject.hasProjectFacet(JavaFacet.FACET)) { |
| actions.add(new IFacetedProject.Action(IFacetedProject.Action.Type.INSTALL, javaFv, null)); |
| } else if (!facetedProject.hasProjectFacet(javaFv)) { |
| actions.add(new IFacetedProject.Action(IFacetedProject.Action.Type.VERSION_CHANGE, javaFv, null)); |
| } |
| } |
| |
| /** |
| * Adds uninstall actions of facets from the faceted project that conflict with the given facetVersion. |
| */ |
| private void removeConflictingFacets(IFacetedProject project, IProjectFacetVersion facetVersion, Set<Action> actions) { |
| if (project == null) { |
| throw new IllegalArgumentException("project can not be null"); |
| } |
| if (facetVersion == null) { |
| throw new IllegalArgumentException("Facet version can not be null"); |
| } |
| if (actions == null) { |
| throw new IllegalArgumentException("actions can not be null"); |
| } |
| for (IProjectFacetVersion existingFacetVersion : project.getProjectFacets()) { |
| if (facetVersion.conflictsWith(existingFacetVersion)) { |
| actions.add(new IFacetedProject.Action(IFacetedProject.Action.Type.UNINSTALL, existingFacetVersion, null)); |
| } |
| } |
| } |
| |
| |
| private String[] getDefaultWtpNatures() { |
| return new String[] { |
| "org.eclipse.wst.jsdt.core.jsNature", |
| "org.eclipse.wst.common.project.facet.core.nature", |
| "org.eclipse.wst.common.modulecore.ModuleCoreNature", |
| "org.eclipse.jem.workbench.JavaEMFNature" |
| }; |
| } |
| } |
| } |