You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by db...@apache.org on 2012/06/06 05:52:12 UTC

svn commit: r1346728 - in /commons/sandbox/classscan/branches/commons-finder/src/main/java/org/apache/commons/classscan/finder: AnnotationFinder.java model/InfoHandler.java parse/ parse/AsmParser.java parse/Parser.java

Author: dblevins
Date: Wed Jun  6 03:52:11 2012
New Revision: 1346728

URL: http://svn.apache.org/viewvc?rev=1346728&view=rev
Log:
Abstracted ASM out of the AnnotationFinder behind a Parser interface that uses the InfoHandler "Listener" interface.
Went for the SAX Handler lingo on the "listener" as it seemed more appropriate.

Added:
    commons/sandbox/classscan/branches/commons-finder/src/main/java/org/apache/commons/classscan/finder/parse/
    commons/sandbox/classscan/branches/commons-finder/src/main/java/org/apache/commons/classscan/finder/parse/AsmParser.java
    commons/sandbox/classscan/branches/commons-finder/src/main/java/org/apache/commons/classscan/finder/parse/Parser.java
Modified:
    commons/sandbox/classscan/branches/commons-finder/src/main/java/org/apache/commons/classscan/finder/AnnotationFinder.java
    commons/sandbox/classscan/branches/commons-finder/src/main/java/org/apache/commons/classscan/finder/model/InfoHandler.java

Modified: commons/sandbox/classscan/branches/commons-finder/src/main/java/org/apache/commons/classscan/finder/AnnotationFinder.java
URL: http://svn.apache.org/viewvc/commons/sandbox/classscan/branches/commons-finder/src/main/java/org/apache/commons/classscan/finder/AnnotationFinder.java?rev=1346728&r1=1346727&r2=1346728&view=diff
==============================================================================
--- commons/sandbox/classscan/branches/commons-finder/src/main/java/org/apache/commons/classscan/finder/AnnotationFinder.java (original)
+++ commons/sandbox/classscan/branches/commons-finder/src/main/java/org/apache/commons/classscan/finder/AnnotationFinder.java Wed Jun  6 03:52:11 2012
@@ -32,14 +32,9 @@ import org.apache.commons.classscan.find
 import org.apache.commons.classscan.finder.model.InfoHandler;
 import org.apache.commons.classscan.finder.model.MethodInfo;
 import org.apache.commons.classscan.finder.model.PackageInfo;
+import org.apache.commons.classscan.finder.parse.AsmParser;
+import org.apache.commons.classscan.finder.parse.Parser;
 import org.apache.commons.classscan.finder.util.SingleLinkedList;
-import org.objectweb.asm.AnnotationVisitor;
-import org.objectweb.asm.Attribute;
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.FieldVisitor;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Type;
-import org.objectweb.asm.commons.EmptyVisitor;
 
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
@@ -80,9 +75,11 @@ public class AnnotationFinder implements
     protected final Map<String, ClassInfo> originalInfos = new HashMap<String, ClassInfo>();
     private final List<String> classesNotLoaded = new ArrayList<String>();
     private final Archive archive;
+    private Parser parser;
 
     private AnnotationFinder(AnnotationFinder parent, Iterable<String> classNames) {
         this.archive = new SubArchive(classNames);
+        this.parser = new AsmParser(this, archive);
         this.metaroots.addAll(parent.metaroots);
         for (Class<? extends Annotation> metaroot : metaroots) {
             final ClassInfo info = parent.classInfos.get(metaroot.getName());
@@ -120,16 +117,8 @@ public class AnnotationFinder implements
     public AnnotationFinder(Archive archive) {
         this.archive = archive;
 
-        for (Archive.Entry entry : archive) {
-            final String className = entry.getName();
-            try {
-                readClassDef(entry.getBytecode());
-            } catch (NoClassDefFoundError e) {
-                throw new NoClassDefFoundError("Could not fully load class: " + className + "\n due to:" + e.getMessage());
-            } catch (IOException e) {
-                e.printStackTrace();
-            }
-        }
+        parser = new AsmParser(this, archive);
+        parser.parse();
 
         // keep track of what was originally from the archives
         originalInfos.putAll(classInfos);
@@ -1059,6 +1048,11 @@ public class AnnotationFinder implements
         index(annotationInfo, info);
     }
 
+    @Override
+    public void error(String className, Throwable throwable) {
+        classesNotLoaded.add(className);
+    }
+
     protected void readClassDef(String className) {
         if (classInfos.containsKey(className)) return;
         try {
@@ -1106,128 +1100,7 @@ public class AnnotationFinder implements
         }
     }
 
-    //----------------------------------------------------------------------------
-    //
-    //  From here below are the ASM specific parts.
-    //
-    //  With a cleaned up model, this could easily be abstracted
-    //
-    //----------------------------------------------------------------------------
-    public static class AsmParser {
-
-        private final InfoHandler handler;
-
-        public AsmParser(InfoHandler handler) {
-            this.handler = handler;
-        }
-
-    }
-
     protected void readClassDef(InputStream in) throws IOException {
-        try {
-            final ClassReader classReader = new ClassReader(in);
-            final int flags = ClassReader.SKIP_CODE + ClassReader.SKIP_DEBUG + ClassReader.SKIP_FRAMES;
-            classReader.accept(new InfoBuildingVisitor(), flags);
-        } finally {
-            in.close();
-        }
-    }
-
-    private final InfoHandler handler = this;
-
-    public  class InfoBuildingVisitor extends EmptyVisitor {
-
-        private Info info;
-
-        public InfoBuildingVisitor() {
-        }
-
-        public InfoBuildingVisitor(Info info) {
-            this.info = info;
-        }
-
-
-        @Override
-        public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
-            if (name.endsWith("package-info")) {
-                info = new PackageInfo(archive, javaName(name));
-                handler.visit((PackageInfo) info);
-            } else {
-
-                ClassInfo classInfo = new ClassInfo(archive, javaName(name), javaName(superName));
-
-                for (String interfce : interfaces) {
-                    classInfo.getInterfaces().add(javaName(interfce));
-                }
-
-                info = classInfo;
-
-                handler.visit((ClassInfo) info);
-            }
-        }
-
-        private String javaName(String name) {
-            return (name == null) ? null : name.replace('/', '.');
-        }
-
-        @Override
-        public void visitInnerClass(String name, String outerName, String innerName, int access) {
-            super.visitInnerClass(name, outerName, innerName, access);
-        }
-
-        @Override
-        public void visitAttribute(Attribute attribute) {
-            super.visitAttribute(attribute);
-        }
-
-        @Override
-        public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-            final String name = Type.getType(desc).getClassName();
-            AnnotationInfo annotationInfo = new AnnotationInfo(name);
-            info.getAnnotations().add(annotationInfo);
-
-            handler.visit(annotationInfo, info);
-
-            return new InfoBuildingVisitor(annotationInfo);
-        }
-
-        @Override
-        public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {
-            ClassInfo classInfo = ((ClassInfo) info);
-            FieldInfo fieldInfo = new FieldInfo(classInfo, name, desc);
-            classInfo.getFields().add(fieldInfo);
-
-            handler.visit(fieldInfo);
-
-            return new InfoBuildingVisitor(fieldInfo);
-        }
-
-        @Override
-        public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
-            final ClassInfo classInfo = ((ClassInfo) info);
-            final List<String> params = new ArrayList<String>();
-            org.objectweb.asm.commons.Method method = new org.objectweb.asm.commons.Method(name, desc);
-            for (Type type : method.getArgumentTypes()) {
-                params.add(type.getClassName());
-            }
-
-            MethodInfo methodInfo = new MethodInfo(classInfo, name, params);
-            classInfo.getMethods().add(methodInfo);
-
-            handler.visit(methodInfo);
-
-            return new InfoBuildingVisitor(methodInfo);
-        }
-
-
-        @Override
-        public AnnotationVisitor visitParameterAnnotation(int param, String desc, boolean visible) {
-            final MethodInfo methodInfo = ((MethodInfo) info);
-            final List<AnnotationInfo> annotationInfos = methodInfo.getParameterAnnotations(param);
-            final String name = Type.getType(desc).getClassName();
-            final AnnotationInfo annotationInfo = new AnnotationInfo(name);
-            annotationInfos.add(annotationInfo);
-            return new InfoBuildingVisitor(annotationInfo);
-        }
+        parser.parse(in);
     }
 }
\ No newline at end of file

Modified: commons/sandbox/classscan/branches/commons-finder/src/main/java/org/apache/commons/classscan/finder/model/InfoHandler.java
URL: http://svn.apache.org/viewvc/commons/sandbox/classscan/branches/commons-finder/src/main/java/org/apache/commons/classscan/finder/model/InfoHandler.java?rev=1346728&r1=1346727&r2=1346728&view=diff
==============================================================================
--- commons/sandbox/classscan/branches/commons-finder/src/main/java/org/apache/commons/classscan/finder/model/InfoHandler.java (original)
+++ commons/sandbox/classscan/branches/commons-finder/src/main/java/org/apache/commons/classscan/finder/model/InfoHandler.java Wed Jun  6 03:52:11 2012
@@ -16,6 +16,8 @@
  */
 package org.apache.commons.classscan.finder.model;
 
+import java.io.IOException;
+
 /**
  * @version $Rev$ $Date$
  */
@@ -26,4 +28,6 @@ public interface InfoHandler {
     public void visit(FieldInfo info);
     public void visit(PackageInfo info);
     public void visit(AnnotationInfo annotationInfo, Info info);
+
+    public void error(String className, Throwable throwable);
 }

Added: commons/sandbox/classscan/branches/commons-finder/src/main/java/org/apache/commons/classscan/finder/parse/AsmParser.java
URL: http://svn.apache.org/viewvc/commons/sandbox/classscan/branches/commons-finder/src/main/java/org/apache/commons/classscan/finder/parse/AsmParser.java?rev=1346728&view=auto
==============================================================================
--- commons/sandbox/classscan/branches/commons-finder/src/main/java/org/apache/commons/classscan/finder/parse/AsmParser.java (added)
+++ commons/sandbox/classscan/branches/commons-finder/src/main/java/org/apache/commons/classscan/finder/parse/AsmParser.java Wed Jun  6 03:52:11 2012
@@ -0,0 +1,173 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ *  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 org.apache.commons.classscan.finder.parse;
+
+import org.apache.commons.classscan.finder.archive.Archive;
+import org.apache.commons.classscan.finder.model.AnnotationInfo;
+import org.apache.commons.classscan.finder.model.ClassInfo;
+import org.apache.commons.classscan.finder.model.FieldInfo;
+import org.apache.commons.classscan.finder.model.Info;
+import org.apache.commons.classscan.finder.model.InfoHandler;
+import org.apache.commons.classscan.finder.model.MethodInfo;
+import org.apache.commons.classscan.finder.model.PackageInfo;
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.commons.EmptyVisitor;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+* @version $Rev$ $Date$
+*/
+public class AsmParser implements Parser {
+    private final InfoHandler handler;
+    private final Archive archive;
+
+    public AsmParser(InfoHandler handler, Archive archive) {
+        this.handler = handler;
+        this.archive = archive;
+    }
+
+    @Override
+    public void parse() {
+        for (Archive.Entry entry : archive) {
+            final String className = entry.getName();
+            try {
+                parse(entry.getBytecode());
+            } catch (NoClassDefFoundError e) {
+                throw new NoClassDefFoundError("Could not fully load class: " + className + "\n due to:" + e.getMessage());
+            } catch (IOException e) {
+                handler.error(entry.getName(), e);
+            }
+        }
+    }
+
+    @Override
+    public void parse(InputStream in) throws IOException {
+        try {
+            final ClassReader classReader = new ClassReader(in);
+            final int flags = ClassReader.SKIP_CODE + ClassReader.SKIP_DEBUG + ClassReader.SKIP_FRAMES;
+            classReader.accept(new InfoBuildingVisitor(), flags);
+        } finally {
+            in.close();
+        }
+    }
+
+    public  class InfoBuildingVisitor extends EmptyVisitor {
+
+        private Info info;
+
+        public InfoBuildingVisitor() {
+        }
+
+        public InfoBuildingVisitor(Info info) {
+            this.info = info;
+        }
+
+
+        @Override
+        public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
+            if (name.endsWith("package-info")) {
+                info = new PackageInfo(archive, javaName(name));
+                handler.visit((PackageInfo) info);
+            } else {
+
+                ClassInfo classInfo = new ClassInfo(archive, javaName(name), javaName(superName));
+
+                for (String interfce : interfaces) {
+                    classInfo.getInterfaces().add(javaName(interfce));
+                }
+
+                info = classInfo;
+
+                handler.visit((ClassInfo) info);
+            }
+        }
+
+        private String javaName(String name) {
+            return (name == null) ? null : name.replace('/', '.');
+        }
+
+        @Override
+        public void visitInnerClass(String name, String outerName, String innerName, int access) {
+            super.visitInnerClass(name, outerName, innerName, access);
+        }
+
+        @Override
+        public void visitAttribute(Attribute attribute) {
+            super.visitAttribute(attribute);
+        }
+
+        @Override
+        public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
+            final String name = Type.getType(desc).getClassName();
+            AnnotationInfo annotationInfo = new AnnotationInfo(name);
+            info.getAnnotations().add(annotationInfo);
+
+            handler.visit(annotationInfo, info);
+
+            return new InfoBuildingVisitor(annotationInfo);
+        }
+
+        @Override
+        public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {
+            ClassInfo classInfo = ((ClassInfo) info);
+            FieldInfo fieldInfo = new FieldInfo(classInfo, name, desc);
+            classInfo.getFields().add(fieldInfo);
+
+            handler.visit(fieldInfo);
+
+            return new InfoBuildingVisitor(fieldInfo);
+        }
+
+        @Override
+        public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
+            final ClassInfo classInfo = ((ClassInfo) info);
+            final List<String> params = new ArrayList<String>();
+            org.objectweb.asm.commons.Method method = new org.objectweb.asm.commons.Method(name, desc);
+            for (Type type : method.getArgumentTypes()) {
+                params.add(type.getClassName());
+            }
+
+            MethodInfo methodInfo = new MethodInfo(classInfo, name, params);
+            classInfo.getMethods().add(methodInfo);
+
+            handler.visit(methodInfo);
+
+            return new InfoBuildingVisitor(methodInfo);
+        }
+
+
+        @Override
+        public AnnotationVisitor visitParameterAnnotation(int param, String desc, boolean visible) {
+            final MethodInfo methodInfo = ((MethodInfo) info);
+            final List<AnnotationInfo> annotationInfos = methodInfo.getParameterAnnotations(param);
+            final String name = Type.getType(desc).getClassName();
+            final AnnotationInfo annotationInfo = new AnnotationInfo(name);
+            annotationInfos.add(annotationInfo);
+            return new InfoBuildingVisitor(annotationInfo);
+        }
+    }
+
+}

Added: commons/sandbox/classscan/branches/commons-finder/src/main/java/org/apache/commons/classscan/finder/parse/Parser.java
URL: http://svn.apache.org/viewvc/commons/sandbox/classscan/branches/commons-finder/src/main/java/org/apache/commons/classscan/finder/parse/Parser.java?rev=1346728&view=auto
==============================================================================
--- commons/sandbox/classscan/branches/commons-finder/src/main/java/org/apache/commons/classscan/finder/parse/Parser.java (added)
+++ commons/sandbox/classscan/branches/commons-finder/src/main/java/org/apache/commons/classscan/finder/parse/Parser.java Wed Jun  6 03:52:11 2012
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ *  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 org.apache.commons.classscan.finder.parse;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public interface Parser {
+    void parse();
+
+    void parse(InputStream in) throws IOException;
+}