Search in sources :

Example 1 with Nested

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

the class ValueBinder method bind.

public <V> ValueBinding<V> bind(HasValue<V> component, ValueSource<V> valueSource) {
    if (valueSource instanceof ApplicationContextAware) {
        ((ApplicationContextAware) valueSource).setApplicationContext(applicationContext);
    }
    ValueBindingImpl<V> binding = new ValueBindingImpl<>(component, valueSource);
    if (component instanceof Component.Editable) {
        ((Component.Editable) component).setEditable(!valueSource.isReadOnly());
    }
    if (valueSource instanceof EntityValueSource) {
        EntityValueSource entityValueSource = (EntityValueSource) valueSource;
        MetaPropertyPath metaPropertyPath = entityValueSource.getMetaPropertyPath();
        if (component instanceof Field) {
            initRequired((Field) component, metaPropertyPath);
            initBeanValidator((Field<?>) component, metaPropertyPath);
        }
        if (entityValueSource.isDataModelSecurityEnabled()) {
            UiEntityAttributeContext attributeContext = new UiEntityAttributeContext(metaPropertyPath);
            accessManager.applyRegisteredConstraints(attributeContext);
            if (component instanceof Component.Editable) {
                MetaClass metaClass = entityValueSource.getEntityMetaClass();
                boolean permittedIfEmbedded = true;
                if (entityValueSource instanceof ContainerValueSource) {
                    InstanceContainer<?> container = ((ContainerValueSource<?, ?>) entityValueSource).getContainer();
                    if (container instanceof Nested && metaClass != null && metadataTools.isJpaEmbeddable(metaClass)) {
                        String embeddedProperty = ((Nested) container).getProperty();
                        MetaClass masterMetaClass = ((Nested) container).getMaster().getEntityMetaClass();
                        UiEntityAttributeContext embeddedAttributeContext = new UiEntityAttributeContext(masterMetaClass, embeddedProperty);
                        accessManager.applyRegisteredConstraints(embeddedAttributeContext);
                        permittedIfEmbedded = embeddedAttributeContext.canModify();
                    }
                    if (permittedIfEmbedded && metaPropertyPath.length() > 1) {
                        for (MetaProperty property : metaPropertyPath.getMetaProperties()) {
                            if (metadataTools.isEmbedded(property)) {
                                UiEntityAttributeContext childAttributeContext = new UiEntityAttributeContext(property.getDomain(), property.getName());
                                accessManager.applyRegisteredConstraints(childAttributeContext);
                                if (!childAttributeContext.canModify()) {
                                    permittedIfEmbedded = false;
                                    break;
                                }
                            }
                        }
                    }
                }
                if (!attributeContext.canModify() || !permittedIfEmbedded) {
                    ((Component.Editable) component).setEditable(false);
                }
            }
            if (!attributeContext.canView()) {
                component.setVisible(false);
            }
        }
    }
    binding.bind();
    return binding;
}
Also used : EntityValueSource(io.jmix.ui.component.data.meta.EntityValueSource) ApplicationContextAware(org.springframework.context.ApplicationContextAware) UiEntityAttributeContext(io.jmix.ui.accesscontext.UiEntityAttributeContext) MetaPropertyPath(io.jmix.core.metamodel.model.MetaPropertyPath) Nested(io.jmix.ui.model.Nested) Field(io.jmix.ui.component.Field) MetaClass(io.jmix.core.metamodel.model.MetaClass) MetaProperty(io.jmix.core.metamodel.model.MetaProperty)

Example 2 with Nested

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

the class EditorBuilderProcessor method initEntity.

@Nullable
protected <E> E initEntity(EditorBuilder<E> builder, @Nullable CollectionContainer<E> container) {
    E entity;
    boolean oneToOneComposition = false;
    EntityValueSource entityValueSource = null;
    HasValue<E> field = builder.getField();
    if (field instanceof HasValueSource) {
        ValueSource valueSource = ((HasValueSource) field).getValueSource();
        if (valueSource instanceof EntityValueSource) {
            entityValueSource = (EntityValueSource) valueSource;
            oneToOneComposition = isCompositionProperty(entityValueSource);
        }
    }
    if (builder.getMode() == EditMode.CREATE || (oneToOneComposition && field.getValue() == null)) {
        if (builder.getNewEntity() == null) {
            entity = metadata.create(builder.getEntityClass());
        } else {
            entity = builder.getNewEntity();
        }
        if (container instanceof Nested) {
            initializeNestedEntity(entity, (Nested) container);
        }
        if (oneToOneComposition) {
            Object ownerEntity = entityValueSource.getItem();
            MetaProperty inverseProp = entityValueSource.getMetaPropertyPath().getMetaProperty().getInverse();
            if (inverseProp != null) {
                EntityValues.setValue(entity, inverseProp.getName(), ownerEntity);
            }
        }
        if (builder.getInitializer() != null) {
            builder.getInitializer().accept(entity);
        }
    } else {
        entity = builder.getEditedEntity();
    }
    return entity;
}
Also used : EntityValueSource(io.jmix.ui.component.data.meta.EntityValueSource) ValueSource(io.jmix.ui.component.data.ValueSource) EntityValueSource(io.jmix.ui.component.data.meta.EntityValueSource) HasValueSource(io.jmix.ui.component.data.HasValueSource) Nested(io.jmix.ui.model.Nested) HasValueSource(io.jmix.ui.component.data.HasValueSource) MetaProperty(io.jmix.core.metamodel.model.MetaProperty) Nullable(javax.annotation.Nullable)

Example 3 with Nested

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

the class EditorBuilderProcessor method setupParentDataContext.

@Nullable
protected DataContext setupParentDataContext(FrameOwner origin, Screen screen, @Nullable InstanceContainer container, @Nullable DataContext parentContext) {
    DataContext dataContext = parentContext;
    if (dataContext == null && container instanceof Nested) {
        InstanceContainer masterContainer = ((Nested) container).getMaster();
        String property = ((Nested) container).getProperty();
        MetaClass masterMetaClass = masterContainer.getEntityMetaClass();
        MetaProperty metaProperty = masterMetaClass.getProperty(property);
        if (metaProperty.getType() == MetaProperty.Type.COMPOSITION) {
            dataContext = UiControllerUtils.getScreenData(origin).getDataContextOrNull();
        }
    }
    if (dataContext != null) {
        DataContext childContext = UiControllerUtils.getScreenData(screen).getDataContextOrNull();
        checkDataContext(screen, childContext);
        childContext.setParent(dataContext);
    }
    return dataContext;
}
Also used : DataContext(io.jmix.ui.model.DataContext) MetaClass(io.jmix.core.metamodel.model.MetaClass) Nested(io.jmix.ui.model.Nested) InstanceContainer(io.jmix.ui.model.InstanceContainer) MetaProperty(io.jmix.core.metamodel.model.MetaProperty) Nullable(javax.annotation.Nullable)

Example 4 with Nested

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

the class LookupBuilderProcessor method handleSelectionWithContainer.

protected <E> void handleSelectionWithContainer(LookupBuilder<E> builder, CollectionContainer<E> collectionDc, Collection<E> itemsFromLookup) {
    if (itemsFromLookup.isEmpty()) {
        return;
    }
    Collection<E> selectedItems = transform(itemsFromLookup, builder);
    boolean initializeMasterReference = false;
    Object masterItem = null;
    MetaProperty inverseMetaProperty = null;
    // update holder reference if needed
    if (collectionDc instanceof Nested) {
        InstanceContainer masterDc = ((Nested) collectionDc).getMaster();
        String property = ((Nested) collectionDc).getProperty();
        masterItem = masterDc.getItem();
        MetaProperty metaProperty = metadata.getClass(masterItem).getProperty(property);
        inverseMetaProperty = metaProperty.getInverse();
        if (inverseMetaProperty != null && !inverseMetaProperty.getRange().getCardinality().isMany()) {
            Class<?> inversePropClass = extendedEntities.getEffectiveClass(inverseMetaProperty.getDomain());
            Class<?> dcClass = extendedEntities.getEffectiveClass(collectionDc.getEntityMetaClass());
            initializeMasterReference = inversePropClass.isAssignableFrom(dcClass);
        }
    }
    DataContext dataContext = UiControllerUtils.getScreenData(builder.getOrigin()).getDataContext();
    List<E> mergedItems = new ArrayList<>(selectedItems.size());
    FetchPlan viewForCollectionContainer = screenProperties.isReloadUnfetchedAttributesFromLookupScreens() && collectionDc.getEntityMetaClass() != null && metadataTools.isJpaEntity(collectionDc.getEntityMetaClass()) ? getFetchPlanForCollectionContainer(collectionDc, initializeMasterReference, inverseMetaProperty) : null;
    for (E item : selectedItems) {
        if (!collectionDc.containsItem(EntityValues.getId(item))) {
            if (viewForCollectionContainer != null && !entityStates.isLoadedWithFetchPlan(item, viewForCollectionContainer)) {
                // noinspection unchecked
                item = (E) dataManager.load(Id.of(item)).fetchPlan(viewForCollectionContainer).one();
            }
            // track changes in the related instance
            E mergedItem = dataContext.merge(item);
            if (initializeMasterReference) {
                // change reference, now it will be marked as modified
                EntityValues.setValue(mergedItem, inverseMetaProperty.getName(), masterItem);
            }
            mergedItems.add(mergedItem);
        }
    }
    collectionDc.getMutableItems().addAll(mergedItems);
}
Also used : Nested(io.jmix.ui.model.Nested) InstanceContainer(io.jmix.ui.model.InstanceContainer) DataContext(io.jmix.ui.model.DataContext) MetaProperty(io.jmix.core.metamodel.model.MetaProperty)

Example 5 with Nested

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

the class ExcludeAction method isPermitted.

@Override
protected boolean isPermitted() {
    if (target == null || !(target.getItems() instanceof ContainerDataUnit)) {
        return false;
    }
    ContainerDataUnit<E> containerDataUnit = (ContainerDataUnit) target.getItems();
    MetaClass metaClass = containerDataUnit.getEntityMetaClass();
    if (metaClass == null) {
        return false;
    }
    if (containerDataUnit.getContainer() instanceof Nested) {
        Nested nestedContainer = (Nested) containerDataUnit.getContainer();
        MetaClass masterMetaClass = nestedContainer.getMaster().getEntityMetaClass();
        MetaProperty metaProperty = masterMetaClass.getProperty(nestedContainer.getProperty());
        UiEntityAttributeContext attributeContext = new UiEntityAttributeContext(masterMetaClass, metaProperty.getName());
        accessManager.applyRegisteredConstraints(attributeContext);
        boolean attrPermitted = attributeContext.canModify();
        if (!attrPermitted) {
            return false;
        }
    }
    return super.isPermitted();
}
Also used : MetaClass(io.jmix.core.metamodel.model.MetaClass) UiEntityAttributeContext(io.jmix.ui.accesscontext.UiEntityAttributeContext) Nested(io.jmix.ui.model.Nested) ContainerDataUnit(io.jmix.ui.component.data.meta.ContainerDataUnit) MetaProperty(io.jmix.core.metamodel.model.MetaProperty)

Aggregations

Nested (io.jmix.ui.model.Nested)9 MetaProperty (io.jmix.core.metamodel.model.MetaProperty)7 MetaClass (io.jmix.core.metamodel.model.MetaClass)5 UiEntityAttributeContext (io.jmix.ui.accesscontext.UiEntityAttributeContext)4 ContainerDataUnit (io.jmix.ui.component.data.meta.ContainerDataUnit)4 EntityValueSource (io.jmix.ui.component.data.meta.EntityValueSource)3 DataContext (io.jmix.ui.model.DataContext)3 InstanceContainer (io.jmix.ui.model.InstanceContainer)3 Nullable (javax.annotation.Nullable)3 HasValueSource (io.jmix.ui.component.data.HasValueSource)2 ValueSource (io.jmix.ui.component.data.ValueSource)2 MetaPropertyPath (io.jmix.core.metamodel.model.MetaPropertyPath)1 Screens (io.jmix.ui.Screens)1 UiEntityContext (io.jmix.ui.accesscontext.UiEntityContext)1 io.jmix.ui.component (io.jmix.ui.component)1 Field (io.jmix.ui.component.Field)1 DataUnit (io.jmix.ui.component.data.DataUnit)1 Options (io.jmix.ui.component.data.Options)1 EntityOptions (io.jmix.ui.component.data.meta.EntityOptions)1 ApplicationContextAware (org.springframework.context.ApplicationContextAware)1