1. This annotation causes all parameters from value attribute to be inherited. Remember that value
must be an annotation.
2. Kendal handlers handling value will receive also annotations that inherit parameters from value
using @Inherit.
Note that this relation is transitive.
This annotation will add named parameter to all usages of annotated annotation.
Use @Attribute.List to add multiple parameters.
Parameters will be added to usages of annotation before handlers are called.
Use @AttrReference as placeholder for values of any other attributes.
Java does not allow using parameters of annotation to define other parameters of the same annotation.
But sometimes we want to, so here we introduce annotation that will be replaced with value of another parameter.
It can be used only inside value expression for @Attribute.
Some expressions using @AttrReference will cause the compiler to break compilation before annotation processing -
in such case @AttrReference will never work. This feature is currently considered a proof of concept showing that it
is possible to access other attributes of annotation to define value of attribute.
public class SomeClass {
class CsvTransformer {
String transform(List<Object> inputCollection) {
return "imagine here is the original collection serialized to csv";
}
}
@RequestMapping(value = "/method1", method = "POST")
public List<Object> method1(RequestBody body) {
List<Object> result = new ArrayList();
// some logic
return result;
}
@RequestMapping(value = "/method2", method = "POST")
public List<Object> method2(RequestBody body) {
List<Object> result = new ArrayList();
// some logic
return result;
}
@AnotherAnnotation
@RequestMapping(value = "/method1/csv", method = "POST")
public String method1Csv(RequestBody body) {
List<Object> result = new ArrayList();
// some logic
return new CsvTransformer().transform(result);
}
@AnotherAnnotation
@RequestMapping(value = "/method2/csv", method = "POST")
public String method2Csv(RequestBody body) {
List<Object> result = new ArrayList();
// some logic
return new CsvTransformer().transform(result);
}
@interface AnotherAnnotation {}
}
Impossible!
public class SomeClass {
@Inherit(@Clone(transformer = CsvTransformer.class))
@Attribute(name = "onMethod", value = {@RequestMapping(value = @AttrReference("endpoint"), method = "POST"),
@AnotherAnnotation})
@interface CsvEndpoint {
String endpoint();
}
class CsvTransformer implements Clone.Transformer<List<Object>, String> {
@Override
public String transform(List<Object> inputCollection) {
return "imagine here is the original collection serialized to csv";
}
}
@CsvEndpoint(endpoint = "method1/csv", methodName = "method1Csv")
@RequestMapping(value = "/method1", method = "POST")
public List<Object> method1(RequestBody body) {
List<Object> result = new ArrayList();
// some logic
return result;
}
@CsvEndpoint(endpoint = "method2/csv", methodName = "method2Csv")
@RequestMapping(value = "/method2", method = "POST")
public List<Object> method2(RequestBody body) {
List<Object> result = new ArrayList();
// some logic
return result;
}
@interface AnotherAnnotation {}
}
class SomeClass {
int primitiveField;
SomeClass(int primitiveField) {
this.primitiveField = primitiveField;
}
private int aMethod() {
return this.primitiveField + 15;
}
}
class SomeClass {
SomeClass(@Private(makeFinal = false) int primitiveField) { }
private int aMethod() {
return this.primitiveField + 15;
}
}
class SomeClass {
SomeClass(@PrivateNotFinal int primitiveField) { }
private int aMethod() {
return this.primitiveField + 15;
}
@Inherit(@Private(makeFinal = false))
@Target(ElementType.PARAMETER)
@interface PrivateNotFinal { }
}