X-Git-Url: https://juplo.de/gitweb/?p=scannotation;a=blobdiff_plain;f=src%2Fmain%2Fjava%2Forg%2Fscannotation%2FAnnotationDB.java;h=bf27515e32448ade0497c9698843b24f03aee84e;hp=92e28c68a8bfdb42c576965859f34f9004f4401f;hb=a63b5346cc43457b0efccb238f15367f36244291;hpb=6f8bc0038ccf20fceaf363d36c22b731e0a998e3 diff --git a/src/main/java/org/scannotation/AnnotationDB.java b/src/main/java/org/scannotation/AnnotationDB.java index 92e28c6..bf27515 100644 --- a/src/main/java/org/scannotation/AnnotationDB.java +++ b/src/main/java/org/scannotation/AnnotationDB.java @@ -28,11 +28,11 @@ import java.util.Set; * The class allows you to scan an arbitrary set of "archives" for .class files. These class files * are parsed to see what annotations they use. Two indexes are created. The javax, java, sun, com.sun, and javassist * packages will not be scanned by default. - * + *

* One is a map of annotations and what classes * use those annotations. This could be used, for example, by an EJB deployer to find all the EJBs contained * in the archive - * + *

* Another is a mpa of classes and what annotations those classes use. * * @author Bill Burke @@ -49,6 +49,8 @@ public class AnnotationDB implements Serializable protected transient boolean scanParameterAnnotations = true; protected transient boolean scanFieldAnnotations = true; protected transient String[] ignoredPackages = {"javax", "java", "sun", "com.sun", "javassist"}; + protected transient String[] scanPackages = null; + protected transient boolean ignoreBadURLs = false; public class CrossReferenceException extends Exception { @@ -65,6 +67,22 @@ public class AnnotationDB implements Serializable } } + public String[] getScanPackages() + { + return scanPackages; + } + + /** + * Set explicit packages to scan. + * Set to null to enable ignore list. + * + * @param scanPackages packages to scan or null + */ + public void setScanPackages(String[] scanPackages) + { + this.scanPackages = scanPackages; + } + public String[] getIgnoredPackages() { return ignoredPackages; @@ -86,22 +104,22 @@ public class AnnotationDB implements Serializable int i = 0; for (String ign : ignoredPackages) tmp[i++] = ign; for (String ign : ignored) tmp[i++] = ign; + this.ignoredPackages = tmp; } /** * This method will cross reference annotations in the annotation index with any meta-annotations that they have * and create additional entries as needed. For example: * - * @HttpMethod("GET") - * public @interface GET {} - * + *

+    * @ HttpMethod("GET") public @interface GET {}
+    * 
+ *

* The HttpMethod index will have additional classes added to it for any classes annotated with annotations that * have the HttpMethod meta-annotation. - * + *

* WARNING: If the annotation class has not already been scaned, this method will load all annotation classes indexed - * as a resource so they must be in your classpath - * - * + * as a resource so they must be in your classpath */ public void crossReferenceMetaAnnotations() throws CrossReferenceException { @@ -142,7 +160,7 @@ public class AnnotationDB implements Serializable { annotationIndex.get(xref).addAll(annotationIndex.get(annotation)); } - + } if (unresolved.size() > 0) throw new CrossReferenceException(unresolved); } @@ -153,7 +171,6 @@ public class AnnotationDB implements Serializable * a class's implemented interfaces. The cross references will be added to the annotationIndex and * classIndex indexes * - * @param ignoredPackages var arg list of packages to ignore * @throws CrossReferenceException an Exception thrown if referenced interfaces haven't been scanned */ public void crossReferenceImplementedInterfaces() throws CrossReferenceException @@ -171,12 +188,19 @@ public class AnnotationDB implements Serializable { unresolved.add(intf); } - Set classAnnotations = classIndex.get(clazz); - classAnnotations.addAll(xrefAnnotations); - for (String annotation : xrefAnnotations) + else { - Set classes = annotationIndex.get(annotation); - classes.add(clazz); + Set classAnnotations = classIndex.get(clazz); + if (classAnnotations == null) + { + classIndex.put(clazz, xrefAnnotations); + } + else classAnnotations.addAll(xrefAnnotations); + for (String annotation : xrefAnnotations) + { + Set classes = annotationIndex.get(annotation); + classes.add(clazz); + } } } } @@ -186,11 +210,23 @@ public class AnnotationDB implements Serializable private boolean ignoreScan(String intf) { + if (scanPackages != null) + { + for (String scan : scanPackages) + { + // do not ignore if on packages to scan list + if (intf.startsWith(scan + ".")) + { + return false; + } + } + return true; // didn't match whitelist, ignore + } for (String ignored : ignoredPackages) { if (intf.startsWith(ignored + ".")) { - return true; + return true; } else { @@ -203,7 +239,6 @@ public class AnnotationDB implements Serializable /** * returns a map keyed by the fully qualified string name of a annotation class. The Set returne is * a list of classes that use that annotation somehow. - * */ public Map> getAnnotationIndex() { @@ -213,7 +248,6 @@ public class AnnotationDB implements Serializable /** * returns a map keyed by the list of classes scanned. The value set returned is a list of annotations * used by that class. - * */ public Map> getClassIndex() { @@ -261,9 +295,18 @@ public class AnnotationDB implements Serializable this.scanFieldAnnotations = scanFieldAnnotations; } - - - /** + /** + * Whether or not you want AnnotationDB to ignore bad URLs passed to scanArchives. + * Default is to throw an IOException. + * + * @param ignoreBadURLs + */ + public void setIgnoreBadURLs(boolean ignoreBadURLs) + { + this.ignoreBadURLs = ignoreBadURLs; + } + + /** * Scan a url that represents an "archive" this is a classpath directory or jar file * * @param urls variable list of URLs to scan as archives @@ -279,18 +322,30 @@ public class AnnotationDB implements Serializable { if (filename.endsWith(".class")) { - if (filename.startsWith("/")) filename = filename.substring(1); - if (!ignoreScan(filename.replace('/', '.'))) return true; + if (filename.startsWith("/") || filename.startsWith("\\")) + filename = filename.substring(1); + if (!ignoreScan(filename.replace('/', '.'))) + return true; //System.out.println("IGNORED: " + filename); } return false; } }; - StreamIterator it = IteratorFactory.create(url, filter); - - InputStream stream; - while ((stream = it.next()) != null) scanClass(stream); + try + { + StreamIterator it = IteratorFactory.create(url, filter); + + InputStream stream; + while ((stream = it.next()) != null) scanClass(stream); + } + catch (IOException e) + { + if (ignoreBadURLs) + continue; + else + throw e; + } } } @@ -309,8 +364,8 @@ public class AnnotationDB implements Serializable { cf = new ClassFile(dstream); classIndex.put(cf.getName(), new HashSet()); - if (scanClassAnnotations) ; - scanClass(cf); + if (scanClassAnnotations) + scanClass(cf); if (scanMethodAnnotations || scanParameterAnnotations) scanMethods(cf); if (scanFieldAnnotations) scanFields(cf);