package japicmp.maven.util;
import japicmp.util.ModifierHelper;
import javassist.CannotCompileException;
import javassist.CtClass;
import javassist.CtField;
import javassist.Modifier;
import javassist.bytecode.AnnotationsAttribute;
import javassist.bytecode.ClassFile;
import javassist.bytecode.ConstPool;
import javassist.bytecode.annotation.Annotation;
import java.util.ArrayList;
import java.util.List;
public class CtFieldBuilder {
public static final String DEFAULT_FIELD_NAME = "field";
private CtClass type = CtClass.intType;
private String name = DEFAULT_FIELD_NAME;
private int modifier = Modifier.PUBLIC;
private List<String> annotations = new ArrayList<>();
private Object constantValue = null;
public CtFieldBuilder type(CtClass ctClass) {
this.type = ctClass;
return this;
}
public CtFieldBuilder name(String name) {
this.name = name;
return this;
}
public CtFieldBuilder syntheticModifier() {
this.modifier = this.modifier | ModifierHelper.ACC_SYNTHETIC;
return this;
}
public CtField addToClass(CtClass ctClass) throws CannotCompileException {
CtField ctField = new CtField(this.type, this.name, ctClass);
ctField.setModifiers(this.modifier);
if (constantValue != null) {
if (constantValue instanceof Boolean) {
ctClass.addField(ctField, CtField.Initializer.constant((Boolean) constantValue));
} else if (constantValue instanceof Integer) {
ctClass.addField(ctField, CtField.Initializer.constant((Integer) constantValue));
} else if (constantValue instanceof Long) {
ctClass.addField(ctField, CtField.Initializer.constant((Long) constantValue));
} else if (constantValue instanceof String) {
ctClass.addField(ctField, CtField.Initializer.constant((String) constantValue));
} else {
throw new IllegalArgumentException("Provided constant value for field is of unsupported type: " + constantValue.getClass().getName());
}
} else {
ctClass.addField(ctField);
}
for (String annotation : annotations) {
ClassFile classFile = ctClass.getClassFile();
ConstPool constPool = classFile.getConstPool();
AnnotationsAttribute attr = new AnnotationsAttribute(constPool, AnnotationsAttribute.visibleTag);
Annotation annot = new Annotation(annotation, constPool);
attr.setAnnotation(annot);
ctField.getFieldInfo().addAttribute(attr);
}
return ctField;
}
public static CtFieldBuilder create() {
return new CtFieldBuilder();
}
public CtFieldBuilder withAnnotation(String annotation) {
this.annotations.add(annotation);
return this;
}
public CtFieldBuilder staticAccess() {
this.modifier = this.modifier | Modifier.STATIC;
return this;
}
public CtFieldBuilder privateAccess() {
this.modifier = this.modifier & ~Modifier.PUBLIC;
this.modifier = this.modifier | Modifier.PRIVATE;
return this;
}
public CtFieldBuilder packageProtectedAccess() {
this.modifier = this.modifier & ~Modifier.PUBLIC;
return this;
}
public CtFieldBuilder protectedAccess() {
this.modifier = this.modifier & ~Modifier.PROTECTED;
return this;
}
public CtFieldBuilder finalAccess() {
this.modifier = this.modifier | Modifier.FINAL;
return this;
}
public CtFieldBuilder withConstantValue(Object value) {
this.constantValue = value;
return this;
}
}