Hi members,
I am trying to create a custom annotation. The idea was very simple, it would set the data in a string field.
Here is the code I have done till now,
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface RunMode {
}
@component(service = Injector.class, immediate = true)
public class RunModeInjector implements Injector {
@reference
private AppSettingService appSettingService;
@Override
public String getName() {
return "runmode";
}
@Override
public @nullable Object getValue(@NotNull Object adaptable, String name, @notnull Type type,
@notnull AnnotatedElement annotatedElement,
@notnull DisposalCallbackRegistry disposalCallbackRegistry) {
if (annotatedElement.isAnnotationPresent(RunMode.class)) {
return appSettingService.getRunMode();
}
return null;
}
}
Usages,
// Sling Model
// value is assigned
// But I was supposed to it will work without the extra @inject annotation.
@Inject @RunMode
private String runMode;
// OSGI Service/servlet
// value is null,
// The annotatedElement.isAnnotationPresent(RunMode.class) condition is not satisfied from injector class.
@RunMode
private String runMode;
What I missed, or how to make it work?
Thanks in advance.
Views
Replies
Total Likes
Hi @Sady_Rifat
Please check examples at following blogs
Thanks for the related blogs. But those all are related to only sling model. Those are not working for service/servlet level.
However, I got an alternative solution, which is for service/servlet.
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Field;
@Component(immediate = true, service = OSGiFieldInjector.class)
public class OSGiFieldInjector {
private static final Logger log = LoggerFactory.getLogger(OSGiFieldInjector.class);
@reference
private AppSettingService appSettingService;
@activate
protected void activate(ComponentContext context) {
BundleContext bundleContext = context.getBundleContext();
bundleContext.addServiceListener(event -> {
ServiceReference<?> serviceReference = event.getServiceReference();
Object serviceInstance = bundleContext.getService(serviceReference);
injectRunModeFields(serviceInstance);
});
}
private void injectRunModeFields(Object serviceInstance) {
Field[] fields = serviceInstance.getClass().getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(RunMode.class)) {
try {
field.setAccessible(true);
String runModeValue = appSettingService.getRunMode();
field.set(serviceInstance, runModeValue);
} catch (IllegalAccessException e) {
log.error("Failed to inject run mode into field", e);
}
}
}
}
}
But I don't like this solution, since it's behind-work complexity is too high.
@Sady_Rifat Did you find the suggestion helpful? Please let us know if you require more information. Otherwise, please mark the answer as correct for posterity. If you've discovered a solution yourself, we would appreciate it if you could share it with the community. Thank you!
Views
Replies
Total Likes
Views
Likes
Replies