/* * Copyright 2016, Stuart Douglas, and individual contributors as indicated * by the @authors tag. * * 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.fakereplace.data; import java.lang.reflect.Array; import java.lang.reflect.Method; import javassist.bytecode.ConstPool; import javassist.bytecode.annotation.Annotation; 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.MemberValue; import javassist.bytecode.annotation.ShortMemberValue; import javassist.bytecode.annotation.StringMemberValue; /** * Created a Javassist Annotation from a java one * * @author stuart */ public class AnnotationBuilder { public static javassist.bytecode.annotation.Annotation createJavassistAnnotation(java.lang.annotation.Annotation annotation, ConstPool cp) { try { javassist.bytecode.annotation.Annotation a = new Annotation(annotation.annotationType().getName(), cp); for (Method m : annotation.annotationType().getDeclaredMethods()) { Object val = m.invoke(annotation); a.addMemberValue(m.getName(), createMemberValue(m.getReturnType(), val, cp)); } return a; } catch (Exception e) { throw new RuntimeException(e); } } private static MemberValue createMemberValue(Class<?> type, Object val, ConstPool cp) { if (type == int.class) { return new IntegerMemberValue(cp, (Integer) val); } else if (type == short.class) { return new ShortMemberValue((Short) val, cp); } else if (type == long.class) { return new LongMemberValue((Long) val, cp); } else if (type == byte.class) { return new ByteMemberValue((Byte) val, cp); } else if (type == float.class) { return new FloatMemberValue((Float) val, cp); } else if (type == double.class) { return new DoubleMemberValue((Double) val, cp); } else if (type == char.class) { return new CharMemberValue((Character) val, cp); } else if (type == boolean.class) { return new BooleanMemberValue((Boolean) val, cp); } else if (type == String.class) { return new StringMemberValue((String) val, cp); } else if (type == Class.class) { return new ClassMemberValue(((Class<?>) val).getName(), cp); } else if (type.isEnum()) { EnumMemberValue e = new EnumMemberValue(cp); e.setType(type.getName()); e.setValue(((Enum<?>) val).name()); return e; } else if (type.isAnnotation()) { return new AnnotationMemberValue(createJavassistAnnotation((java.lang.annotation.Annotation) val, cp), cp); } else if (type.isArray()) { Class<?> arrayType = type.getComponentType(); int length = Array.getLength(val); MemberValue arrayval = createEmptyMemberValue(arrayType, cp); ArrayMemberValue ret = new ArrayMemberValue(arrayval, cp); MemberValue[] vals = new MemberValue[length]; for (int i = 0; i < length; ++i) { vals[i] = createMemberValue(arrayType, Array.get(val, i), cp); } ret.setValue(vals); return ret; } throw new RuntimeException("Invalid array type " + type + " value: " + val); } private static MemberValue createEmptyMemberValue(Class<?> type, ConstPool cp) { if (type == int.class) { return new IntegerMemberValue(cp); } else if (type == short.class) { return new ShortMemberValue(cp); } else if (type == long.class) { return new LongMemberValue(cp); } else if (type == byte.class) { return new ByteMemberValue(cp); } else if (type == float.class) { return new FloatMemberValue(cp); } else if (type == double.class) { return new DoubleMemberValue(cp); } else if (type == char.class) { return new CharMemberValue(cp); } else if (type == boolean.class) { return new BooleanMemberValue(cp); } else if (type == String.class) { return new StringMemberValue(cp); } else if (type == Class.class) { return new ClassMemberValue(cp); } else if (type.isEnum()) { EnumMemberValue e = new EnumMemberValue(cp); e.setType(type.getName()); return e; } else if (type.isAnnotation()) { AnnotationMemberValue a = new AnnotationMemberValue(cp); return a; } else if (type.isArray()) { Class<?> arrayType = type.getComponentType(); MemberValue arrayval = createEmptyMemberValue(arrayType, cp); ArrayMemberValue ret = new ArrayMemberValue(arrayval, cp); return ret; } throw new RuntimeException("Invalid array type " + type + " with no value "); } }