javapoet
A Java API for generating .java source files.
How would I generate a method with the following signature?
public <T extends MyClass> void doSomething(T t)
So far I have:
MethodSpec.methodBuilder("doSomething")
.addModifiers(Modifier.PUBLIC)
.addTypeVariable(TypeVariableName.get("T", MyClass.class))
.build()
EDIT This is what the above code is generating (I don't know how to add the parameter):
public <T extends Myclass> void doSomething()
Source: (StackOverflow)
I'm generating code with JavaPoet.
Somewhere in the generated code I want to add a method which has the following argument.
...
public B someMethod(final AbstractObjectBuilder<Persoon,?> builder) {
...
}
...
So my JavaPoet code should look something like this
//This does not compile, since I don't know what to put as last argument (questionmark)
ParameterizedTypeName parameterizedTypeName = ParameterizedTypeName.get(AbstractObjectBuilder.class, propertyType,?);
ParameterSpec parameterSpec = ParameterSpec.builder(parameterizedTypeName, name+"Builder", Modifier.FINAL).build();
MethodSpec modMethod = MethodSpec.methodBuilder(name)
.addModifiers(Modifier.PUBLIC)
.addParameter(parameterSpec)
.returns(TypeVariableName.get("B"));
...
Source: (StackOverflow)
I have been experimenting with code generation in an annotation processor.
Consider the following piece of code that adds a constructor that has a statement in it.
private void addRegister(ExecutableElement el) {
MethodSpec builder = MethodSpec.constructorBuilder().addStatement("$T.register(this)", EventExecutor.class).build();
TypeSpec spec = TypeSpec.classBuilder(el.getEnclosingElement().getSimpleName().toString()).addOriginatingElement(el).addMethod(builder).build();
JavaFile file = JavaFile.builder(pEnv.getElementUtils().getPackageOf(el.getEnclosingElement()).getQualifiedName().toString(), spec).build();
pEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, file.toString());
}
Now, when given an executable element named "bla" in class "Test" the result is this:
class Test {
Test() {
EventExecutor.register(this);
}
}
However this class already exists and I want to append the constructor to the existing code rather than create this fresh class here.
Existing code:
public class Test {
@Event
public void bla(TestEvent event) {
}
}
Can I do this?
Source: (StackOverflow)
I am writing a code generator using JavaPoet and need to put an annotation on the class
For example :
package some.package
import org.hibernate.annotations.CacheConcurrencyStrategy;
import javax.persistence.Entity;
import javax.persistence.Cache
@Entity
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class SomeClass {
}
My code looks like this:
TypeSpec spec = TypeSpec
.classBuilder("SomeClass")
.addAnnotation(Entity.class)
.addAnnotation(AnnotationSpec.builder(Cache.class)
.addMember("usage", "$L", CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
.build())
.build()
This code generates the class but the resulting code is missing the import statement for the CacheConcurrencyStrategy.
How can I generate the code so that all the required code is outputted?
Source: (StackOverflow)
Is it possible to generate static initializer using javapoet
? See an example of what I'm trying to generate below:
class Foo {
static int one = 1;
static int two = 2;
static int sum;
static {
sum = one + two;
}
}
I tried adding static initializer as a constructor with static
modifier:
TypeSpec.classBuilder("Foo")
.addField(FieldSpec.builder(int.class, "one", Modifier.STATIC).initializer("1").build())
.addField(FieldSpec.builder(int.class, "two", Modifier.STATIC).initializer("2").build())
.addField(int.class, "sum", Modifier.STATIC)
.addMethod(MethodSpec.constructorBuilder()
.addModifier(Modifier.STATIC)
.addCode("sum = one + two;")
.build())
.build();
But this produces static Foo() { ... }
instead of static {...}
, which is incorrect syntax.
Is there a way to do it?
Source: (StackOverflow)
How could I generate the following:
class A extends B<A> {}
I'm stuck at constructing the ParameterizedTypeName to add the super class, I cannot seem to find a way to reference the type of A before it is constructed...
Any pointers? Is this at all possible?
Source: (StackOverflow)
I am writing an annotation Processor that generates Agenerated class from an annotated A class.
I would like to be able to do something like
AgeneratedInst.getFoo().getBar()...
In order to do so I have to specify the return type wich is the current class I am writing...Is there a way to do so?
Source: (StackOverflow)
I need to compare the annotated type of a field (or method parameter) with a ParameterSpec instance. The name of the parameter does not matter in this context. The context is somewhat related to the unresolved issue 136.
The following tests are green - but the comparing code uses not so type-safe string conversions. Who can think of a more type-safe approach?
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.AnnotatedType;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import org.junit.Assert;
import org.junit.Test;
import com.squareup.javapoet.ParameterSpec;
@SuppressWarnings("javadoc")
public class JavaPoetTest {
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.PARAMETER, ElementType.TYPE_USE })
@interface Tag {}
public static int n;
public static @Tag int t;
public static boolean isParameterSpecSameAsAnnotatedType(ParameterSpec parameter, AnnotatedType type) {
if (!parameter.type.toString().equals(type.getType().getTypeName()))
return false;
List<String> specAnnotations = parameter.annotations.stream()
.map(a -> a.type.toString())
.collect(Collectors.toList());
List<String> typeAnnotations = Arrays.asList(type.getAnnotations()).stream()
.map(a -> a.toString().replace('$', '.').replace("()", "").replace("@", ""))
.collect(Collectors.toList());
return specAnnotations.equals(typeAnnotations);
}
@Test
public void testN() throws Exception {
AnnotatedType annotatedType = JavaPoetTest.class.getField("n").getAnnotatedType();
ParameterSpec parameterSpec = ParameterSpec.builder(int.class, "name").build();
Assert.assertTrue(isParameterSpecSameAsAnnotatedType(parameterSpec, annotatedType));
}
@Test
public void testT() throws Exception {
AnnotatedType annotatedType = JavaPoetTest.class.getField("t").getAnnotatedType();
ParameterSpec parameterSpec = ParameterSpec.builder(int.class, "name").addAnnotation(Tag.class).build();
Assert.assertTrue(isParameterSpecSameAsAnnotatedType(parameterSpec, annotatedType));
}
}
Source: (StackOverflow)
I've built an annotation processor for my Android project that builds a source file using JavaPoet. However, every time I need to call addModifiers
on any JavaPoet object, Android Studio flags it as an error. It will say either
Cannot resolve method addModifiers(javax.lang.model.element.Modifier)
or
addModifiers(javax.lang.model.element.Modifier) cannot be applied to javax.lang.model.element.Modifier
depending on which object I'm calling the method on. I've checked many times that the two fully qualified class names match perfectly. These methods in JavaPoet use VarArgs arguments, but that shouldn't make a difference since I'm compiling to Java 7.
Now here's the kicker: The package compiles just fine, and creates my source file. It only gives me the error in the IDE, not when javac runs. The modifiers are correct in the generated file.
So I guess what I want answered is: How do I get rid of the IDE error, and who do I report this to? Is this a JavaPoet issue, an Android Studio issue, or an IntelliJ issue, or something I haven't considered yet?
Source: (StackOverflow)
I use JavaPoet to create Java code. I defined the following array:
String[] testArr = new String[] {"1","2"};
and a constructor:
ArrayTypeName stringArray = ArrayTypeName.of(String.class);
MethodSpec constroctMethod = MethodSpec.constructorBuilder()
.addModifiers(Modifier.PUBLIC)
.addStatement("$T names", stringArray)
.addStatement("names = $N", testArr)
.build();
The former does not work. I want to create the statement:
String[] names = new String[] {"1","2"};
How can I assign an Array to a Statement like in the previous line?
Source: (StackOverflow)
I am writing a code generator using JavaPoet and need to put an annotation on a class
For example :
@RequestMapping("/api")
public class SomeResource {
// rest of the code elided
}
I am able to get this far:
TypeSpec spec = TypeSpec
.classBuilder("SomeResource")
.addAnnotation(AnnotationSpec.builder(RequestMapping.class)
// what should go here?
.build())
.build();
There is an addMember method in the AnnotationSpec.Builder but that does not appear to do what I want.
Source: (StackOverflow)