| /******************************************************************************* |
| * Copyright (c) 2008, 2014 Sonatype, Inc. 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 |
| *******************************************************************************/ |
| |
| package org.eclipse.m2e.wtp; |
| |
| import static org.eclipse.m2e.wtp.WTPProjectsUtil.removeConflictingFacets; |
| |
| import java.util.LinkedHashSet; |
| import java.util.Set; |
| |
| import org.apache.maven.artifact.Artifact; |
| import org.apache.maven.artifact.resolver.filter.ArtifactFilter; |
| import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter; |
| import org.apache.maven.project.MavenProject; |
| import org.eclipse.core.resources.IFolder; |
| 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.jst.j2ee.jca.project.facet.ConnectorFacetInstallDataModelProvider; |
| import org.eclipse.jst.j2ee.jca.project.facet.IConnectorFacetInstallDataModelProperties; |
| import org.eclipse.m2e.core.MavenPlugin; |
| import org.eclipse.m2e.core.project.IMavenProjectFacade; |
| import org.eclipse.m2e.core.project.MavenProjectUtils; |
| import org.eclipse.m2e.wtp.namemapping.FileNameMappingFactory; |
| import org.eclipse.wst.common.componentcore.ComponentCore; |
| import org.eclipse.wst.common.componentcore.ModuleCoreNature; |
| import org.eclipse.wst.common.componentcore.resources.IVirtualComponent; |
| import org.eclipse.wst.common.componentcore.resources.IVirtualFolder; |
| import org.eclipse.wst.common.componentcore.resources.IVirtualReference; |
| import org.eclipse.wst.common.componentcore.resources.IVirtualResource; |
| 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; |
| |
| /** |
| * Configures Connector (RAR) projects based on their maven-rar-plugin configuration. |
| * |
| * @author Fred Bricon |
| */ |
| class ConnectorProjectConfiguratorDelegate extends AbstractProjectConfiguratorDelegate{ |
| |
| public static final ArtifactFilter SCOPE_FILTER_RUNTIME = new ScopeArtifactFilter(Artifact.SCOPE_RUNTIME); |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.m2e.wtp.AbstractProjectConfiguratorDelegate#configure(org.eclipse.core.resources.IProject, org.apache.maven.project.MavenProject, org.eclipse.core.runtime.IProgressMonitor) |
| */ |
| @Override |
| protected void configure(IProject project, MavenProject mavenProject, IProgressMonitor monitor) throws CoreException { |
| IFacetedProject facetedProject = ProjectFacetsManager.create(project, true, monitor); |
| if (facetedProject == null) { |
| return; |
| } |
| |
| Set<Action> actions = new LinkedHashSet<>(); |
| installJavaFacet(actions, project, facetedProject); |
| |
| IMavenProjectFacade facade = MavenPlugin.getMavenProjectRegistry().create(project, monitor); |
| RarPluginConfiguration config = new RarPluginConfiguration(facade); |
| |
| String contentDir = config.getRarContentDirectory(); |
| |
| IProjectFacetVersion connectorFv = config.getConnectorFacetVersion(); |
| |
| IDataModel rarModelCfg = DataModelFactory.createDataModel(new ConnectorFacetInstallDataModelProvider()); |
| |
| IFolder contentFolder = project.getFolder(contentDir); |
| if(!facetedProject.hasProjectFacet(WTPProjectsUtil.JCA_FACET)) { |
| |
| // Configuring content directory, used by WTP to create META-INF/manifest.mf, ra.xml |
| |
| rarModelCfg.setProperty(IConnectorFacetInstallDataModelProperties.CONFIG_FOLDER, contentDir); |
| //Don't generate ra.xml by default - Setting will be ignored for JCA 1.6 |
| rarModelCfg.setProperty(IConnectorFacetInstallDataModelProperties.GENERATE_DD, false); |
| rarModelCfg.setBooleanProperty(IConnectorFacetInstallDataModelProperties.ADD_TO_EAR, false); |
| |
| removeConflictingFacets(facetedProject, connectorFv, actions); |
| |
| actions.add(new IFacetedProject.Action(IFacetedProject.Action.Type.INSTALL, connectorFv, rarModelCfg)); |
| } else { |
| IProjectFacetVersion projectFacetVersion = facetedProject.getProjectFacetVersion(WTPProjectsUtil.JCA_FACET); |
| |
| if(projectFacetVersion.getVersionString() != null && !projectFacetVersion.getVersionString().equals(projectFacetVersion.getVersionString())){ |
| |
| removeConflictingFacets(facetedProject, connectorFv, actions); |
| |
| actions.add(new IFacetedProject.Action(IFacetedProject.Action.Type.VERSION_CHANGE, connectorFv, rarModelCfg)); |
| } |
| } |
| String customRaXml = config.getCustomRaXml(); |
| |
| if(!actions.isEmpty()) { |
| ResourceCleaner fileCleaner = new ResourceCleaner(project); |
| try { |
| addFoldersToClean(fileCleaner, facade); |
| fileCleaner.addFiles(contentFolder.getFile("META-INF/MANIFEST.MF").getProjectRelativePath()); //$NON-NLS-1$ |
| if (customRaXml != null) { |
| fileCleaner.addFiles(contentFolder.getFile("META-INF/ra.xml").getProjectRelativePath()); //$NON-NLS-1$ |
| } |
| |
| facetedProject.modify(actions, monitor); |
| } finally { |
| //Remove any unwanted MANIFEST.MF the Facet installation has created |
| fileCleaner.cleanUp(); |
| } |
| } |
| |
| //MECLIPSEWTP-41 Fix the missing moduleCoreNature |
| fixMissingModuleCoreNature(project, monitor); |
| |
| IVirtualComponent component = ComponentCore.createComponent(project); |
| if (component != null) { |
| |
| if (config.isJarIncluded()) { |
| addSourceLinks(component, mavenProject, monitor); |
| } else { |
| //project classes won't be jar'ed in the resulting rar. |
| removeSourceLinks(component, mavenProject, monitor); |
| } |
| |
| removeTestFolderLinks(project, mavenProject, monitor, "/"); //$NON-NLS-1$ |
| |
| linkFileFirst(project, customRaXml, "META-INF/ra.xml", monitor); //$NON-NLS-1$ |
| |
| IPath contentDirPath = new Path("/").append(contentDir); //$NON-NLS-1$ |
| |
| if (!WTPProjectsUtil.hasLink(project, ROOT_PATH, contentDirPath, monitor)) { |
| component.getRootFolder().createLink(contentDirPath, IVirtualResource.NONE, monitor); |
| } |
| |
| WTPProjectsUtil.setDefaultDeploymentDescriptorFolder(component.getRootFolder(), contentDirPath, monitor); |
| } |
| |
| setNonDependencyAttributeToContainer(project, monitor); |
| |
| //Remove "library unavailable at runtime" warning. TODO is it relevant for connector projects? |
| WTPProjectsUtil.removeWTPClasspathContainer(project); |
| |
| setModuleDependencies(project, mavenProject, monitor); |
| |
| } |
| |
| private void addSourceLinks(IVirtualComponent component, MavenProject mavenProject, IProgressMonitor monitor) throws CoreException { |
| IProject project = component.getProject(); |
| IPath classesPath = MavenProjectUtils.getProjectRelativePath(project, mavenProject.getBuild().getOutputDirectory()); |
| if (classesPath != null) { |
| for(IPath location : MavenProjectUtils.getSourceLocations(project, mavenProject.getCompileSourceRoots())) { |
| addLinkIfNecessary(component, location, monitor); |
| } |
| for(IPath location : MavenProjectUtils.getResourceLocations(project, mavenProject.getResources())) { |
| addLinkIfNecessary(component, location, monitor); |
| } |
| } |
| } |
| |
| private void addLinkIfNecessary(IVirtualComponent component, IPath location, IProgressMonitor monitor) throws CoreException { |
| IProject project = component.getProject(); |
| if (location!=null && !WTPProjectsUtil.hasLink(project, ROOT_PATH, location, monitor)) { |
| if (project.getFolder(location).isAccessible()) { |
| component.getRootFolder().createLink(location, IVirtualResource.NONE, monitor); |
| } |
| } |
| } |
| |
| |
| |
| private void removeSourceLinks(IVirtualComponent component, MavenProject mavenProject, IProgressMonitor monitor) throws CoreException { |
| IVirtualFolder jsrc = component.getRootFolder(); |
| IProject project = component.getProject(); |
| for(IPath location : MavenProjectUtils.getSourceLocations(project, mavenProject.getCompileSourceRoots())) { |
| jsrc.removeLink(location, 0, monitor); |
| } |
| for(IPath location : MavenProjectUtils.getResourceLocations(project, mavenProject.getResources())) { |
| jsrc.removeLink(location, 0, monitor); |
| } |
| } |
| |
| |
| |
| /** |
| * @see org.eclipse.m2e.wtp.IProjectConfiguratorDelegate#setModuleDependencies(org.eclipse.core.resources.IProject, org.apache.maven.project.MavenProject, org.eclipse.core.runtime.IProgressMonitor) |
| */ |
| @Override |
| public void setModuleDependencies(IProject project, MavenProject mavenProject, IProgressMonitor monitor) |
| throws CoreException { |
| |
| IVirtualComponent rarComponent = ComponentCore.createComponent(project); |
| |
| Set<IVirtualReference> newRefs = new LinkedHashSet<>(); |
| |
| Set<Artifact> artifacts = mavenProject.getArtifacts(); |
| |
| //Adding artifact references in .component. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=297777#c1 |
| for(Artifact artifact : artifacts) { |
| ArtifactHelper.fixArtifactHandler(artifact.getArtifactHandler()); |
| //Don't deploy pom, non runtime or optional dependencies |
| if("pom".equals(artifact.getType()) || !SCOPE_FILTER_RUNTIME.include(artifact) || artifact.isOptional()) { //$NON-NLS-1$ |
| continue; |
| } |
| |
| IMavenProjectFacade workspaceDependency = projectManager.getMavenProject(artifact.getGroupId(), artifact |
| .getArtifactId(), artifact.getVersion()); |
| |
| if(workspaceDependency != null && !workspaceDependency.getProject().equals(project) |
| && workspaceDependency.getFullPath(artifact.getFile()) != null) { |
| //artifact dependency is a workspace project |
| IProject depProject = preConfigureDependencyProject(workspaceDependency, monitor); |
| if (ModuleCoreNature.isFlexibleProject(depProject)) { |
| newRefs.add(createReference(rarComponent, depProject, artifact)); |
| } |
| } else { |
| //artifact dependency should be added as a JEE module, referenced with M2_REPO variable |
| newRefs.add(createReference(rarComponent, artifact)); |
| } |
| } |
| |
| IVirtualReference[] newRefsArray = new IVirtualReference[newRefs.size()]; |
| newRefs.toArray(newRefsArray); |
| |
| //Only change the project references if they've changed |
| IVirtualReference[] references = WTPProjectsUtil.extractHardReferences(rarComponent, false); |
| if (WTPProjectsUtil.hasChanged(references, newRefsArray)) { |
| rarComponent.setReferences(newRefsArray); |
| } |
| } |
| |
| private IVirtualReference createReference(IVirtualComponent rarComponent, IProject project, Artifact artifact) { |
| IVirtualComponent depComponent = ComponentCore.createComponent(project); |
| IVirtualReference depRef = ComponentCore.createReference(rarComponent, depComponent); |
| String deployedFileName = FileNameMappingFactory.getDefaultFileNameMapping().mapFileName(artifact); |
| depRef.setArchiveName(deployedFileName); |
| return depRef; |
| } |
| |
| private IVirtualReference createReference(IVirtualComponent rarComponent, Artifact artifact) { |
| //Create dependency component, referenced from the local Repo. |
| String artifactPath = ArtifactHelper.getM2REPOVarPath(artifact); |
| IVirtualComponent depComponent = ComponentCore.createArchiveComponent(rarComponent.getProject(), artifactPath); |
| return ComponentCore.createReference(rarComponent, depComponent); |
| } |
| |
| |
| } |