/**
   * Processes a {@link IClasspathEntry} and add it to one of the list if applicable.
   *
   * @param entry the entry to process
   * @param javaProject the {@link IJavaProject} from which this entry came.
   * @param wsRoot the {@link IWorkspaceRoot}
   * @param projects the project list to add to
   * @param jarFiles the jar list to add to
   * @param includeJarFiles whether to include jar files or just projects. This is useful when
   *     calling on an Android project (value should be <code>false</code>)
   */
  private static void processCPE(
      IClasspathEntry entry,
      IJavaProject javaProject,
      IWorkspaceRoot wsRoot,
      Set<IProject> projects,
      Set<File> jarFiles,
      boolean includeJarFiles) {

    // if this is a classpath variable reference, we resolve it.
    if (entry.getEntryKind() == IClasspathEntry.CPE_VARIABLE) {
      entry = JavaCore.getResolvedClasspathEntry(entry);
    }

    if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT) {
      IProject refProject = wsRoot.getProject(entry.getPath().lastSegment());
      try {
        // ignore if it's an Android project, or if it's not a Java Project
        if (refProject.hasNature(JavaCore.NATURE_ID)
            && refProject.hasNature(AndmoreAndroidConstants.NATURE_DEFAULT) == false) {
          // add this project to the list
          projects.add(refProject);

          // also get the dependency from this project.
          getDependencyListFromClasspath(refProject, projects, jarFiles, true /*includeJarFiles*/);
        }
      } catch (CoreException exception) {
        // can't query the project nature? ignore
      }
    } else if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
      if (includeJarFiles) {
        handleClasspathLibrary(entry, wsRoot, jarFiles);
      }
    } else if (entry.getEntryKind() == IClasspathEntry.CPE_CONTAINER) {
      // get the container and its content
      try {
        IClasspathContainer container =
            JavaCore.getClasspathContainer(entry.getPath(), javaProject);
        // ignore the system and default_system types as they represent
        // libraries that are part of the runtime.
        if (container != null && container.getKind() == IClasspathContainer.K_APPLICATION) {
          IClasspathEntry[] entries = container.getClasspathEntries();
          for (IClasspathEntry cpe : entries) {
            processCPE(cpe, javaProject, wsRoot, projects, jarFiles, includeJarFiles);
          }
        }
      } catch (JavaModelException jme) {
        // can't resolve the container? ignore it.
        AndmoreAndroidPlugin.log(jme, "Failed to resolve ClasspathContainer: %s", entry.getPath());
      }
    }
  }
示例#2
0
  /**
   * Add a path to current java search scope or all project fragment roots if null. Use project
   * resolved classpath to retrieve and store access restriction on each classpath entry. Recurse if
   * dependent projects are found.
   *
   * @param javaProject Project used to get resolved classpath entries
   * @param pathToAdd Path to add in case of single element or null if user want to add all project
   *     package fragment roots
   * @param includeMask Mask to apply on classpath entries
   * @param projectsToBeAdded Set to avoid infinite recursion
   * @param visitedProjects Set to avoid adding twice the same project
   * @param referringEntry Project raw entry in referring project classpath
   * @throws JavaModelException May happen while getting java model info
   */
  void add(
      JavaProject javaProject,
      IPath pathToAdd,
      int includeMask,
      HashSet projectsToBeAdded,
      HashSet visitedProjects,
      IClasspathEntry referringEntry)
      throws JavaModelException {
    IProject project = javaProject.getProject();
    if (!project.isAccessible() || !visitedProjects.add(project)) return;

    IPath projectPath = project.getFullPath();
    String projectPathString = projectPath.toString();
    addEnclosingProjectOrJar(projectPath);

    IClasspathEntry[] entries = javaProject.getResolvedClasspath();
    IJavaModel model = javaProject.getJavaModel();
    JavaModelManager.PerProjectInfo perProjectInfo = javaProject.getPerProjectInfo();
    for (int i = 0, length = entries.length; i < length; i++) {
      IClasspathEntry entry = entries[i];
      AccessRuleSet access = null;
      ClasspathEntry cpEntry = (ClasspathEntry) entry;
      if (referringEntry != null) {
        // Add only exported entries.
        // Source folder are implicitly exported.
        if (!entry.isExported() && entry.getEntryKind() != IClasspathEntry.CPE_SOURCE) {
          continue;
        }
        cpEntry = cpEntry.combineWith((ClasspathEntry) referringEntry);
        //				cpEntry = ((ClasspathEntry)referringEntry).combineWith(cpEntry);
      }
      access = cpEntry.getAccessRuleSet();
      switch (entry.getEntryKind()) {
        case IClasspathEntry.CPE_LIBRARY:
          IClasspathEntry rawEntry = null;
          Map rootPathToRawEntries = perProjectInfo.rootPathToRawEntries;
          if (rootPathToRawEntries != null) {
            rawEntry = (IClasspathEntry) rootPathToRawEntries.get(entry.getPath());
          }
          if (rawEntry == null) break;
          rawKind:
          switch (rawEntry.getEntryKind()) {
            case IClasspathEntry.CPE_LIBRARY:
            case IClasspathEntry.CPE_VARIABLE:
              if ((includeMask & APPLICATION_LIBRARIES) != 0) {
                IPath path = entry.getPath();
                if (pathToAdd == null || pathToAdd.equals(path)) {
                  Object target = JavaModel.getTarget(path, false /*don't check existence*/);
                  if (target instanceof IFolder) // case of an external folder
                  path = ((IFolder) target).getFullPath();
                  String pathToString =
                      path.getDevice() == null ? path.toString() : path.toOSString();
                  add(
                      projectPath.toString(),
                      "",
                      pathToString,
                      false /*not a package*/,
                      access); //$NON-NLS-1$
                  addEnclosingProjectOrJar(entry.getPath());
                }
              }
              break;
            case IClasspathEntry.CPE_CONTAINER:
              IClasspathContainer container =
                  JavaCore.getClasspathContainer(rawEntry.getPath(), javaProject);
              if (container == null) break;
              switch (container.getKind()) {
                case IClasspathContainer.K_APPLICATION:
                  if ((includeMask & APPLICATION_LIBRARIES) == 0) break rawKind;
                  break;
                case IClasspathContainer.K_SYSTEM:
                case IClasspathContainer.K_DEFAULT_SYSTEM:
                  if ((includeMask & SYSTEM_LIBRARIES) == 0) break rawKind;
                  break;
                default:
                  break rawKind;
              }
              IPath path = entry.getPath();
              if (pathToAdd == null || pathToAdd.equals(path)) {
                Object target = JavaModel.getTarget(path, false /*don't check existence*/);
                if (target instanceof IFolder) // case of an external folder
                path = ((IFolder) target).getFullPath();
                String pathToString =
                    path.getDevice() == null ? path.toString() : path.toOSString();
                add(
                    projectPath.toString(),
                    "",
                    pathToString,
                    false /*not a package*/,
                    access); //$NON-NLS-1$
                addEnclosingProjectOrJar(entry.getPath());
              }
              break;
          }
          break;
        case IClasspathEntry.CPE_PROJECT:
          if ((includeMask & REFERENCED_PROJECTS) != 0) {
            IPath path = entry.getPath();
            if (pathToAdd == null || pathToAdd.equals(path)) {
              JavaProject referencedProject = (JavaProject) model.getJavaProject(path.toOSString());
              if (!projectsToBeAdded.contains(
                  referencedProject)) { // do not recurse if depending project was used to create
                                        // the scope
                add(
                    referencedProject,
                    null,
                    includeMask,
                    projectsToBeAdded,
                    visitedProjects,
                    cpEntry);
              }
            }
          }
          break;
        case IClasspathEntry.CPE_SOURCE:
          if ((includeMask & SOURCES) != 0) {
            IPath path = entry.getPath();
            if (pathToAdd == null || pathToAdd.equals(path)) {
              add(
                  projectPath.toString(),
                  Util.relativePath(path, projectPath.segmentCount() /*remove project segment*/),
                  projectPathString,
                  false /*not a package*/,
                  access);
            }
          }
          break;
      }
    }
  }