use of io.jmix.ui.sys.UiControllerReflectionInspector.AnnotatedMethod in project jmix by jmix-framework.
the class UiControllerDependencyInjector method initInstallMethods.
protected void initInstallMethods(FrameOwner frameOwner, ScreenIntrospectionData screenIntrospectionData) {
List<AnnotatedMethod<Install>> installMethods = screenIntrospectionData.getInstallMethods();
for (AnnotatedMethod<Install> annotatedMethod : installMethods) {
Install annotation = annotatedMethod.getAnnotation();
Frame frame = UiControllerUtils.getFrame(frameOwner);
Object targetInstance = getInstallTargetInstance(frameOwner, annotation, frame);
if (targetInstance == null) {
if (annotation.required()) {
throw new DevelopmentException(String.format("Unable to find @Install target for method %s in %s", annotatedMethod.getMethod(), frameOwner.getClass()));
}
log.trace("Skip @Install method {} of {} : it is not required and target not found", annotatedMethod.getMethod().getName(), frameOwner.getClass());
continue;
}
Class<?> instanceClass = targetInstance.getClass();
Method installMethod = annotatedMethod.getMethod();
MethodHandle targetSetterMethod = getInstallTargetSetterMethod(annotation, frame, instanceClass, installMethod);
Class<?> targetParameterType = targetSetterMethod.type().parameterList().get(1);
Object handler = null;
if (targetInstance instanceof InstallTargetHandler) {
handler = ((InstallTargetHandler) targetInstance).createInstallHandler(targetParameterType, frameOwner, installMethod);
}
if (handler == null) {
handler = createInstallHandler(frameOwner, installMethod, targetParameterType);
}
try {
targetSetterMethod.invoke(targetInstance, handler);
} catch (Error e) {
throw e;
} catch (Throwable e) {
throw new RuntimeException("Unable to set declarative @Install handler for " + installMethod, e);
}
}
}
use of io.jmix.ui.sys.UiControllerReflectionInspector.AnnotatedMethod in project jmix by jmix-framework.
the class UiControllerDependencyInjector method initSubscribeListeners.
protected void initSubscribeListeners(FrameOwner frameOwner, ScreenIntrospectionData screenIntrospectionData) {
Class<? extends FrameOwner> clazz = frameOwner.getClass();
List<AnnotatedMethod<Subscribe>> eventListenerMethods = screenIntrospectionData.getSubscribeMethods();
Frame frame = UiControllerUtils.getFrame(frameOwner);
ScreenData screenData = getScreenData(frameOwner);
for (AnnotatedMethod<Subscribe> annotatedMethod : eventListenerMethods) {
Method method = annotatedMethod.getMethod();
Subscribe annotation = annotatedMethod.getAnnotation();
String target = UiDescriptorUtils.getInferredSubscribeId(annotation);
Parameter parameter = method.getParameters()[0];
Class<?> eventType = parameter.getType();
Object eventTarget = null;
if (Strings.isNullOrEmpty(target)) {
switch(annotation.target()) {
// if kept default value
case COMPONENT:
case CONTROLLER:
eventTarget = frameOwner;
break;
case FRAME:
eventTarget = frame;
break;
case PARENT_CONTROLLER:
if (frameOwner instanceof Screen) {
throw new DevelopmentException(String.format("Screen %s cannot use @Subscribe with target = PARENT_CONTROLLER", frame.getId()));
}
eventTarget = ((ScreenFragment) frameOwner).getHostController();
break;
case DATA_CONTEXT:
eventTarget = screenData.getDataContext();
break;
default:
throw new UnsupportedOperationException("Unsupported @Subscribe target " + annotation.target());
}
} else {
switch(annotation.target()) {
case CONTROLLER:
Object componentTarget = findMethodTarget(frame, target);
if (!(componentTarget instanceof Fragment)) {
throw new UnsupportedOperationException("Unsupported @Subscribe target " + annotation.target() + ". It is not a Fragment.");
}
eventTarget = ((Fragment) componentTarget).getFrameOwner();
break;
case COMPONENT:
// component event
eventTarget = findMethodTarget(frame, target);
break;
case DATA_LOADER:
if (screenData.getLoaderIds().contains(target)) {
eventTarget = screenData.getLoader(target);
}
break;
case DATA_CONTAINER:
if (screenData.getContainerIds().contains(target)) {
eventTarget = screenData.getContainer(target);
}
break;
default:
throw new UnsupportedOperationException("Unsupported @Subscribe target " + annotation.target());
}
}
if (eventTarget == null) {
if (annotation.required()) {
throw new DevelopmentException(String.format("Unable to find @Subscribe target %s in %s", target, frame.getId()));
}
log.trace("Skip @Subscribe method {} of {} : it is not required and target not found", annotatedMethod.getMethod().getName(), frameOwner.getClass());
continue;
}
Consumer listener;
// in Java 17+
if (SystemUtils.isJavaVersionAtMost(JavaVersion.JAVA_16) || getClass().getClassLoader() == frameOwner.getClass().getClassLoader()) {
MethodHandle consumerMethodFactory = reflectionInspector.getConsumerMethodFactory(clazz, annotatedMethod, eventType);
try {
listener = (Consumer) consumerMethodFactory.invoke(frameOwner);
} catch (Error e) {
throw e;
} catch (Throwable e) {
throw new RuntimeException("Unable to bind consumer handler", e);
}
} else {
listener = event -> {
try {
annotatedMethod.getMethodHandle().invoke(frameOwner, event);
} catch (Throwable e) {
throw new RuntimeException("Error subscribe listener method invocation", e);
}
};
}
MethodHandle addListenerMethod = reflectionInspector.getAddListenerMethod(eventTarget.getClass(), eventType);
if (addListenerMethod == null) {
throw new DevelopmentException(String.format("Target %s does not support event type %s", eventTarget.getClass().getName(), eventType));
}
try {
addListenerMethod.invoke(eventTarget, listener);
} catch (Error e) {
throw e;
} catch (Throwable e) {
throw new RuntimeException("Unable to add listener" + method, e);
}
}
}
Aggregations