/******************************************************************************* * Copyright (c) 2008-2010 Sonatype, Inc. * 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 * * Contributors: * Sonatype, Inc. - initial API and implementation *******************************************************************************/ package org.eclipse.m2e.core.internal.project.registry; import java.io.File; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.TreeMap; import org.eclipse.aether.artifact.Artifact; import org.eclipse.aether.repository.WorkspaceReader; import org.eclipse.aether.repository.WorkspaceRepository; import org.eclipse.aether.util.version.GenericVersionScheme; import org.eclipse.aether.version.InvalidVersionSpecificationException; import org.eclipse.aether.version.Version; import org.eclipse.aether.version.VersionConstraint; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IPath; import org.apache.maven.repository.LocalArtifactRepository; import org.eclipse.m2e.core.embedder.ArtifactKey; public final class EclipseWorkspaceArtifactRepository extends LocalArtifactRepository implements WorkspaceReader { private static final GenericVersionScheme versionScheme = new GenericVersionScheme(); private final transient ProjectRegistryManager.Context context; private static final ThreadLocal<Boolean> disabled = new ThreadLocal<Boolean>(); private WorkspaceRepository workspaceRepository; public EclipseWorkspaceArtifactRepository(ProjectRegistryManager.Context context) { this.context = context; this.workspaceRepository = new WorkspaceRepository("ide", getClass()); //$NON-NLS-1$ } protected File resolveAsEclipseProject(String groupId, String artifactId, String baseVersion, String classifier, String extension) { if(isDisabled()) { return null; } if(context == null) { // XXX this is actually a bug return null; } // check in the workspace, note that workspace artifacts never have classifiers IFile pom = getWorkspaceArtifact(groupId, artifactId, baseVersion); if(pom == null || !pom.isAccessible()) { return null; } if(context.pom != null && pom.equals(context.pom)) { return null; } // if(!"pom".equals(artifact.getType())) { // return false; // } if(context.resolverConfiguration.shouldResolveWorkspaceProjects()) { IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); IPath file = pom.getLocation(); if(!"pom".equals(extension)) { //$NON-NLS-1$ MavenProjectFacade facade = context.state.getProjectFacade(pom); if(facade.getOutputLocation() != null) { IFolder outputLocation = root.getFolder(facade.getOutputLocation()); if(outputLocation.exists()) { file = outputLocation.getLocation(); } } } return file.toFile(); } return null; } private IFile getWorkspaceArtifact(String groupId, String artifactId, String version) { Map<ArtifactKey, Collection<IFile>> workspaceArtifacts = context.state.getWorkspaceArtifacts(groupId, artifactId); if(workspaceArtifacts.isEmpty()) { return null; } VersionConstraint constraint; try { constraint = versionScheme.parseVersionConstraint(version); } catch(InvalidVersionSpecificationException e) { return null; // broken version range spec does not match anything } TreeMap<Version, ArtifactKey> matchingArtifacts = new TreeMap<>(); // in vast majority of cases there will be single workspace artifact with matching groupId and artifactId for(ArtifactKey workspaceArtifact : workspaceArtifacts.keySet()) { try { Version workspaceVersion = versionScheme.parseVersion(workspaceArtifact.getVersion()); if(constraint.containsVersion(workspaceVersion)) { matchingArtifacts.put(workspaceVersion, workspaceArtifact); } } catch(InvalidVersionSpecificationException e) { // this can't happen with GenericVersionScheme } } if(matchingArtifacts.isEmpty()) { return null; } ArtifactKey matchingArtifact = matchingArtifacts.values().iterator().next(); return workspaceArtifacts.get(matchingArtifact).iterator().next(); } public File findArtifact(Artifact artifact) { return resolveAsEclipseProject(artifact.getGroupId(), artifact.getArtifactId(), artifact.getBaseVersion(), artifact.getClassifier(), artifact.getExtension()); } public org.apache.maven.artifact.Artifact find(org.apache.maven.artifact.Artifact artifact) { File file = resolveAsEclipseProject(artifact.getGroupId(), artifact.getArtifactId(), artifact.getBaseVersion(), artifact.getClassifier(), artifact.getType()); if(file != null) { artifact.setFile(file); artifact.setResolved(true); } return artifact; } public boolean hasLocalMetadata() { return false; // XXX } public static void setDisabled(boolean disable) { disabled.set(disable ? Boolean.TRUE : null); } public static boolean isDisabled() { return Boolean.TRUE.equals(disabled.get()); } public int hashCode() { return 0; // no state } public boolean equals(Object obj) { return obj instanceof EclipseWorkspaceArtifactRepository; } public List<String> findVersions(Artifact artifact) { return findVersions(artifact.getGroupId(), artifact.getArtifactId()); } @Override public List<String> findVersions(org.apache.maven.artifact.Artifact artifact) { return findVersions(artifact.getGroupId(), artifact.getArtifactId()); } private List<String> findVersions(String groupId, String artifactId) { ArrayList<String> versions = new ArrayList<String>(); if(isDisabled()) { return versions; } if(context == null) { // XXX this is actually a bug return versions; } for(MavenProjectFacade facade : context.state.getProjects()) { ArtifactKey artifactKey = facade.getArtifactKey(); if(groupId.equals(artifactKey.getGroupId()) && artifactId.equals(artifactKey.getArtifactId())) { versions.add(artifactKey.getVersion()); } } return versions; } public WorkspaceRepository getRepository() { return workspaceRepository; } }