diff options
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/LibraryClasspathContainerInitializer.java')
-rw-r--r-- | eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/LibraryClasspathContainerInitializer.java | 641 |
1 files changed, 0 insertions, 641 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/LibraryClasspathContainerInitializer.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/LibraryClasspathContainerInitializer.java deleted file mode 100644 index 8fbee4089..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/LibraryClasspathContainerInitializer.java +++ /dev/null @@ -1,641 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.ide.eclipse.adt.internal.project; - -import static com.android.ide.eclipse.adt.AdtConstants.CONTAINER_DEPENDENCIES; - -import com.android.SdkConstants; -import com.android.ide.common.sdk.LoadStatus; -import com.android.ide.eclipse.adt.AdtConstants; -import com.android.ide.eclipse.adt.AdtPlugin; -import com.android.ide.eclipse.adt.AndroidPrintStream; -import com.android.ide.eclipse.adt.internal.sdk.ProjectState; -import com.android.ide.eclipse.adt.internal.sdk.Sdk; -import com.android.sdklib.BuildToolInfo; -import com.android.sdklib.build.JarListSanitizer; -import com.android.sdklib.build.JarListSanitizer.DifferentLibException; -import com.android.sdklib.build.JarListSanitizer.Sha1Exception; -import com.android.sdklib.build.RenderScriptProcessor; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IFolder; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IWorkspaceRoot; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.core.runtime.Path; -import org.eclipse.jdt.core.IAccessRule; -import org.eclipse.jdt.core.IClasspathAttribute; -import org.eclipse.jdt.core.IClasspathContainer; -import org.eclipse.jdt.core.IClasspathEntry; -import org.eclipse.jdt.core.IJavaProject; -import org.eclipse.jdt.core.JavaCore; -import org.eclipse.jdt.core.JavaModelException; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.net.MalformedURLException; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Properties; -import java.util.Set; - -public class LibraryClasspathContainerInitializer extends BaseClasspathContainerInitializer { - - private final static String ATTR_SRC = "src"; //$NON-NLS-1$ - private final static String ATTR_DOC = "doc"; //$NON-NLS-1$ - private final static String DOT_PROPERTIES = ".properties"; //$NON-NLS-1$ - - public LibraryClasspathContainerInitializer() { - } - - /** - * Updates the {@link IJavaProject} objects with new library. - * @param androidProjects the projects to update. - * @return <code>true</code> if success, <code>false</code> otherwise. - */ - public static boolean updateProjects(IJavaProject[] androidProjects) { - try { - // Allocate a new AndroidClasspathContainer, and associate it to the library - // container id for each projects. - int projectCount = androidProjects.length; - - IClasspathContainer[] libraryContainers = new IClasspathContainer[projectCount]; - IClasspathContainer[] dependencyContainers = new IClasspathContainer[projectCount]; - for (int i = 0 ; i < projectCount; i++) { - libraryContainers[i] = allocateLibraryContainer(androidProjects[i]); - dependencyContainers[i] = allocateDependencyContainer(androidProjects[i]); - } - - // give each project their new container in one call. - JavaCore.setClasspathContainer( - new Path(AdtConstants.CONTAINER_PRIVATE_LIBRARIES), - androidProjects, libraryContainers, new NullProgressMonitor()); - - JavaCore.setClasspathContainer( - new Path(AdtConstants.CONTAINER_DEPENDENCIES), - androidProjects, dependencyContainers, new NullProgressMonitor()); - return true; - } catch (JavaModelException e) { - return false; - } - } - - /** - * Updates the {@link IJavaProject} objects with new library. - * @param androidProjects the projects to update. - * @return <code>true</code> if success, <code>false</code> otherwise. - */ - public static boolean updateProject(List<ProjectState> projects) { - List<IJavaProject> javaProjectList = new ArrayList<IJavaProject>(projects.size()); - for (ProjectState p : projects) { - IJavaProject javaProject = JavaCore.create(p.getProject()); - if (javaProject != null) { - javaProjectList.add(javaProject); - } - } - - IJavaProject[] javaProjects = javaProjectList.toArray( - new IJavaProject[javaProjectList.size()]); - - return updateProjects(javaProjects); - } - - @Override - public void initialize(IPath containerPath, IJavaProject project) throws CoreException { - if (AdtConstants.CONTAINER_PRIVATE_LIBRARIES.equals(containerPath.toString())) { - IClasspathContainer libraries = allocateLibraryContainer(project); - if (libraries != null) { - JavaCore.setClasspathContainer(new Path(AdtConstants.CONTAINER_PRIVATE_LIBRARIES), - new IJavaProject[] { project }, - new IClasspathContainer[] { libraries }, - new NullProgressMonitor()); - } - - } else if(AdtConstants.CONTAINER_DEPENDENCIES.equals(containerPath.toString())) { - IClasspathContainer dependencies = allocateDependencyContainer(project); - if (dependencies != null) { - JavaCore.setClasspathContainer(new Path(AdtConstants.CONTAINER_DEPENDENCIES), - new IJavaProject[] { project }, - new IClasspathContainer[] { dependencies }, - new NullProgressMonitor()); - } - } - } - - private static IClasspathContainer allocateLibraryContainer(IJavaProject javaProject) { - final IProject iProject = javaProject.getProject(); - - // check if the project has a valid target. - ProjectState state = Sdk.getProjectState(iProject); - if (state == null) { - // getProjectState should already have logged an error. Just bail out. - return null; - } - - /* - * At this point we're going to gather a list of all that need to go in the - * dependency container. - * - Library project outputs (direct and indirect) - * - Java project output (those can be indirectly referenced through library projects - * or other other Java projects) - * - Jar files: - * + inside this project's libs/ - * + inside the library projects' libs/ - * + inside the referenced Java projects' classpath - */ - List<IClasspathEntry> entries = new ArrayList<IClasspathEntry>(); - - // list of java project dependencies and jar files that will be built while - // going through the library projects. - Set<File> jarFiles = new HashSet<File>(); - Set<IProject> refProjects = new HashSet<IProject>(); - - // process all the libraries - - List<IProject> libProjects = state.getFullLibraryProjects(); - for (IProject libProject : libProjects) { - // process all of the library project's dependencies - getDependencyListFromClasspath(libProject, refProjects, jarFiles, true); - } - - // now process this projects' referenced projects only. - processReferencedProjects(iProject, refProjects, jarFiles); - - // and the content of its libs folder - getJarListFromLibsFolder(iProject, jarFiles); - - // now add a classpath entry for each Java project (this is a set so dups are already - // removed) - for (IProject p : refProjects) { - entries.add(JavaCore.newProjectEntry(p.getFullPath(), true /*isExported*/)); - } - - entries.addAll(convertJarsToClasspathEntries(iProject, jarFiles)); - - return allocateContainer(javaProject, entries, new Path(AdtConstants.CONTAINER_PRIVATE_LIBRARIES), - "Android Private Libraries"); - } - - private static List<IClasspathEntry> convertJarsToClasspathEntries(final IProject iProject, - Set<File> jarFiles) { - List<IClasspathEntry> entries = new ArrayList<IClasspathEntry>(jarFiles.size()); - - // and process the jar files list, but first sanitize it to remove dups. - JarListSanitizer sanitizer = new JarListSanitizer( - iProject.getFolder(SdkConstants.FD_OUTPUT).getLocation().toFile(), - new AndroidPrintStream(iProject, null /*prefix*/, - AdtPlugin.getOutStream())); - - String errorMessage = null; - - try { - List<File> sanitizedList = sanitizer.sanitize(jarFiles); - - for (File jarFile : sanitizedList) { - if (jarFile instanceof CPEFile) { - CPEFile cpeFile = (CPEFile) jarFile; - IClasspathEntry e = cpeFile.getClasspathEntry(); - - entries.add(JavaCore.newLibraryEntry( - e.getPath(), - e.getSourceAttachmentPath(), - e.getSourceAttachmentRootPath(), - e.getAccessRules(), - e.getExtraAttributes(), - true /*isExported*/)); - } else { - String jarPath = jarFile.getAbsolutePath(); - - IPath sourceAttachmentPath = null; - IClasspathAttribute javaDocAttribute = null; - - File jarProperties = new File(jarPath + DOT_PROPERTIES); - if (jarProperties.isFile()) { - Properties p = new Properties(); - InputStream is = null; - try { - p.load(is = new FileInputStream(jarProperties)); - - String value = p.getProperty(ATTR_SRC); - if (value != null) { - File srcPath = getFile(jarFile, value); - - if (srcPath.exists()) { - sourceAttachmentPath = new Path(srcPath.getAbsolutePath()); - } - } - - value = p.getProperty(ATTR_DOC); - if (value != null) { - File docPath = getFile(jarFile, value); - if (docPath.exists()) { - try { - javaDocAttribute = JavaCore.newClasspathAttribute( - IClasspathAttribute.JAVADOC_LOCATION_ATTRIBUTE_NAME, - docPath.toURI().toURL().toString()); - } catch (MalformedURLException e) { - AdtPlugin.log(e, "Failed to process 'doc' attribute for %s", - jarProperties.getAbsolutePath()); - } - } - } - - } catch (FileNotFoundException e) { - // shouldn't happen since we check upfront - } catch (IOException e) { - AdtPlugin.log(e, "Failed to read %s", jarProperties.getAbsolutePath()); - } finally { - if (is != null) { - try { - is.close(); - } catch (IOException e) { - // ignore - } - } - } - } - - if (javaDocAttribute != null) { - entries.add(JavaCore.newLibraryEntry(new Path(jarPath), - sourceAttachmentPath, null /*sourceAttachmentRootPath*/, - new IAccessRule[0], - new IClasspathAttribute[] { javaDocAttribute }, - true /*isExported*/)); - } else { - entries.add(JavaCore.newLibraryEntry(new Path(jarPath), - sourceAttachmentPath, null /*sourceAttachmentRootPath*/, - true /*isExported*/)); - } - } - } - } catch (DifferentLibException e) { - errorMessage = e.getMessage(); - AdtPlugin.printErrorToConsole(iProject, (Object[]) e.getDetails()); - } catch (Sha1Exception e) { - errorMessage = e.getMessage(); - } - - processError(iProject, errorMessage, AdtConstants.MARKER_DEPENDENCY, - true /*outputToConsole*/); - - return entries; - } - - private static IClasspathContainer allocateDependencyContainer(IJavaProject javaProject) { - final IProject iProject = javaProject.getProject(); - final List<IClasspathEntry> entries = new ArrayList<IClasspathEntry>(); - final Set<File> jarFiles = new HashSet<File>(); - final IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); - - AdtPlugin plugin = AdtPlugin.getDefault(); - if (plugin == null) { // This is totally weird, but I've seen it happen! - return null; - } - - synchronized (Sdk.getLock()) { - boolean sdkIsLoaded = plugin.getSdkLoadStatus() == LoadStatus.LOADED; - - // check if the project has a valid target. - final ProjectState state = Sdk.getProjectState(iProject); - if (state == null) { - // getProjectState should already have logged an error. Just bail out. - return null; - } - - // annotations support for older version of android - if (state.getTarget() != null && state.getTarget().getVersion().getApiLevel() <= 15) { - File annotationsJar = new File(Sdk.getCurrent().getSdkOsLocation(), - SdkConstants.FD_TOOLS + File.separator + SdkConstants.FD_SUPPORT + - File.separator + SdkConstants.FN_ANNOTATIONS_JAR); - - jarFiles.add(annotationsJar); - } - - if (state.getRenderScriptSupportMode()) { - if (!sdkIsLoaded) { - return null; - } - BuildToolInfo buildToolInfo = state.getBuildToolInfo(); - if (buildToolInfo == null) { - buildToolInfo = Sdk.getCurrent().getLatestBuildTool(); - - if (buildToolInfo == null) { - return null; - } - } - - File renderScriptSupportJar = RenderScriptProcessor.getSupportJar( - buildToolInfo.getLocation().getAbsolutePath()); - - jarFiles.add(renderScriptSupportJar); - } - - // process all the libraries - - List<IProject> libProjects = state.getFullLibraryProjects(); - for (IProject libProject : libProjects) { - // get the project output - IFolder outputFolder = BaseProjectHelper.getAndroidOutputFolder(libProject); - - if (outputFolder != null) { // can happen when closing/deleting a library) - IFile jarIFile = outputFolder.getFile(libProject.getName().toLowerCase() + - SdkConstants.DOT_JAR); - - // get the source folder for the library project - List<IPath> srcs = BaseProjectHelper.getSourceClasspaths(libProject); - // find the first non-derived source folder. - IPath sourceFolder = null; - for (IPath src : srcs) { - IFolder srcFolder = workspaceRoot.getFolder(src); - if (srcFolder.isDerived() == false) { - sourceFolder = src; - break; - } - } - - // we can directly add a CPE for this jar as there's no risk of a duplicate. - IClasspathEntry entry = JavaCore.newLibraryEntry( - jarIFile.getLocation(), - sourceFolder, // source attachment path - null, // default source attachment root path. - true /*isExported*/); - - entries.add(entry); - } - } - - entries.addAll(convertJarsToClasspathEntries(iProject, jarFiles)); - - return allocateContainer(javaProject, entries, new Path(CONTAINER_DEPENDENCIES), - "Android Dependencies"); - } - } - - private static IClasspathContainer allocateContainer(IJavaProject javaProject, - List<IClasspathEntry> entries, IPath id, String description) { - - if (AdtPlugin.getDefault() == null) { // This is totally weird, but I've seen it happen! - return null; - } - - // First check that the project has a library-type container. - try { - IClasspathEntry[] rawClasspath = javaProject.getRawClasspath(); - final IClasspathEntry[] oldRawClasspath = rawClasspath; - - boolean foundContainer = false; - for (IClasspathEntry entry : rawClasspath) { - // get the entry and kind - final int kind = entry.getEntryKind(); - - if (kind == IClasspathEntry.CPE_CONTAINER) { - String path = entry.getPath().toString(); - String idString = id.toString(); - if (idString.equals(path)) { - foundContainer = true; - break; - } - } - } - - // if there isn't any, add it. - if (foundContainer == false) { - // add the android container to the array - rawClasspath = ProjectHelper.addEntryToClasspath(rawClasspath, - JavaCore.newContainerEntry(id, true /*isExported*/)); - } - - // set the new list of entries to the project - if (rawClasspath != oldRawClasspath) { - javaProject.setRawClasspath(rawClasspath, new NullProgressMonitor()); - } - } catch (JavaModelException e) { - // This really shouldn't happen, but if it does, simply return null (the calling - // method will fails as well) - return null; - } - - return new AndroidClasspathContainer( - entries.toArray(new IClasspathEntry[entries.size()]), - id, - description, - IClasspathContainer.K_APPLICATION); - } - - private static File getFile(File root, String value) { - File file = new File(value); - if (file.isAbsolute() == false) { - file = new File(root.getParentFile(), value); - } - - return file; - } - - /** - * Finds all the jar files inside a project's libs folder. - * @param project - * @param jarFiles - */ - private static void getJarListFromLibsFolder(IProject project, Set<File> jarFiles) { - IFolder libsFolder = project.getFolder(SdkConstants.FD_NATIVE_LIBS); - if (libsFolder.exists()) { - try { - IResource[] members = libsFolder.members(); - for (IResource member : members) { - if (member.getType() == IResource.FILE && - SdkConstants.EXT_JAR.equalsIgnoreCase(member.getFileExtension())) { - IPath location = member.getLocation(); - if (location != null) { - jarFiles.add(location.toFile()); - } - } - } - } catch (CoreException e) { - // can't get the list? ignore this folder. - } - } - } - - /** - * Process reference projects from the main projects to add indirect dependencies coming - * from Java project. - * @param project the main project - * @param projects the project list to add to - * @param jarFiles the jar list to add to. - */ - private static void processReferencedProjects(IProject project, - Set<IProject> projects, Set<File> jarFiles) { - try { - IProject[] refs = project.getReferencedProjects(); - for (IProject p : refs) { - // ignore if it's an Android project, or if it's not a Java - // Project - if (p.hasNature(JavaCore.NATURE_ID) - && p.hasNature(AdtConstants.NATURE_DEFAULT) == false) { - - // process this project's dependencies - getDependencyListFromClasspath(p, projects, jarFiles, true /*includeJarFiles*/); - } - } - } catch (CoreException e) { - // can't get the referenced projects? ignore - } - } - - /** - * Finds all the dependencies of a given project and add them to a project list and - * a jar list. - * Only classpath entries that are exported are added, and only Java project (not Android - * project) are added. - * - * @param project the project to query - * @param projects the referenced 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 getDependencyListFromClasspath(IProject project, Set<IProject> projects, - Set<File> jarFiles, boolean includeJarFiles) { - IJavaProject javaProject = JavaCore.create(project); - IWorkspaceRoot wsRoot = ResourcesPlugin.getWorkspace().getRoot(); - - // we could use IJavaProject.getResolvedClasspath directly, but we actually - // want to see the containers themselves. - IClasspathEntry[] classpaths = javaProject.readRawClasspath(); - if (classpaths != null) { - for (IClasspathEntry e : classpaths) { - // ignore entries that are not exported - if (!e.getPath().toString().equals(CONTAINER_DEPENDENCIES) && e.isExported()) { - processCPE(e, javaProject, wsRoot, projects, jarFiles, includeJarFiles); - } - } - } - } - - /** - * 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(AdtConstants.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. - AdtPlugin.log(jme, "Failed to resolve ClasspathContainer: %s", entry.getPath()); - } - } - } - - private static final class CPEFile extends File { - private static final long serialVersionUID = 1L; - - private final IClasspathEntry mClasspathEntry; - - public CPEFile(String pathname, IClasspathEntry classpathEntry) { - super(pathname); - mClasspathEntry = classpathEntry; - } - - public CPEFile(File file, IClasspathEntry classpathEntry) { - super(file.getAbsolutePath()); - mClasspathEntry = classpathEntry; - } - - public IClasspathEntry getClasspathEntry() { - return mClasspathEntry; - } - } - - private static void handleClasspathLibrary(IClasspathEntry e, IWorkspaceRoot wsRoot, - Set<File> jarFiles) { - // get the IPath - IPath path = e.getPath(); - - IResource resource = wsRoot.findMember(path); - - if (SdkConstants.EXT_JAR.equalsIgnoreCase(path.getFileExtension())) { - // case of a jar file (which could be relative to the workspace or a full path) - if (resource != null && resource.exists() && - resource.getType() == IResource.FILE) { - jarFiles.add(new CPEFile(resource.getLocation().toFile(), e)); - } else { - // if the jar path doesn't match a workspace resource, - // then we get an OSString and check if this links to a valid file. - String osFullPath = path.toOSString(); - - File f = new CPEFile(osFullPath, e); - if (f.isFile()) { - jarFiles.add(f); - } - } - } - } -} |