| /******************************************************************************* |
| * Copyright (c) 2008, 2013 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.io.File; |
| import java.io.IOException; |
| import java.lang.reflect.Field; |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.LinkedHashSet; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import org.apache.maven.artifact.Artifact; |
| import org.apache.maven.project.MavenProject; |
| import org.codehaus.plexus.util.FileUtils; |
| import org.codehaus.plexus.util.StringUtils; |
| 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.Path; |
| import org.eclipse.jdt.core.IClasspathAttribute; |
| import org.eclipse.jdt.core.JavaCore; |
| import org.eclipse.jst.j2ee.classpathdep.IClasspathDependencyConstants; |
| import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities; |
| 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.MavenPlugin; |
| import org.eclipse.m2e.core.embedder.ArtifactKey; |
| import org.eclipse.m2e.core.internal.IMavenConstants; |
| import org.eclipse.m2e.core.project.IMavenProjectFacade; |
| import org.eclipse.m2e.jdt.IClasspathDescriptor; |
| import org.eclipse.m2e.jdt.IClasspathEntryDescriptor; |
| import org.eclipse.m2e.wtp.internal.ExtensionReader; |
| import org.eclipse.m2e.wtp.internal.Messages; |
| import org.eclipse.m2e.wtp.internal.filtering.WebResourceFilteringConfiguration; |
| import org.eclipse.m2e.wtp.internal.utilities.DebugUtilities; |
| import org.eclipse.m2e.wtp.namemapping.FileNameMapping; |
| 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.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; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| |
| |
| /** |
| * Configures web projects based on their maven-war-plugin configuration. |
| * |
| * @author Igor Fedorenko |
| * @author Fred Bricon |
| */ |
| @SuppressWarnings("restriction") |
| class WebProjectConfiguratorDelegate extends AbstractProjectConfiguratorDelegate { |
| |
| private static final Logger LOG = LoggerFactory.getLogger(WebProjectConfiguratorDelegate.class); |
| /** |
| * See http://wiki.eclipse.org/ClasspathEntriesPublishExportSupport |
| */ |
| static final IClasspathAttribute DEPENDENCY_ATTRIBUTE = JavaCore.newClasspathAttribute( |
| IClasspathDependencyConstants.CLASSPATH_COMPONENT_DEPENDENCY, "/WEB-INF/lib"); //$NON-NLS-1$ |
| |
| private static final String CLASSPATH_ARCHIVENAME_ATTRIBUTE; |
| |
| static { |
| String archiveNameAttribute = null; |
| try { |
| Field classpathArchiveNameField = IClasspathDependencyConstants.class.getField("CLASSPATH_ARCHIVENAME_ATTRIBUTE"); //$NON-NLS-1$ |
| archiveNameAttribute = (String)classpathArchiveNameField.get(null); |
| } catch (Exception e) { |
| LOG.warn(Messages.WebProjectConfiguratorDelegate_Renamed_Dependencies_Will_Be_Copied); |
| } |
| CLASSPATH_ARCHIVENAME_ATTRIBUTE = archiveNameAttribute; |
| } |
| |
| /** |
| * Name of maven property that overrides WTP context root. |
| */ |
| private static final String M2ECLIPSE_WTP_CONTEXT_ROOT = "m2eclipse.wtp.contextRoot"; //$NON-NLS-1$ |
| |
| @Override |
| protected void configure(IProject project, MavenProject mavenProject, IProgressMonitor monitor) |
| throws CoreException { |
| IFacetedProject facetedProject = ProjectFacetsManager.create(project, true, monitor); |
| IMavenProjectFacade facade = MavenPlugin.getMavenProjectRegistry().create(project.getFile(IMavenConstants.POM_FILE_NAME), true, monitor); |
| |
| // make sure to update the main deployment folder |
| WarPluginConfiguration config = new WarPluginConfiguration(mavenProject, project); |
| String warSourceDirectory = config.getWarSourceDirectory(); |
| |
| IFolder contentFolder = project.getFolder(warSourceDirectory); |
| |
| Set<Action> actions = new LinkedHashSet<Action>(); |
| |
| installJavaFacet(actions, project, facetedProject); |
| |
| IVirtualComponent component = ComponentCore.createComponent(project, true); |
| |
| //MNGECLIPSE-2279 get the context root from the final name of the project, or artifactId by default. |
| String contextRoot = getContextRoot(mavenProject, config.getWarName()); |
| |
| IProjectFacetVersion webFv = config.getWebFacetVersion(project); |
| IDataModel webModelCfg = getWebModelConfig(warSourceDirectory, contextRoot); |
| 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)); |
| } |
| } |
| |
| String customWebXml = config.getCustomWebXml(project); |
| |
| if(!actions.isEmpty()) { |
| ResourceCleaner fileCleaner = new ResourceCleaner(project, contentFolder); |
| try { |
| addFoldersToClean(fileCleaner, facade); |
| fileCleaner.addFiles(contentFolder.getFile("META-INF/MANIFEST.MF").getProjectRelativePath()); //$NON-NLS-1$ |
| fileCleaner.addFolder(contentFolder.getFolder("WEB-INF/lib")); //$NON-NLS-1$ |
| if (customWebXml != null) { |
| fileCleaner.addFiles(contentFolder.getFile("WEB-INF/web.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); |
| |
| // MNGECLIPSE-632 remove test sources/resources from WEB-INF/classes |
| removeTestFolderLinks(project, mavenProject, monitor, "/WEB-INF/classes"); //$NON-NLS-1$ |
| |
| addContainerAttribute(project, DEPENDENCY_ATTRIBUTE, monitor); |
| |
| //MNGECLIPSE-2279 change the context root if needed |
| if (!contextRoot.equals(J2EEProjectUtilities.getServerContextRoot(project))) { |
| J2EEProjectUtilities.setServerContextRoot(project, contextRoot); |
| } |
| |
| if (customWebXml != null) { |
| linkFileFirst(project, customWebXml, "/WEB-INF/web.xml", monitor); //$NON-NLS-1$ |
| } |
| |
| |
| component = ComponentCore.createComponent(project, true); |
| if(component != null) { |
| IPath warPath = new Path("/").append(contentFolder.getProjectRelativePath()); //$NON-NLS-1$ |
| List<IPath> sourcePaths = new ArrayList<IPath>(); |
| sourcePaths.add(warPath); |
| if (!WTPProjectsUtil.hasLink(project, ROOT_PATH, warPath, monitor)) { |
| component.getRootFolder().createLink(warPath, IVirtualResource.NONE, monitor); |
| } |
| //MECLIPSEWTP-22 support web filtered resources. Filtered resources directory must be declared BEFORE |
| //the regular web source directory. First resources discovered take precedence on deployment |
| IPath filteredFolder = new Path("/").append(WebResourceFilteringConfiguration.getTargetFolder(mavenProject, project)); //$NON-NLS-1$ |
| |
| boolean useBuildDir = MavenWtpPlugin.getDefault().getMavenWtpPreferencesManager().getPreferences(project).isWebMavenArchiverUsesBuildDirectory(); |
| boolean useWebresourcefiltering = config.getWebResources() != null |
| && config.getWebResources().length > 0 |
| || config.isFilteringDeploymentDescriptorsEnabled(); |
| |
| if (useBuildDir || useWebresourcefiltering) { |
| |
| if (!useBuildDir && useWebresourcefiltering) { |
| mavenMarkerManager.addMarker(project, MavenWtpConstants.WTP_MARKER_CONFIGURATION_ERROR_ID, |
| Messages.markers_mavenarchiver_output_settings_ignored_warning, -1, IMarker.SEVERITY_WARNING); |
| } |
| sourcePaths.add(filteredFolder); |
| WTPProjectsUtil.insertLinkBefore(project, filteredFolder, warPath, new Path("/"), monitor); //$NON-NLS-1$ |
| } else { |
| component.getRootFolder().removeLink(filteredFolder,IVirtualResource.NONE, monitor); |
| } |
| |
| WTPProjectsUtil.deleteLinks(project, ROOT_PATH, sourcePaths, monitor); |
| |
| WTPProjectsUtil.setDefaultDeploymentDescriptorFolder(component.getRootFolder(), warPath, monitor); |
| |
| addComponentExclusionPatterns(component, config); |
| |
| } |
| |
| setModuleDependencies(project, mavenProject, monitor); |
| WTPProjectsUtil.removeWTPClasspathContainer(project); |
| } |
| |
| private IDataModel getWebModelConfig(String warSourceDirectory, String contextRoot) { |
| IDataModel webModelCfg = DataModelFactory.createDataModel(new WebFacetInstallDataModelProvider()); |
| webModelCfg.setProperty(IJ2EEModuleFacetInstallDataModelProperties.CONFIG_FOLDER, warSourceDirectory); |
| webModelCfg.setProperty(IWebFacetInstallDataModelProperties.CONTEXT_ROOT, contextRoot); |
| webModelCfg.setProperty(IJ2EEModuleFacetInstallDataModelProperties.GENERATE_DD, false); |
| webModelCfg.setBooleanProperty(IWebFacetInstallDataModelProperties.ADD_TO_EAR, false); |
| return webModelCfg; |
| } |
| |
| @Override |
| public void setModuleDependencies(IProject project, MavenProject mavenProject, IProgressMonitor monitor) |
| throws CoreException { |
| IVirtualComponent component = ComponentCore.createComponent(project); |
| //if the attempt to create dependencies happens before the project is actually created, abort. |
| //this will be created again when the project exists. |
| if(component == null){ |
| return; |
| } |
| //MECLIPSEWTP-41 Fix the missing moduleCoreNature |
| fixMissingModuleCoreNature(project, monitor); |
| |
| DebugUtilities.debug("==============Processing "+project.getName()+" dependencies ==============="); //$NON-NLS-1$ //$NON-NLS-2$ |
| WarPluginConfiguration config = new WarPluginConfiguration(mavenProject, project); |
| IPackagingConfiguration opts = new PackagingConfiguration(config.getPackagingIncludes(), config.getPackagingExcludes()); |
| FileNameMapping fileNameMapping = config.getFileNameMapping(); |
| |
| List<AbstractDependencyConfigurator> depConfigurators = ExtensionReader.readDependencyConfiguratorExtensions(projectManager, |
| MavenPlugin.getMavenRuntimeManager(), mavenMarkerManager); |
| |
| Set<IVirtualReference> references = new LinkedHashSet<IVirtualReference>(); |
| List<IMavenProjectFacade> exportedDependencies = getWorkspaceDependencies(project, mavenProject); |
| |
| Set<String> dups = new HashSet<String>(); |
| Set<String> names = new HashSet<String>(); |
| Map<IVirtualReference, Artifact> referenceMapping = new HashMap<IVirtualReference, Artifact>(exportedDependencies.size()); |
| for(IMavenProjectFacade dependency : exportedDependencies) { |
| String depPackaging = dependency.getPackaging(); |
| if ("pom".equals(depPackaging) //MNGECLIPSE-744 pom dependencies shouldn't be deployed //$NON-NLS-1$ |
| || "war".equals(depPackaging) //Overlays are dealt with the overlay configurator //$NON-NLS-1$ |
| || "zip".equals(depPackaging)) { //$NON-NLS-1$ |
| continue; |
| } |
| |
| try { |
| preConfigureDependencyProject(dependency, monitor); |
| |
| if (!ModuleCoreNature.isFlexibleProject(dependency.getProject())) { |
| //Projects unsupported by WTP (ex. adobe flex projects) should not be added as references |
| continue; |
| } |
| MavenProject depMavenProject = dependency.getMavenProject(monitor); |
| |
| IVirtualComponent depComponent = ComponentCore.createComponent(dependency.getProject()); |
| |
| ArtifactKey artifactKey = ArtifactHelper.toArtifactKey(depMavenProject.getArtifact()); |
| //Get artifact using the proper classifier |
| Artifact artifact = ArtifactHelper.getArtifact(mavenProject.getArtifacts(), artifactKey); |
| if (artifact == null) { |
| //could not map key to artifact |
| artifact = depMavenProject.getArtifact(); |
| } |
| ArtifactHelper.fixArtifactHandler(artifact.getArtifactHandler()); |
| String deployedName = fileNameMapping.mapFileName(artifact); |
| |
| boolean isDeployed = !artifact.isOptional() && opts.isPackaged("WEB-INF/lib/"+deployedName); //$NON-NLS-1$ |
| |
| //an artifact in mavenProject.getArtifacts() doesn't have the "optional" value as depMavenProject.getArtifact(); |
| if (isDeployed) { |
| IVirtualReference reference = ComponentCore.createReference(component, depComponent); |
| IPath path = new Path("/WEB-INF/lib"); //$NON-NLS-1$ |
| reference.setArchiveName(deployedName); |
| reference.setRuntimePath(path); |
| references.add(reference); |
| |
| referenceMapping.put(reference, artifact); |
| if (!names.add(deployedName)) { |
| dups.add(deployedName); |
| } |
| } |
| } catch(RuntimeException ex) { |
| //Should probably be NPEs at this point |
| String dump = DebugUtilities.dumpProjectState("An error occured while configuring a dependency of "+project.getName()+DebugUtilities.SEP, dependency.getProject()); //$NON-NLS-1$ |
| LOG.error(dump); |
| throw ex; |
| } |
| } |
| |
| for (IVirtualReference reference : references) { |
| if (dups.contains(reference.getArchiveName())) { |
| Artifact a = referenceMapping.get(reference); |
| String newName = a.getGroupId() + "-" + reference.getArchiveName(); //$NON-NLS-1$ |
| reference.setArchiveName(newName); |
| } |
| } |
| |
| IVirtualReference[] oldRefs = WTPProjectsUtil.extractHardReferences(component, false); |
| |
| IVirtualReference[] newRefs = references.toArray(new IVirtualReference[references.size()]); |
| |
| if (WTPProjectsUtil.hasChanged(oldRefs, newRefs)){ |
| //Only write in the .component file if necessary |
| IVirtualReference[] overlayRefs = WTPProjectsUtil.extractHardReferences(component, true); |
| IVirtualReference[] allRefs = new IVirtualReference[overlayRefs.length + newRefs.length]; |
| System.arraycopy(newRefs, 0, allRefs, 0, newRefs.length); |
| System.arraycopy(overlayRefs, 0, allRefs, newRefs.length, overlayRefs.length); |
| component.setReferences(allRefs); |
| } |
| |
| //TODO why a 2nd loop??? |
| for(IMavenProjectFacade dependency : exportedDependencies) { |
| MavenProject depMavenProject = dependency.getMavenProject(monitor); |
| Iterator<AbstractDependencyConfigurator> configurators = depConfigurators.iterator(); |
| while (configurators.hasNext()) { |
| try { |
| configurators.next().configureDependency(mavenProject, project, depMavenProject, dependency.getProject(), monitor); |
| } catch(MarkedException ex) { |
| //XXX handle this |
| } |
| } |
| } |
| |
| } |
| |
| /** |
| * Get the context root from a maven web project |
| * @param mavenProject |
| * @param warName |
| * @return the final name of the project if it exists, or the project's artifactId. |
| */ |
| protected String getContextRoot(MavenProject mavenProject, String warName) { |
| String contextRoot; |
| //MECLIPSEWTP-43 : Override with maven property |
| String property = mavenProject.getProperties().getProperty(M2ECLIPSE_WTP_CONTEXT_ROOT); |
| if (StringUtils.isBlank(property)) { |
| String finalName = warName; |
| if (StringUtils.isBlank(finalName) |
| || finalName.equals(mavenProject.getArtifactId() + "-" + mavenProject.getVersion())) { //$NON-NLS-1$ |
| contextRoot = mavenProject.getArtifactId(); |
| } else { |
| contextRoot = finalName; |
| } |
| } else { |
| contextRoot = property; |
| } |
| |
| return contextRoot.trim().replace(" ", "_"); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| |
| @Override |
| public void configureClasspath(IProject project, MavenProject mavenProject, IClasspathDescriptor classpath, |
| IProgressMonitor monitor) throws CoreException { |
| |
| //Improve skinny war support by generating the manifest classpath |
| //similar to mvn eclipse:eclipse |
| //http://maven.apache.org/plugins/maven-war-plugin/examples/skinny-wars.html |
| WarPluginConfiguration config = new WarPluginConfiguration(mavenProject, project); |
| IPackagingConfiguration opts = new PackagingConfiguration(config.getPackagingIncludes(), config.getPackagingExcludes()); |
| /* |
| * Need to take care of three separate cases |
| * |
| * 1. remove any project dependencies (they are represented as J2EE module dependencies) |
| * 2. add non-dependency attribute for entries originated by artifacts with |
| * runtime, system, test scopes or optional dependencies (not sure about the last one) |
| * 3. make sure all dependency JAR files have unique file names, i.e. artifactId/version collisions |
| */ |
| |
| Set<String> dups = new LinkedHashSet<String>(); |
| Set<String> names = new HashSet<String>(); |
| |
| IVirtualComponent component = ComponentCore.createComponent(project); |
| if (component != null) { |
| for (IVirtualReference vr : component.getReferences()) { |
| if (!vr.getReferencedComponent().isBinary()) { |
| names.add(vr.getArchiveName()); |
| } |
| } |
| } |
| |
| FileNameMapping fileNameMapping = config.getFileNameMapping(); |
| String targetDir = mavenProject.getBuild().getDirectory(); |
| |
| // first pass removes projects, adds non-dependency attribute and collects colliding filenames |
| Iterator<IClasspathEntryDescriptor> iter = classpath.getEntryDescriptors().iterator(); |
| while (iter.hasNext()) { |
| IClasspathEntryDescriptor descriptor = iter.next(); |
| String scope = descriptor.getScope(); |
| Artifact artifact = ArtifactHelper.getArtifact(mavenProject.getArtifacts(), descriptor.getArtifactKey()); |
| |
| ArtifactHelper.fixArtifactHandler(artifact.getArtifactHandler()); |
| |
| String deployedName = fileNameMapping.mapFileName(artifact); |
| |
| boolean isDeployed = (Artifact.SCOPE_COMPILE.equals(scope) || Artifact.SCOPE_RUNTIME.equals(scope)) |
| && !descriptor.isOptionalDependency() |
| && opts.isPackaged("WEB-INF/lib/"+deployedName) //$NON-NLS-1$ |
| && !isWorkspaceProject(artifact); |
| |
| // add non-dependency attribute if this classpathentry is not meant to be deployed |
| // or if it's a workspace project (projects already have a reference created in configure()) |
| if(!isDeployed) { |
| descriptor.setClasspathAttribute(NONDEPENDENCY_ATTRIBUTE.getName(), NONDEPENDENCY_ATTRIBUTE.getValue()); |
| //Bug #382078 : no need to rename non-deployed artifacts. |
| continue; |
| } |
| |
| String fileName = descriptor.getPath().lastSegment(); |
| if (!deployedName.equals(fileName)) { |
| if (CLASSPATH_ARCHIVENAME_ATTRIBUTE == null) { |
| //If custom fileName is used, check if the underlying file already exists |
| // if it doesn't, copy and rename the artifact under the build dir |
| IPath newPath = descriptor.getPath().removeLastSegments(1).append(deployedName); |
| if (!new File(newPath.toOSString()).exists()) { |
| newPath = renameArtifact(targetDir, descriptor.getPath(), deployedName ); |
| } |
| if (newPath != null) { |
| descriptor.setPath(newPath); |
| } |
| } else { |
| descriptor.getClasspathAttributes().put(CLASSPATH_ARCHIVENAME_ATTRIBUTE, deployedName); |
| } |
| } |
| |
| if (!names.add(deployedName)) { |
| dups.add(deployedName); |
| } |
| } |
| |
| // second pass disambiguates colliding entry file names |
| iter = classpath.getEntryDescriptors().iterator(); |
| while (iter.hasNext()) { |
| IClasspathEntryDescriptor descriptor = iter.next(); |
| if (descriptor.getClasspathAttributes().containsKey(NONDEPENDENCY_ATTRIBUTE.getName())) { |
| //No need to rename if not deployed |
| continue; |
| } |
| if (dups.contains(descriptor.getPath().lastSegment())) { |
| String newName = descriptor.getGroupId() + "-" + descriptor.getPath().lastSegment(); //$NON-NLS-1$ |
| if (CLASSPATH_ARCHIVENAME_ATTRIBUTE == null) { |
| IPath newPath = renameArtifact(targetDir, descriptor.getPath(), newName ); |
| if (newPath != null) { |
| descriptor.setPath(newPath); |
| } |
| } else { |
| descriptor.getClasspathAttributes().put(CLASSPATH_ARCHIVENAME_ATTRIBUTE, newName); |
| } |
| } |
| } |
| } |
| |
| |
| @Deprecated |
| private IPath renameArtifact(String targetDir, IPath source, String newName) { |
| File src = new File(source.toOSString()); |
| File dst = new File(targetDir, newName); |
| try { |
| if (src.isFile() && src.canRead()) { |
| if (isDifferent(src, dst)) { // uses lastModified |
| FileUtils.copyFile(src, dst); |
| dst.setLastModified(src.lastModified()); |
| } |
| return Path.fromOSString(dst.getCanonicalPath()); |
| } |
| } catch(IOException ex) { |
| LOG.error(Messages.WebProjectConfiguratorDelegate_File_Copy_Failed, ex); |
| } |
| return null; |
| } |
| |
| private boolean isWorkspaceProject(Artifact artifact) { |
| IMavenProjectFacade facade = projectManager.getMavenProject(artifact.getGroupId(), |
| artifact.getArtifactId(), |
| artifact.getVersion()); |
| |
| return facade != null |
| && facade.getFullPath(artifact.getFile()) != null; |
| |
| } |
| |
| @Deprecated |
| private static boolean isDifferent(File src, File dst) { |
| if (!dst.exists()) { |
| return true; |
| } |
| |
| return src.length() != dst.length() |
| || src.lastModified() != dst.lastModified(); |
| } |
| |
| } |