HHH-8962 - Create a set of light reflection classes

This commit is contained in:
Steve Ebersole 2014-02-12 15:33:43 -06:00
parent 83e9ceb429
commit c5cbf662b4
11 changed files with 767 additions and 1 deletions

View File

@ -0,0 +1,82 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2014, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.metamodel.reflite.internal;
import org.hibernate.metamodel.reflite.spi.Name;
import org.jboss.jandex.DotName;
/**
* {@link Name} adapter for Janxdex {@link DotName}
*
* @author Steve Ebersole
*/
public class DotNameAdapter implements Name {
private final DotName dotName;
public DotNameAdapter(String name) {
final int loc = name.lastIndexOf( '.' );
if ( loc < 0 ) {
this.dotName = DotName.createSimple( name );
}
else {
this.dotName = DotName.createComponentized(
DotName.createSimple( name.substring( 0, loc ) ),
name.substring( loc + 1 )
);
}
}
@Override
public String getQualifier() {
return dotName.prefix() == null ? null : dotName.prefix().toString();
}
@Override
public String getUnqualifiedName() {
return dotName.local();
}
@Override
public String toString() {
return dotName.toString();
}
@Override
public boolean equals(Object o) {
if ( this == o ) {
return true;
}
if ( o == null || getClass() != o.getClass() ) {
return false;
}
final DotNameAdapter that = (DotNameAdapter) o;
return dotName.equals( that.dotName );
}
@Override
public int hashCode() {
return dotName.hashCode();
}
}

View File

@ -0,0 +1,58 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2014, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.metamodel.reflite.internal;
import org.hibernate.metamodel.reflite.spi.FieldDescriptor;
import org.hibernate.metamodel.reflite.spi.TypeDescriptor;
/**
* @author Steve Ebersole
*/
public class FieldDescriptorImpl implements FieldDescriptor {
private final String name;
private final TypeDescriptor fieldType;
private final TypeDescriptor declaringType;
public FieldDescriptorImpl(String name, TypeDescriptor fieldType, TypeDescriptor declaringType) {
this.name = name;
this.fieldType = fieldType;
this.declaringType = declaringType;
}
@Override
public String getName() {
return name;
}
@Override
public TypeDescriptor getType() {
return fieldType;
}
@Override
public TypeDescriptor getDeclaringType() {
return declaringType;
}
}

View File

@ -0,0 +1,68 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2014, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.metamodel.reflite.internal;
import org.hibernate.metamodel.reflite.spi.MethodDescriptor;
import org.hibernate.metamodel.reflite.spi.TypeDescriptor;
/**
* @author Steve Ebersole
*/
public class MethodDescriptorImpl implements MethodDescriptor {
private final String name;
private final TypeDescriptor declaringType;
private final TypeDescriptor returnType;
private final TypeDescriptor[] parameterTypes;
public MethodDescriptorImpl(
String name,
TypeDescriptor declaringType,
TypeDescriptor returnType,
TypeDescriptor[] parameterTypes) {
this.name = name;
this.declaringType = declaringType;
this.returnType = returnType;
this.parameterTypes = parameterTypes;
}
@Override
public String getName() {
return name;
}
@Override
public TypeDescriptor getDeclaringType() {
return declaringType;
}
@Override
public TypeDescriptor getReturnType() {
return returnType;
}
@Override
public TypeDescriptor[] getParameterTypes() {
return parameterTypes;
}
}

View File

@ -0,0 +1,217 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2014, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.metamodel.reflite.internal;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
import org.hibernate.metamodel.reflite.spi.FieldDescriptor;
import org.hibernate.metamodel.reflite.spi.MethodDescriptor;
import org.hibernate.metamodel.reflite.spi.Name;
import org.hibernate.metamodel.reflite.spi.Repository;
import org.hibernate.metamodel.reflite.spi.TypeDescriptor;
import org.hibernate.service.ServiceRegistry;
import org.jboss.logging.Logger;
/**
* This is the "interim" implementation of Repository that loads Classes to ascertain this
* information. Ultimately the goal is to hand this responsibility off to Jandex once
* (if) it exposes these capabilities.
*
* @author Steve Ebersole
*/
public class RepositoryImpl implements Repository {
private static final Logger log = Logger.getLogger( RepositoryImpl.class );
private ClassLoader jpaTempClassLoader;
private final ClassLoaderService classLoaderService;
private Map<Name,TypeDescriptor> typeDescriptorMap = new HashMap<Name, TypeDescriptor>();
public RepositoryImpl(ClassLoader jpaTempClassLoader, ServiceRegistry serviceRegistry) {
this.jpaTempClassLoader = jpaTempClassLoader;
this.classLoaderService = serviceRegistry.getService( ClassLoaderService.class );
}
@Override
public Name buildName(String name) {
return new DotNameAdapter( name );
}
@Override
public TypeDescriptor getType(Name className) {
TypeDescriptor descriptor = typeDescriptorMap.get( className );
if ( descriptor == null ) {
descriptor = makeTypeDescriptor( className );
}
return descriptor;
}
protected TypeDescriptor makeTypeDescriptor(Name typeName) {
if ( isSafeClass( typeName ) ) {
return makeTypeDescriptor( typeName, classLoaderService.classForName( typeName.toString() ) );
}
else {
if ( jpaTempClassLoader == null ) {
log.debug(
"Request to makeTypeDescriptor(%s) - but passed class is not known to be " +
"safe (it might be, it might not be). However, there was no " +
"temp ClassLoader provided; we will use the live ClassLoader"
);
// this reference is "safe" because it was loaded from the live ClassLoader
return makeTypeDescriptor( typeName, classLoaderService.classForName( typeName.toString() ) );
}
else {
log.debug(
"Request to makeTypeDescriptor(%s) - passed class is not known to be " +
"safe (it might be, it might not be). There was a temp ClassLoader " +
"provided, so we will use that"
);
// this is the Class reference that is unsafe to keep around...
final Class unSafeReference;
try {
unSafeReference = jpaTempClassLoader.loadClass( typeName.toString() );
}
catch (ClassNotFoundException e) {
throw new ClassLoadingException(
"Unable to load class " + typeName.toString() + " using temp ClassLoader",
e
);
}
return makeTypeDescriptor( typeName, unSafeReference );
}
}
}
private boolean isSafeClass(Name className) {
final String classNameString = className.toString();
return classNameString.startsWith( "java." )
|| classNameString.startsWith( "javax." )
|| classNameString.startsWith( "org.hibernate" );
}
private static TypeDescriptor[] NO_TYPES = new TypeDescriptor[0];
private static FieldDescriptor[] NO_FIELDS = new FieldDescriptor[0];
private static MethodDescriptor[] NO_METHODS = new MethodDescriptor[0];
// todo : this is not circular reference safe in terms of fields/methods referring back to this type
private TypeDescriptor makeTypeDescriptor(Name typeName, Class clazz) {
// we build and register it now to protect against circular references
final TypeDescriptorImpl typeDescriptor = new TypeDescriptorImpl(
typeName,
clazz.isInterface(),
hasDefaultCtor( clazz )
);
typeDescriptorMap.put( typeName, typeDescriptor );
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// super type
TypeDescriptor superType = null;
if ( !clazz.isInterface() ) {
final Class superclass = clazz.getSuperclass();
if ( superclass != null ) {
superType = getType( buildName( superclass.getName() ) );
}
}
typeDescriptor.setSuperType( superType );
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// interfaces
TypeDescriptor[] interfaceTypes = null;
final Class[] interfaces = clazz.getInterfaces();
if ( interfaces != null && interfaces.length > 0 ) {
interfaceTypes = new TypeDescriptor[ interfaces.length ];
for ( int i = 0; i < interfaces.length; i++ ) {
interfaceTypes[i] = getType( buildName( interfaces[i].getName() ) );
}
}
typeDescriptor.setInterfaces( interfaceTypes == null ? NO_TYPES : interfaceTypes );
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// fields
FieldDescriptor[] fieldDescriptors = null;
final Field[] fields = clazz.getDeclaredFields();
if ( fields != null && fields.length > 0 ) {
fieldDescriptors = new FieldDescriptor[ fields.length ];
for ( int i = 0; i < fields.length; i++ ) {
fieldDescriptors[i] = new FieldDescriptorImpl(
fields[i].getName(),
getType( buildName( fields[i].getType().getName() ) ),
typeDescriptor
);
}
}
typeDescriptor.setFields( fieldDescriptors == null ? NO_FIELDS : fieldDescriptors );
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// methods
MethodDescriptor[] methodDescriptors = null;
final Method[] methods = clazz.getDeclaredMethods();
if ( methods != null && methods.length > 0 ) {
methodDescriptors = new MethodDescriptor[ methods.length ];
for ( int i = 0; i < methods.length; i++ ) {
final Class[] parameterTypes = methods[i].getParameterTypes();
final TypeDescriptor[] argumentTypes;
if ( parameterTypes.length == 0 ) {
argumentTypes = NO_TYPES;
}
else {
argumentTypes = new TypeDescriptor[ parameterTypes.length ];
for ( int x = 0; x < parameterTypes.length; x++ ) {
argumentTypes[x] = getType( buildName( parameterTypes[x].getName() ) );
}
}
methodDescriptors[i] = new MethodDescriptorImpl(
methods[i].getName(),
typeDescriptor,
getType( buildName( methods[i].getReturnType().getName() ) ),
argumentTypes
);
}
}
typeDescriptor.setMethods( methodDescriptors == null ? NO_METHODS : methodDescriptors );
return typeDescriptor;
}
@SuppressWarnings("unchecked")
private static boolean hasDefaultCtor(Class clazz) {
try {
return !clazz.isInterface() && clazz.getConstructor() != null;
}
catch (NoSuchMethodException ignore) {
return false;
}
}
}

View File

@ -0,0 +1,104 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2014, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.metamodel.reflite.internal;
import org.hibernate.metamodel.reflite.spi.FieldDescriptor;
import org.hibernate.metamodel.reflite.spi.MethodDescriptor;
import org.hibernate.metamodel.reflite.spi.Name;
import org.hibernate.metamodel.reflite.spi.TypeDescriptor;
/**
* Implementation of a type descriptor
*
* @author Steve Ebersole
*/
public class TypeDescriptorImpl implements TypeDescriptor {
private final Name name;
private final boolean isInterface;
private final boolean hasDefaultConstructor;
private TypeDescriptor superType;
private TypeDescriptor[] interfaces;
private FieldDescriptor[] fieldDescriptors;
private MethodDescriptor[] methodDescriptors;
public TypeDescriptorImpl(Name name, boolean isInterface, boolean hasDefaultConstructor) {
this.name = name;
this.isInterface = isInterface;
this.hasDefaultConstructor = hasDefaultConstructor;
}
@Override
public Name getName() {
return name;
}
@Override
public boolean isInterface() {
return isInterface;
}
@Override
public boolean hasDefaultConstructor() {
return hasDefaultConstructor;
}
@Override
public TypeDescriptor getSuperType() {
return superType;
}
@Override
public TypeDescriptor[] getInterfaceTypes() {
return interfaces;
}
@Override
public FieldDescriptor[] getDeclaredFields() {
return fieldDescriptors;
}
@Override
public MethodDescriptor[] getDeclaredMethods() {
return methodDescriptors;
}
void setSuperType(TypeDescriptor superType) {
this.superType = superType;
}
void setInterfaces(TypeDescriptor[] interfaces) {
this.interfaces = interfaces;
}
void setFields(FieldDescriptor[] fieldDescriptors) {
this.fieldDescriptors = fieldDescriptors;
}
void setMethods(MethodDescriptor[] methodDescriptors) {
this.methodDescriptors = methodDescriptors;
}
}

View File

@ -0,0 +1,52 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2014, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.metamodel.reflite.spi;
/**
* Describes a field in a class
*
* @author Steve Ebersole
*/
public interface FieldDescriptor {
/**
* The field name
*
* @return The field name
*/
public String getName();
/**
* The type of the field.
*
* @return The type of the field.
*/
public TypeDescriptor getType();
/**
* The declaring type
*
* @return
*/
public TypeDescriptor getDeclaringType();
}

View File

@ -0,0 +1,36 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2014, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.metamodel.reflite.spi;
/**
* Describes a method in a class
*
* @author Steve Ebersole
*/
public interface MethodDescriptor {
public String getName();
public TypeDescriptor getDeclaringType();
public TypeDescriptor getReturnType();
public TypeDescriptor[] getParameterTypes();
}

View File

@ -0,0 +1,38 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2014, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.metamodel.reflite.spi;
/**
* Represents a name in a typed fashion rather than simple strings.Generally this
* refers to a package or class name.
* <p/>
* Modelled after Jandex's DotName, which is modelled after {@link javax.naming.Name}, etc
*
* @author Steve Ebersole
*/
public interface Name {
public String getQualifier();
public String getUnqualifiedName();
public String toString();
}

View File

@ -0,0 +1,34 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2014, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.metamodel.reflite.spi;
/**
* The repository of reflite info.
*
* @author Steve Ebersole
*/
public interface Repository {
public Name buildName(String name);
public TypeDescriptor getType(Name className);
}

View File

@ -0,0 +1,77 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2014, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.metamodel.reflite.spi;
import java.util.Collection;
/**
* Describes information about a class.
*
* @author Steve Ebersole
*/
public interface TypeDescriptor {
public Name getName();
/**
* Is this type an interface (as opposed to a class)?
*
* @return {@code true} indicates it is a interface; {@code false} indicates it is a class.
*/
public boolean isInterface();
/**
* The super type for this type (if it is a class)
*
* @return The super type
*/
public TypeDescriptor getSuperType();
/**
* Get the interfaces implemented by this type
*
* @return The implemented interfaces
*/
public TypeDescriptor[] getInterfaceTypes();
/**
* Did the class define a default (no-arg) constructor?
*
* @return {@code true} indicates the class did have a default (no arg) constructor.
*/
public boolean hasDefaultConstructor();
/**
* Get all the fields declared by this type.
*
* @return All fields declared by this type
*/
public FieldDescriptor[] getDeclaredFields();
/**
* Get all the methods declared by this type.
*
* @return All fields declared by this type
*/
public MethodDescriptor[] getDeclaredMethods();
}

View File

@ -69,7 +69,7 @@ public class ClassFileArchiveEntryHandler extends AbstractJavaArtifactArchiveEnt
return; return;
} }
// we are only interested in classes with certain annotations, so see if the ClassDescriptor // we are only interested in classes with certain annotations, so see if the TypeDescriptor
// represents a class which contains any of those annotations // represents a class which contains any of those annotations
if ( ! containsClassAnnotationsOfInterest( classFile ) ) { if ( ! containsClassAnnotationsOfInterest( classFile ) ) {
return; return;