/** * Returns the transitive closure of buildpath entries for the given project entry. * * @param projectEntry project buildpath entry * @param expandedPath a list of entries already expanded, should be empty to begin, and contains * the result * @param expanding a list of projects that have been or are currently being expanded (to detect * cycles) * @exception CoreException if unable to expand the buildpath */ private void expandProject(IBuildpathEntry projectEntry, List expandedPath, List expanding) throws CoreException { expanding.add(projectEntry); // 1. Get the raw buildpath // 2. Replace source folder entries with a project entry IPath projectPath = projectEntry.getPath(); IResource res = ResourcesPlugin.getWorkspace().getRoot().findMember(projectPath.lastSegment()); if (res == null) { // add project entry and return expandedPath.add(projectEntry); return; } IScriptProject project = (IScriptProject) DLTKCore.create(res); if (project == null || !project.getProject().isOpen() || !project.exists()) { // add project entry and return expandedPath.add(projectEntry); return; } IBuildpathEntry[] buildPath = project.getRawBuildpath(); List unexpandedPath = new ArrayList(buildPath.length); // boolean projectAdded = false; for (int i = 0; i < buildPath.length; i++) { IBuildpathEntry buildpathEntry = buildPath[i]; if (buildpathEntry.getEntryKind() == IBuildpathEntry.BPE_SOURCE) { // sources // are // always // added unexpandedPath.add(buildpathEntry); } else { // add exported entires, as configured if (buildpathEntry.isExported()) { unexpandedPath.add(buildpathEntry); } else if (!isExportedEntriesOnly() || project.equals(getScriptProject())) { // add non exported entries from root project or if we are // including all entries unexpandedPath.add(buildpathEntry); } } } // 3. expand each project entry (except for the root project) // 4. replace each container entry with a runtime entry associated with // the project Iterator iter = unexpandedPath.iterator(); while (iter.hasNext()) { IBuildpathEntry entry = (IBuildpathEntry) iter.next(); if (entry == projectEntry) { expandedPath.add(entry); } else { switch (entry.getEntryKind()) { case IBuildpathEntry.BPE_PROJECT: if (!expanding.contains(entry)) { expandProject(entry, expandedPath, expanding); } break; case IBuildpathEntry.BPE_CONTAINER: IBuildpathContainer container = DLTKCore.getBuildpathContainer(entry.getPath(), project); int property = -1; if (container != null) { switch (container.getKind()) { case IBuildpathContainer.K_APPLICATION: property = IRuntimeBuildpathEntry.USER_ENTRY; break; case IBuildpathContainer.K_DEFAULT_SYSTEM: property = IRuntimeBuildpathEntry.STANDARD_ENTRY; break; case IBuildpathContainer.K_SYSTEM: property = IRuntimeBuildpathEntry.BOOTSTRAP_ENTRY; break; } IRuntimeBuildpathEntry r = ScriptRuntime.newRuntimeContainerBuildpathEntry( entry.getPath(), property, project); // check for duplicate/redundant entries boolean duplicate = false; BuildpathContainerInitializer initializer = DLTKCore.getBuildpathContainerInitializer(r.getPath().segment(0)); for (int i = 0; i < expandedPath.size(); i++) { Object o = expandedPath.get(i); if (o instanceof IRuntimeBuildpathEntry) { IRuntimeBuildpathEntry re = (IRuntimeBuildpathEntry) o; if (re.getType() == IRuntimeBuildpathEntry.CONTAINER) { BuildpathContainerInitializer initializer2 = DLTKCore.getBuildpathContainerInitializer(re.getPath().segment(0)); Object id1 = null; Object id2 = null; if (initializer == null) { id1 = r.getPath().segment(0); } else { id1 = initializer.getComparisonID(r.getPath(), project); } if (initializer2 == null) { id2 = re.getPath().segment(0); } else { IScriptProject context = re.getScriptProject(); if (context == null) { context = project; } id2 = initializer2.getComparisonID(re.getPath(), context); } if (id1 == null) { duplicate = id2 == null; } else { duplicate = id1.equals(id2); } if (duplicate) { break; } } } } if (!duplicate) { expandedPath.add(r); } } break; default: if (!expandedPath.contains(entry)) { expandedPath.add(entry); } break; } } } return; }