/**
* Copyright 2011 meltmedia
*
* 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 org.xchain.framework.util;
import java.io.DataInputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import javassist.CtBehavior;
import javassist.CtClass;
import javassist.bytecode.AnnotationsAttribute;
import javassist.bytecode.AttributeInfo;
import javassist.bytecode.ClassFile;
import javassist.bytecode.annotation.MemberValue;
import javassist.bytecode.annotation.AnnotationMemberValue;
import javassist.bytecode.annotation.ArrayMemberValue;
import javassist.bytecode.annotation.BooleanMemberValue;
import javassist.bytecode.annotation.ByteMemberValue;
import javassist.bytecode.annotation.CharMemberValue;
import javassist.bytecode.annotation.ClassMemberValue;
import javassist.bytecode.annotation.DoubleMemberValue;
import javassist.bytecode.annotation.EnumMemberValue;
import javassist.bytecode.annotation.FloatMemberValue;
import javassist.bytecode.annotation.IntegerMemberValue;
import javassist.bytecode.annotation.LongMemberValue;
import javassist.bytecode.annotation.ShortMemberValue;
import javassist.bytecode.annotation.StringMemberValue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class AnnotationUtil
{
public static Logger log = LoggerFactory.getLogger(AnnotationUtil.class);
public static boolean hasAnnotation(ClassFile classFile, Class<? extends Annotation> annotationType)
{
AnnotationsAttribute visibleAnnotations = (AnnotationsAttribute)classFile.getAttribute(AnnotationsAttribute.visibleTag);
if( visibleAnnotations == null ) { return false; }
return visibleAnnotations.getAnnotation(annotationType.getName()) != null;
}
public static boolean hasAnnotation( CtClass ctClass, Class<? extends Annotation> annotationType )
throws ClassNotFoundException
{
for( Object annotation: ctClass.getAnnotations() ) {
if( annotationType.isInstance(annotation) ) {
return true;
}
}
return false;
}
public static boolean hasAnnotation( Method method, Class<? extends Annotation> annotationType )
{
return method.getAnnotation(annotationType) != null;
}
/**
* Tests to see if a CtMethod or a CtConstructor has the specified annotation.
*/
public static boolean hasAnnotation( CtBehavior behavior, Class<? extends Annotation> annotationType )
throws ClassNotFoundException
{
for( Object annotation : behavior.getAnnotations() ) {
if( annotationType.isInstance(annotation) ) {
return true;
}
}
return false;
}
public static Object getAnnotationValue(ClassFile classFile, Class<? extends Annotation> annotationType, String memberName)
{
AnnotationsAttribute visibleAnnotations = (AnnotationsAttribute)classFile.getAttribute(AnnotationsAttribute.visibleTag);
if( visibleAnnotations == null ) return null;
return getAnnotationValue( visibleAnnotations.getAnnotation(annotationType.getName()), memberName );
}
public static Object getAnnotationValue( CtBehavior behavior, Class<? extends Annotation> annotationType, String memberName )
throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, java.lang.reflect.InvocationTargetException
{
for( Object annotation : behavior.getAnnotations() ) {
if( annotationType.isInstance(annotation) ) {
return annotationType.getMethod(memberName, new Class[] {}).invoke(annotation, new Object[] {});
}
}
return false;
}
public static Object getAnnotationValue( javassist.bytecode.annotation.Annotation annotation, String memberName )
{
if( annotation == null ) return null;
return getAnnotationValue(annotation.getMemberValue(memberName));
}
public static Object getAnnotationValue( MemberValue memberValue )
{
if( memberValue == null ) {
return null;
}
else if( memberValue instanceof AnnotationMemberValue ) {
return ((AnnotationMemberValue)memberValue).getValue();
}
else if( memberValue instanceof ArrayMemberValue ) {
return ((ArrayMemberValue)memberValue).getValue();
}
else if( memberValue instanceof BooleanMemberValue ) {
return ((BooleanMemberValue)memberValue).getValue();
}
else if( memberValue instanceof ByteMemberValue ) {
return ((ByteMemberValue)memberValue).getValue();
}
else if( memberValue instanceof CharMemberValue ) {
return ((CharMemberValue)memberValue).getValue();
}
else if( memberValue instanceof ClassMemberValue ) {
return ((ClassMemberValue)memberValue).getValue();
}
else if( memberValue instanceof DoubleMemberValue ) {
return ((DoubleMemberValue)memberValue).getValue();
}
else if( memberValue instanceof EnumMemberValue ) {
return ((EnumMemberValue)memberValue).getValue();
}
else if( memberValue instanceof FloatMemberValue ) {
return ((FloatMemberValue)memberValue).getValue();
}
else if( memberValue instanceof IntegerMemberValue ) {
return ((IntegerMemberValue)memberValue).getValue();
}
else if( memberValue instanceof LongMemberValue ) {
return ((LongMemberValue)memberValue).getValue();
}
else if( memberValue instanceof ShortMemberValue ) {
return ((ShortMemberValue)memberValue).getValue();
}
else if( memberValue instanceof StringMemberValue ) {
return ((StringMemberValue)memberValue).getValue();
}
else {
throw new RuntimeException("The value type of this annotation is not yet supported.");
}
}
public static ClassFile getClassFile( String resourceName, ClassLoader classLoader )
{
DataInputStream dstream = null;
ClassFile classFile = null;
try
{
dstream = new DataInputStream(classLoader.getResourceAsStream(resourceName));
classFile = new ClassFile(dstream);
}
catch( Exception e ) {
if( log.isDebugEnabled() ) {
log.debug("A javassist ClassFile could not be created for '"+resourceName+"'.", e);
}
}
finally
{
if( dstream != null ) {
try {
dstream.close();
}
catch( Exception e ) {
if( log.isWarnEnabled() ) {
log.warn("Could not close DataInputStream for '"+resourceName+"'.", e);
}
}
}
}
return classFile;
}
}