Sander_M
Sander_M

Reputation: 1119

Roaster: How to provide a custom parameter value with an annotation?

Given the following:

public class CodeGenerator {

    private final static String PACKAGE = "nl.sander.mieras";
    private final static String CLASS = "Person";
    private final static Class<String> DATA_TYPE = String.class;
    private static final String INDEX = "index";
    private List<String> columnNames;

    public CodeGenerator() {
        columnNames = new ArrayList<>();
        columnNames.add("personId");
        columnNames.add("firstName");
        System.out.println(generateClass());
    }

    private String generateClass() {
        final JavaClassSource javaClass = Roaster.create(JavaClassSource.class);
        javaClass.setPackage(PACKAGE).setName(CLASS);
        int columnCount = -1;
        for (String columnName : columnNames) {
            columnCount++;
            String columnIndex = Integer.toString(columnCount);         
            javaClass.addProperty(DATA_TYPE, columnName).getField()
                    .addAnnotation(com.univocity.parsers.annotations.Parsed.class)
                    .addAnnotationValue(INDEX);                     
        }

        return javaClass.toString();
    }

}

the output looks like this:

public class Person {

    @Parsed(index = @MISSING)
    private String personId;
    @Parsed(index = @MISSING)
    private String firstName;

    public String getPersonId() {
        return personId;
    }

    public void setPersonId(String personId) {
        this.personId = personId;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
}

How do I add a parameter (in this case a counter) to the annotation using the roaster library to get the following result?

@Parsed(index = 0)
private String personId;

I tried some methods with no succes...

Using setAnnotationValue():

javaClass.addProperty(DATA_TYPE, columnName).getField()
                    .addAnnotation(com.univocity.parsers.annotations.Parsed.class)
                    .addAnnotationValue(INDEX).setAnnotationValue(columnIndex);

Throws

Exception in thread "main" java.lang.ClassCastException: org.jboss.forge.roaster._shade.org.eclipse.jdt.core.dom.SingleMemberAnnotation cannot be cast to org.jboss.forge.roaster._shade.org.eclipse.jdt.core.dom.NormalAnnotation
    at org.jboss.forge.roaster.model.impl.AnnotationImpl.setAnnotationValue(AnnotationImpl.java:597)
    at nl.sander.mieras.CodeGenerator.generateClass(CodeGenerator.java:33)
    at nl.sander.mieras.CodeGenerator.<init>(CodeGenerator.java:21)
    at nl.sander.mieras.Main.main(Main.java:6)

and using setLiteralValue() method:

javaClass.addProperty(DATA_TYPE, columnName).getField()
                    .addAnnotation(com.univocity.parsers.annotations.Parsed.class)
                    .addAnnotationValue(INDEX).setLiteralValue(columnIndex);

results in:

@Parsed(index = @MISSING(0))
private String personId;

The tests from https://github.com/forge/roaster/blob/master/tests/src/test/java/org/jboss/forge/test/roaster/model/common/AnnotationTest.java show some use cases but I can't figure out how to get the result that I want.

Upvotes: 0

Views: 1147

Answers (1)

jNayden
jNayden

Reputation: 1620

I guess you know the answer 4 months later, but ... in short it should be like that :

property.addAnnotation(annotation)
                .setLiteralValue(
                        "index", "0");

Keep in mind if you need string..., then it is a bit stranger, since you need to put an extra " so it become

property.addAnnotation(annotation)
                .setLiteralValue(
                        "index", "\"string-value\"");

Upvotes: 1

Related Questions