All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.feilong.lib.javassist.bytecode.annotation.Annotation Maven / Gradle / Ivy

Go to download

feilong is a suite of core and expanded libraries that include utility classes, http, excel,cvs, io classes, and much much more.

There is a newer version: 4.0.8
Show newest version
/*
 * Javassist, a Java-bytecode translator toolkit.
 * Copyright (C) 2004 Bill Burke. All Rights Reserved.
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License.  Alternatively, the contents of this file may be used under
 * the terms of the GNU Lesser General Public License Version 2.1 or later,
 * or the Apache License Version 2.0.
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 */

package com.feilong.lib.javassist.bytecode.annotation;

import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

import com.feilong.lib.javassist.ClassPool;
import com.feilong.lib.javassist.CtClass;
import com.feilong.lib.javassist.CtMethod;
import com.feilong.lib.javassist.NotFoundException;
import com.feilong.lib.javassist.bytecode.ConstPool;
import com.feilong.lib.javassist.bytecode.Descriptor;

/**
 * The annotation structure.
 *
 * 

* An instance of this class is returned by * getAnnotations() in AnnotationsAttribute * or in ParameterAnnotationsAttribute. * * @see com.feilong.lib.javassist.bytecode.AnnotationsAttribute#getAnnotations() * @see com.feilong.lib.javassist.bytecode.ParameterAnnotationsAttribute#getAnnotations() * @see MemberValue * @see MemberValueVisitor * @see AnnotationsWriter * * @author Bill Burke * @author Shigeru Chiba * @author Adrian Brock */ public class Annotation{ static class Pair{ int name; MemberValue value; } ConstPool pool; int typeIndex; Map members; // this sould be LinkedHashMap // but it is not supported by JDK 1.3. /** * Constructs an annotation including no members. A member can be * later added to the created annotation by addMemberValue(). * * @param type * the index into the constant pool table. * the entry at that index must be the * CONSTANT_Utf8_Info structure * repreenting the name of the annotation interface type. * @param cp * the constant pool table. * * @see #addMemberValue(String, MemberValue) */ public Annotation(int type, ConstPool cp){ pool = cp; typeIndex = type; members = null; } /** * Constructs an annotation including no members. A member can be * later added to the created annotation by addMemberValue(). * * @param typeName * the fully-qualified name of the annotation interface type. * @param cp * the constant pool table. * * @see #addMemberValue(String, MemberValue) */ public Annotation(String typeName, ConstPool cp){ this(cp.addUtf8Info(Descriptor.of(typeName)), cp); } /** * Constructs an annotation that can be accessed through the interface * represented by clazz. The values of the members are * not specified. * * @param cp * the constant pool table. * @param clazz * the interface. * @throws NotFoundException * when the clazz is not found */ public Annotation(ConstPool cp, CtClass clazz) throws NotFoundException{ // todo Enums are not supported right now. this(cp.addUtf8Info(Descriptor.of(clazz.getName())), cp); if (!clazz.isInterface()){ throw new RuntimeException("Only interfaces are allowed for Annotation creation."); } CtMethod[] methods = clazz.getDeclaredMethods(); if (methods.length > 0){ members = new LinkedHashMap<>(); } for (CtMethod m : methods){ addMemberValue(m.getName(), createMemberValue(cp, m.getReturnType())); } } /** * Makes an instance of MemberValue. * * @param cp * the constant pool table. * @param type * the type of the member. * @return the member value * @throws NotFoundException * when the type is not found */ public static MemberValue createMemberValue(ConstPool cp,CtClass type) throws NotFoundException{ if (type == CtClass.booleanType){ return new BooleanMemberValue(cp); }else if (type == CtClass.byteType){ return new ByteMemberValue(cp); }else if (type == CtClass.charType){ return new CharMemberValue(cp); }else if (type == CtClass.shortType){ return new ShortMemberValue(cp); }else if (type == CtClass.intType){ return new IntegerMemberValue(cp); }else if (type == CtClass.longType){ return new LongMemberValue(cp); }else if (type == CtClass.floatType){ return new FloatMemberValue(cp); }else if (type == CtClass.doubleType){ return new DoubleMemberValue(cp); }else if (type.getName().equals("java.lang.Class")){ return new ClassMemberValue(cp); }else if (type.getName().equals("java.lang.String")){ return new StringMemberValue(cp); }else if (type.isArray()){ CtClass arrayType = type.getComponentType(); MemberValue member = createMemberValue(cp, arrayType); return new ArrayMemberValue(member, cp); }else if (type.isInterface()){ Annotation info = new Annotation(cp, type); return new AnnotationMemberValue(info, cp); }else{ // treat as enum. I know this is not typed, // but JBoss has an Annotation Compiler for JDK 1.4 // and I want it to work with that. - Bill Burke EnumMemberValue emv = new EnumMemberValue(cp); emv.setType(type.getName()); return emv; } } /** * Adds a new member. * * @param nameIndex * the index into the constant pool table. * The entry at that index must be * a CONSTANT_Utf8_info structure. * structure representing the member name. * @param value * the member value. */ public void addMemberValue(int nameIndex,MemberValue value){ Pair p = new Pair(); p.name = nameIndex; p.value = value; addMemberValue(p); } /** * Adds a new member. * * @param name * the member name. * @param value * the member value. */ public void addMemberValue(String name,MemberValue value){ Pair p = new Pair(); p.name = pool.addUtf8Info(name); p.value = value; if (members == null){ members = new LinkedHashMap<>(); } members.put(name, p); } private void addMemberValue(Pair pair){ String name = pool.getUtf8Info(pair.name); if (members == null){ members = new LinkedHashMap<>(); } members.put(name, pair); } /** * Returns a string representation of the annotation. */ @Override public String toString(){ StringBuffer buf = new StringBuffer("@"); buf.append(getTypeName()); if (members != null){ buf.append("("); for (String name : members.keySet()){ buf.append(name).append("=").append(getMemberValue(name)).append(", "); } buf.setLength(buf.length() - 2); buf.append(")"); } return buf.toString(); } /** * Obtains the name of the annotation type. * * @return the type name */ public String getTypeName(){ return Descriptor.toClassName(pool.getUtf8Info(typeIndex)); } /** * Obtains all the member names. * * @return null if no members are defined. */ public Set getMemberNames(){ if (members == null){ return null; } return members.keySet(); } /** * Obtains the member value with the given name. * *

* If this annotation does not have a value for the * specified member, * this method returns null. It does not return a * MemberValue with the default value. * The default value can be obtained from the annotation type. * * @param name * the member name * @return null if the member cannot be found or if the value is * the default value. * * @see com.feilong.lib.javassist.bytecode.AnnotationDefaultAttribute */ public MemberValue getMemberValue(String name){ if (members == null || members.get(name) == null){ return null; } return members.get(name).value; } /** * Constructs an annotation-type object representing this annotation. * For example, if this annotation represents @Author, * this method returns an Author object. * * @param cl * class loader for loading an annotation type. * @param cp * class pool for obtaining class files. * @return the annotation * @throws ClassNotFoundException * if the class cannot found. * @throws NoSuchClassError * if the class linkage fails. */ public Object toAnnotationType(ClassLoader cl,ClassPool cp) throws ClassNotFoundException,NoSuchClassError{ Class clazz = MemberValue.loadClass(cl, getTypeName()); try{ return AnnotationImpl.make(cl, clazz, cp, this); }catch (IllegalArgumentException e){ /* * AnnotationImpl.make() may throw this exception * when it fails to make a proxy object for some * reason. */ throw new ClassNotFoundException(clazz.getName(), e); }catch (IllegalAccessError e2){ // also IllegalAccessError throw new ClassNotFoundException(clazz.getName(), e2); } } /** * Writes this annotation. * * @param writer * the output. * @throws IOException * for an error during the write */ public void write(AnnotationsWriter writer) throws IOException{ String typeName = pool.getUtf8Info(typeIndex); if (members == null){ writer.annotation(typeName, 0); return; } writer.annotation(typeName, members.size()); for (Pair pair : members.values()){ writer.memberValuePair(pair.name); pair.value.write(writer); } } @Override public int hashCode(){ return getTypeName().hashCode() + (members == null ? 0 : members.hashCode()); } /** * Returns true if the given object represents the same annotation * as this object. The equality test checks the member values. */ @Override public boolean equals(Object obj){ if (obj == this){ return true; } if (obj == null || obj instanceof Annotation == false){ return false; } Annotation other = (Annotation) obj; if (getTypeName().equals(other.getTypeName()) == false){ return false; } Map otherMembers = other.members; if (members == otherMembers){ return true; }else if (members == null){ return otherMembers == null; }else if (otherMembers == null){ return false; }else{ return members.equals(otherMembers); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy