/******************************************************************************* * Copyright (c) 2004, 2006 * Thomas Hallgren, Kenneth Olwing, Mitch Sonies * Pontus Rydin, Nils Unden, Peer Torngren * The code, documentation and other materials contained herein have been * licensed under the Eclipse Public License - v 1.0 by the individual * copyright holders listed above, as Initial Contributors under such license. * The text of such license is available at www.eclipse.org. *******************************************************************************/ package org.eclipse.buckminster.jdt.internal; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import org.eclipse.buckminster.core.cspec.model.CSpec; import org.eclipse.buckminster.core.cspec.model.ComponentIdentifier; import org.eclipse.buckminster.core.cspec.model.ComponentRequest; import org.eclipse.buckminster.core.metadata.ModelCache; import org.eclipse.buckminster.core.metadata.WorkspaceInfo; import org.eclipse.buckminster.core.metadata.model.IModelCache; import org.eclipse.buckminster.jdt.JdtPlugin; import org.eclipse.buckminster.jdt.Messages; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.jdt.core.IClasspathContainer; import org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jdt.core.JavaCore; public class BMClasspathContainer implements IClasspathContainer { public static final IPath PATH = new Path(JdtPlugin.CLASSPATH_CONTAINER_ID); private final IProject project; private final IClasspathEntry[] entries; public BMClasspathContainer(IProject project, String topTarget) throws CoreException { this.project = project; ArrayList<IClasspathEntry> cpes = new ArrayList<IClasspathEntry>(); CSpec cspec = WorkspaceInfo.getCSpec(project); if (cspec != null) this.addNodeToClassPath(cspec, cpes, new ModelCache(), new HashSet<ComponentIdentifier>(), 0); this.entries = cpes.toArray(new IClasspathEntry[cpes.size()]); } /** * Checks wether this container has the exact same entries as cp. The * entries are compared for equality but not resolved. The order of the * entries is significant. * * @param cp * The container to compare with. * @return true if the two containers have the exact same classpath. */ @Override public boolean equals(Object o) { if (o == this) return true; if (!(o instanceof BMClasspathContainer)) return false; BMClasspathContainer that = (BMClasspathContainer) o; if (!Arrays.equals(this.entries, that.entries)) return false; return true; } @Override public final IClasspathEntry[] getClasspathEntries() { return entries; } @Override public String getDescription() { return Messages.BMClasspathContainer_description; } @Override public int getKind() { return K_APPLICATION; } @Override public IPath getPath() { return PATH; } @Override public int hashCode() { return Arrays.hashCode(entries); } private void addNodeToClassPath(CSpec cspec, ArrayList<IClasspathEntry> cpes, IModelCache cache, HashSet<ComponentIdentifier> seenIDs, int depth) throws CoreException { // Depth == 0 is the component itself, depth == 1 is the component // scanning its // own dependencies. // // TODO: We must currently assume that all dependencies are re-exported. // Rectify // this when the actions enters the scene. // // if(cref != null && depth > 1 && !cref.isExported()) // return; ComponentIdentifier cid = cspec.getComponentIdentifier(); if (seenIDs.contains(cid)) return; seenIDs.add(cid); for (ComponentRequest refToChild : cspec.getDependencies()) { CSpec childSpec = cache.findCSpec(cspec, refToChild); this.addNodeToClassPath(childSpec, cpes, cache, seenIDs, depth + 1); } IPath componentHome = cspec.getComponentLocation(); IProject proj = WorkspaceInfo.getProject(cid); if (proj != null) { if (proj.getName().equals(project.getName())) // // Skip the project itself. // return; if (proj.isOpen() && proj.hasNature(JavaCore.NATURE_ID)) { // If we have a project entry, add that and nothing else. // IClasspathEntry cpe = JavaCore.newProjectEntry(proj.getFullPath()); if (!cpes.contains(cpe)) cpes.add(cpe); } return; } if (!componentHome.toFile().isFile()) return; if (componentHome.lastSegment().endsWith(".jar")) //$NON-NLS-1$ { IClasspathEntry cpe = JavaCore.newLibraryEntry(componentHome, null, null); if (!cpes.contains(cpe)) cpes.add(cpe); } } }