Search in sources :

Example 16 with ScreenData

use of io.jmix.ui.model.ScreenData in project jmix by jmix-framework.

the class UiDataFilterSupport method getFragmentFilterConfigurationModel.

protected FilterConfiguration getFragmentFilterConfigurationModel(Filter.Configuration configuration, ScreenFragment configurationFragment) {
    Filter filter = configuration.getOwner();
    FilterConfiguration configurationModel;
    if (configurationFragment instanceof UiDataFilterConfigurationModelFragment) {
        ScreenData screenData = UiControllerUtils.getScreenData(configurationFragment.getHostController());
        InstanceContainer<FilterConfiguration> configurationDc = screenData.getContainer(CONFIGURATION_CONTAINER_ID);
        configurationModel = configurationDc.getItem();
        if (filter.getId() != null && filter.getFrame() != null && ((UiDataFilterConfigurationModelFragment) configurationFragment).getDefaultForMeFieldVisible()) {
            ScreenSettingsFacet settingsFacet = UiControllerUtils.getFacet(filter.getFrame(), ScreenSettingsFacet.class);
            if (settingsFacet != null) {
                saveFilterSettings(settingsFacet, filter.getId(), configurationModel);
            }
        }
    } else {
        configurationModel = loadFilterConfigurationModel(filter, configuration.getId());
    }
    if (configurationModel == null) {
        configurationModel = createFilterConfigurationModel(configuration);
    }
    return configurationModel;
}
Also used : ScreenSettingsFacet(io.jmix.ui.settings.facet.ScreenSettingsFacet) Filter(io.jmix.ui.component.Filter) FilterConfiguration(io.jmix.uidata.entity.FilterConfiguration) UiDataFilterConfigurationModelFragment(io.jmix.uidata.app.filter.configuration.UiDataFilterConfigurationModelFragment) ScreenData(io.jmix.ui.model.ScreenData)

Example 17 with ScreenData

use of io.jmix.ui.model.ScreenData in project jmix by jmix-framework.

the class DataLoadCoordinatorImpl method configureAutomatically.

@Override
public void configureAutomatically() {
    FrameOwner frameOwner = getFrameOwner();
    ScreenData screenData = UiControllerUtils.getScreenData(frameOwner);
    getUnconfiguredLoaders(screenData).forEach(loader -> configureAutomatically(loader, frameOwner));
}
Also used : FrameOwner(io.jmix.ui.screen.FrameOwner) ScreenData(io.jmix.ui.model.ScreenData)

Example 18 with ScreenData

use of io.jmix.ui.model.ScreenData in project jmix by jmix-framework.

the class AbstractSingleFilterComponentLoader method loadDataLoader.

protected void loadDataLoader(C resultComponent, Element element) {
    String dataLoaderId = element.attributeValue("dataLoader");
    if (StringUtils.isNotBlank(dataLoaderId)) {
        FrameOwner frameOwner = getComponentContext().getFrame().getFrameOwner();
        ScreenData screenData = UiControllerUtils.getScreenData(frameOwner);
        DataLoader dataLoader = screenData.getLoader(dataLoaderId);
        resultComponent.setDataLoader(dataLoader);
    }
}
Also used : DataLoader(io.jmix.ui.model.DataLoader) FrameOwner(io.jmix.ui.screen.FrameOwner) ScreenData(io.jmix.ui.model.ScreenData)

Example 19 with ScreenData

use of io.jmix.ui.model.ScreenData 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);
        }
    }
}
Also used : AnnotatedMethod(io.jmix.ui.sys.UiControllerReflectionInspector.AnnotatedMethod) AnnotatedMethod(io.jmix.ui.sys.UiControllerReflectionInspector.AnnotatedMethod) DevelopmentException(io.jmix.core.DevelopmentException) Consumer(java.util.function.Consumer) UiControllerUtils.getScreenData(io.jmix.ui.screen.UiControllerUtils.getScreenData) ScreenData(io.jmix.ui.model.ScreenData) MethodHandle(java.lang.invoke.MethodHandle)

Example 20 with ScreenData

use of io.jmix.ui.model.ScreenData in project jmix by jmix-framework.

the class UiControllerDependencyInjector method getInjectedInstance.

@Nullable
protected Object getInjectedInstance(Class<?> type, String name, InjectElement injectElement, FrameOwner frameOwner, ScreenOptions options) {
    AnnotatedElement element = injectElement.getElement();
    Class annotationClass = injectElement.getAnnotationClass();
    Frame frame = UiControllerUtils.getFrame(frameOwner);
    if (annotationClass == WindowParam.class) {
        if (options instanceof MapScreenOptions) {
            return ((MapScreenOptions) options).getParams().get(name);
        }
        // Injecting a parameter
        return null;
    } else if (ScreenFragment.class.isAssignableFrom(type)) {
        // Injecting inner fragment controller
        Component fragment = frame.getComponent(name);
        if (fragment == null) {
            return null;
        }
        return ((Fragment) fragment).getFrameOwner();
    } else if (Component.class.isAssignableFrom(type)) {
        // / if legacy frame - inject controller
        Component component = frame.getComponent(name);
        if (component instanceof Fragment) {
            ScreenFragment fragmentFrameOwner = ((Fragment) component).getFrameOwner();
            if (type.isAssignableFrom(fragmentFrameOwner.getClass())) {
                return fragmentFrameOwner;
            }
        }
        // Injecting a UI component
        return component;
    } else if (InstanceContainer.class.isAssignableFrom(type)) {
        // Injecting a container
        ScreenData data = getScreenData(frameOwner);
        return data.getContainer(name);
    } else if (DataLoader.class.isAssignableFrom(type)) {
        // Injecting a loader
        ScreenData data = getScreenData(frameOwner);
        return data.getLoader(name);
    } else if (DataContext.class.isAssignableFrom(type)) {
        // Injecting the data context
        ScreenData data = getScreenData(frameOwner);
        return data.getDataContext();
    } else if (FrameContext.class.isAssignableFrom(type)) {
        // Injecting the FrameContext
        return frame.getContext();
    } else if (Action.class.isAssignableFrom(type)) {
        // Injecting an action
        return ComponentsHelper.findAction(name, frame);
    } else if (Facet.class.isAssignableFrom(type)) {
        // Injecting non-visual component
        String[] elements = ValuePathHelper.parse(name);
        if (elements.length == 1) {
            return frame.getFacet(name);
        }
        String prefix = pathPrefix(elements);
        Component component = frame.getComponent(prefix);
        if (component == null) {
            return null;
        }
        if (!(component instanceof Fragment)) {
            throw new UnsupportedOperationException(String.format("Unable to inject facet with id %s and type %s. Component %s is not a fragment", name, type, prefix));
        }
        String facetId = elements[elements.length - 1];
        return ((Fragment) component).getFacet(facetId);
    } else if (Downloader.class.isAssignableFrom(type)) {
        // Injecting a Downloader
        return applicationContext.getBean(Downloader.class);
    } else if (MessageBundle.class == type) {
        return createMessageBundle(element, frameOwner, frame);
    } else if (ThemeConstants.class == type) {
        // Injecting a Theme
        ThemeConstantsManager themeManager = applicationContext.getBean(ThemeConstantsManager.class);
        return themeManager.getConstants();
    } else if (BeanFactory.class.isAssignableFrom(type)) {
        return applicationContext;
    } else if (ObjectProvider.class.isAssignableFrom(type)) {
        if (!(element instanceof Field && ((Field) element).getGenericType() instanceof ParameterizedType) && !(element instanceof Method && ((Method) element).getGenericParameterTypes().length > 0 && ((Method) element).getGenericParameterTypes()[0] instanceof ParameterizedType)) {
            throw new UnsupportedOperationException("Unable to inject ObjectProvider without generic parameter");
        }
        Type genericType;
        if (element instanceof Field) {
            genericType = ((ParameterizedType) ((Field) element).getGenericType()).getActualTypeArguments()[0];
        } else {
            genericType = ((ParameterizedType) ((Method) element).getGenericParameterTypes()[0]).getActualTypeArguments()[0];
        }
        if (genericType instanceof ParameterizedType) {
            genericType = ((ParameterizedType) genericType).getRawType();
        }
        return applicationContext.getBeanProvider((Class<?>) genericType);
    } else if (ActionsAwareDialogFacet.DialogAction.class.isAssignableFrom(type)) {
        // facet's action
        Facet facet;
        String actionId;
        String[] path = ValuePathHelper.parse(name);
        if (path.length == 2) {
            facet = frame.getFacet(path[0]);
            actionId = path[1];
        } else {
            String prefix = ValuePathHelper.pathPrefix(path, 2);
            Component component = frame.getComponent(prefix);
            if (component == null) {
                return null;
            }
            if (!(component instanceof Fragment)) {
                throw new UnsupportedOperationException(String.format("Unable to inject dialog action with id '%s'. Component '%s' is not a fragment", name, prefix));
            }
            actionId = path[path.length - 1];
            facet = ((Fragment) component).getFacet(path[path.length - 2]);
        }
        if (!(facet instanceof ActionsAwareDialogFacet)) {
            return null;
        }
        // noinspection unchecked
        Collection<ActionsAwareDialogFacet.DialogAction<Facet>> actions = ((ActionsAwareDialogFacet<Facet>) facet).getActions();
        if (CollectionUtils.isNotEmpty(actions)) {
            return actions.stream().filter(action -> action.getId().equals(actionId)).findFirst().orElse(null);
        }
    } else {
        Object instance;
        // Try to find a Spring bean
        Map<String, ?> beans = applicationContext.getBeansOfType(type);
        if (!beans.isEmpty()) {
            instance = beans.get(name);
            // If a bean with required name found, return it
            if (instance != null) {
                return instance;
            } else {
                // Otherwise get a bean from the context again to respect @Primary annotation
                return applicationContext.getBean(type);
            }
        }
    }
    return null;
}
Also used : Action(io.jmix.ui.action.Action) ThemeConstantsManager(io.jmix.ui.theme.ThemeConstantsManager) Downloader(io.jmix.ui.download.Downloader) InstanceContainer(io.jmix.ui.model.InstanceContainer) ThemeConstants(io.jmix.ui.theme.ThemeConstants) Field(java.lang.reflect.Field) DataContext(io.jmix.ui.model.DataContext) AnnotatedMethod(io.jmix.ui.sys.UiControllerReflectionInspector.AnnotatedMethod) ObjectProvider(org.springframework.beans.factory.ObjectProvider) UiControllerUtils.getScreenData(io.jmix.ui.screen.UiControllerUtils.getScreenData) ScreenData(io.jmix.ui.model.ScreenData) Nullable(javax.annotation.Nullable)

Aggregations

ScreenData (io.jmix.ui.model.ScreenData)25 FrameOwner (io.jmix.ui.screen.FrameOwner)16 InstanceContainer (io.jmix.ui.model.InstanceContainer)13 GuiDevelopmentException (io.jmix.ui.GuiDevelopmentException)11 CollectionContainer (io.jmix.ui.model.CollectionContainer)10 DataLoader (io.jmix.ui.model.DataLoader)4 ContainerDataProvider (io.jmix.ui.data.impl.ContainerDataProvider)3 ContainerOptions (io.jmix.ui.component.data.options.ContainerOptions)2 ScreenDataXmlLoader (io.jmix.ui.model.impl.ScreenDataXmlLoader)2 UiControllerUtils.getScreenData (io.jmix.ui.screen.UiControllerUtils.getScreenData)2 AnnotatedMethod (io.jmix.ui.sys.UiControllerReflectionInspector.AnnotatedMethod)2 FilterConfiguration (io.jmix.uidata.entity.FilterConfiguration)2 Nullable (javax.annotation.Nullable)2 Element (org.dom4j.Element)2 LoadDataBeforeShow (com.haulmont.cuba.gui.screen.LoadDataBeforeShow)1 DevelopmentException (io.jmix.core.DevelopmentException)1 Action (io.jmix.ui.action.Action)1 Filter (io.jmix.ui.component.Filter)1 ContainerTreeItems (io.jmix.ui.component.data.tree.ContainerTreeItems)1 ContainerValueSourceProvider (io.jmix.ui.component.data.value.ContainerValueSourceProvider)1