* 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 and Java 2 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 { * u4 magic; * u2 minor_version; * u2 major_version; * u2 constant_pool_count; * cp_info constant_pool[constant_pool_count-1]; * u2 access_flags; * u2 this_class; * u2 super_class; * u2 interfaces_count; * u2 interfaces[interfaces_count]; * u2 fields_count; * field_info fields[fields_count]; * u2 methods_count; * method_info methods[methods_count]; * u2 attributes_count; * attribute_info attributes[attributes_count]; * } * * Where: * u1 unsigned byte {@link java.io.DataInput#readUnsignedByte()} * u2 unsigned short {@link java.io.DataInput#readUnsignedShort()} * u4 unsigned int {@link java.io.DataInput#readInt()} * * Annotations are stored as Attributes (i.e. "RuntimeVisibleAnnotations" and * "RuntimeInvisibleAnnotations"). ** References: *
* 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 {
/**
* {@code Reporter} is the base interface, used to report the detected annotations.
* Every category of annotations (i.e. Type, Field and Method) has its own specialized
* interface. This enables an efficient way of reporting the detected annotations.
*/
public interface Reporter {
/**
* Return the {@code Annotation} classes which must be reported (all other
* annotations are skipped).
*/
Class extends Annotation>[] annotations();
}
/**
* A {@code Reporter} for type annotations.
*/
public interface TypeReporter extends Reporter {
/**
* This call back method is used to report an type level {@code Annotation}.
* Only {@code Annotation}s, specified by {@link #annotations()} are reported!
*/
void reportTypeAnnotation(Class extends Annotation> annotation, String className);
}
/**
* A {@code Reporter} for field annotations.
*/
public interface FieldReporter extends Reporter {
/**
* This call back method is used to report an field level {@code Annotation}.
* Only {@code Annotation}s, specified by {@link #annotations()} are reported!
*/
void reportFieldAnnotation(Class extends Annotation> annotation, String className,
String fieldName);
}
/**
* A {@code Reporter} for method annotations.
*/
public interface MethodReporter extends Reporter {
/**
* This call back method is used to report an method level {@code Annotation}.
* Only {@code Annotation}s, specified by {@link #annotations()} are reported!
*/
void reportMethodAnnotation(Class extends Annotation> annotation, String className,
String methodName);
}
// Only used during development. If set to "true" debug messages are displayed.
private static final boolean DEBUG = false;
// Constant Pool type tags
private static final int CP_UTF8 = 1;
private static final int CP_INTEGER = 3;
private static final int CP_FLOAT = 4;
private static final int CP_LONG = 5;
private static final int CP_DOUBLE = 6;
private static final int CP_CLASS = 7;
private static final int CP_STRING = 8;
private static final int CP_REF_FIELD = 9;
private static final int CP_REF_METHOD = 10;
private static final int CP_REF_INTERFACE = 11;
private static final int CP_NAME_AND_TYPE = 12;
private static final int CP_METHOD_HANDLE = 15;
private static final int CP_METHOD_TYPE = 16;
private static final int CP_INVOKE_DYNAMIC = 18;
// AnnotationElementValue
private static final int BYTE = 'B';
private static final int CHAR = 'C';
private static final int DOUBLE = 'D';
private static final int FLOAT = 'F';
private static final int INT = 'I';
private static final int LONG = 'J';
private static final int SHORT = 'S';
private static final int BOOLEAN = 'Z';
// used for AnnotationElement only
private static final int STRING = 's';
private static final int ENUM = 'e';
private static final int CLASS = 'c';
private static final int ANNOTATION = '@';
private static final int ARRAY = '[';
// The buffer is reused during the life cycle of this AnnotationDetector instance
private final ClassFileBuffer cpBuffer = new ClassFileBuffer();
// the annotation types to report, see {@link #annotations()}
private final Map
* In Java, the
*
* Class path contains directories (top level directory as package root) and/or
* jar files (including zip files).
*
* Note that non-class files (files, not starting with the magic number
* {@code CAFEBABE} are silently ignored.
*
* @param filesOrDirectories Valid files are: jar files, Java *.class files (all other
* files are silently ignored) and directories which are package root directories
*/
public void detect(final File... filesOrDirectories) throws IOException {
if (DEBUG) {
print("detectFilesOrDirectories: %s", (Object)filesOrDirectories);
}
detect(new ClassFileIterator(filesOrDirectories, null));
}
// private
private File toFile(final URL url) {
// only correct way to convert the URL to a File object, also see issue #16
// Do not use URLDecoder
try {
return new File(url.toURI().getPath());
} catch (URISyntaxException ex) {
// we do not expect an URISyntaxException here
throw new AssertionError("Unable to convert URI to File: " + url);
}
}
@SuppressWarnings("illegalcatch")
private void detect(final ResourceIterator iterator) throws IOException {
InputStream stream;
while ((stream = iterator.next()) != null) {
try {
cpBuffer.readFrom(stream);
if (hasCafebabe(cpBuffer)) {
detect(cpBuffer);
} // else ignore
} catch (Throwable t) {
// catch all errors
if (!(stream instanceof FileInputStream)) {
// in case of an error we close the ZIP File here
stream.close();
}
} finally {
// closing InputStream from ZIP Entry is handled by ZipFileIterator
if (stream instanceof FileInputStream) {
stream.close();
}
}
}
}
private boolean hasCafebabe(final ClassFileBuffer buffer) throws IOException {
return buffer.size() > 4 && buffer.readInt() == 0xCAFEBABE;
}
/**
* Inspect the given (Java) class file in streaming mode.
*/
private void detect(final DataInput di) throws IOException {
readVersion(di);
readConstantPoolEntries(di);
readAccessFlags(di);
readThisClass(di);
readSuperClass(di);
readInterfaces(di);
readFields(di);
readMethods(di);
readAttributes(di, 'T', typeReporter == null);
}
private void readVersion(final DataInput di) throws IOException {
// sequence: minor version, major version (argument_index is 1-based)
if (DEBUG) {
print("Java Class version %2$d.%1$d",
di.readUnsignedShort(), di.readUnsignedShort());
} else {
di.skipBytes(4);
}
}
private void readConstantPoolEntries(final DataInput di) throws IOException {
final int count = di.readUnsignedShort();
constantPool = new Object[count];
for (int i = 1; i < count; ++i) {
if (readConstantPoolEntry(di, i)) {
// double slot
++i;
}
}
}
/**
* Return {@code true} if a double slot is read (in case of Double or Long constant).
*/
private boolean readConstantPoolEntry(final DataInput di, final int index)
throws IOException {
final int tag = di.readUnsignedByte();
switch (tag) {
case CP_METHOD_TYPE:
di.skipBytes(2); // readUnsignedShort()
return false;
case CP_METHOD_HANDLE:
di.skipBytes(3);
return false;
case CP_INTEGER:
case CP_FLOAT:
case CP_REF_FIELD:
case CP_REF_METHOD:
case CP_REF_INTERFACE:
case CP_NAME_AND_TYPE:
case CP_INVOKE_DYNAMIC:
di.skipBytes(4); // readInt() / readFloat() / readUnsignedShort() * 2
return false;
case CP_LONG:
case CP_DOUBLE:
di.skipBytes(8); // readLong() / readDouble()
return true;
case CP_UTF8:
constantPool[index] = di.readUTF();
return false;
case CP_CLASS:
case CP_STRING:
// reference to CP_UTF8 entry. The referenced index can have a higher number!
constantPool[index] = di.readUnsignedShort();
return false;
default:
throw new ClassFormatError(
"Unkown tag value for constant pool entry: " + tag);
}
}
private void readAccessFlags(final DataInput di) throws IOException {
di.skipBytes(2); // u2
}
private void readThisClass(final DataInput di) throws IOException {
typeName = resolveUtf8(di);
if (DEBUG) {
print("read type '%s'", typeName);
}
}
private void readSuperClass(final DataInput di) throws IOException {
di.skipBytes(2); // u2
}
private void readInterfaces(final DataInput di) throws IOException {
final int count = di.readUnsignedShort();
di.skipBytes(count * 2); // count * u2
}
private void readFields(final DataInput di) throws IOException {
final int count = di.readUnsignedShort();
if (DEBUG) {
print("field count = %d", count);
}
for (int i = 0; i < count; ++i) {
readAccessFlags(di);
memberName = resolveUtf8(di);
final String descriptor = resolveUtf8(di);
readAttributes(di, 'F', fieldReporter == null);
if (DEBUG) {
print("Field: %s, descriptor: %s", memberName, descriptor);
}
}
}
private void readMethods(final DataInput di) throws IOException {
final int count = di.readUnsignedShort();
if (DEBUG) {
print("method count = %d", count);
}
for (int i = 0; i < count; ++i) {
readAccessFlags(di);
memberName = resolveUtf8(di);
final String descriptor = resolveUtf8(di);
readAttributes(di, 'M', methodReporter == null);
if (DEBUG) {
print("Method: %s, descriptor: %s", memberName, descriptor);
}
}
}
private void readAttributes(final DataInput di, final char reporterType,
final boolean skipReporting) throws IOException {
final int count = di.readUnsignedShort();
if (DEBUG) {
print("attribute count (%s) = %d", reporterType, count);
}
for (int i = 0; i < count; ++i) {
final String name = resolveUtf8(di);
// in bytes, use this to skip the attribute info block
final int length = di.readInt();
if (!skipReporting &&
("RuntimeVisibleAnnotations".equals(name) ||
"RuntimeInvisibleAnnotations".equals(name))) {
readAnnotations(di, reporterType);
} else {
if (DEBUG) {
print("skip attribute %s", name);
}
di.skipBytes(length);
}
}
}
private void readAnnotations(final DataInput di, final char reporterType)
throws IOException {
// the number of Runtime(In)VisibleAnnotations
final int count = di.readUnsignedShort();
if (DEBUG) {
print("annotation count (%s) = %d", reporterType, count);
}
for (int i = 0; i < count; ++i) {
final String rawTypeName = readAnnotation(di);
final Class extends Annotation> type = annotations.get(rawTypeName);
if (type == null) {
continue;
}
final String externalTypeName = typeName.replace('/', '.');
switch (reporterType) {
case 'T':
typeReporter.reportTypeAnnotation(type, externalTypeName);
break;
case 'F':
fieldReporter.reportFieldAnnotation(type, externalTypeName, memberName);
break;
case 'M':
methodReporter.reportMethodAnnotation(type, externalTypeName, memberName);
break;
default:
throw new AssertionError("reporterType=" + reporterType);
}
}
}
private String readAnnotation(final DataInput di) throws IOException {
final String rawTypeName = resolveUtf8(di);
// num_element_value_pairs
final int count = di.readUnsignedShort();
if (DEBUG) {
print("annotation elements count: %d", count);
}
for (int i = 0; i < count; ++i) {
if (DEBUG) {
print("element '%s'", resolveUtf8(di));
} else {
di.skipBytes(2);
}
readAnnotationElementValue(di);
}
return rawTypeName;
}
private void readAnnotationElementValue(final DataInput di) throws IOException {
final int tag = di.readUnsignedByte();
if (DEBUG) {
print("tag='%c'", (char)tag);
}
switch (tag) {
case BYTE:
case CHAR:
case DOUBLE:
case FLOAT:
case INT:
case LONG:
case SHORT:
case BOOLEAN:
case STRING:
di.skipBytes(2);
break;
case ENUM:
di.skipBytes(4); // 2 * u2
break;
case CLASS:
di.skipBytes(2);
break;
case ANNOTATION:
readAnnotation(di);
break;
case ARRAY:
final int count = di.readUnsignedShort();
for (int i = 0; i < count; ++i) {
readAnnotationElementValue(di);
}
break;
default:
throw new ClassFormatError("Not a valid annotation element type tag: 0x" +
Integer.toHexString(tag));
}
}
/**
* Look up the String value, identified by the u2 index value from constant pool
* (direct or indirect).
*/
private String resolveUtf8(final DataInput di) throws IOException {
final int index = di.readUnsignedShort();
final Object value = constantPool[index];
final String s;
if (value instanceof Integer) {
s = (String)constantPool[(Integer)value];
if (DEBUG) {
print("resolveUtf8(%d): %d --> %s", index, value, s);
}
} else {
s = (String)value;
if (DEBUG) {
print("resolveUtf8(%d): %s", index, s);
}
}
return s;
}
/**
* Helper method for simple (debug) logging.
*/
@SuppressWarnings("regexpsinglelinejava")
private static void print(final String message, final Object... args) {
if (DEBUG) {
final String logMessage;
if (args.length == 0) {
logMessage = message;
} else {
for (int i = 0; i < args.length; ++i) {
// arguments may be null
if (args[i] == null) {
continue;
}
if (args[i].getClass().isArray()) {
// cast back to array! Note that primitive arrays are not supported
args[i] = Arrays.toString((Object[])args[i]);
} else if (args[i] == Class.class) {
args[i] = ((Class>)args[i]).getName();
}
}
logMessage = String.format(message, args);
}
System.out.println(logMessage);
}
}
}
ClassFileBuffer.java 0000664 0000000 0000000 00000015417 12611230567 0034571 0 ustar 00root root 0000000 0000000 infomas-asl-infomas-asl-3.0.5/annotation-detector/src/main/java/eu/infomas/annotation /* ClassFileBuffer.java
*
* Created: 2011-10-10 (Year-Month-Day)
* Character encoding: UTF-8
*
****************************************** LICENSE *******************************************
*
* Copyright (c) 2011 - 2013 XIAM Solutions B.V. (http://www.xiam.nl)
*
* Licensed 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 eu.infomas.annotation;
import java.io.DataInput;
import java.io.DataInputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
/**
* {@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 {
private byte[] buffer;
private int size; // the number of significant bytes read
private int pointer; // the "read pointer"
/**
* Create a new, empty {@code ClassFileBuffer} with the default initial capacity (8 kb).
*/
ClassFileBuffer() {
this(8 * 1024);
}
/**
* Create a new, empty {@code ClassFileBuffer} with the specified initial capacity.
* The initial capacity must be greater than zero. The internal buffer will grow
* automatically when a higher capacity is required. However, buffer resizing occurs
* extra overhead. So in good initial capacity is important in performance critical
* situations.
*/
ClassFileBuffer(final int initialCapacity) {
if (initialCapacity < 1) {
throw new IllegalArgumentException("initialCapacity < 1: " + initialCapacity);
}
this.buffer = new byte[initialCapacity];
}
/**
* Clear and fill the buffer of this {@code ClassFileBuffer} with the
* supplied byte stream.
* The read pointer is reset to the start of the byte array.
*/
public void readFrom(final InputStream in) throws IOException {
pointer = 0;
size = 0;
int n;
do {
n = in.read(buffer, size, buffer.length - size);
if (n > 0) {
size += n;
}
resizeIfNeeded();
} while (n >= 0);
}
/**
* 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 {
if (position < 0) {
throw new IllegalArgumentException("position < 0: " + position);
}
if (position > size) {
throw new EOFException();
}
this.pointer = position;
}
/**
* Return the size (in bytes) of this Java ClassFile file.
*/
public int size() {
return size;
}
// DataInput
@Override
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 {
if (length < 0 || offset < 0 || offset + length > bytes.length) {
throw new IndexOutOfBoundsException();
}
if (pointer + length > size) {
throw new EOFException();
}
System.arraycopy(buffer, pointer, bytes, offset, length);
pointer += length;
}
@Override
public int skipBytes(final int n) throws IOException {
seek(pointer + n);
return n;
}
@Override
public byte readByte() throws IOException {
if (pointer >= size) {
throw new EOFException();
}
return buffer[pointer++];
}
@Override
public boolean readBoolean() throws IOException {
return readByte() != 0;
}
@Override
public int readUnsignedByte() throws IOException {
if (pointer >= size) {
throw new EOFException();
}
return read();
}
@Override
public int readUnsignedShort() throws IOException {
if (pointer + 2 > size) {
throw new EOFException();
}
return (read() << 8) + read();
}
@Override
public short readShort() throws IOException {
return (short)readUnsignedShort();
}
@Override
public char readChar() throws IOException {
return (char)readUnsignedShort();
}
@Override
public int readInt() throws IOException {
if (pointer + 4 > size) {
throw new EOFException();
}
return (read() << 24) +
(read() << 16) +
(read() << 8) +
read();
}
@Override
public long readLong() throws IOException {
if (pointer + 8 > size) {
throw new EOFException();
}
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 {
return Float.intBitsToFloat(readInt());
}
@Override
public double readDouble() throws IOException {
return Double.longBitsToDouble(readLong());
}
/**
* This methods throws an {@link UnsupportedOperationException} because the method
* is deprecated and not used in the context of this implementation.
*
* @deprecated Does not support UTF-8, use readUTF() instead
*/
@Override
@Deprecated
public String readLine() throws IOException {
throw new UnsupportedOperationException("readLine() is deprecated and not supported");
}
@Override
public String readUTF() throws IOException {
return DataInputStream.readUTF(this);
}
// private
private int read() {
return buffer[pointer++] & 0xff;
}
private void resizeIfNeeded() {
if (size >= buffer.length) {
final byte[] newBuffer = new byte[buffer.length * 2];
System.arraycopy(buffer, 0, newBuffer, 0, buffer.length);
buffer = newBuffer;
}
}
}
ClassFileIterator.java 0000664 0000000 0000000 00000012155 12611230567 0035145 0 ustar 00root root 0000000 0000000 infomas-asl-infomas-asl-3.0.5/annotation-detector/src/main/java/eu/infomas/annotation /* ClassFileIterator.java
*
* Created: 2011-10-10 (Year-Month-Day)
* Character encoding: UTF-8
*
****************************************** LICENSE *******************************************
*
* Copyright (c) 2011 - 2013 XIAM Solutions B.V. (http://www.xiam.nl)
*
* Licensed 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 eu.infomas.annotation;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.ZipFile;
/**
* {@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
*/
final class ClassFileIterator implements ResourceIterator {
private final FileIterator fileIterator;
private final String[] pkgNameFilter;
private ZipFileIterator zipIterator;
/**
* Create a new {@code ClassFileIterator} returning all Java ClassFile files available
* from the class path ({@code System.getProperty("java.class.path")}).
*/
ClassFileIterator() throws IOException {
this(classPath(), null);
}
/**
* 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 '.').
*/
ClassFileIterator(final File[] filesOrDirectories, final String[] pkgNameFilter)
throws IOException {
this.fileIterator = new FileIterator(filesOrDirectories);
this.pkgNameFilter = pkgNameFilter;
}
/**
* Return the name of the Java ClassFile returned from the last call to {@link #next()}.
* The name is either the path name of a file or the name of an ZIP/JAR file entry.
*/
public String getName() {
// Both getPath() and getName() are very light weight method calls
return zipIterator == null ?
fileIterator.getFile().getPath() :
zipIterator.getEntry().getName();
}
@Override
public InputStream next() throws IOException {
while (true) {
if (zipIterator == null) {
final File file = fileIterator.next();
// not all specified Files exists!
if (file == null || !file.isFile()) {
return null;
} else {
final String name = file.getName();
if (name.endsWith(".class")) {
return new FileInputStream(file);
} else if (fileIterator.isRootFile() &&
(endsWithIgnoreCase(name, ".jar") || isZipFile(file))) {
zipIterator = new ZipFileIterator(new ZipFile(file), pkgNameFilter);
} // else just ignore
}
} else {
final InputStream is = zipIterator.next();
if (is == null) {
zipIterator = null;
} else {
return is;
}
}
}
}
// private
private boolean isZipFile(final File file) {
DataInputStream in = null;
try {
in = new DataInputStream(new FileInputStream(file));
final int n = in.readInt();
return n == 0x504b0304;
} catch (IOException ex) {
// silently ignore read exceptions
return false;
} finally {
if (in != null) {
try {
in.close();
} catch (IOException ex) {
// ignore
}
}
}
}
/**
* Returns the class path of the current JVM instance as an array of {@link File} objects.
*/
private static File[] classPath() {
final String[] fileNames =
System.getProperty("java.class.path").split(File.pathSeparator);
final File[] files = new File[fileNames.length];
for (int i = 0; i < files.length; ++i) {
files[i] = new File(fileNames[i]);
}
return files;
}
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);
}
}
FileIterator.java 0000664 0000000 0000000 00000007076 12611230567 0034165 0 ustar 00root root 0000000 0000000 infomas-asl-infomas-asl-3.0.5/annotation-detector/src/main/java/eu/infomas/annotation /* FileIterator.java
*
* Created: 2011-10-10 (Year-Month-Day)
* Character encoding: UTF-8
*
****************************************** LICENSE *******************************************
*
* Copyright (c) 2011 - 2013 XIAM Solutions B.V. (http://www.xiam.nl)
*
* Licensed 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 eu.infomas.annotation;
import java.io.File;
import java.io.IOException;
import java.util.Deque;
import java.util.LinkedList;
import java.util.NoSuchElementException;
/**
* {@code FileIterator} enables iteration over all files in a directory and all its sub
* directories.
*
* Usage:
*
* 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)
*/
FileIterator(final File... filesOrDirectories) {
addReverse(filesOrDirectories);
rootCount = stack.size();
}
/**
* Return the last returned file or {@code null} if no more files are available.
*
* @see #next()
*/
public File getFile() {
return current;
}
/**
* Return {@code true} if the current file is one of the files originally
* specified as one of the constructor file parameters, i.e. is a root file
* or directory.
*/
public boolean isRootFile() {
if (current == null) {
throw new NoSuchElementException();
}
return stack.size() < rootCount;
}
/**
* Return the next {@link File} object or {@code null} if no more files are
* available.
*
* @see #getFile()
*/
public File next() throws IOException {
if (stack.isEmpty()) {
current = null;
return null;
} else {
current = stack.removeLast();
if (current.isDirectory()) {
if (stack.size() < rootCount) {
rootCount = stack.size();
}
addReverse(current.listFiles());
return next();
} else {
return current;
}
}
}
/**
* Add the specified files in reverse order.
*/
private void addReverse(final File[] files) {
for (int i = files.length - 1; i >= 0; --i) {
stack.add(files[i]);
}
}
}
ResourceIterator.java 0000664 0000000 0000000 00000002540 12611230567 0035064 0 ustar 00root root 0000000 0000000 infomas-asl-infomas-asl-3.0.5/annotation-detector/src/main/java/eu/infomas/annotation /* ResourceIterator.java
*
* Created: 2015-10-17 (Year-Month-Day)
* Character encoding: UTF-8
*
****************************************** LICENSE *******************************************
*
* Copyright (c) 2015 XIAM Solutions B.V. (http://www.xiam.nl)
*
* Licensed 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 eu.infomas.annotation;
import java.io.IOException;
import java.io.InputStream;
/**
* {@code ResourceIterator} is an abstraction for an iterator of (Java) Class Files, provided
* as {@link InputStream}.
*
* @author Ronald K. Muller
* @since INFOMAS NG 3.0
*/
interface ResourceIterator {
/**
* Return the next Java ClassFile as an {@code InputStream}.
*
* NOTICE: Client code MUST close the returned {@code InputStream}!
*/
InputStream next() throws IOException;
}
VfsResourceIterator.java 0000664 0000000 0000000 00000004452 12611230567 0035547 0 ustar 00root root 0000000 0000000 infomas-asl-infomas-asl-3.0.5/annotation-detector/src/main/java/eu/infomas/annotation /* VfsResourceIterator.java
*
* Created: 2015-10-17 (Year-Month-Day)
* Character encoding: UTF-8
*
****************************************** LICENSE *******************************************
*
* Copyright (c) 2015 XIAM Solutions B.V. (http://www.xiam.nl)
*
* Licensed 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 eu.infomas.annotation;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.List;
import org.jboss.vfs.VirtualFile;
/**
* {@code VfsResourceIterator} is a {@link ResourceIterator} for the JBoss Virtual File System
* (VFS) as used by JBoss AS and JBoss WildFly.
*
* VFS URL's look like:
*
* 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 {
private final ZipFile zipFile;
private final String[] entryNameFilter;
private final Enumeration extends ZipEntry> entries;
private ZipEntry current;
/**
* Create a new {@code ZipFileIterator} instance.
*
* @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
*/
ZipFileIterator(final ZipFile zipFile, final String[] entryNameFilter) throws IOException {
this.zipFile = zipFile;
this.entryNameFilter = entryNameFilter;
this.entries = zipFile.entries();
}
public ZipEntry getEntry() {
return current;
}
@SuppressWarnings("emptyblock")
public InputStream next() throws IOException {
while (entries.hasMoreElements()) {
current = entries.nextElement();
if (accept(current)) {
return zipFile.getInputStream(current);
}
}
// no more entries in this ZipFile, so close ZipFile
try {
// zipFile is never null here
zipFile.close();
} catch (IOException ex) {
// suppress IOException, otherwise close() is called twice
}
return null;
}
private boolean accept(final ZipEntry entry) {
if (entry.isDirectory()) {
return false;
}
if (entryNameFilter == null) {
return true;
}
for (final String filter : entryNameFilter) {
if (entry.getName().startsWith(filter)) {
return true;
}
}
return false;
}
}
package-info.java 0000664 0000000 0000000 00000002114 12611230567 0034104 0 ustar 00root root 0000000 0000000 infomas-asl-infomas-asl-3.0.5/annotation-detector/src/main/java/eu/infomas/annotation /* package-info.java
*
* Created: 2013-07-09 (Year-Month-Day)
* Character encoding: UTF-8
*
****************************************** LICENSE *******************************************
*
* Copyright (c) 2013 XIAM Solutions B.V. (http://www.xiam.nl)
*
* Licensed 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.
*/
/**
* This library can be used to scan (part of) the class path for annotated classes,
* methods or instance variables.
*
* For more information see
* Github site.
*/
package eu.infomas.annotation;
infomas-asl-infomas-asl-3.0.5/annotation-detector/src/test/ 0000775 0000000 0000000 00000000000 12611230567 0023671 5 ustar 00root root 0000000 0000000 infomas-asl-infomas-asl-3.0.5/annotation-detector/src/test/java/ 0000775 0000000 0000000 00000000000 12611230567 0024612 5 ustar 00root root 0000000 0000000 infomas-asl-infomas-asl-3.0.5/annotation-detector/src/test/java/eu/ 0000775 0000000 0000000 00000000000 12611230567 0025223 5 ustar 00root root 0000000 0000000 infomas-asl-infomas-asl-3.0.5/annotation-detector/src/test/java/eu/infomas/ 0000775 0000000 0000000 00000000000 12611230567 0026657 5 ustar 00root root 0000000 0000000 infomas-asl-infomas-asl-3.0.5/annotation-detector/src/test/java/eu/infomas/annotation/ 0000775 0000000 0000000 00000000000 12611230567 0031031 5 ustar 00root root 0000000 0000000 AnnotationDetectorTest.java 0000664 0000000 0000000 00000014416 12611230567 0036267 0 ustar 00root root 0000000 0000000 infomas-asl-infomas-asl-3.0.5/annotation-detector/src/test/java/eu/infomas/annotation package eu.infomas.annotation;
import java.io.File;
import java.io.IOException;
import java.lang.annotation.Annotation;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static eu.infomas.util.TestSupport.*;
@RuntimeInvisibleTestAnnotation
// This annotation is only used to test a complex annotation type
@RuntimeVisibleTestAnnotations({
@RuntimeVisibleTestAnnotation(name="a"),
@RuntimeVisibleTestAnnotation(name="b")
})
public final class AnnotationDetectorTest {
private static final boolean DEBUG = false;
@SuppressWarnings("unused") // used for testing only
@RuntimeVisibleTestAnnotation
private String fieldWithAnnotation;
static class CountingReporter
implements AnnotationDetector.TypeReporter, AnnotationDetector.MethodReporter, AnnotationDetector.FieldReporter {
private final Class extends Annotation>[] annotations;
private int typeCount;
private int fieldCount;
private int methodCount;
CountingReporter(Class extends Annotation>... annotations) {
this.annotations = annotations;
}
public final Class extends Annotation>[] annotations() {
return annotations;
}
public final void reportTypeAnnotation(Class extends Annotation> annotation, String className) {
++typeCount;
if (DEBUG) System.out.printf("%d reportTypeAnnotation on type '%s': @%s\n",
typeCount, className, annotation.getName());
}
@Override
public void reportFieldAnnotation(Class extends Annotation> annotation,
String className, String fieldName) {
++fieldCount;
if (DEBUG) System.out.printf("%d reportFieldAnnotation on field '%s#%s': @%s\n",
fieldCount, className, fieldName, annotation.getName());
}
public final void reportMethodAnnotation(Class extends Annotation> annotation,
String className, String methodName) {
++methodCount;
if (DEBUG) System.out.printf("%d reportMethodAnnotation on method '%s#%s': @%s\n",
methodCount, className, methodName, annotation.getName());
}
public final int getTypeCount() {
return typeCount;
}
public int getFieldCount() {
return fieldCount;
}
public final int getMethodCount() {
return methodCount;
}
}
// rt.jar is our test file: always available when running the unit tests
// and BIG (about 50MB). Number of .class files: 17436 @ Java 6 update 26
private static final File RT_JAR = new File(new File(System.getProperty("java.home")), "lib/rt.jar");
// Mainly used as benchmark (timing) method
@Test
public void testClassPathScannerRT() throws IOException {
for (int i = 0; i < 6; ++i) {
final long time = System.currentTimeMillis();
final CountingReporter counter = new CountingReporter(Deprecated.class);
final AnnotationDetector cf = new AnnotationDetector(counter);
// Scan all Java Class Files in the specified files (i.e. rt.jar)
cf.detect(RT_JAR); // scan specific files and directories
if (i == 5) {
// report, first 5 iterations where for warming up VM
// java-6-oracle (u26): Time: 255 ms. Type Count: 66, Method Count: 395
// java-7-oracle (u7): Time: 315 ms. Type Count: 83, Method Count: 435
// java-7-openjdk (u7): Time: 994 ms. Type Count: 70, Method Count: 427
log("Time: %d ms. Type Count: %d, Method Count: %d",
System.currentTimeMillis() - time, counter.getTypeCount(),
counter.methodCount);
// we cannot use the returned count as useful value, because it differs from
// JDK version to JDK version, but The Deprecated class must be detected
assertTrue(counter.getTypeCount() > 0);
}
}
}
@Test
public void testMethodAnnotationsOnCompleteClasspath() throws IOException {
final long time = System.currentTimeMillis();
final CountingReporter counter = new CountingReporter(Test.class);
final AnnotationDetector cf = new AnnotationDetector(counter);
cf.detect(); // complete class path is scanned
// 120 ms
if (DEBUG) log("Time: %d ms.", System.currentTimeMillis() - time);
assertEquals(0, counter.getTypeCount());
assertEquals(0, counter.getFieldCount());
assertEquals(15, counter.getMethodCount());
}
@Test
public void testMethodAnnotationsPackageOnly() throws IOException {
final long time = System.currentTimeMillis();
@SuppressWarnings("unchecked")
final CountingReporter counter = new CountingReporter(Test.class);
final AnnotationDetector cf = new AnnotationDetector(counter);
cf.detect("eu.infomas"); // only this package and sub package(s) are scanned
// 6 ms
if (DEBUG) log("Time: %d ms.", System.currentTimeMillis() - time);
assertEquals(0, counter.getTypeCount());
assertEquals(0, counter.getFieldCount());
assertEquals(15, counter.getMethodCount());
}
/**
* Test the more complex annotation on this class (RuntimeVisibleTestAnnotations).
* Ensure that both visible and invisible annotations are reported.
*/
@Test
@RuntimeVisibleTestAnnotation
@RuntimeInvisibleTestAnnotation
public void testTestComplexAnnotations() throws IOException {
@SuppressWarnings("unchecked")
final CountingReporter counter = new CountingReporter(
RuntimeVisibleTestAnnotations.class,
RuntimeVisibleTestAnnotation.class,
RuntimeInvisibleTestAnnotation.class);
// only in this package == only this class!
new AnnotationDetector(counter).detect("eu.infomas.annotation");
assertEquals(2, counter.getTypeCount());
assertEquals(1, counter.getFieldCount());
assertEquals(2, counter.getMethodCount());
}
}
ClassFileIteratorTest.java 0000664 0000000 0000000 00000001025 12611230567 0036032 0 ustar 00root root 0000000 0000000 infomas-asl-infomas-asl-3.0.5/annotation-detector/src/test/java/eu/infomas/annotation package eu.infomas.annotation;
import org.junit.Test;
import static org.junit.Assert.assertNotNull;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
public class ClassFileIteratorTest {
@Test
public void testJarFile() throws IOException {
File [] f = {new File("./src/test/resources/test.jar.extension")};
String [] s = {"eu/infomas/annotation"};
InputStream stream = new ClassFileIterator(f, s).next();
assertNotNull(stream);
stream.close();
}
}
FileIteratorTest.java 0000664 0000000 0000000 00000006730 12611230567 0035054 0 ustar 00root root 0000000 0000000 infomas-asl-infomas-asl-3.0.5/annotation-detector/src/test/java/eu/infomas/annotation package eu.infomas.annotation;
import eu.infomas.annotation.FileIterator;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.io.IOException;
import org.junit.Test;
public final class FileIteratorTest {
@Test
public void testNoFile() throws IOException {
FileIterator iter = new FileIterator();
assertEquals(0, countFiles(iter));
}
@Test
public void testSingleFile() throws IOException {
FileIterator iter = new FileIterator(
new File("./src/test/java/eu/infomas/annotation/FileIteratorTest.java"));
assertEquals(1, countFiles(iter));
}
@Test
public void testSingleDirectory1() throws IOException {
FileIterator iter = new FileIterator(
new File("./src/test/java/eu/infomas/annotation"));
assertEquals(7, countFiles(iter));
}
@Test
public void testSingleDirectory4() throws IOException {
FileIterator iter = new FileIterator(
new File("./src/test/java/eu/infomas"));
// 5 in annotation and 2 in util
assertEquals(8, countFiles(iter));
}
@Test
public void testMixed() throws IOException {
FileIterator iter = new FileIterator(
new File("./src/test/java/eu/infomas/util/TestSupport.java"),
new File("./src/test/java/eu/infomas/annotation/"));
assertEquals(8, countFiles(iter));
}
@Test
public void testIsRoot1() throws IOException {
FileIterator iter = new FileIterator(
new File("./src/test/java/eu/infomas/util/FileIteratorTest.java"));
assertNotNull(iter.next());
assertTrue(iter.isRootFile());
assertNull(iter.next());
}
@Test
public void testIsRoot2() throws IOException {
FileIterator iter = new FileIterator(new File("./src/test/java/eu/infomas/util/"));
assertNotNull(iter.next());
assertFalse(iter.isRootFile());
assertNull(iter.next());
}
@Test
public void testIsRoot3() throws IOException {
FileIterator iter = new FileIterator(
new File("./src/test/java/eu/infomas/util/TestSupport.java"),
new File("./src/test/java/eu/infomas/annotation/")
);
while (iter.next() != null) {
if ("TestSupport.java".equals(iter.getFile().getName())) {
assertTrue(iter.isRootFile());
} else {
assertFalse(iter.getFile().toString(), iter.isRootFile());
}
}
}
@Test
public void testIsRoot4() throws IOException {
FileIterator iter = new FileIterator(
new File("./src/test/java/eu/infomas/annotation/"),
new File("./src/test/java/eu/infomas/util/TestSupport.java")
);
while (iter.next() != null) {
if ("TestSupport.java".equals(iter.getFile().getName())) {
assertTrue(iter.isRootFile());
} else {
assertFalse(iter.getFile().toString(), iter.isRootFile());
}
}
}
private int countFiles(final FileIterator iter) throws IOException {
int counter = 0;
while (iter.next() != null) {
++counter;
//System.out.println(iter.getName());
}
return counter;
}
}
RuntimeInvisibleTestAnnotation.java 0000664 0000000 0000000 00000000436 12611230567 0040003 0 ustar 00root root 0000000 0000000 infomas-asl-infomas-asl-3.0.5/annotation-detector/src/test/java/eu/infomas/annotation package eu.infomas.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
// default retention policy creates a "RuntimeInvisibleAnnotation" attribute
@Retention(RetentionPolicy.CLASS)
public @interface RuntimeInvisibleTestAnnotation {
}
RuntimeVisibleTestAnnotation.java 0000664 0000000 0000000 00000000426 12611230567 0037453 0 ustar 00root root 0000000 0000000 infomas-asl-infomas-asl-3.0.5/annotation-detector/src/test/java/eu/infomas/annotation package eu.infomas.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
// see RuntimeVisibleTestAnnotations
@Retention(RetentionPolicy.RUNTIME)
public @interface RuntimeVisibleTestAnnotation {
String name() default "";
}
RuntimeVisibleTestAnnotations.java 0000664 0000000 0000000 00000000447 12611230567 0037641 0 ustar 00root root 0000000 0000000 infomas-asl-infomas-asl-3.0.5/annotation-detector/src/test/java/eu/infomas/annotation package eu.infomas.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
// see RuntimeVisibleTestAnnotation
@Retention(RetentionPolicy.RUNTIME)
public @interface RuntimeVisibleTestAnnotations {
RuntimeVisibleTestAnnotation[] value();
}
ZipFileIteratorTest.java 0000664 0000000 0000000 00000010366 12611230567 0035537 0 ustar 00root root 0000000 0000000 infomas-asl-infomas-asl-3.0.5/annotation-detector/src/test/java/eu/infomas/annotation package eu.infomas.annotation;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import org.junit.Test;
import static eu.infomas.util.TestSupport.*;
/**
* This class is used for simple benchmarking different ways to read a ZIP file in Java.
* {@code rt.jar} is our test file. Always available and BIG (about 50MB).
* When using an Oracle JVM using ZipFile is (considerable) faster.
* Note that when using OpenJDK this is not the case. Also note that the OpenJDK
* is (also in this case) MUCH slower than the Oracle JVM's.
*
* FileIterator iter = new FileIterator(new File("./src"));
* File f;
* while ((f = iter.next()) != null) {
* // do something with f
* assert f == iter.getCurrent();
* }
*
*
* @author Ronald K. Muller
* @since annotation-detector 3.0.0
*/
final class FileIterator {
private final Deque
* vfs:/foo/bar/website.war/WEB-INF/classes/nl/dvelop/
* vfs:/foo/bar/website.war/WEB-INF/lib/dwebcore-0.0.1.jar/nl/dvelop/
*
*
* Known VFS protocols are "vfs", "vfsfile", "vfszip", "vfsjar", and "vfsmemory".
*
* Also see
*
* Some example timings (on same hardware, Ubuntu 12.04 LTS x64):
*
* java version "1.6.0_26" (/usr/lib/jvm/java-6-sun-1.6.0.26/jre)
* Java(TM) SE Runtime Environment (build 1.6.0_26-b03)
* Java HotSpot(TM) 64-Bit Server VM (build 20.1-b02, mixed mode)
* Timing using ZipFile: 78 ms, using ZipInputStream: 176 ms.
*
* java version "1.7.0_07" (/usr/lib/jvm/jdk1.7.0_07/jre)
* Java(TM) SE Runtime Environment (build 1.7.0_07-b10)
* Java HotSpot(TM) 64-Bit Server VM (build 23.3-b01, mixed mode)
* Timing using ZipFile: 120 ms, using ZipInputStream: 154 ms.
*
* java version "1.7.0_07" (/usr/lib/jvm/java-7-openjdk-amd64/jre)
* OpenJDK Runtime Environment (build 1.7.0_07-b30)
* OpenJDK 64-Bit Server VM (build 23.2-b09, mixed mode)
* Timing using ZipFile: 797 ms, using ZipInputStream: 724 ms.
*
*/
public final class ZipFileIteratorTest {
private static final boolean DEBUG = false;
// count=17436, bytes=49115087 @ Java 6 update 26 (Oracle)
// count=19002, bytes=59124405 @ Java 7 update 7 (Oracle)
// count=18322, bytes=63983889 @ OpenJDK 7 update 7
private static final File RT_JAR =
new File(new File(System.getProperty("java.home")), "lib/rt.jar");
@Test
public void benchmarkReadZip() throws IOException {
// warm up VM
for (int i = 0; i < 5; ++i) {
testReadZipUsingZipFile(); // about up to 3 times faster! 60 ms versus 170 ms
testReadZipUsingZipInputStream();
}
log(javaVersion());
log("Timing using ZipFile: %d ms, using ZipInputStream: %d ms.",
testReadZipUsingZipFile(),
testReadZipUsingZipInputStream());
}
private long testReadZipUsingZipFile() throws IOException {
ClassFileBuffer buffer = new ClassFileBuffer(128 * 1024);
long time = System.currentTimeMillis();
int count = 0;
long bytes = 0;
final ZipFile zf = new ZipFile(RT_JAR); // open in OPEN_READ mode
try {
final Enumeration extends ZipEntry> e = zf.entries();
while (e.hasMoreElements()) {
final ZipEntry ze = e.nextElement();
if (ze.isDirectory()) {
continue;
}
final InputStream is = zf.getInputStream(ze);
buffer.readFrom(is);
bytes += buffer.size();
++count;
}
} finally {
zf.close();
}
time = System.currentTimeMillis() - time;
if (DEBUG) {
log("Time: %d ms, count=%d, bytes=%d ZipFile", time, count, bytes);
}
return time;
}
private long testReadZipUsingZipInputStream() throws IOException {
ClassFileBuffer buffer = new ClassFileBuffer(128 * 1024);
long time = System.currentTimeMillis();
int count = 0;
long bytes = 0;
final ZipInputStream zi = new ZipInputStream(new FileInputStream(RT_JAR));
try {
ZipEntry ze;
while ((ze = zi.getNextEntry()) != null) {
if (ze.isDirectory()) {
continue;
}
final InputStream is = zi;
buffer.readFrom(is);
bytes += buffer.size();
++count;
}
} finally {
zi.close();
}
time = System.currentTimeMillis() - time;
if (DEBUG) {
log("Time: %d ms, count=%d, bytes=%d ZipInputStream", time, count, bytes);
}
return time;
}
}
infomas-asl-infomas-asl-3.0.5/annotation-detector/src/test/java/eu/infomas/util/ 0000775 0000000 0000000 00000000000 12611230567 0027634 5 ustar 00root root 0000000 0000000 infomas-asl-infomas-asl-3.0.5/annotation-detector/src/test/java/eu/infomas/util/TestSupport.java 0000664 0000000 0000000 00000005250 12611230567 0033015 0 ustar 00root root 0000000 0000000 /* TestSupport.java
*
* Created: 2012-10-01 (Year-Month-Day)
* Character encoding: UTF-8
*
****************************************** LICENSE *******************************************
*
* Copyright (c) 2012 - 2013 XIAM Solutions B.V. (http://www.xiam.nl)
*
* Licensed 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 eu.infomas.util;
/**
* {@code TestSupport} offers some simple utility methods useful during development and
* testing.
*
* @author Ronald K. Muller
* @since annotation-detector 3.0.2
*/
public final class TestSupport {
// utility class
private TestSupport() {
}
/**
* Return detailed information about the current Java VM.
* Output should more or less the same as running the 'java' command in your OS shell:
*
* $ java -version
* java version "1.7.0_07"
* Java(TM) SE Runtime Environment (build 1.7.0_07-b10)
* Java HotSpot(TM) 64-Bit Server VM (build 23.3-b01, mixed mode)
*
*/
public static String javaVersion() {
return String.format("java version \"%s\" (%s)\n%s (build %s)\n%s (build %s, %s)",
System.getProperty("java.version"),
System.getProperty("java.home"),
System.getProperty("java.runtime.name"),
System.getProperty("java.runtime.version"),
System.getProperty("java.vm.name"),
System.getProperty("java.vm.version"),
System.getProperty("java.vm.info"));
}
/**
* Minimalistic logger: log the String value of the supplied argument or print the
* stack trace if it is an {@link Throwable}.
*/
public static void log(final Object log) {
if (log instanceof Throwable) {
((Throwable)log).printStackTrace(System.err);
} else {
System.out.println(String.valueOf(log));
}
}
/**
* Minimalistic logger: format the supplied message using
* {@link String#format(java.lang.String, java.lang.Object[]) }.
*/
public static void log(final String msg, final Object... args) {
System.out.println(args.length == 0 ? msg : String.format(msg, args));
}
}
infomas-asl-infomas-asl-3.0.5/annotation-detector/src/test/resources/ 0000775 0000000 0000000 00000000000 12611230567 0025703 5 ustar 00root root 0000000 0000000 infomas-asl-infomas-asl-3.0.5/annotation-detector/src/test/resources/test.jar.extension 0000664 0000000 0000000 00000035577 12611230567 0031414 0 ustar 00root root 0000000 0000000 PK $E META-INF/MANIFEST.MF SMo0 z]%J6i-E6%Cω3X{{s-7vh-l-fb{9]lr"oC2
G㐌nZ@#U#߄
lb@I8Dd0
njtP&l(%׃%ҹNԙ;o\eMBfJIZX|!=8~P㗺&c`\łmG,M{ʅ3'e&t-z~ǼV`c@u:nd(&\ϏMԂm~G Dw$i;vD`75ZXfQQi:0k
s7h_dnNoN!;#J5Ծ7=T:/kmK*kuRN-C-˩1(n/= C:B!4PK&P A PK $E META-INF/ PK PK $E META-INF/maven/ PK PK $E META-INF/maven/eu.infomas/ PK PK $E . META-INF/maven/eu.infomas/annotation-detector/ PK PK $E <