aboutsummaryrefslogtreecommitdiff
path: root/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ProjectClassLoader.java
diff options
context:
space:
mode:
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ProjectClassLoader.java')
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ProjectClassLoader.java376
1 files changed, 0 insertions, 376 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ProjectClassLoader.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ProjectClassLoader.java
deleted file mode 100644
index e07f09927..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ProjectClassLoader.java
+++ /dev/null
@@ -1,376 +0,0 @@
-/*
- * Copyright (C) 2008 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.resources.manager;
-
-import com.android.SdkConstants;
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.build.BuildHelper;
-import com.android.ide.eclipse.adt.internal.sdk.ProjectState;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
-
-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.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 org.objectweb.asm.ClassReader;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.ClassWriter;
-import org.objectweb.asm.Opcodes;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * ClassLoader able to load class from output of an Eclipse project.
- */
-public final class ProjectClassLoader extends ClassLoader {
-
- private final IJavaProject mJavaProject;
- private URLClassLoader mJarClassLoader;
- private boolean mInsideJarClassLoader = false;
-
- public ProjectClassLoader(ClassLoader parentClassLoader, IProject project) {
- super(parentClassLoader);
- mJavaProject = JavaCore.create(project);
- }
-
- @Override
- protected Class<?> findClass(String name) throws ClassNotFoundException {
- // if we are here through a child classloader, throw an exception.
- if (mInsideJarClassLoader) {
- throw new ClassNotFoundException(name);
- }
-
- // attempt to load the class from the main project
- Class<?> clazz = loadFromProject(mJavaProject, name);
-
- if (clazz != null) {
- return clazz;
- }
-
- // attempt to load the class from the jar dependencies
- clazz = loadClassFromJar(name);
- if (clazz != null) {
- return clazz;
- }
-
- // attempt to load the class from the libraries
- try {
- // get the project info
- ProjectState projectState = Sdk.getProjectState(mJavaProject.getProject());
-
- // this can happen if the project has no project.properties.
- if (projectState != null) {
-
- List<IProject> libProjects = projectState.getFullLibraryProjects();
- List<IJavaProject> referencedJavaProjects = BuildHelper.getJavaProjects(
- libProjects);
-
- for (IJavaProject javaProject : referencedJavaProjects) {
- clazz = loadFromProject(javaProject, name);
-
- if (clazz != null) {
- return clazz;
- }
- }
- }
- } catch (CoreException e) {
- // log exception?
- }
-
- throw new ClassNotFoundException(name);
- }
-
- /**
- * Attempts to load a class from a project output folder.
- * @param project the project to load the class from
- * @param name the name of the class
- * @return a class object if found, null otherwise.
- */
- private Class<?> loadFromProject(IJavaProject project, String name) {
- try {
- // get the project output folder.
- IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
- IPath outputLocation = project.getOutputLocation();
- IResource outRes = root.findMember(outputLocation);
- if (outRes == null) {
- return null;
- }
-
- File outFolder = new File(outRes.getLocation().toOSString());
-
- // get the class name segments
- String[] segments = name.split("\\."); //$NON-NLS-1$
-
- // try to load the class from the bin folder of the project.
- File classFile = getFile(outFolder, segments, 0);
- if (classFile == null) {
- return null;
- }
-
- // load the content of the file and create the class.
- FileInputStream fis = new FileInputStream(classFile);
- byte[] data = new byte[(int)classFile.length()];
- int read = 0;
- try {
- read = fis.read(data);
- } catch (IOException e) {
- data = null;
- }
- fis.close();
-
- if (data != null) {
- try {
- Class<?> clazz = defineClass(null, data, 0, read);
- if (clazz != null) {
- return clazz;
- }
- } catch (UnsupportedClassVersionError e) {
- // Attempt to reload on lower version
- int maxVersion = 50; // JDK 1.6
- try {
- byte[] rewritten = rewriteClass(data, maxVersion, 0);
- return defineClass(null, rewritten, 0, rewritten.length);
- } catch (UnsupportedClassVersionError e2) {
- throw e; // throw *original* exception, not attempt to rewrite
- }
- }
- }
- } catch (Exception e) {
- // log the exception?
- }
-
- return null;
- }
-
- /**
- * Rewrites the given class to the given target class file version.
- */
- public static byte[] rewriteClass(byte[] classData, final int maxVersion, final int minVersion) {
- assert maxVersion >= minVersion;
- ClassWriter classWriter = new ClassWriter(0);
- ClassVisitor classVisitor = new ClassVisitor(Opcodes.ASM5, classWriter) {
- @Override
- public void visit(int version, int access, String name, String signature,
- String superName, String[] interfaces) {
- if (version > maxVersion) {
- version = maxVersion;
- }
- if (version < minVersion) {
- version = minVersion;
- }
- super.visit(version, access, name, signature, superName, interfaces);
- }
- };
- ClassReader reader = new ClassReader(classData);
- reader.accept(classVisitor, 0);
- return classWriter.toByteArray();
- }
-
- /**
- * Returns the File matching the a certain path from a root {@link File}.
- * <p/>The methods checks that the file ends in .class even though the last segment
- * does not.
- * @param parent the root of the file.
- * @param segments the segments containing the path of the file
- * @param index the offset at which to start looking into segments.
- * @throws FileNotFoundException
- */
- private File getFile(File parent, String[] segments, int index)
- throws FileNotFoundException {
- // reached the end with no match?
- if (index == segments.length) {
- throw new FileNotFoundException();
- }
-
- String toMatch = segments[index];
- File[] files = parent.listFiles();
-
- // we're at the last segments. we look for a matching <file>.class
- if (index == segments.length - 1) {
- toMatch = toMatch + ".class";
-
- if (files != null) {
- for (File file : files) {
- if (file.isFile() && file.getName().equals(toMatch)) {
- return file;
- }
- }
- }
-
- // no match? abort.
- throw new FileNotFoundException();
- }
-
- String innerClassName = null;
-
- if (files != null) {
- for (File file : files) {
- if (file.isDirectory()) {
- if (toMatch.equals(file.getName())) {
- return getFile(file, segments, index+1);
- }
- } else if (file.getName().startsWith(toMatch)) {
- if (innerClassName == null) {
- StringBuilder sb = new StringBuilder(segments[index]);
- for (int i = index + 1 ; i < segments.length ; i++) {
- sb.append('$');
- sb.append(segments[i]);
- }
- sb.append(".class");
-
- innerClassName = sb.toString();
- }
-
- if (file.getName().equals(innerClassName)) {
- return file;
- }
- }
- }
- }
-
- return null;
- }
-
- /**
- * Loads a class from the 3rd party jar present in the project
- *
- * @return the class loader or null if not found.
- */
- private Class<?> loadClassFromJar(String name) {
- if (mJarClassLoader == null) {
- // get the OS path to all the external jars
- URL[] jars = getExternalJars();
-
- mJarClassLoader = new URLClassLoader(jars, this /* parent */);
- }
-
- try {
- // because a class loader always look in its parent loader first, we need to know
- // that we are querying the jar classloader. This will let us know to not query
- // it again for classes we don't find, or this would create an infinite loop.
- mInsideJarClassLoader = true;
- return mJarClassLoader.loadClass(name);
- } catch (ClassNotFoundException e) {
- // not found? return null.
- return null;
- } finally {
- mInsideJarClassLoader = false;
- }
- }
-
- /**
- * Returns an array of external jar files used by the project.
- * @return an array of OS-specific absolute file paths
- */
- private final URL[] getExternalJars() {
- // get a java project from it
- IJavaProject javaProject = JavaCore.create(mJavaProject.getProject());
-
- ArrayList<URL> oslibraryList = new ArrayList<URL>();
- IClasspathEntry[] classpaths = javaProject.readRawClasspath();
- if (classpaths != null) {
- for (IClasspathEntry e : classpaths) {
- if (e.getEntryKind() == IClasspathEntry.CPE_LIBRARY ||
- e.getEntryKind() == IClasspathEntry.CPE_VARIABLE) {
- // if this is a classpath variable reference, we resolve it.
- if (e.getEntryKind() == IClasspathEntry.CPE_VARIABLE) {
- e = JavaCore.getResolvedClasspathEntry(e);
- }
-
- handleClassPathEntry(e, oslibraryList);
- } else if (e.getEntryKind() == IClasspathEntry.CPE_CONTAINER) {
- // get the container.
- try {
- IClasspathContainer container = JavaCore.getClasspathContainer(
- e.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 entry : entries) {
- // TODO: Xav -- is this necessary?
- if (entry.getEntryKind() == IClasspathEntry.CPE_VARIABLE) {
- entry = JavaCore.getResolvedClasspathEntry(entry);
- }
-
- handleClassPathEntry(entry, oslibraryList);
- }
- }
- } catch (JavaModelException jme) {
- // can't resolve the container? ignore it.
- AdtPlugin.log(jme, "Failed to resolve ClasspathContainer: %s",
- e.getPath());
- }
- }
- }
- }
-
- return oslibraryList.toArray(new URL[oslibraryList.size()]);
- }
-
- private void handleClassPathEntry(IClasspathEntry e, ArrayList<URL> oslibraryList) {
- // get the IPath
- IPath path = e.getPath();
-
- // check the name ends with .jar
- if (SdkConstants.EXT_JAR.equalsIgnoreCase(path.getFileExtension())) {
- boolean local = false;
- IResource resource = ResourcesPlugin.getWorkspace().getRoot().findMember(path);
- if (resource != null && resource.exists() &&
- resource.getType() == IResource.FILE) {
- local = true;
- try {
- oslibraryList.add(new File(resource.getLocation().toOSString())
- .toURI().toURL());
- } catch (MalformedURLException mue) {
- // pass
- }
- }
-
- if (local == false) {
- // 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 File(osFullPath);
- if (f.exists()) {
- try {
- oslibraryList.add(f.toURI().toURL());
- } catch (MalformedURLException mue) {
- // pass
- }
- }
- }
- }
- }
-}