Package org.aspectj.org.eclipse.jdt.internal.core

Source Code of org.aspectj.org.eclipse.jdt.internal.core.JavaProjectElementInfo

/*******************************************************************************
* Copyright (c) 2000, 2007 IBM Corporation and others.
* 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:
*     IBM Corporation - initial API and implementation
*******************************************************************************/
package org.aspectj.org.eclipse.jdt.internal.core;

import java.util.HashMap;
import java.util.Map;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.aspectj.org.eclipse.jdt.core.*;
import org.aspectj.org.eclipse.jdt.internal.core.util.HashSetOfArray;
import org.aspectj.org.eclipse.jdt.internal.core.util.Util;
import org.aspectj.org.eclipse.jdt.internal.core.util.HashtableOfArrayToObject;

/**
* Info for IJavaProject.
* <p>
* Note: <code>getChildren()</code> returns all of the <code>IPackageFragmentRoots</code>
* specified on the classpath for the project.  This can include roots external to the
* project. See <code>JavaProject#getAllPackageFragmentRoots()</code> and
* <code>JavaProject#getPackageFragmentRoots()</code>.  To get only the <code>IPackageFragmentRoots</code>
* that are internal to the project, use <code>JavaProject#getChildren()</code>.
*/

/* package */
class JavaProjectElementInfo extends OpenableElementInfo {
 
  static final IPackageFragmentRoot[] NO_ROOTS = new IPackageFragmentRoot[0];

  static class ProjectCache {
    ProjectCache(IPackageFragmentRoot[] allPkgFragmentRootsCache, Map rootToResolvedEntries, Map pkgFragmentsCaches) {
      this.allPkgFragmentRootsCache = allPkgFragmentRootsCache;
      this.rootToResolvedEntries = rootToResolvedEntries;
      this.pkgFragmentsCaches = pkgFragmentsCaches;
    }
   
    /*
     * A cache of all package fragment roots of this project.
     */
    public IPackageFragmentRoot[] allPkgFragmentRootsCache;
   
    /*
     * A cache of all package fragments in this project.
     * (a map from String[] (the package name) to IPackageFragmentRoot[] (the package fragment roots that contain a package fragment with this name))
     */
    public HashtableOfArrayToObject allPkgFragmentsCache;
   
    /*
     * A cache of package fragments for each package fragment root of this project
     * (a map from IPackageFragmentRoot to a set of String[] (the package name))
     */
    public Map pkgFragmentsCaches;
   
    public Map rootToResolvedEntries;   
  }
 
  /**
   * A array with all the non-java resources contained by this PackageFragment
   */
  private Object[] nonJavaResources;
 
  ProjectCache projectCache;
 
  /*
   * Adds the given name and its super names to the given set
   * (e.g. for {"a", "b", "c"}, adds {"a", "b", "c"}, {"a", "b"}, and {"a"})
   */
  static void addSuperPackageNames(String[] pkgName, HashtableOfArrayToObject packageFragments) {
    for (int i = pkgName.length-1; i > 0; i--) {
      if (packageFragments.getKey(pkgName, i) == null) {
        System.arraycopy(pkgName, 0, pkgName = new String[i], 0, i);
        packageFragments.put(pkgName, NO_ROOTS);
      }
    }
  }
 
  /**
   * Create and initialize a new instance of the receiver
   */
  public JavaProjectElementInfo() {
    this.nonJavaResources = null;
  }
 
  /**
   * Compute the non-java resources contained in this java project.
   */
  private Object[] computeNonJavaResources(JavaProject project) {
   
    // determine if src == project and/or if bin == project
    IPath projectPath = project.getProject().getFullPath();
    boolean srcIsProject = false;
    boolean binIsProject = false;
    char[][] inclusionPatterns = null;
    char[][] exclusionPatterns = null;
    IPath projectOutput = null;
    boolean isClasspathResolved = true;
    try {
      IClasspathEntry entry = project.getClasspathEntryFor(projectPath);
      if (entry != null) {
        srcIsProject = true;
        inclusionPatterns = ((ClasspathEntry)entry).fullInclusionPatternChars();
        exclusionPatterns = ((ClasspathEntry)entry).fullExclusionPatternChars();
      }
      projectOutput = project.getOutputLocation();
      binIsProject = projectPath.equals(projectOutput);
    } catch (JavaModelException e) {
      isClasspathResolved = false;
    }

    Object[] resources = new IResource[5];
    int resourcesCounter = 0;
    try {
      IResource[] members = ((IContainer) project.getResource()).members();
      int length = members.length;
      if (length > 0) {
        String sourceLevel = project.getOption(JavaCore.COMPILER_SOURCE, true);
        String complianceLevel = project.getOption(JavaCore.COMPILER_COMPLIANCE, true);
        IClasspathEntry[] classpath = project.getResolvedClasspath();
        for (int i = 0; i < length; i++) {
          IResource res = members[i];
          switch (res.getType()) {
            case IResource.FILE :
              IPath resFullPath = res.getFullPath();
              String resName = res.getName();
           
              // ignore a jar file on the classpath
              if (isClasspathResolved && org.aspectj.org.eclipse.jdt.internal.compiler.util.Util.isArchiveFileName(resName) && this.isClasspathEntryOrOutputLocation(resFullPath, classpath, projectOutput)) {
                break;
              }
              // ignore .java file if src == project
              if (srcIsProject
                  && Util.isValidCompilationUnitName(resName, sourceLevel, complianceLevel)
                  && !Util.isExcluded(res, inclusionPatterns, exclusionPatterns)) {
                break;
              }
              // ignore .class file if bin == project
              if (binIsProject && Util.isValidClassFileName(resName, sourceLevel, complianceLevel)) {
                break;
              }
              // else add non java resource
              if (resources.length == resourcesCounter) {
                // resize
                System.arraycopy(
                    resources,
                    0,
                    (resources = new IResource[resourcesCounter * 2]),
                    0,
                    resourcesCounter);
              }
              resources[resourcesCounter++] = res;
              break;
            case IResource.FOLDER :
              resFullPath = res.getFullPath();
           
              // ignore non-excluded folders on the classpath or that correspond to an output location
              if ((srcIsProject && !Util.isExcluded(res, inclusionPatterns, exclusionPatterns) && Util.isValidFolderNameForPackage(res.getName(), sourceLevel, complianceLevel))
                  || (isClasspathResolved && this.isClasspathEntryOrOutputLocation(resFullPath, classpath, projectOutput))) {
                break;
              }
              // else add non java resource
              if (resources.length == resourcesCounter) {
                // resize
                System.arraycopy(
                    resources,
                    0,
                    (resources = new IResource[resourcesCounter * 2]),
                    0,
                    resourcesCounter);
              }
              resources[resourcesCounter++] = res;
          }
        }
      }
      if (resources.length != resourcesCounter) {
        System.arraycopy(
          resources,
          0,
          (resources = new IResource[resourcesCounter]),
          0,
          resourcesCounter);
      }
    } catch (CoreException e) {
      resources = NO_NON_JAVA_RESOURCES;
      resourcesCounter = 0;
    }
    return resources;
  }
 
  ProjectCache getProjectCache(JavaProject project) {
    ProjectCache cache = this.projectCache;
    if (cache == null) {
      IPackageFragmentRoot[] roots;
      Map reverseMap = new HashMap(3);
      try {
        roots = project.getAllPackageFragmentRoots(reverseMap);
      } catch (JavaModelException e) {
        // project does not exist: cannot happen since this is the info of the project
        roots = new IPackageFragmentRoot[0];
        reverseMap.clear();
      }
     
      HashMap rootInfos = JavaModelManager.getJavaModelManager().deltaState.roots;
      HashMap pkgFragmentsCaches = new HashMap();
      int length = roots.length;
      for (int i = 0; i < length; i++) {
        IPackageFragmentRoot root = roots[i];
        DeltaProcessor.RootInfo rootInfo = (DeltaProcessor.RootInfo) rootInfos.get(root.getPath());
        if (rootInfo == null || rootInfo.project.equals(project)) {
          // compute fragment cache
          HashSetOfArray fragmentsCache = new HashSetOfArray();
          initializePackageNames(root, fragmentsCache);
          pkgFragmentsCaches.put(root, fragmentsCache);
        }
      }
     
      cache = new ProjectCache(roots, reverseMap, pkgFragmentsCaches);
      this.projectCache = cache;
    }
    return cache;
  }
 
  /**
   * Returns an array of non-java resources contained in the receiver.
   */
  Object[] getNonJavaResources(JavaProject project) {

    if (this.nonJavaResources == null) {
      this.nonJavaResources = computeNonJavaResources(project);
    }
    return this.nonJavaResources;
  }
 
  private void initializePackageNames(IPackageFragmentRoot root, HashSetOfArray fragmentsCache) {
    IJavaElement[] frags = null;
    try {
      if (!root.isOpen()) {
        PackageFragmentRootInfo info = root.isArchive() ? new JarPackageFragmentRootInfo() : new PackageFragmentRootInfo();
        ((PackageFragmentRoot) root).computeChildren(info, new HashMap());
        frags = info.children;
      } else
        frags = root.getChildren();
    } catch (JavaModelException e) {
      // root doesn't exist: ignore
      return;
    }
    for (int j = 0, length2 = frags.length; j < length2; j++) {
      fragmentsCache.add(((PackageFragment) frags[j]).names);
    }
  }

  /*
   * Returns whether the given path is a classpath entry or an output location.
   */
  private boolean isClasspathEntryOrOutputLocation(IPath path, IClasspathEntry[] resolvedClasspath, IPath projectOutput) {
    if (projectOutput.equals(path)) return true;
    for (int i = 0, length = resolvedClasspath.length; i < length; i++) {
      IClasspathEntry entry = resolvedClasspath[i];
      if (entry.getPath().equals(path)) {
        return true;
      }
      IPath output;
      if ((output = entry.getOutputLocation()) != null && output.equals(path)) {
        return true;
      }
    }
    return false;
  }
 
  /*
   * Creates a new name lookup for this project info.
   * The given project is assumed to be the handle of this info.
   * This name lookup first looks in the given working copies.
   */
  NameLookup newNameLookup(JavaProject project, ICompilationUnit[] workingCopies) {
    ProjectCache cache = getProjectCache(project);
    HashtableOfArrayToObject allPkgFragmentsCache = cache.allPkgFragmentsCache;
    if (allPkgFragmentsCache == null) {
      HashMap rootInfos = JavaModelManager.getJavaModelManager().deltaState.roots;
      IPackageFragmentRoot[] allRoots = cache.allPkgFragmentRootsCache;
      int length = allRoots.length;
      allPkgFragmentsCache = new HashtableOfArrayToObject();
      for (int i = 0; i < length; i++) {
        IPackageFragmentRoot root = allRoots[i];
        DeltaProcessor.RootInfo rootInfo = (DeltaProcessor.RootInfo) rootInfos.get(root.getPath());
        JavaProject rootProject = rootInfo == null ? project : rootInfo.project;
        HashSetOfArray fragmentsCache;
        if (rootProject.equals(project)) {
          // retrieve package fragments cache from this project
          fragmentsCache = (HashSetOfArray) cache.pkgFragmentsCaches.get(root);
        } else {
          // retrieve package fragments  cache from the root's project
          ProjectCache rootProjectCache;
          try {
            rootProjectCache = rootProject.getProjectCache();
          } catch (JavaModelException e) {
            // project doesn't exit
            continue;
          }
          fragmentsCache = (HashSetOfArray) rootProjectCache.pkgFragmentsCaches.get(root);
        }
        if (fragmentsCache == null) { // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=183833
          fragmentsCache = new HashSetOfArray();
          initializePackageNames(root, fragmentsCache);
        }
        Object[][] set = fragmentsCache.set;
        for (int j = 0, length2 = set.length; j < length2; j++) {
          String[] pkgName = (String[]) set[j];
          if (pkgName == null)
            continue;
          Object existing = allPkgFragmentsCache.get(pkgName);
          if (existing == null || existing == NO_ROOTS) {
            allPkgFragmentsCache.put(pkgName, root);
            // ensure super packages (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=119161)
            // are also in the map
            addSuperPackageNames(pkgName, allPkgFragmentsCache);
          } else {
            if (existing instanceof PackageFragmentRoot) {
              allPkgFragmentsCache.put(pkgName, new IPackageFragmentRoot[] {(PackageFragmentRoot) existing, root});
            } else {
              IPackageFragmentRoot[] roots = (IPackageFragmentRoot[]) existing;
              int rootLength = roots.length;
              System.arraycopy(roots, 0, roots = new IPackageFragmentRoot[rootLength+1], 0, rootLength);
              roots[rootLength] = root;
              allPkgFragmentsCache.put(pkgName, roots);
            }
          }
        }
      }
      cache.allPkgFragmentsCache = allPkgFragmentsCache;
    }
    return new NameLookup(cache.allPkgFragmentRootsCache, cache.allPkgFragmentsCache, workingCopies, cache.rootToResolvedEntries);
  }
 
  /*
   * Reset the package fragment roots and package fragment caches
   */
  void resetCaches() {
    this.projectCache = null;
  }
 
  /**
   * Set the fNonJavaResources to res value
   */
  void setNonJavaResources(Object[] resources) {

    this.nonJavaResources = resources;
  }
 
}
TOP

Related Classes of org.aspectj.org.eclipse.jdt.internal.core.JavaProjectElementInfo

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.