michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: package org.mozilla.gecko.annotationProcessors.classloader; michael@0: michael@0: import java.lang.annotation.Annotation; michael@0: import java.lang.reflect.InvocationTargetException; michael@0: import java.lang.reflect.Method; michael@0: import java.util.Iterator; michael@0: michael@0: /** michael@0: * Class for iterating over an IterableJarLoadingURLClassLoader's classes. michael@0: */ michael@0: public class JarClassIterator implements Iterator { michael@0: private IterableJarLoadingURLClassLoader mTarget; michael@0: private Iterator mTargetClassListIterator; michael@0: michael@0: public JarClassIterator(IterableJarLoadingURLClassLoader aTarget) { michael@0: mTarget = aTarget; michael@0: mTargetClassListIterator = aTarget.classNames.iterator(); michael@0: } michael@0: michael@0: @Override michael@0: public boolean hasNext() { michael@0: return mTargetClassListIterator.hasNext(); michael@0: } michael@0: michael@0: @Override michael@0: public ClassWithOptions next() { michael@0: String className = mTargetClassListIterator.next(); michael@0: try { michael@0: Class ret = mTarget.loadClass(className); michael@0: final String canonicalName; michael@0: michael@0: // Incremental builds can leave stale classfiles in the jar. Such classfiles will cause michael@0: // an exception at this point. We can safely ignore these classes - they cannot possibly michael@0: // ever be loaded as they conflict with their parent class and will be killed by Proguard michael@0: // later on anyway. michael@0: try { michael@0: canonicalName = ret.getCanonicalName(); michael@0: } catch (IncompatibleClassChangeError e) { michael@0: return next(); michael@0: } michael@0: michael@0: if (canonicalName == null || "null".equals(canonicalName)) { michael@0: // Anonymous inner class - unsupported. michael@0: return next(); michael@0: } else { michael@0: String generateName = null; michael@0: for (Annotation annotation : ret.getAnnotations()) { michael@0: Class annotationType = annotation.annotationType(); michael@0: if (annotationType.getCanonicalName().equals("org.mozilla.gecko.mozglue.generatorannotations.GeneratorOptions")) { michael@0: try { michael@0: // Determine the explicitly-given name of the stub to generate, if any. michael@0: final Method generateNameMethod = annotationType.getDeclaredMethod("generatedClassName"); michael@0: generateNameMethod.setAccessible(true); michael@0: generateName = (String) generateNameMethod.invoke(annotation); michael@0: break; michael@0: } catch (NoSuchMethodException e) { michael@0: System.err.println("Unable to find expected field on GeneratorOptions annotation. Did the signature change?"); michael@0: e.printStackTrace(System.err); michael@0: System.exit(3); michael@0: } catch (IllegalAccessException e) { michael@0: System.err.println("IllegalAccessException reading fields on GeneratorOptions annotation. Seems the semantics of Reflection have changed..."); michael@0: e.printStackTrace(System.err); michael@0: System.exit(4); michael@0: } catch (InvocationTargetException e) { michael@0: System.err.println("InvocationTargetException reading fields on GeneratorOptions annotation. This really shouldn't happen."); michael@0: e.printStackTrace(System.err); michael@0: System.exit(5); michael@0: } michael@0: } michael@0: } michael@0: if (generateName == null) { michael@0: generateName = ret.getSimpleName(); michael@0: } michael@0: return new ClassWithOptions(ret, generateName); michael@0: } michael@0: } catch (ClassNotFoundException e) { michael@0: System.err.println("Unable to enumerate class: " + className + ". Corrupted jar file?"); michael@0: e.printStackTrace(); michael@0: System.exit(2); michael@0: } michael@0: return null; michael@0: } michael@0: michael@0: @Override michael@0: public void remove() { michael@0: throw new UnsupportedOperationException("Removal of classes from iterator not supported."); michael@0: } michael@0: }