Is it possible to conditionally apply annotation in an annotation? - java

I'm trying to do something like the following:
#Target(ElementType.TYPE)
#Retention(RetentionPolicy.RUNTIME)
public #interface AnnotationOne {
boolean annotationTwoToggler() default false
{
if (annotationTwoToggler) {
// Apply annotation AnnotationTwo to calling type
}
}
}
An example of how I would use this:
#AnnotationOne(true) // Implies AnnotationTwo
public class MyClass { ... }
AnnotationTwo and its implementations are in the API that I'm using, and cannot be changed. I want to cause all implementations of AnnotationTwo to trigger given a true parameter to AnnotationOne.
How can I do this?

Related

Add an annotation to check if any of the class object fields is null java

I want to add an annotation which essentially verifies if any of the fields in the java class object is null. It should return true if any of the object values is null, otherwise false.. i.e
#NameBinding
#Target({ElementType.METHOD, ElementType.TYPE})
#Retention(RetentionPolicy.CLASS)
public #interface IsNull {}
I should be able to use this annotation on any of the classes
Eg:
#IsNull
public class EmployeeRequest {
String name;
}
Usage:
EmployeeRequest empRequest = new EmployeeRequest();
if(empRequest.isNull())
fail request
Is this possible?
I want to add this as an annotation because , i want to use this isNull on different classes.

Define custom annotation within another custom annotation with default value

I am trying to declare custom annotation in following way:
Retention(RetentionPolicy.RUNTIME)
#Target({ElementType.TYPE, ElementType.METHOD})
public #interface InnerAnnotation {
}
Retention(RetentionPolicy.RUNTIME)
#Target({ElementType.TYPE, ElementType.METHOD})
public #interface OuterAnnotation {
public String default "";
public InnerAnnotation innerAnnotation(); //here I wanted to do "public InnerAnnotation innerAnnotation() default {some default value}"
}
I wanted to use it in a way:
class first{
#OuterAnnotation(value = "new") //wanted to declare something like this without need to define innerAnnotation
public void func(){
}
}
I wanted to assign some default value to inner annotation usage(so that I don't have to provide any mandatory value while using it), but some how I am not able to do that as compiler asks for compile time constant for this.Can any please suggest how to use inner annotation with any default value ?
The syntax for what you what is as follows:
#Retention(RetentionPolicy.RUNTIME)
#Target({ElementType.TYPE, ElementType.METHOD})
public #interface OuterAnnotation {
public String default "";
public InnerAnnotation innerAnnotation() default #InnerAnnotation(); //this does the trick;
}

Can we set Annotation id at runtime

Is there a way by which I can set the id inside annotated method...
Annotation class:
import java.lang.annotation.*;
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.METHOD)
public
#interface MyAnnotation {
int id();
}
//Set id at runtime
public class A {
#MyAnnotation(id = ? )
public void method1() {
// I want to set the id here for my annotation...
}
}
Yes, but it's a bit unintuitive. You'll have to edit its bytecode using a tool like JavaAssist.
Here is an article describing what you're after.

Java annotation to determine whether the annotated method executes

In my methods, all my code is in an if block, testing certain condition.
public void myMethod() {
if (/* some condition */) {
//do something
}
}
I would like to do this by annotation - meaning the annotation will execute some code that will "decide" whether or not the method should be invoked.
#AllowInvokeMethod(/* some parameters to decide */)
public void myMethod() {
//do something (if annotation allows invokation)
}
Is this possible?
You can use Spring AOP to create an ASpect to advise methods that are annotated your custom annotation
For example create an FilteredExecution annotation to be specified on your methods
#Target(ElementType.METHOD)
#Retention(RetentionPolicy.RUNTIME)
public #interface FilteredExecution{
Class<? extends ExecutionFilter> value();
}
ExecutionFilter is an interface to decide whether execution should occur
public interface ExecutionFilter{
boolean sholudExecute();
}
Then the aspect
#Aspect
#Component
public class FilteredExceutionAspect{
#Around("#annotion(filterAnnotation)")
public void filter(ProceedingJoinPoint pjp , FilteredExecution filterAnnotation){
boolean shouldExecute = checkShouldExecute(filterAnnotation);
if(shouldExecute){
pjp.proceed();
}
}
private boolean checkShouldExecute(FilteredExecution filterAnnotation){
//use reflection to invoke the ExecutionFilter specified on filterAnnotatoon
}
You need to setup your context so that your beans with the custom annotation are auto proxied by using #EnableAspectjAutoProxy on your configuration class
you can try this, documentation above metoh.
this annotation is show when the method is invoke, and see the document of
meothd
/**
* descripcion of the method
* #param value , any value
*/
public void myMethod(String value) {
//do something (if annotation allows invokation)
}
if you put this structure you can't see the documentation when you
call some method,,
//descripcion of the method
public void myMethod(String value) {
//do something (if annotation allows invokation)
}
in my case, it works, i hope this works for you

Guice custom binding annotation fails, but #Named works?

I'd thought that a custom binding annotation #Foo was equivalent in functionality to #Named("foo"). Is this not true?
I've got, in separate GuiceModules, two things providing the same item type:
In GuiceModuleFoo
#Foo
#Provides
public String provideFoo() { return "foo"; }
In GuiceModuleBar
#Bar
#Provides
public String provideBar() { return "bar"; }
class MyOtherThing extends Thing {
#Inject
public MyOtherThing(#Foo String s) {
super(s);
}
}
Further, in case it matters, I'm using Modules.override so that GuiceModuleBar overrides GuiceModuleFoo (for an unrelated provide).
MyOtherThing is not getting injected with the #Foo provided value though. It's getting the value from the #Bar provider. It actually seems somewhat random what provides it when I added a 3rd provider #Baz.
However, when converting everything to use #Named (e.g. #Named("foo")), it works exactly as desired!
So...am I misunderstanding how binding annotations work? The custom annotations looked like this:
#BindingAnnotation
#Target({ FIELD, PARAMETER, METHOD }) #Retention(RUNTIME)
public #interface Foo {
}

Categories