/*
* Copyright 2001-2008 Geert Bevin (gbevin[remove] at uwyn dot com)
* Licensed under the Apache License, Version 2.0 (the "License")
* $Id: MetaDataClassAnnotationDetector.java 3918 2008-04-14 17:35:35Z gbevin $
*/
package com.uwyn.rife.site.instrument;
import com.uwyn.rife.asm.*;
/**
* Detects whether a class has the {@code MetaDataClass} class annotation
* by analyzing its byte code.
*
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
* @version $Revision: 3918 $
* @since 1.6.2
*/
public abstract class MetaDataClassAnnotationDetector
{
private final static String META_DATA_ANNOTATION_INTERNAL_TYPE = "Lcom/uwyn/rife/site/annotations/MetaDataClass;";
/**
* Retrieves the class name of the meta data class that is associated
* through the {@code MetaDataClass} class annotation.
*
* @param bytes the array of bytes that defines the class that needs to be
* analyzed
* @return the name of the associated meta data class; or
* <p>
* {@code null} if no meta data class was specified through an annotation
* @since 1.6.2
*/
public static String getMetaDataClassName(final byte[] bytes)
{
DetectionClassVisitor visitor = new DetectionClassVisitor();
ClassReader detection_reader = new ClassReader(bytes);
detection_reader.accept(visitor, ClassReader.SKIP_DEBUG|ClassReader.SKIP_FRAMES);
return visitor.getMetaDataClassName();
}
private static class DetectionClassVisitor implements ClassVisitor
{
private String mMetaDataClassName = null;
private String getMetaDataClassName()
{
return mMetaDataClassName;
}
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces)
{
}
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions)
{
return null;
}
public void visitInnerClass(String name, String outerName, String innerName, int access)
{
}
public void visitOuterClass(String owner, String name, String desc)
{
}
public FieldVisitor visitField(int access, String name, String desc, String signature, Object value)
{
return null;
}
public void visitSource(String source, String debug)
{
}
public AnnotationVisitor visitAnnotation(String desc, boolean visible)
{
if (META_DATA_ANNOTATION_INTERNAL_TYPE.equals(desc)) {
return new AnnotationVisitor() {
public void visit(String name, Object value)
{
if ("value".equals(name) &&
value != null)
{
mMetaDataClassName = ((Type)value).getClassName();
}
}
public void visitEnum(String name, String desc, String value)
{
}
public AnnotationVisitor visitAnnotation(String name, String desc)
{
return null;
}
public AnnotationVisitor visitArray(String name)
{
return null;
}
public void visitEnd()
{
}
};
}
return null;
}
public void visitAttribute(Attribute attr)
{
}
public void visitEnd()
{
}
}
}