下面列出了javax.validation.Constraint#javassist.bytecode.annotation.MemberValue 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private List<AnnotationDescriptor> getAnnotationDescriptors(AnnotationsAttribute annotationsAttr) {
if (annotationsAttr == null) {
return Collections.emptyList();
}
List<AnnotationDescriptor> annotationDescriptors = new ArrayList<>(annotationsAttr.numAnnotations());
for (javassist.bytecode.annotation.Annotation annotation : annotationsAttr.getAnnotations()) {
// Sigh: javassist uses raw collections (is this 2002?)
Set<String> memberNames = annotation.getMemberNames();
List<AttributeDescriptor> attributes = new ArrayList<>();
if (memberNames != null) {
for (String name : memberNames) {
MemberValue memberValue = annotation.getMemberValue(name);
final List<String> values = new ArrayList<>();
memberValue.accept(new ListingMemberValueVisitor(values));
attributes.add(new AttributeDescriptor(name, values));
}
}
annotationDescriptors.add(new AnnotationDescriptor(annotation.getTypeName(), attributes));
}
return annotationDescriptors;
}
private List<AnnotationDescriptor> getAnnotationDescriptors(AnnotationsAttribute annotationsAttr) {
List<AnnotationDescriptor> annotationDescriptors = new ArrayList<>(annotationsAttr.numAnnotations());
for (javassist.bytecode.annotation.Annotation annotation : annotationsAttr.getAnnotations()) {
// Sigh: javassist uses raw collections (is this 2002?)
@SuppressWarnings("unchecked")
Set<String> memberNames = annotation.getMemberNames();
List<AttributeDescriptor> attributes = new ArrayList<>();
if (memberNames != null) {
for (String name : memberNames) {
MemberValue memberValue = annotation.getMemberValue(name);
final List<String> values = new ArrayList<>();
memberValue.accept(new ListingMemberValueVisitor(values));
attributes.add(new AttributeDescriptor(name, values));
}
}
annotationDescriptors.add(new AnnotationDescriptor(annotation.getTypeName(), attributes));
}
return annotationDescriptors;
}
@Override
public DynamicField href(boolean click, String... value) {
Annotation annot = new Annotation(Href.class.getName(), cpool);
annot.addMemberValue("click", new BooleanMemberValue(click, cpool));
ArrayMemberValue arrayMemberValue = new ArrayMemberValue(cpool);
MemberValue[] memberValues = new StringMemberValue[value.length];
for(int i = 0; i < value.length; i++) {
memberValues[i] = new StringMemberValue(value[i], cpool);
}
arrayMemberValue.setValue(memberValues);
annot.addMemberValue("value", arrayMemberValue);
attr.addAnnotation(annot);
return this;
}
@Override
public DynamicField image(String download, String... value) {
Annotation annot = new Annotation(Image.class.getName(), cpool);
annot.addMemberValue("download", new StringMemberValue(download, cpool));
ArrayMemberValue arrayMemberValue = new ArrayMemberValue(cpool);
MemberValue[] memberValues = new StringMemberValue[value.length];
for(int i = 0; i < value.length; i++) {
memberValues[i] = new StringMemberValue(value[i], cpool);
}
arrayMemberValue.setValue(memberValues);
annot.addMemberValue("value", arrayMemberValue);
attr.addAnnotation(annot);
return this;
}
static
private void removeValue(ArrayMemberValue memberValue, String value){
List<MemberValue> values = new ArrayList<>(Arrays.asList(memberValue.getValue()));
boolean removed = false;
Iterator<MemberValue> it = values.iterator();
while(it.hasNext()){
StringMemberValue stringValue = (StringMemberValue)it.next();
if((value).equals(stringValue.getValue())){
it.remove();
removed = true;
}
}
if(!removed){
throw new RuntimeException(value + " not in " + values);
}
memberValue.setValue(values.toArray(new MemberValue[values.size()]));
}
@Override
protected void addEndpointMapping(CtMethod ctMethod, String method, String request) {
MethodInfo methodInfo = ctMethod.getMethodInfo();
ConstPool constPool = methodInfo.getConstPool();
AnnotationsAttribute attr = new AnnotationsAttribute(constPool, AnnotationsAttribute.visibleTag);
Annotation requestMapping = new Annotation(RequestMapping.class.getName(), constPool);
ArrayMemberValue valueVals = new ArrayMemberValue(constPool);
StringMemberValue valueVal = new StringMemberValue(constPool);
valueVal.setValue(request);
valueVals.setValue(new MemberValue[]{valueVal});
requestMapping.addMemberValue("value", valueVals);
ArrayMemberValue methodVals = new ArrayMemberValue(constPool);
EnumMemberValue methodVal = new EnumMemberValue(constPool);
methodVal.setType(RequestMethod.class.getName());
methodVal.setValue(method);
methodVals.setValue(new MemberValue[]{methodVal});
requestMapping.addMemberValue("method", methodVals);
attr.addAnnotation(requestMapping);
methodInfo.addAttribute(attr);
}
public static void addClassAnnotation(CtClass clazz, Class<?> annotationClass, Object... values) {
ClassFile ccFile = clazz.getClassFile();
ConstPool constPool = ccFile.getConstPool();
AnnotationsAttribute attr = getAnnotationsAttribute(ccFile);
Annotation annot = new Annotation(annotationClass.getName(), constPool);
for(int i = 0; i < values.length; i = i + 2) {
String valueName = (String)values[i];
Object value = values[i+1];
if (valueName != null && value != null) {
MemberValue memberValue = createMemberValue(constPool, value);
annot.addMemberValue(valueName, memberValue);
}
}
attr.addAnnotation(annot);
}
private Map<String, Optional<MemberValue>> buildMemberValueMap(Annotation annotation) {
Map<String, Optional<MemberValue>> map = new HashMap<>();
@SuppressWarnings("unchecked")
Set<String> memberNames = annotation.getMemberNames();
if (memberNames != null) {
for (String memberName : memberNames) {
MemberValue memberValue = annotation.getMemberValue(memberName);
if (memberValue == null) {
map.put(memberName, Optional.<MemberValue>absent());
} else {
map.put(memberName, Optional.of(memberValue));
}
}
}
return map;
}
private void appendAnnotationElement(StringBuilder sb, String signs, JApiAnnotationElement jApiAnnotationElement, int numberOfTabs) {
sb.append(String.format("%s%s %s ELEMENT: %s=", tabs(numberOfTabs), signs, jApiAnnotationElement.getChangeStatus(), jApiAnnotationElement.getName()));
Optional<MemberValue> oldValue = jApiAnnotationElement.getOldValue();
Optional<MemberValue> newValue = jApiAnnotationElement.getNewValue();
if (oldValue.isPresent() && newValue.isPresent()) {
if (jApiAnnotationElement.getChangeStatus() == JApiChangeStatus.UNCHANGED) {
sb.append(elementValueList2String(jApiAnnotationElement.getNewElementValues()));
} else if (jApiAnnotationElement.getChangeStatus() == JApiChangeStatus.REMOVED) {
sb.append(String.format("%s (-)", elementValueList2String(jApiAnnotationElement.getOldElementValues())));
} else if (jApiAnnotationElement.getChangeStatus() == JApiChangeStatus.NEW) {
sb.append(String.format("%s (+)", elementValueList2String(jApiAnnotationElement.getNewElementValues())));
} else if (jApiAnnotationElement.getChangeStatus() == JApiChangeStatus.MODIFIED) {
sb.append(String.format("%s (<- %s)", elementValueList2String(jApiAnnotationElement.getNewElementValues()), elementValueList2String(jApiAnnotationElement.getOldElementValues())));
}
} else if (!oldValue.isPresent() && newValue.isPresent()) {
sb.append(String.format("%s (+)", elementValueList2String(jApiAnnotationElement.getNewElementValues())));
} else if (oldValue.isPresent() && !newValue.isPresent()) {
sb.append(String.format("%s (-)", elementValueList2String(jApiAnnotationElement.getOldElementValues())));
} else {
sb.append(" n.a.");
}
sb.append("\n");
}
private static MemberValue createMemberValue(ConstPool cp, CtClass type, Object value) throws NotFoundException {
MemberValue memberValue = javassist.bytecode.annotation.Annotation.createMemberValue(cp, type);
if (memberValue instanceof BooleanMemberValue)
((BooleanMemberValue) memberValue).setValue((Boolean) value);
else if (memberValue instanceof ByteMemberValue)
((ByteMemberValue) memberValue).setValue((Byte) value);
else if (memberValue instanceof CharMemberValue)
((CharMemberValue) memberValue).setValue((Character) value);
else if (memberValue instanceof ShortMemberValue)
((ShortMemberValue) memberValue).setValue((Short) value);
else if (memberValue instanceof IntegerMemberValue)
((IntegerMemberValue) memberValue).setValue((Integer) value);
else if (memberValue instanceof LongMemberValue)
((LongMemberValue) memberValue).setValue((Long) value);
else if (memberValue instanceof FloatMemberValue)
((FloatMemberValue) memberValue).setValue((Float) value);
else if (memberValue instanceof DoubleMemberValue)
((DoubleMemberValue) memberValue).setValue((Double) value);
else if (memberValue instanceof ClassMemberValue)
((ClassMemberValue) memberValue).setValue(((Class<?>) value).getName());
else if (memberValue instanceof StringMemberValue)
((StringMemberValue) memberValue).setValue((String) value);
else if (memberValue instanceof EnumMemberValue)
((EnumMemberValue) memberValue).setValue(((Enum<?>) value).name());
/* else if (memberValue instanceof AnnotationMemberValue) */
else if (memberValue instanceof ArrayMemberValue) {
CtClass arrayType = type.getComponentType();
int len = Array.getLength(value);
MemberValue[] members = new MemberValue[len];
for (int i = 0; i < len; i++) {
members[i] = createMemberValue(cp, arrayType, Array.get(value, i));
}
((ArrayMemberValue) memberValue).setValue(members);
}
return memberValue;
}
private MemberValue getMemberValue(Object obj, ConstPool cp) {
if (obj == null) {
return null;
}
if (obj instanceof Integer) {
return new IntegerMemberValue(cp, (Integer) obj);
} else if (obj instanceof Boolean) {
return new BooleanMemberValue((Boolean) obj, cp);
} else if (obj instanceof Double) {
return new DoubleMemberValue((Double) obj, cp);
} else if (obj instanceof Float) {
return new FloatMemberValue((Float) obj, cp);
} else if (obj instanceof Short) {
return new ShortMemberValue((Short) obj, cp);
} else if (obj instanceof String) {
return new StringMemberValue((String) obj, cp);
} else if (obj instanceof String[]) {
String[] oo = (String[]) obj;
MemberValue[] memberValues = new MemberValue[oo.length];
ArrayMemberValue value = new ArrayMemberValue(cp);
for (int i = 0; i < oo.length; i++) {
memberValues[i] = getMemberValue(oo[i], cp);
}
value.setValue(memberValues);
return value;
} else if (obj instanceof Byte) {
return new ByteMemberValue((Byte) obj, cp);
} else if (obj instanceof Annotation) {
return new AnnotationMemberValue((Annotation) obj, cp);
} else if (obj instanceof ArrayMemberValue) {
return new ArrayMemberValue((MemberValue) obj, cp);
} else if (obj instanceof Character) {
return new CharMemberValue((char) obj, cp);
} else if (obj instanceof Long) {
return new LongMemberValue((Long) obj, cp);
}
return null;
}
@Override
public void visitArrayMemberValue(ArrayMemberValue node) {
final MemberValue type = node.getType();
if (type != null && type.toString().endsWith(".class")) {
final String clazz = type.toString();
imports.add(extractClass(clazz));
}
}
private static MemberValue createMemberValue(ConstPool cp, CtClass type, Object value) throws NotFoundException {
MemberValue memberValue = javassist.bytecode.annotation.Annotation.createMemberValue(cp, type);
if (memberValue instanceof BooleanMemberValue)
((BooleanMemberValue) memberValue).setValue((Boolean) value);
else if (memberValue instanceof ByteMemberValue)
((ByteMemberValue) memberValue).setValue((Byte) value);
else if (memberValue instanceof CharMemberValue)
((CharMemberValue) memberValue).setValue((Character) value);
else if (memberValue instanceof ShortMemberValue)
((ShortMemberValue) memberValue).setValue((Short) value);
else if (memberValue instanceof IntegerMemberValue)
((IntegerMemberValue) memberValue).setValue((Integer) value);
else if (memberValue instanceof LongMemberValue)
((LongMemberValue) memberValue).setValue((Long) value);
else if (memberValue instanceof FloatMemberValue)
((FloatMemberValue) memberValue).setValue((Float) value);
else if (memberValue instanceof DoubleMemberValue)
((DoubleMemberValue) memberValue).setValue((Double) value);
else if (memberValue instanceof ClassMemberValue)
((ClassMemberValue) memberValue).setValue(((Class<?>)value).getName());
else if (memberValue instanceof StringMemberValue)
((StringMemberValue) memberValue).setValue((String) value);
else if (memberValue instanceof EnumMemberValue)
((EnumMemberValue) memberValue).setValue(((Enum<?>) value).name());
/* else if (memberValue instanceof AnnotationMemberValue) */
else if (memberValue instanceof ArrayMemberValue) {
CtClass arrayType = type.getComponentType();
int len = Array.getLength(value);
MemberValue[] members = new MemberValue[len];
for (int i = 0; i < len; i ++) {
members[i] = createMemberValue(cp, arrayType, Array.get(value, i));
}
((ArrayMemberValue) memberValue).setValue(members);
}
return memberValue;
}
private static MemberValue createMemberValue(ConstPool cp, CtClass type, Object value) throws NotFoundException {
MemberValue memberValue = javassist.bytecode.annotation.Annotation.createMemberValue(cp, type);
if (memberValue instanceof BooleanMemberValue)
((BooleanMemberValue) memberValue).setValue((Boolean) value);
else if (memberValue instanceof ByteMemberValue)
((ByteMemberValue) memberValue).setValue((Byte) value);
else if (memberValue instanceof CharMemberValue)
((CharMemberValue) memberValue).setValue((Character) value);
else if (memberValue instanceof ShortMemberValue)
((ShortMemberValue) memberValue).setValue((Short) value);
else if (memberValue instanceof IntegerMemberValue)
((IntegerMemberValue) memberValue).setValue((Integer) value);
else if (memberValue instanceof LongMemberValue)
((LongMemberValue) memberValue).setValue((Long) value);
else if (memberValue instanceof FloatMemberValue)
((FloatMemberValue) memberValue).setValue((Float) value);
else if (memberValue instanceof DoubleMemberValue)
((DoubleMemberValue) memberValue).setValue((Double) value);
else if (memberValue instanceof ClassMemberValue)
((ClassMemberValue) memberValue).setValue(((Class<?>)value).getName());
else if (memberValue instanceof StringMemberValue)
((StringMemberValue) memberValue).setValue((String) value);
else if (memberValue instanceof EnumMemberValue)
((EnumMemberValue) memberValue).setValue(((Enum<?>) value).name());
/* else if (memberValue instanceof AnnotationMemberValue) */
else if (memberValue instanceof ArrayMemberValue) {
CtClass arrayType = type.getComponentType();
int len = Array.getLength(value);
MemberValue[] members = new MemberValue[len];
for (int i = 0; i < len; i ++) {
members[i] = createMemberValue(cp, arrayType, Array.get(value, i));
}
((ArrayMemberValue) memberValue).setValue(members);
}
return memberValue;
}
private static MemberValue createMemberValue(ConstPool cp, CtClass type, Object value) throws NotFoundException {
MemberValue memberValue = javassist.bytecode.annotation.Annotation.createMemberValue(cp, type);
if (memberValue instanceof BooleanMemberValue)
((BooleanMemberValue) memberValue).setValue((Boolean) value);
else if (memberValue instanceof ByteMemberValue)
((ByteMemberValue) memberValue).setValue((Byte) value);
else if (memberValue instanceof CharMemberValue)
((CharMemberValue) memberValue).setValue((Character) value);
else if (memberValue instanceof ShortMemberValue)
((ShortMemberValue) memberValue).setValue((Short) value);
else if (memberValue instanceof IntegerMemberValue)
((IntegerMemberValue) memberValue).setValue((Integer) value);
else if (memberValue instanceof LongMemberValue)
((LongMemberValue) memberValue).setValue((Long) value);
else if (memberValue instanceof FloatMemberValue)
((FloatMemberValue) memberValue).setValue((Float) value);
else if (memberValue instanceof DoubleMemberValue)
((DoubleMemberValue) memberValue).setValue((Double) value);
else if (memberValue instanceof ClassMemberValue)
((ClassMemberValue) memberValue).setValue(((Class<?>)value).getName());
else if (memberValue instanceof StringMemberValue)
((StringMemberValue) memberValue).setValue((String) value);
else if (memberValue instanceof EnumMemberValue)
((EnumMemberValue) memberValue).setValue(((Enum<?>) value).name());
/* else if (memberValue instanceof AnnotationMemberValue) */
else if (memberValue instanceof ArrayMemberValue) {
CtClass arrayType = type.getComponentType();
int len = Array.getLength(value);
MemberValue[] members = new MemberValue[len];
for (int i = 0; i < len; i ++) {
members[i] = createMemberValue(cp, arrayType, Array.get(value, i));
}
((ArrayMemberValue) memberValue).setValue(members);
}
return memberValue;
}
private static MemberValue createMemberValue(Class<?> type, Object val, ConstPool cp) {
if (type == String.class) {
return new StringMemberValue((String) val, cp);
} else {
throw new RuntimeException("Only support string param value! Invalid param value type:" + type + " and value: " + val);
}
}
private boolean equals(CtMethod cm, String name, CtClass[] parameters)
throws NotFoundException {
if (!cm.getName().equals(name))
return false;
if (Arrays.equals(cm.getParameterTypes(), parameters))
return true;
if (cm.getParameterTypes().length != 1)
return false;
MethodInfo mi = cm.getMethodInfo();
AnnotationsAttribute ainfo = (AnnotationsAttribute) mi
.getAttribute(AnnotationsAttribute.invisibleTag);
if (ainfo == null)
return false;
Annotation[] anno = ainfo.getAnnotations();
if (anno == null)
return false;
String typeName = ParameterTypes.class.getName();
for (int i = 0; i < anno.length; i++) {
if (anno[i].getTypeName().equals(typeName)) {
ArrayMemberValue mv = (ArrayMemberValue) anno[i]
.getMemberValue("value");
MemberValue[] mvalues = mv.getValue();
if (mvalues.length != parameters.length)
return false;
for (int j = 0; j < mvalues.length; j++) {
ClassMemberValue cmv = (ClassMemberValue) mvalues[j];
if (!parameters[j].getName().equals(cmv.getValue()))
return false;
}
return true;
}
}
return false;
}
private static MemberValue createMemberValue(ConstPool cp, CtClass type, Object value) throws NotFoundException {
MemberValue memberValue = javassist.bytecode.annotation.Annotation.createMemberValue(cp, type);
if (memberValue instanceof BooleanMemberValue)
((BooleanMemberValue) memberValue).setValue((Boolean) value);
else if (memberValue instanceof ByteMemberValue)
((ByteMemberValue) memberValue).setValue((Byte) value);
else if (memberValue instanceof CharMemberValue)
((CharMemberValue) memberValue).setValue((Character) value);
else if (memberValue instanceof ShortMemberValue)
((ShortMemberValue) memberValue).setValue((Short) value);
else if (memberValue instanceof IntegerMemberValue)
((IntegerMemberValue) memberValue).setValue((Integer) value);
else if (memberValue instanceof LongMemberValue)
((LongMemberValue) memberValue).setValue((Long) value);
else if (memberValue instanceof FloatMemberValue)
((FloatMemberValue) memberValue).setValue((Float) value);
else if (memberValue instanceof DoubleMemberValue)
((DoubleMemberValue) memberValue).setValue((Double) value);
else if (memberValue instanceof ClassMemberValue)
((ClassMemberValue) memberValue).setValue(((Class<?>)value).getName());
else if (memberValue instanceof StringMemberValue)
((StringMemberValue) memberValue).setValue((String) value);
else if (memberValue instanceof EnumMemberValue)
((EnumMemberValue) memberValue).setValue(((Enum<?>) value).name());
/* else if (memberValue instanceof AnnotationMemberValue) */
else if (memberValue instanceof ArrayMemberValue) {
CtClass arrayType = type.getComponentType();
int len = Array.getLength(value);
MemberValue[] members = new MemberValue[len];
for (int i = 0; i < len; i ++) {
members[i] = createMemberValue(cp, arrayType, Array.get(value, i));
}
((ArrayMemberValue) memberValue).setValue(members);
}
return memberValue;
}
@Override
public JavassistDynamicBean gecco(String[] matchUrl, String downloader, int timeout, String... pipelines) {
AnnotationsAttribute attr = new AnnotationsAttribute(cpool, AnnotationsAttribute.visibleTag);
Annotation annot = new Annotation(Gecco.class.getName(), cpool);
// matchUrl
//annot.addMemberValue("matchUrl", new StringMemberValue(matchUrl, cpool));
ArrayMemberValue arrayMemberValueMatchUrl = new ArrayMemberValue(cpool);
MemberValue[] elementMatchUrls = new StringMemberValue[matchUrl.length];
for (int i = 0; i < matchUrl.length; i++) {
elementMatchUrls[i] = new StringMemberValue(matchUrl[i], cpool);
}
arrayMemberValueMatchUrl.setValue(elementMatchUrls);
annot.addMemberValue("matchUrl", arrayMemberValueMatchUrl);
// downloader
annot.addMemberValue("downloader", new StringMemberValue(downloader, cpool));
// timeout
annot.addMemberValue("timeout", new IntegerMemberValue(cpool, timeout));
// pipelines
ArrayMemberValue arrayMemberValue = new ArrayMemberValue(cpool);
MemberValue[] elements = new StringMemberValue[pipelines.length];
for (int i = 0; i < pipelines.length; i++) {
elements[i] = new StringMemberValue(pipelines[i], cpool);
}
arrayMemberValue.setValue(elements);
annot.addMemberValue("pipelines", arrayMemberValue);
attr.addAnnotation(annot);
cfile.addAttribute(attr);
return this;
}
/**
* Create a new annotation to be dynamically inserted in the byte code.
*/
protected static void createAnnotation(AnnotationsAttribute attribute, Class<? extends Annotation> annotationType, Map<String, MemberValue> members) {
javassist.bytecode.annotation.Annotation annotation = new javassist.bytecode.annotation.Annotation(annotationType.getName(), attribute.getConstPool());
for (Map.Entry<String, MemberValue> member : members.entrySet()) {
annotation.addMemberValue(member.getKey(), member.getValue());
}
attribute.addAnnotation(annotation);
}
private Annotation copyAnnotation(ConstPool constPool,
java.lang.annotation.Annotation annotation) throws NotFoundException {
// Create annotation from specified type
Annotation byteCodeAnnotation = createAnnotation(
constPool,
annotation.annotationType()
);
// Copy annotation methods
for (Method m : annotation.annotationType().getDeclaredMethods()) {
Object value = invoke(m, annotation);
MemberValue memberValue = createMemberValue(
constPool,
classPool.get(value.getClass().getName())
);
invoke(from(memberValue.getClass())
.method("setValue", new Class[]{value.getClass()})
.orElseThrow(() -> new NotFoundException("Cannot copy value of qualifier parameter "
+ m.getName())),
memberValue,
value);
byteCodeAnnotation.addMemberValue(
m.getName(),
memberValue
);
}
return byteCodeAnnotation;
}
/**
* Iterate the annotations, look for a 'required' parameter, and set it to false.
*/
private void disableBooleanMember(final String booleanMemberName, final CtField field) {
// This is the JCommander package name
final String packageName = JCommander.class.getPackage().getName();
final AnnotationsAttribute fieldAttributes =
(AnnotationsAttribute) field.getFieldInfo().getAttribute(AnnotationsAttribute.visibleTag);
// Look for annotations that have a 'names' attribute, and whose package
// starts with the expected JCommander package.
for (final Annotation annotation : fieldAttributes.getAnnotations()) {
if (annotation.getTypeName().startsWith(packageName)) {
// See if it has a 'names' member variable.
final MemberValue requiredMember = annotation.getMemberValue(booleanMemberName);
// We have a names member!!!
if (requiredMember != null) {
final BooleanMemberValue booleanRequiredMember = (BooleanMemberValue) requiredMember;
// Set it to not required.
booleanRequiredMember.setValue(false);
// This is KEY! For some reason, the existing annotation
// will not be modified unless
// you call 'setAnnotation' here. I'm guessing
// 'getAnnotation()' creates a copy.
fieldAttributes.setAnnotation(annotation);
// Finished processing names.
break;
}
}
}
}
private String getStringMemberValue(Annotation aAnnotation, String aValue) {
MemberValue v = aAnnotation.getMemberValue(aValue);
if (v == null) {
return "";
} else {
return ((StringMemberValue) v).getValue();
}
}
private MemberValue memberValue(Class<?> type, Object value) {
if (type.isArray()) {
Object[] array = (Object[]) value;
MemberValue[] memberValues = new MemberValue[array.length];
Class<?> componentType = type.getComponentType();
for (int i = 0; i < array.length; i++) {
memberValues[i] = memberValue(componentType, array[i]);
}
ArrayMemberValue arrayMemberValue = new ArrayMemberValue(constPool);
arrayMemberValue.setValue(memberValues);
return arrayMemberValue;
} else {
if (type == int.class) {
return new IntegerMemberValue(constPool, (int) value);
} else if (long.class.equals(type)) {
return new LongMemberValue((long) value, constPool);
} else if (short.class.equals(type)) {
return new ShortMemberValue((short) value, constPool);
} else if (byte.class.equals(type)) {
return new ByteMemberValue((byte) value, constPool);
} else if (char.class.equals(type)) {
return new CharMemberValue((char) value, constPool);
} else if (float.class.equals(type)) {
return new FloatMemberValue((float) value, constPool);
} else if (double.class.equals(type)) {
return new DoubleMemberValue((double) value, constPool);
} else if (String.class.equals(type)) {
return new StringMemberValue((String) value, constPool);
} else if (boolean.class.equals(type)) {
return new BooleanMemberValue((boolean) value, constPool);
} else if (Class.class.equals(type)) {
return new ClassMemberValue(((Class) value).getName(), constPool);
} else if (Enum.class.isAssignableFrom(type)) {
EnumMemberValue enumMemberValue = new EnumMemberValue(constPool);
enumMemberValue.setType(type.getName());
enumMemberValue.setValue(((Enum) value).name());
return enumMemberValue;
} else {
throw new ApplicationException("unsupported annotation method type, type={}", type);
}
}
}
@Override
public Validator createValidator(TableMetaData tableMetaData) {
Proxy<MapBean> proxy = Proxy.create(MapBean.class);
StringBuilder keySet = new StringBuilder("public java.util.Set keySet(){\n return new java.util.HashSet(java.util.Arrays.asList(new String[]{");
int index = 0;
for (ColumnMetaData column : tableMetaData.getColumns()) {
String propertyName = column.getAlias();
Class type = column.getJavaType();
String typeName = type.getName();
if (index++ > 0) {
keySet.append(",");
}
keySet.append("\"")
.append(propertyName)
.append("\"");
proxy.custom(ctClass -> {
try {
CtField ctField = CtField.make("private " + type.getName() + " " + propertyName + ";", ctClass);
List<JSR303AnnotationInfo> jsr303 = createValidatorAnnotation(column.getValidator());
//添加注解
if (!CollectionUtils.isEmpty(jsr303)) {
ConstPool constPool = ctClass.getClassFile().getConstPool();
AnnotationsAttribute attributeInfo = new AnnotationsAttribute(constPool, AnnotationsAttribute.visibleTag);
for (JSR303AnnotationInfo jsr303AnnotationInfo : jsr303) {
Class<? extends java.lang.annotation.Annotation> jsr303Ann = jsr303AnnotationInfo.getAnnotation();
Annotation ann = new javassist.bytecode.annotation.Annotation(jsr303Ann.getName(), constPool);
if (!CollectionUtils.isEmpty(jsr303AnnotationInfo.getProperties())) {
jsr303AnnotationInfo.getProperties().forEach((key, value) -> {
MemberValue memberValue = createMemberValue(value, constPool);
if (memberValue != null) {
ann.addMemberValue(key, memberValue);
}
});
}
attributeInfo.addAnnotation(ann);
}
ctField.getFieldInfo().addAttribute(attributeInfo);
}
ctClass.addField(ctField);
} catch (Exception e) {
throw new RuntimeException(e);
}
});
proxy.addMethod("public void set" + StringUtils.toUpperCaseFirstOne(propertyName) + "(" + typeName + " " + propertyName + "){\n" +
"this." + propertyName + "=" + propertyName + ";\n" +
"\n};");
proxy.addMethod("public " + typeName + " get" + StringUtils.toUpperCaseFirstOne(propertyName) + "(){\n" +
"return this." + propertyName + ";\n" +
"\n};");
}
keySet.append("}));\n}");
proxy.addMethod(keySet.toString());
proxy.addMethod(createSetPropertyCode(tableMetaData));
proxy.addMethod(createGetPropertyCode(tableMetaData));
//尝试一下能否创建实例
MapBean mapBean = proxy.newInstance();
Assert.notNull(mapBean, "创建验证器失败!");
return new DynamicBeanValidator(proxy::newInstance);
}
/**
* Create a new annotation to be dynamically inserted in the byte code.
*/
protected static void createAnnotation(AnnotationsAttribute attribute, Class<? extends Annotation> annotationType) {
createAnnotation(attribute, annotationType, new HashMap<String, MemberValue>());
}
/**
* Iterate the annotations, look for a 'names' parameter, and override it to prepend the given
* prefix.
*/
private void overrideParameterPrefixes(final CtField field, final String[] names) {
// This is the JCommander package name
final String packageName = JCommander.class.getPackage().getName();
final AnnotationsAttribute fieldAttributes =
(AnnotationsAttribute) field.getFieldInfo().getAttribute(AnnotationsAttribute.visibleTag);
// Look for annotations that have a 'names' attribute, and whose package
// starts with the expected JCommander package.
for (final Annotation annotation : fieldAttributes.getAnnotations()) {
if (annotation.getTypeName().startsWith(packageName)) {
// See if it has a 'names' member variable.
final MemberValue namesMember = annotation.getMemberValue(NAMES_MEMBER);
// We have a names member!!!
if (namesMember != null) {
final ArrayMemberValue arrayNamesMember = (ArrayMemberValue) namesMember;
// Iterate and transform each item in 'names()' list and
// transform it.
final MemberValue[] newMemberValues = new MemberValue[names.length];
for (int i = 0; i < names.length; i++) {
newMemberValues[i] =
new StringMemberValue(names[i], field.getFieldInfo2().getConstPool());
}
// Override the member values in nameMember with the new
// one's we've generated
arrayNamesMember.setValue(newMemberValues);
// This is KEY! For some reason, the existing annotation
// will not be modified unless
// you call 'setAnnotation' here. I'm guessing
// 'getAnnotation()' creates a copy.
fieldAttributes.setAnnotation(annotation);
// Finished processing names.
break;
}
}
}
}
/**
* This function will take the given annotations attribute and create a new attribute, cloning all
* the annotations and specified values within the attribute. The annotations attribute can then
* be set on a method, class, or field.
*/
public static AnnotationsAttribute cloneAnnotationsAttribute(
final ConstPool constPool,
final AnnotationsAttribute attr,
final ElementType validElementType) {
// We can use system class loader here because the annotations for
// Target
// are part of the Java System.
final ClassLoader cl = ClassLoader.getSystemClassLoader();
final AnnotationsAttribute attrNew =
new AnnotationsAttribute(constPool, AnnotationsAttribute.visibleTag);
if (attr != null) {
for (final Annotation annotation : attr.getAnnotations()) {
final Annotation newAnnotation = new Annotation(annotation.getTypeName(), constPool);
// If this must target a certain type of field, then ensure we
// only
// copy over annotations that can target that type of field.
// For instances, a METHOD annotation can't be applied to a
// FIELD or TYPE.
Class<?> annoClass;
try {
annoClass = cl.loadClass(annotation.getTypeName());
final Target target = annoClass.getAnnotation(Target.class);
if ((target != null) && !Arrays.asList(target.value()).contains(validElementType)) {
continue;
}
} catch (final ClassNotFoundException e) {
// Cannot apply this annotation because its type cannot be
// found.
LOGGER.error("Cannot apply this annotation because it's type cannot be found", e);
continue;
}
// Copy over the options for this annotation. For example:
// @Parameter(names = "-blah")
// For this, a member value would be "names" which would be a
// StringMemberValue
if (annotation.getMemberNames() != null) {
for (final Object memberName : annotation.getMemberNames()) {
final MemberValue memberValue = annotation.getMemberValue((String) memberName);
if (memberValue != null) {
newAnnotation.addMemberValue((String) memberName, memberValue);
}
}
}
attrNew.addAnnotation(newAnnotation);
}
}
return attrNew;
}