Search in sources :

Example 1 with AnnotatedMethod

use of com.haulmont.cuba.gui.sys.UiControllerReflectionInspector.AnnotatedMethod in project cuba by cuba-platform.

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;
        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);
        }
        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);
        }
    }
}
Also used : LegacyFrame(com.haulmont.cuba.gui.screen.compatibility.LegacyFrame) AnnotatedMethod(com.haulmont.cuba.gui.sys.UiControllerReflectionInspector.AnnotatedMethod) AnnotatedMethod(com.haulmont.cuba.gui.sys.UiControllerReflectionInspector.AnnotatedMethod) DevelopmentException(com.haulmont.cuba.core.global.DevelopmentException) Consumer(java.util.function.Consumer) UiControllerUtils.getScreenData(com.haulmont.cuba.gui.screen.UiControllerUtils.getScreenData) ScreenData(com.haulmont.cuba.gui.model.ScreenData) MethodHandle(java.lang.invoke.MethodHandle)

Example 2 with AnnotatedMethod

use of com.haulmont.cuba.gui.sys.UiControllerReflectionInspector.AnnotatedMethod in project cuba by cuba-platform.

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);
        }
    }
}
Also used : LegacyFrame(com.haulmont.cuba.gui.screen.compatibility.LegacyFrame) AnnotatedMethod(com.haulmont.cuba.gui.sys.UiControllerReflectionInspector.AnnotatedMethod) AnnotatedMethod(com.haulmont.cuba.gui.sys.UiControllerReflectionInspector.AnnotatedMethod) DevelopmentException(com.haulmont.cuba.core.global.DevelopmentException) MethodHandle(java.lang.invoke.MethodHandle)

Aggregations

DevelopmentException (com.haulmont.cuba.core.global.DevelopmentException)2 LegacyFrame (com.haulmont.cuba.gui.screen.compatibility.LegacyFrame)2 AnnotatedMethod (com.haulmont.cuba.gui.sys.UiControllerReflectionInspector.AnnotatedMethod)2 MethodHandle (java.lang.invoke.MethodHandle)2 ScreenData (com.haulmont.cuba.gui.model.ScreenData)1 UiControllerUtils.getScreenData (com.haulmont.cuba.gui.screen.UiControllerUtils.getScreenData)1 Consumer (java.util.function.Consumer)1