+ *
* A Java Class File consists of a stream of 8-bit bytes. All 16-bit, 32-bit, and 64-bit * quantities are constructed by reading in two, four, and eight consecutive 8-bit * bytes, respectively. Multi byte data items are always stored in big-endian order, * where the high bytes come first. In the Java platforms, this format is * supported by interfaces {@link java.io.DataInput} and {@link java.io.DataOutput}. - *+ *
* A class file consists of a single ClassFile structure: ** ClassFile { @@ -97,7 +84,7 @@ import org.slf4j.LoggerFactory; *
+ *
* Similar projects / libraries: *+ *
* All above mentioned projects make use of a byte code manipulation library (like BCEL, * ASM or Javassist). * * @author Ronald K. Muller * @since annotation-detector 3.0.0 */ -public final class AnnotationDetector implements Builder, Cursor { +public final +class AnnotationDetector implements Builder, Cursor { private static final org.slf4j.Logger LOG = LoggerFactory.getLogger(AnnotationDetector.class); - // Constant Pool type tags + // Constant Pool type ta gs private static final int CP_UTF8 = 1; private static final int CP_INTEGER = 3; private static final int CP_FLOAT = 4; @@ -180,18 +168,20 @@ public final class AnnotationDetector implements Builder, Cursor { // "(Ljava/lang/String;II)I" String, int, int as arguments, return type int private String methodDescriptor; - private AnnotationDetector(ClassLoader loader, final File[] filesOrDirectories, ClassIterator iterator, final String[] pkgNameFilter) { + private + AnnotationDetector(ClassLoader loader, final File[] filesOrDirectories, ClassIterator iterator, final String[] pkgNameFilter) { this.loader = loader; if (iterator == null) { this.cfIterator = new ClassFileIterator(filesOrDirectories, pkgNameFilter); if (filesOrDirectories.length == 0) { LOG.warn("No files or directories to scan!"); - } else if (LOG.isTraceEnabled()) { - LOG.trace("Files and root directories scanned:\n{}", - Arrays.toString(filesOrDirectories).replace(", ", "\n")); } - } else { + else if (LOG.isTraceEnabled()) { + LOG.trace("Files and root directories scanned:\n{}", Arrays.toString(filesOrDirectories).replace(", ", "\n")); + } + } + else { this.cfIterator = iterator; if (LOG.isTraceEnabled()) { @@ -206,8 +196,8 @@ public final class AnnotationDetector implements Builder, Cursor { * Only scan Class Files in the specified packages. If nothing is specified, all classes * on the class path are scanned. */ - public static Builder scanClassPath(final String... packageNames) - throws IOException { + public static + Builder scanClassPath(final String... packageNames) throws IOException { final ClassLoader loader = Thread.currentThread().getContextClassLoader(); return scanClassPath(loader, packageNames); @@ -218,8 +208,8 @@ public final class AnnotationDetector implements Builder, Cursor { * Only scan Class Files in the specified packages. If nothing is specified, all classes * on the class path are scanned. */ - public static Builder scanClassPath(ClassLoader loader, final String... packageNames) - throws IOException { + public static + Builder scanClassPath(ClassLoader loader, final String... packageNames) throws IOException { final String[] pkgNameFilter; @@ -259,7 +249,8 @@ public final class AnnotationDetector implements Builder, Cursor { } return new AnnotationDetector(loader, null, new CustomClassloaderIterator(fileNames, packageNames), pkgNameFilter); - } else { + } + else { final Set+ *
* Valid types are: *+ *
* Valid types are: *+ *
* If the Class File is stored as a single file in the file system the {@code File} * argument in {@link FilenameFilter#accept(java.io.File, java.lang.String) } is the * absolute path to the root directory scanned. - *+ *
* If the Class File is stored in a jar file the {@code File} argument in * {@link FilenameFilter#accept(java.io.File, java.lang.String)} is the absolute path of * the jar file. - *+ *
* The {@code String} argument is the full name of the ClassFile in native format, * including package name, like {@code eu/infomas/annotation/AnnotationDetector$1.class}. - *+ *
* Note that all non-Class Files are already filtered and not seen by the filter. * * @param filter The filter, never {@code null} diff --git a/src/dorkbox/util/annotation/ClassFileBuffer.java b/src/dorkbox/util/annotation/ClassFileBuffer.java index a678a17..b2b6bef 100644 --- a/src/dorkbox/util/annotation/ClassFileBuffer.java +++ b/src/dorkbox/util/annotation/ClassFileBuffer.java @@ -21,24 +21,21 @@ */ package dorkbox.util.annotation; -import java.io.DataInput; -import java.io.DataInputStream; -import java.io.EOFException; -import java.io.IOException; -import java.io.InputStream; +import java.io.*; /** * {@code ClassFileBuffer} is used by {@link AnnotationDetector} to efficiently read Java * ClassFile files from an {@link InputStream} and parse the content via the {@link DataInput} * interface. - *+ *
* Note that Java ClassFile files can grow really big, * {@code com.sun.corba.se.impl.logging.ORBUtilSystemException} is 128.2 kb! * * @author Ronald K. Muller * @since annotation-detector 3.0.0 */ -final class ClassFileBuffer implements DataInput { +final +class ClassFileBuffer implements DataInput { private byte[] buffer; private int size; // the number of significant bytes read @@ -70,7 +67,8 @@ final class ClassFileBuffer implements DataInput { * supplied byte stream. * The read pointer is reset to the start of the byte array. */ - public void readFrom(final InputStream in) throws IOException { + public + void readFrom(final InputStream in) throws IOException { this.pointer = 0; this.size = 0; int n; @@ -87,7 +85,8 @@ final class ClassFileBuffer implements DataInput { * Sets the file-pointer offset, measured from the beginning of this file, * at which the next read or write occurs. */ - public void seek(final int position) throws IOException { + public + void seek(final int position) throws IOException { if (position < 0) { throw new IllegalArgumentException("position < 0: " + position); } @@ -100,20 +99,22 @@ final class ClassFileBuffer implements DataInput { /** * Return the size (in bytes) of this Java ClassFile file. */ - public int size() { + public + int size() { return this.size; } // DataInput @Override - public void readFully(final byte[] bytes) throws IOException { + public + void readFully(final byte[] bytes) throws IOException { readFully(bytes, 0, bytes.length); } @Override - public void readFully(final byte[] bytes, final int offset, final int length) - throws IOException { + public + void readFully(final byte[] bytes, final int offset, final int length) throws IOException { if (length < 0 || offset < 0 || offset + length > bytes.length) { throw new IndexOutOfBoundsException(); @@ -126,13 +127,15 @@ final class ClassFileBuffer implements DataInput { } @Override - public int skipBytes(final int n) throws IOException { + public + int skipBytes(final int n) throws IOException { seek(this.pointer + n); return n; } @Override - public byte readByte() throws IOException { + public + byte readByte() throws IOException { if (this.pointer >= this.size) { throw new EOFException(); } @@ -140,12 +143,14 @@ final class ClassFileBuffer implements DataInput { } @Override - public boolean readBoolean() throws IOException { + public + boolean readBoolean() throws IOException { return readByte() != 0; } @Override - public int readUnsignedByte() throws IOException { + public + int readUnsignedByte() throws IOException { if (this.pointer >= this.size) { throw new EOFException(); } @@ -153,7 +158,8 @@ final class ClassFileBuffer implements DataInput { } @Override - public int readUnsignedShort() throws IOException { + public + int readUnsignedShort() throws IOException { if (this.pointer + 2 > this.size) { throw new EOFException(); } @@ -161,48 +167,54 @@ final class ClassFileBuffer implements DataInput { } @Override - public short readShort() throws IOException { - return (short)readUnsignedShort(); + public + short readShort() throws IOException { + return (short) readUnsignedShort(); } @Override - public char readChar() throws IOException { - return (char)readUnsignedShort(); + public + char readChar() throws IOException { + return (char) readUnsignedShort(); } @Override - public int readInt() throws IOException { + public + int readInt() throws IOException { if (this.pointer + 4 > this.size) { throw new EOFException(); } return (read() << 24) + - (read() << 16) + - (read() << 8) + - read(); + (read() << 16) + + (read() << 8) + + read(); } @Override - public long readLong() throws IOException { + public + long readLong() throws IOException { if (this.pointer + 8 > this.size) { throw new EOFException(); } - return ((long)read() << 56) + - ((long)read() << 48) + - ((long)read() << 40) + - ((long)read() << 32) + - (read() << 24) + - (read() << 16) + - (read() << 8) + - read(); + return ((long) read() << 56) + + ((long) read() << 48) + + ((long) read() << 40) + + ((long) read() << 32) + + (read() << 24) + + (read() << 16) + + (read() << 8) + + read(); } @Override - public float readFloat() throws IOException { + public + float readFloat() throws IOException { return Float.intBitsToFloat(readInt()); } @Override - public double readDouble() throws IOException { + public + double readDouble() throws IOException { return Double.longBitsToDouble(readLong()); } @@ -214,22 +226,26 @@ final class ClassFileBuffer implements DataInput { */ @Override @Deprecated - public String readLine() throws IOException { + public + String readLine() throws IOException { throw new UnsupportedOperationException("readLine() is deprecated and not supported"); } @Override - public String readUTF() throws IOException { + public + String readUTF() throws IOException { return DataInputStream.readUTF(this); } // private - private int read() { + private + int read() { return this.buffer[this.pointer++] & 0xff; } - private void resizeIfNeeded() { + private + void resizeIfNeeded() { if (this.size >= this.buffer.length) { final byte[] newBuffer = new byte[this.buffer.length * 2]; System.arraycopy(this.buffer, 0, newBuffer, 0, this.buffer.length); diff --git a/src/dorkbox/util/annotation/ClassFileIterator.java b/src/dorkbox/util/annotation/ClassFileIterator.java index 5f2641b..24fc147 100644 --- a/src/dorkbox/util/annotation/ClassFileIterator.java +++ b/src/dorkbox/util/annotation/ClassFileIterator.java @@ -21,22 +21,19 @@ */ package dorkbox.util.annotation; -import java.io.File; -import java.io.FileInputStream; -import java.io.FilenameFilter; -import java.io.IOException; -import java.io.InputStream; +import java.io.*; /** * {@code ClassFileIterator} is used to iterate over all Java ClassFile files available within * a specific context. - *+ *
* For every Java ClassFile ({@code .class}) an {@link InputStream} is returned. * * @author Ronald K. Muller * @since annotation-detector 3.0.0 */ -public class ClassFileIterator implements ClassIterator { +public +class ClassFileIterator implements ClassIterator { private FileIterator fileIter; protected final String[] pkgNameFilter; @@ -47,24 +44,26 @@ public class ClassFileIterator implements ClassIterator { /** * Create a new {@code ClassFileIterator} returning all Java ClassFile files available * from the specified files and/or directories, including sub directories. - *+ *
* If the (optional) package filter is defined, only class files staring with one of the * defined package names are returned. * NOTE: package names must be defined in the native format (using '/' instead of '.'). */ - protected ClassFileIterator(final String[] pkgNameFilter) { + protected + ClassFileIterator(final String[] pkgNameFilter) { this.pkgNameFilter = pkgNameFilter; } /** * Create a new {@code ClassFileIterator} returning all Java ClassFile files available * from the specified files and/or directories, including sub directories. - *+ *
* If the (optional) package filter is defined, only class files staring with one of the * defined package names are returned. * NOTE: package names must be defined in the native format (using '/' instead of '.'). */ - protected ClassFileIterator(final File[] filesOrDirectories, final String[] pkgNameFilter) { + protected + ClassFileIterator(final File[] filesOrDirectories, final String[] pkgNameFilter) { this.fileIter = new FileIterator(filesOrDirectories); this.pkgNameFilter = pkgNameFilter; } @@ -74,11 +73,10 @@ public class ClassFileIterator implements ClassIterator { * The name is either the path name of a file or the name of an ZIP/JAR file entry. */ @Override - public String getName() { + public + String getName() { // Both getPath() and getName() are very light weight method calls - return this.zipIter == null ? - this.fileIter.getFile().getPath() : - this.zipIter.getEntry().getName(); + return this.zipIter == null ? this.fileIter.getFile().getPath() : this.zipIter.getEntry().getName(); } /** @@ -88,37 +86,43 @@ public class ClassFileIterator implements ClassIterator { * ZIP File Entry. */ @Override - public boolean isFile() { + public + boolean isFile() { return this.isFile; } /** * Return the next Java ClassFile as an {@code InputStream}. - *+ *
* NOTICE: Client code MUST close the returned {@code InputStream}! */ @Override - public InputStream next(final FilenameFilter filter) throws IOException { + public + InputStream next(final FilenameFilter filter) throws IOException { while (true) { if (this.zipIter == null) { final File file = this.fileIter.next(); if (file == null) { return null; - } else { + } + else { final String path = file.getPath(); - if (path.endsWith(".class") && (filter == null || - filter.accept(this.fileIter.getRootFile(), this.fileIter.relativize(path)))) { + if (path.endsWith(".class") && (filter == null || filter.accept(this.fileIter.getRootFile(), this.fileIter.relativize( + path)))) { this.isFile = true; return new FileInputStream(file); - } else if (this.fileIter.isRootFile() && endsWithIgnoreCase(path, ".jar")) { + } + else if (this.fileIter.isRootFile() && endsWithIgnoreCase(path, ".jar")) { this.zipIter = new ZipFileIterator(file, this.pkgNameFilter); } // else just ignore } - } else { + } + else { final InputStream is = this.zipIter.next(filter); if (is == null) { this.zipIter = null; - } else { + } + else { this.isFile = false; return is; } @@ -128,7 +132,8 @@ public class ClassFileIterator implements ClassIterator { // private - private static boolean endsWithIgnoreCase(final String value, final String suffix) { + private static + boolean endsWithIgnoreCase(final String value, final String suffix) { final int n = suffix.length(); return value.regionMatches(true, value.length() - n, suffix, 0, n); } diff --git a/src/dorkbox/util/annotation/ClassIterator.java b/src/dorkbox/util/annotation/ClassIterator.java index 36aea69..ae18eb3 100644 --- a/src/dorkbox/util/annotation/ClassIterator.java +++ b/src/dorkbox/util/annotation/ClassIterator.java @@ -31,13 +31,14 @@ import java.io.InputStream; /** * {@code ClassFileIterator} is used to iterate over all Java ClassFile files available within * a specific context. - *+ *
* For every Java ClassFile ({@code .class}) an {@link InputStream} is returned. * * @author Ronald K. Muller * @since annotation-detector 3.0.0 */ -public interface ClassIterator { +public +interface ClassIterator { /** * Return the name of the Java ClassFile returned from the last call to {@link #next()}. @@ -55,7 +56,7 @@ public interface ClassIterator { /** * Return the next Java ClassFile as an {@code InputStream}. - *+ *
* NOTICE: Client code MUST close the returned {@code InputStream}! */ InputStream next(final FilenameFilter filter) throws IOException; diff --git a/src/dorkbox/util/annotation/Cursor.java b/src/dorkbox/util/annotation/Cursor.java index acaa969..48606fb 100644 --- a/src/dorkbox/util/annotation/Cursor.java +++ b/src/dorkbox/util/annotation/Cursor.java @@ -33,7 +33,8 @@ import java.lang.reflect.Method; * @author Ronald K. Muller * @since annotation-detector 3.1.0 */ -public interface Cursor { +public +interface Cursor { /** * Return the type name of the currently reported Java Class File. diff --git a/src/dorkbox/util/annotation/CustomClassloaderIterator.java b/src/dorkbox/util/annotation/CustomClassloaderIterator.java index af54ca1..e60d338 100644 --- a/src/dorkbox/util/annotation/CustomClassloaderIterator.java +++ b/src/dorkbox/util/annotation/CustomClassloaderIterator.java @@ -15,6 +15,8 @@ */ package dorkbox.util.annotation; +import dorkbox.util.FileUtil; + import java.io.File; import java.io.FilenameFilter; import java.io.IOException; @@ -26,17 +28,17 @@ import java.util.Iterator; import java.util.List; import java.util.Set; -import dorkbox.util.FileUtil; +public +class CustomClassloaderIterator implements ClassIterator { -public class CustomClassloaderIterator implements ClassIterator { - - private volatile Iterator+ *
* Usage: ** FileIterator iter = new FileIterator(new File("./src")); @@ -43,7 +43,8 @@ import java.util.NoSuchElementException; * @author Ronald K. Muller * @since annotation-detector 3.0.0 */ -final class FileIterator { +final +class FileIterator { private final Dequestack = new LinkedList (); private int rootCount; @@ -52,13 +53,13 @@ final class FileIterator { /** * Create a new {@code FileIterator} using the specified 'filesOrDirectories' as root. - * + *
* If 'filesOrDirectories' contains a file, the iterator just returns that single file. * If 'filesOrDirectories' contains a directory, all files in that directory * and its sub directories are returned (depth first). * * @param filesOrDirectories Zero or more {@link File} objects, which are iterated - * in the specified order (depth first) + * in the specified order (depth first) */ FileIterator(final File... filesOrDirectories) { addReverse(filesOrDirectories); @@ -80,12 +81,12 @@ final class FileIterator { /** * Relativize the absolute full (file) 'path' against the current root file. - *+ *
* Example:
* Let current root be "/path/to/dir". * Then {@code relativize("/path/to/dir/with/file.ext")} equals "with/file.ext" (without * leading '/'). - *+ *
* Note: the paths are not canonicalized! */ String relativize(final String path) { @@ -115,7 +116,8 @@ final class FileIterator { if (this.stack.isEmpty()) { this.current = null; return null; - } else { + } + else { this.current = this.stack.removeLast(); if (this.current.isDirectory()) { if (this.stack.size() < this.rootCount) { @@ -124,7 +126,8 @@ final class FileIterator { } addReverse(this.current.listFiles()); return next(); - } else { + } + else { return this.current; } } @@ -135,7 +138,8 @@ final class FileIterator { /** * Add the specified files in reverse order. */ - private void addReverse(final File[] files) { + private + void addReverse(final File[] files) { for (int i = files.length - 1; i >= 0; --i) { this.stack.add(files[i]); } diff --git a/src/dorkbox/util/annotation/Reporter.java b/src/dorkbox/util/annotation/Reporter.java index a737b74..e7715de 100644 --- a/src/dorkbox/util/annotation/Reporter.java +++ b/src/dorkbox/util/annotation/Reporter.java @@ -24,22 +24,21 @@ package dorkbox.util.annotation; /** * {@code Reporter} is used to report the detected annotations. - *+ *
* This interface is a so called "Single Abstract Method" (SAM) or "Functional Interface", so * can be used as a Lambda in Java 8 (see examples). * - * @see Builder#report(dorkbox.util.annotation.Reporter) - * * @author Ronald K. Muller + * @see Builder#report(dorkbox.util.annotation.Reporter) * @since annotation-detector 3.1.0 */ -public interface Reporter { +public +interface Reporter { /** * This method is called when an {@code Annotation} is detected. Invoke methods on the * provided {@code Cursor} reference to get more specific information about the * {@code Annotation}. - * */ void report(Cursor cursor); diff --git a/src/dorkbox/util/annotation/ReporterFunction.java b/src/dorkbox/util/annotation/ReporterFunction.java index 5261fdc..de41955 100644 --- a/src/dorkbox/util/annotation/ReporterFunction.java +++ b/src/dorkbox/util/annotation/ReporterFunction.java @@ -24,12 +24,12 @@ package dorkbox.util.annotation; /** * {@code ReporterFunction} is used to report the detected annotations. * - * @see Builder#collect(dorkbox.util.annotation.ReporterFunction) - * * @author Ronald K. Muller + * @see Builder#collect(dorkbox.util.annotation.ReporterFunction) * @since annotation-detector 3.1.0 */ -public interface ReporterFunction{ +public +interface ReporterFunction { /** * This method is called when an {@code Annotation} is detected. diff --git a/src/dorkbox/util/annotation/ZipFileIterator.java b/src/dorkbox/util/annotation/ZipFileIterator.java index 98eccbc..9bb355e 100644 --- a/src/dorkbox/util/annotation/ZipFileIterator.java +++ b/src/dorkbox/util/annotation/ZipFileIterator.java @@ -32,15 +32,16 @@ import java.util.zip.ZipFile; /** * {@code ZipFileIterator} is used to iterate over all entries in a given {@code zip} or * {@code jar} file and returning the {@link InputStream} of these entries. - * + *
* It is possible to specify an (optional) entry name filter. - *+ *
* The most efficient way of iterating is used, see benchmark in test classes. * * @author Ronald K. Muller * @since annotation-detector 3.0.0 */ -final class ZipFileIterator { +final +class ZipFileIterator { private final File file; private final ZipFile zipFile; @@ -52,9 +53,9 @@ final class ZipFileIterator { /** * Create a new {@code ZipFileIterator} instance. * - * @param zipFile The ZIP file used to iterate over all entries + * @param zipFile The ZIP file used to iterate over all entries * @param entryNameFilter (optional) file name filter. Only entry names starting with - * one of the specified names in the filter are returned + * one of the specified names in the filter are returned */ ZipFileIterator(final File file, final String[] entryNameFilter) throws IOException { this.file = file; @@ -64,11 +65,13 @@ final class ZipFileIterator { this.entries = this.zipFile.entries(); } - public ZipEntry getEntry() { + public + ZipEntry getEntry() { return this.current; } - public InputStream next(final FilenameFilter filter) throws IOException { + public + InputStream next(final FilenameFilter filter) throws IOException { while (this.entries.hasMoreElements()) { this.current = this.entries.nextElement(); if (filter == null || accept(this.current, filter)) { @@ -85,7 +88,8 @@ final class ZipFileIterator { return null; } - private boolean accept(final ZipEntry entry, final FilenameFilter filter) { + private + boolean accept(final ZipEntry entry, final FilenameFilter filter) { if (entry.isDirectory()) { return false; }