package org.bundlemaker.core.mvn.content; import java.io.File; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.bundlemaker.core.IBundleMakerProject; import org.bundlemaker.core.analysis.IDependency; import org.bundlemaker.core.common.prefs.BundleMakerPreferences; import org.bundlemaker.core.common.prefs.IBundleMakerPreferences; import org.bundlemaker.core.mvn.MvnCoreActivator; import org.bundlemaker.core.mvn.internal.MvnArtifactConverter; import org.bundlemaker.core.mvn.internal.config.DispatchingRepositoryAdapter; import org.bundlemaker.core.mvn.internal.config.IAetherRepositoryAdapter; import org.bundlemaker.core.project.AnalyzeMode; import org.bundlemaker.core.project.IProjectContentEntry; import org.bundlemaker.core.project.IProjectContentProvider; import org.bundlemaker.core.project.IProjectDescription; import org.bundlemaker.core.project.IProjectDescriptionAwareBundleMakerProject; import org.bundlemaker.core.project.spi.AbstractProjectContentProvider; import org.bundlemaker.core.resource.IModuleIdentifier; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.sonatype.aether.RepositorySystemSession; import org.sonatype.aether.artifact.Artifact; import org.sonatype.aether.collection.CollectRequest; import org.sonatype.aether.collection.CollectResult; import org.sonatype.aether.collection.DependencyCollectionException; import org.sonatype.aether.graph.Dependency; import org.sonatype.aether.graph.DependencyNode; import org.sonatype.aether.graph.DependencyVisitor; import org.sonatype.aether.repository.RemoteRepository; import org.sonatype.aether.repository.RepositoryPolicy; import org.sonatype.aether.resolution.ArtifactRequest; import org.sonatype.aether.resolution.ArtifactResolutionException; import org.sonatype.aether.resolution.ArtifactResult; import org.sonatype.aether.util.artifact.DefaultArtifact; import com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; /** * <p> * </p> * * @author Gerd Wütherich (gerd@gerd-wuetherich.de) */ public class MvnContentProvider extends AbstractProjectContentProvider implements IProjectContentProvider { /** - */ @Expose @SerializedName("mvnArtifacts") private List<MvnArtifactType> _mvnArtifactTypes; /** the mvn scope */ private static final String SCOPE_COMPILE = "compile"; /** - */ private IAetherRepositoryAdapter _repositoryAdapter; /** - */ private RepositorySystemSession _currentSystemSession; /** * <p> * Creates a new instance of type {@link MvnContentProvider}. * </p> */ public MvnContentProvider() { // initialize _mvnArtifactTypes = new LinkedList<MvnArtifactType>(); } /** * {@inheritDoc} */ @Override protected void prepare() { // IBundleMakerPreferences preferences = getBundleMakerPreferences(); // _repositoryAdapter = new DispatchingRepositoryAdapter(preferences); } protected IBundleMakerPreferences getBundleMakerPreferences() { return BundleMakerPreferences.getBundleMakerPreferences(MvnCoreActivator.PLUGIN_ID, getBundleMakerProject() .getProject()); } /** * <p> * </p> * * @param groupId * @param artifactId * @param version */ public void addMvnArtifact(String groupId, String artifactId, String version) { // asserts Assert.isNotNull(groupId); Assert.isNotNull(artifactId); Assert.isNotNull(version); // create the new MvnArtifactType MvnArtifactType mvnArtifactType = new MvnArtifactType(); mvnArtifactType.setGroupId(groupId); mvnArtifactType.setArtifactId(artifactId); mvnArtifactType.setVersion(version); // add it to the list of artifacts _mvnArtifactTypes.add(mvnArtifactType); } /** * <p> * </p> * * @param mvnArtifactType */ public void addMvnArtifact(MvnArtifactType mvnArtifactType) { // asserts Assert.isNotNull(mvnArtifactType); // add it to the list of artifacts _mvnArtifactTypes.add(mvnArtifactType); } /** * {@inheritDoc} */ @Override public void onInitializeProjectContent(IProgressMonitor progressMonitor) throws CoreException { // only reload content if the fileBasedContents are not initialized yet reloadContent(true, false, getBundleMakerProject()); } /** * <p> * </p> * * @throws CoreException */ public void reloadContent(final boolean useRemoteRepository, final boolean reloadFromRemote, IProjectDescriptionAwareBundleMakerProject bundleMakerProject) throws CoreException { // create a new session _currentSystemSession = _repositoryAdapter.newSession(); // create the result list clearFileBasedContents(); // iterate over all the specified mvn artifacts for (final MvnArtifactType artifactIdentifier : _mvnArtifactTypes) { // create the aether artifact final Artifact artifact = new DefaultArtifact(artifactIdentifier.getGroupId(), artifactIdentifier.getArtifactId(), "jar", artifactIdentifier.getVersion()); // create the collect request CollectRequest collectRequest = new CollectRequest(); collectRequest.setRoot(new Dependency(artifact, SCOPE_COMPILE)); // add the remote repository is necessary if (useRemoteRepository) { for (RemoteRepository remoteRepository : _repositoryAdapter.getRemoteRepositories()) { // RepositoryPolicy policy = reloadFromRemote ? new RepositoryPolicy(true, RepositoryPolicy.UPDATE_POLICY_ALWAYS, RepositoryPolicy.CHECKSUM_POLICY_IGNORE) : new RepositoryPolicy( true, RepositoryPolicy.UPDATE_POLICY_DAILY, RepositoryPolicy.CHECKSUM_POLICY_IGNORE); // remoteRepository.setPolicy(true, policy); // collectRequest.addRepository(remoteRepository); } } // try { // collect the result CollectResult collectResult = _repositoryAdapter.getRepositorySystem().collectDependencies( _currentSystemSession, collectRequest); final List<Artifact> alreadyHandled = new LinkedList<Artifact>(); final Map<DependencyNode, CoreException> exceptions = new HashMap<DependencyNode, CoreException>(); // visit all the dependencies collectResult.getRoot().accept(new DependencyVisitorAdapter() { @Override public boolean visitEnter(DependencyNode node) { try { System.out.println("NODE: " + node); for (DependencyNode dependencyNode : node.getChildren()) { System.out.println(" - " + dependencyNode + " : " + dependencyNode.getDependency()); } return handleDependencyNode(node, useRemoteRepository, alreadyHandled, artifact.equals(node.getDependency().getArtifact())); } catch (CoreException e) { exceptions.put(node, e); return false; } } }); // if (exceptions.size() > 0) { Entry<DependencyNode, CoreException> entry = exceptions.entrySet().toArray(new Entry[0])[0]; if (artifact.equals(entry.getKey().getDependency().getArtifact())) { throw new CoreException(new Status(Status.ERROR, MvnCoreActivator.PLUGIN_ID, entry.getValue().getMessage(), entry.getValue())); } // else { // TODO System.out.println("TODO: Handle missing artifacts:"); for (DependencyNode node : exceptions.keySet()) { System.out.println(node.toString()); } } } } catch (DependencyCollectionException e) { e.printStackTrace(); throw new CoreException(new Status(Status.ERROR, MvnCoreActivator.PLUGIN_ID, e.getMessage(), e)); } // TODO: Move-up // finally: fire project description recomputed event fireProjectDescriptionRecomputedEvent(); } } /** * <p> * Clears the artifact list * </p> */ public void clearArtifactList() { _mvnArtifactTypes.clear(); } /** * <p> * Returns the current maven artifacts. * </p> * * @return the current maven artifacts. */ public List<MvnArtifactType> getMvnArtifacts() { return _mvnArtifactTypes; } /** * <p> * </p> * * @param bundleMakerProject * @param artifactType * @param node * @return * @throws CoreException */ private boolean handleDependencyNode(DependencyNode node, boolean useRemoteRepository, List<Artifact> alreadyHandled, boolean downloadSources) throws CoreException { // if (alreadyHandled.contains(node.getDependency().getArtifact())) { return false; } // alreadyHandled.add(node.getDependency().getArtifact()); // get the referenced artifact Artifact mvnArtifact = node.getDependency().getArtifact(); // ArtifactRequest artifactRequest = new ArtifactRequest(); artifactRequest.setArtifact(node.getDependency().getArtifact()); // if (useRemoteRepository) { for (RemoteRepository remoteRepository : _repositoryAdapter.getRemoteRepositories()) { artifactRequest.addRepository(remoteRepository); } } try { // ArtifactResult artifactResult = _repositoryAdapter.getRepositorySystem().resolveArtifact(_currentSystemSession, artifactRequest); File sourceFile = null; File binaryFile = null; // Artifact currentMavenArtifact = artifactResult.getArtifact(); // TODO if (downloadSources) { Artifact sourceArtifact = new DefaultArtifact(currentMavenArtifact.getGroupId(), currentMavenArtifact.getArtifactId(), "sources", currentMavenArtifact.getExtension(), currentMavenArtifact.getVersion()); artifactRequest = new ArtifactRequest(); artifactRequest.setArtifact(sourceArtifact); for (RemoteRepository remoteRepository : _repositoryAdapter.getRemoteRepositories()) { artifactRequest.addRepository(remoteRepository); } try { artifactResult = _repositoryAdapter.getRepositorySystem().resolveArtifact(_currentSystemSession, artifactRequest); sourceFile = artifactResult.getArtifact().getFile(); } catch (ArtifactResolutionException e) { e.printStackTrace(); System.out.println(e.getMessage()); } } // binaryFile = currentMavenArtifact.getFile(); // TODO!!! // IModuleIdentifier moduleIdentifier = MvnArtifactConverter.toModuleIdentifier(mvnArtifact.getGroupId(), mvnArtifact.getArtifactId(), mvnArtifact.getVersion()); // AnalyzeMode analyzeMode = AnalyzeMode.DO_NOT_ANALYZE; if (downloadSources) { if (sourceFile != null) { analyzeMode = AnalyzeMode.BINARIES_AND_SOURCES; } else { analyzeMode = AnalyzeMode.BINARIES_ONLY; } } // IProjectContentEntry fileBasedContent = createFileBasedContent(moduleIdentifier.getName(), moduleIdentifier.getVersion(), new File[] { binaryFile }, sourceFile == null ? new File[] {} : new File[] { sourceFile }, analyzeMode); // set user attributes fileBasedContent.getUserAttributes().put(MvnArtifactConverter.ORIGINAL_MVN_GROUP_ID, mvnArtifact.getGroupId()); fileBasedContent.getUserAttributes().put(MvnArtifactConverter.ORIGINAL_MVN_ARTIFACT_ID, mvnArtifact.getArtifactId()); fileBasedContent.getUserAttributes().put(MvnArtifactConverter.ORIGINAL_MODULE_NAME, moduleIdentifier.getName()); } catch (Exception e) { throw new CoreException(new Status(IStatus.ERROR, MvnCoreActivator.PLUGIN_ID, String.format( "Exception while trying to resolve '%s'.", node.toString()), e)); } // return true; } /** * <p> * Internal helper class. * </p> * * @author Gerd Wütherich (gerd@gerd-wuetherich.de) * */ private static class DependencyVisitorAdapter implements DependencyVisitor { /** * {@inheritDoc} */ @Override public boolean visitEnter(DependencyNode node) { return true; } /** * {@inheritDoc} */ @Override public boolean visitLeave(DependencyNode node) { return true; } } }