/** * Constructs a new {@link org.objectweb.asm.ClassReader} object. * * @param is an input stream from which to read the class. * @throws IOException if a problem occurs during reading. */ public AnnotationClassReader(final InputStream is) throws IOException { this(readClass(is, false)); }
/** * Use when resources should have a standard base path. * * @param classLoader The class loader for loading resources * @param basePath The path to look for resources under */ public DefaultClassPathResourceLoader(ClassLoader classLoader, String basePath) { this.classLoader = classLoader; this.basePath = normalize(basePath); }
/** * Makes the given visitor visit the Java class of this {@link org.objectweb.asm.ClassReader} * . This class is the one specified in the constructor (see * {@link #AnnotationClassReader(byte[]) ClassReader}). * * @param classVisitor the visitor that must visit this class. * @param flags the class access flags */ public void accept(final ClassVisitor classVisitor, final int flags) { accept(classVisitor, new Attribute[0], flags); }
private void scanInputStream(String annotation, InputStream inputStream, List<Class> classes) throws IOException, ClassNotFoundException { AnnotationClassReader annotationClassReader = new AnnotationClassReader(inputStream); AnnotatedTypeInfoVisitor classVisitor = new AnnotatedTypeInfoVisitor(); annotationClassReader.accept(classVisitor, AnnotationClassReader.SKIP_DEBUG); if (classVisitor.hasAnnotation(annotation)) { classes.add(classLoader.loadClass(classVisitor.getTypeName())); } } }
/** * @param basePath The path to load resources * @return The resouce loader */ public ResourceLoader forBase(String basePath) { return new DefaultClassPathResourceLoader(classLoader, basePath); }
/** * Reads a class constant pool item in {@link #b b}. <i>This method is * intended for {@link Attribute} sub classes, and is normally not needed by * class generators or adapters.</i> * * @param index the start index of an unsigned short value in {@link #b b}, * whose value is the index of a class constant pool item. * @param buf buffer to be used to read the item. This buffer must be * sufficiently large. It is not automatically resized. * @return the String corresponding to the specified class item. */ public String readClass(final int index, final char[] buf) { // computes the start index of the CONSTANT_Class item in b // and reads the CONSTANT_Utf8 item designated by // the first two bytes of this CONSTANT_Class item return readUTF8(items[readUnsignedShort(index)], buf); }
/** * Returns the internal names of the class's interfaces (see * {@link Type#getInternalName() getInternalName}). * * @return the array of internal names for all implemented interfaces or * <tt>null</tt>. * @see ClassVisitor#visit(int, int, String, String, String, String[]) */ public String[] getInterfaces() { int index = header + 6; int n = readUnsignedShort(index); String[] interfaces = new String[n]; if (n > 0) { char[] buf = new char[maxStringLength]; for (int i = 0; i < n; ++i) { index += 2; interfaces[i] = readClass(index, buf); } } return interfaces; }
/** * Reads an UTF8 string constant pool item in {@link #b b}. <i>This method * is intended for {@link Attribute} sub classes, and is normally not needed * by class generators or adapters.</i> * * @param index the start index of an unsigned short value in {@link #b b}, * whose value is the index of an UTF8 constant pool item. * @param buf buffer to be used to read the item. This buffer must be * sufficiently large. It is not automatically resized. * @return the String corresponding to the specified UTF8 item. */ public String readUTF8(int index, final char[] buf) { int item = readUnsignedShort(index); if (index == 0 || item == 0) { return null; } String s = strings[item]; if (s != null) { return s; } index = items[item]; strings[item] = readUTF(index + 2, readUnsignedShort(index), buf); return strings[item]; }
/** * Returns the start index of the attribute_info structure of this class. * * @return the start index of the attribute_info structure of this class. */ private int getAttributes() { // skips the header int u = header + 8 + readUnsignedShort(header + 6) * 2; // skips fields and methods for (int i = readUnsignedShort(u); i > 0; --i) { for (int j = readUnsignedShort(u + 8); j > 0; --j) { u += 6 + readInt(u + 12); } u += 8; } u += 2; for (int i = readUnsignedShort(u); i > 0; --i) { for (int j = readUnsignedShort(u + 8); j > 0; --j) { u += 6 + readInt(u + 12); } u += 8; } // the attribute_info structure starts just after the methods return u + 2; }
/** * Scans the given package names. * * @param annotation The annotation to scan * @param packages The packages * @return A stream of classes */ default Stream<Class> scan(Class<? extends Annotation> annotation, Package... packages) { return scan(annotation.getName(), packages); }
/** * Returns the class's access flags (see {@link Opcodes}). This value may * not reflect Deprecated and Synthetic flags when bytecode is before 1.5 * and those flags are represented by attributes. * * @return the class access flags * @see ClassVisitor#visit(int, int, String, String, String, String[]) */ public int getAccess() { return readUnsignedShort(header); }
/** * Reads a signed long value in {@link #b b}. <i>This method is intended for * {@link Attribute} sub classes, and is normally not needed by class * generators or adapters.</i> * * @param index the start index of the value to be read in {@link #b b}. * @return the read value. */ public long readLong(final int index) { long l1 = readInt(index); long l0 = readInt(index + 4) & 0xFFFFFFFFL; return (l1 << 32) | l0; }
/** * Scans the given package names. * * @param annotation The annotation to scan * @param packages The package names * @return A stream of classes */ default Stream<Class> scan(Class<? extends Annotation> annotation, String... packages) { return scan(annotation.getName(), packages); } }
/** * Returns the internal name of the class (see * {@link Type#getInternalName() getInternalName}). * * @return the internal class name * @see ClassVisitor#visit(int, int, String, String, String, String[]) */ public String getClassName() { return readClass(header + 2, new char[maxStringLength]); }
/** * Scans the given package names. * * @param annotation The annotation name to scan * @param packages The package names * @return A stream of classes */ default Stream<Class> scan(String annotation, String... packages) { Stream<String> stream = Arrays.stream(packages); return scan(annotation, stream); }
/** * Returns the internal of name of the super class (see * {@link Type#getInternalName() getInternalName}). For interfaces, the * super class is {@link Object}. * * @return the internal name of super class, or <tt>null</tt> for * {@link Object} class. * @see ClassVisitor#visit(int, int, String, String, String, String[]) */ public String getSuperName() { return readClass(header + 4, new char[maxStringLength]); }
/** * Scans the given package names. * * @param annotation The annotation name to scan * @param packages The package names * @return A stream of classes */ default Stream<Class> scan(String annotation, Collection<String> packages) { return scan(annotation, packages.parallelStream()); }
/** * Scans the given package names. * * @param annotation The annotation name to scan * @param packages The package names * @return A stream of classes */ default Stream<Class> scan(String annotation, Stream<String> packages) { return packages .parallel() .flatMap(pkg -> scan(annotation, pkg)); }
/** * Scans the given package names. * * @param annotation The annotation name to scan * @param packages The package names * @return A stream of classes */ default Stream<Class> scan(Class<? extends Annotation> annotation, Collection<String> packages) { return scan(annotation.getName(), packages.parallelStream()); }