Search in sources :

Example 81 with MetaProperty

use of io.jmix.core.metamodel.model.MetaProperty in project jmix by jmix-framework.

the class BulkEditorWindow method getManagedFields.

protected List<ManagedField> getManagedFields(MetaClass metaClass) {
    List<ManagedField> managedFields = new ArrayList<>();
    // sort Fields
    for (MetaProperty metaProperty : metaClass.getProperties()) {
        if (isManagedAttribute(metaClass, metaProperty)) {
            String propertyCaption = messageTools.getPropertyCaption(metaClass, metaProperty.getName());
            if (!metadataTools.isEmbedded(metaProperty)) {
                managedFields.add(new ManagedField(metaProperty.getName(), metaProperty, propertyCaption, null));
            } else {
                List<ManagedField> nestedFields = getManagedFields(metaProperty, metaProperty.getName(), propertyCaption);
                if (nestedFields.size() > 0) {
                    managedEmbeddedProperties.add(metaProperty.getName());
                }
                managedFields.addAll(nestedFields);
            }
        }
    }
    /*if (loadDynamicAttributes) {
            List<CategoryAttribute> categoryAttributes = (List<CategoryAttribute>) dynamicAttributes.getAttributesForMetaClass(metaClass);
            if (!categoryAttributes.isEmpty()) {
                for (CategoryAttribute attribute : categoryAttributes) {
                    MetaPropertyPath metaPropertyPath = DynamicAttributesUtils.getMetaPropertyPath(metaClass, attribute);
                    String propertyCaption = attribute.getLocaleName();

                    if (isManagedDynamicAttribute(metaClass, metaPropertyPath.getMetaProperty())) {
                        managedFields.add(new ManagedField(metaPropertyPath.getMetaProperty().getName(), metaPropertyPath.getMetaProperty(),
                                propertyCaption, null));
                    }
                }
            }
        }*/
    return managedFields;
}
Also used : MetaProperty(io.jmix.core.metamodel.model.MetaProperty)

Example 82 with MetaProperty

use of io.jmix.core.metamodel.model.MetaProperty in project jmix by jmix-framework.

the class BulkEditorWindow method createDataComponents.

@SuppressWarnings("unchecked")
protected void createDataComponents() {
    if (managedFields.isEmpty()) {
        infoLabel.setValue(messages.getMessage("io.jmix.ui.app.bulk/bulk.noEditableProperties"));
        applyButton.setVisible(false);
        return;
    }
    List<ManagedField> editFields = new ArrayList<>(managedFields.values());
    // sort fields
    Comparator comparator;
    if (fieldSorter != null) {
        Map<MetaProperty, Integer> sorted = fieldSorter.apply(editFields.stream().map(ManagedField::getMetaProperty).collect(Collectors.toList()));
        comparator = Comparator.<ManagedField>comparingInt(item -> sorted.get(item.getMetaProperty()));
    } else {
        comparator = Comparator.comparing(ManagedField::getLocalizedName);
    }
    editFields.sort(comparator);
    CssLayout fieldsLayout = uiComponents.create(CssLayout.NAME);
    fieldsLayout.setStyleName("jmix-bulk-editor-fields-layout");
    fieldsLayout.setWidthFull();
    fieldsLayout.setHeightFull();
    int fromField;
    int toField = 0;
    int addedColumns = 0;
    for (int col = 0; col < columnsMode.getColumnsCount(); col++) {
        fromField = toField;
        toField += getFieldsCountForColumn(editFields.size() - toField, columnsMode.getColumnsCount() - col);
        DeviceInfo deviceInfo = deviceInfoProvider.getDeviceInfo();
        VBoxLayout column = uiComponents.create(VBoxLayout.NAME);
        column.setStyleName("jmix-bulk-editor-column");
        column.setWidth(Component.AUTO_SIZE);
        for (int fieldIndex = fromField; fieldIndex < toField; fieldIndex++) {
            ManagedField field = editFields.get(fieldIndex);
            CssLayout row = uiComponents.create(CssLayout.NAME);
            row.setStyleName("jmix-bulk-editor-row");
            row.setWidth("100%");
            Label<String> label = uiComponents.create(Label.NAME);
            label.setValue(field.getLocalizedName());
            label.setStyleName("jmix-bulk-editor-label");
            row.add(label);
            Datasource<Entity> fieldDs = datasource;
            // so we can check field domain
            if (metadataTools.isJpaEmbeddable(field.getMetaProperty().getDomain())) {
                fieldDs = datasources.get(field.getParentFqn());
            }
            BulkEditorFieldFactory fieldFactory = getFieldFactory();
            Field<?> editField = fieldFactory.createField(fieldDs, field.getMetaProperty());
            if (editField != null) {
                editField.setFrame(getFrame());
                editField.setStyleName("jmix-bulk-editor-field");
                if (isPickerFieldWrapperNeeded(editField, deviceInfo)) {
                    CssLayout wrapper = uiComponents.create(CssLayout.NAME);
                    wrapper.setStyleName("jmix-bulk-editor-picker-field-wrapper");
                    wrapper.add(editField);
                    row.add(wrapper);
                } else {
                    row.add(editField);
                }
                boolean required = editField.isRequired();
                if (!required) {
                    Button clearButton = uiComponents.create(Button.class);
                    clearButton.setIconFromSet(JmixIcon.TRASH);
                    clearButton.setCaption("");
                    clearButton.setDescription(messages.getMessage("io.jmix.ui.app.bulk/bulk.clearAttribute"));
                    clearButton.addClickListener(e -> {
                        editField.setEnabled(!editField.isEnabled());
                        if (!editField.isEnabled()) {
                            if (editField instanceof ListEditor) {
                                ((Field) editField).setValue(Collections.EMPTY_LIST);
                            } else {
                                editField.setValue(null);
                            }
                            e.getSource().setIconFromSet(JmixIcon.EDIT);
                            e.getSource().setDescription(messages.getMessage("io.jmix.ui.app.bulk/bulk.editAttribute"));
                        } else {
                            e.getSource().setIconFromSet(JmixIcon.TRASH);
                            e.getSource().setDescription(messages.getMessage("io.jmix.ui.app.bulk/bulk.clearAttribute"));
                        }
                    });
                    row.add(clearButton);
                } else {
                    // hidden component for correctly showing layout
                    Button spacerButton = uiComponents.create(Button.class);
                    spacerButton.setIconFromSet(JmixIcon.TRASH);
                    spacerButton.setStyleName("jmix-bulk-editor-spacer");
                    row.add(spacerButton);
                }
                // disable bean validator
                // noinspection RedundantCast
                editField.getValidators().stream().filter(v -> v instanceof AbstractBeanValidator).findFirst().ifPresent(((Field) editField)::removeValidator);
                // disable required
                editField.setRequired(false);
                if (editField instanceof ListEditor) {
                    ((Field) editField).setValue(Collections.EMPTY_LIST);
                } else {
                    editField.setValue(null);
                }
                if (fieldValidators != null) {
                    Consumer validator = fieldValidators.get(field.getFqn());
                    if (validator != null) {
                        editField.addValidator(validator);
                    }
                }
                column.add(row);
                dataFields.put(field.getFqn(), editField);
            } else {
                column.add(uiComponents.create(Label.class));
            }
        }
        fieldsLayout.add(column);
        // if there is no fields remain
        if (editFields.size() - toField == 0) {
            addedColumns = col + 1;
            break;
        }
    }
    fieldsLayout.addStyleName(COLUMN_COUNT_STYLENAME + addedColumns);
    fieldsScrollBox.add(fieldsLayout);
    dataFields.values().stream().filter(f -> f instanceof Focusable).findFirst().ifPresent(f -> ((Focusable) f).focus());
}
Also used : MetaClass(io.jmix.core.metamodel.model.MetaClass) LoadDescriptor(io.jmix.ui.bulk.BulkEditorDataService.LoadDescriptor) java.util(java.util) Datasource(com.haulmont.cuba.gui.data.Datasource) BulkEditorDataService(io.jmix.ui.bulk.BulkEditorDataService) MetaPropertyPath(io.jmix.core.metamodel.model.MetaPropertyPath) AbstractBeanValidator(io.jmix.ui.component.validator.AbstractBeanValidator) LoggerFactory(org.slf4j.LoggerFactory) Autowired(org.springframework.beans.factory.annotation.Autowired) StringUtils(org.apache.commons.lang3.StringUtils) EntityValues(io.jmix.core.entity.EntityValues) com.haulmont.cuba.core.global(com.haulmont.cuba.core.global) EntityOp(io.jmix.core.security.EntityOp) FieldSorter(io.jmix.ui.app.bulk.FieldSorter) Component(io.jmix.ui.component.Component) Type(io.jmix.ui.action.DialogAction.Type) DatasourceImpl(com.haulmont.cuba.gui.data.impl.DatasourceImpl) Action(io.jmix.ui.action.Action) TWO_COLUMNS(io.jmix.ui.app.bulk.ColumnsMode.TWO_COLUMNS) DialogAction(io.jmix.ui.action.DialogAction) MetadataTools(io.jmix.core.MetadataTools) com.haulmont.cuba.gui.components(com.haulmont.cuba.gui.components) Preconditions.checkNotNullArgument(io.jmix.core.common.util.Preconditions.checkNotNullArgument) Logger(org.slf4j.Logger) EmbeddedDatasourceImpl(com.haulmont.cuba.gui.data.impl.EmbeddedDatasourceImpl) DsContextImpl(com.haulmont.cuba.gui.data.impl.DsContextImpl) FetchPlan(io.jmix.core.FetchPlan) Collectors(java.util.stream.Collectors) ColumnsMode(io.jmix.ui.app.bulk.ColumnsMode) WindowParam(io.jmix.ui.WindowParam) DeviceInfo(io.jmix.ui.deviceinfo.DeviceInfo) JmixIcon(io.jmix.ui.icon.JmixIcon) Status(io.jmix.ui.action.Action.Status) Consumer(java.util.function.Consumer) ValidationException(io.jmix.ui.component.ValidationException) EntityAttrAccess(com.haulmont.cuba.security.entity.EntityAttrAccess) Button(io.jmix.ui.component.Button) Entity(io.jmix.core.Entity) DeviceInfoProvider(io.jmix.ui.deviceinfo.DeviceInfoProvider) Pattern(java.util.regex.Pattern) UiComponents(com.haulmont.cuba.gui.UiComponents) MetaProperty(io.jmix.core.metamodel.model.MetaProperty) MessageTools(io.jmix.core.MessageTools) DataSupplier(com.haulmont.cuba.gui.data.DataSupplier) NestedDatasource(com.haulmont.cuba.gui.data.NestedDatasource) Entity(io.jmix.core.Entity) Consumer(java.util.function.Consumer) Button(io.jmix.ui.component.Button) DeviceInfo(io.jmix.ui.deviceinfo.DeviceInfo) MetaProperty(io.jmix.core.metamodel.model.MetaProperty) AbstractBeanValidator(io.jmix.ui.component.validator.AbstractBeanValidator)

Example 83 with MetaProperty

use of io.jmix.core.metamodel.model.MetaProperty in project jmix by jmix-framework.

the class EntityMutationDataFetcher method populateAndCheckComposition.

/**
 * Walk through entity graph and check that all compositions have correct relations. If composition inverse value is
 * null - update it to correct value. If composition inverse value doesn't match parent - throw exception.
 *
 * @param entity  entity to be checked
 * @param visited a set of entities that already be checked in graph
 */
protected void populateAndCheckComposition(Object entity, Set<Object> visited) {
    if (visited.contains(entity)) {
        return;
    }
    MetaClass metaClass = metadata.getClass(entity);
    visited.add(entity);
    metaClass.getProperties().stream().filter(metaProperty -> MetaProperty.Type.COMPOSITION.equals(metaProperty.getType())).filter(metaProperty -> !visited.contains(EntityValues.getValue(entity, metaProperty.getName()))).filter(metaProperty -> EntityValues.getValue(entity, metaProperty.getName()) != null).forEach(metaProperty -> {
        // value from COMPOSITION metaProperty
        Object childEntity = EntityValues.getValue(entity, metaProperty.getName());
        Stream<?> childEntityStream = (childEntity instanceof Iterable<?>) ? StreamSupport.stream(((Iterable<?>) childEntity).spliterator(), false) : Stream.of(childEntity);
        childEntityStream.forEach(childElement -> {
            // have to check a linking for retrieved composition with a parent it can be different
            assureCompositionInverseLink(entity, metaClass, metaProperty, childElement);
            // digging deeper for child element to find any compositions inside
            populateAndCheckComposition(childElement, visited);
        });
    });
}
Also used : Id(io.jmix.core.Id) MetaClass(io.jmix.core.metamodel.model.MetaClass) java.util(java.util) EntityImportPlanProperty(io.jmix.core.EntityImportPlanProperty) LoggerFactory(org.slf4j.LoggerFactory) Autowired(org.springframework.beans.factory.annotation.Autowired) CrudEntityContext(io.jmix.core.accesscontext.CrudEntityContext) EntityValues(io.jmix.core.entity.EntityValues) EntitySerialization(io.jmix.core.EntitySerialization) AccessDeniedException(io.jmix.core.security.AccessDeniedException) ObjectProvider(org.springframework.beans.factory.ObjectProvider) GraphQLUpsertEntityDataFetcher(io.jmix.graphql.modifier.GraphQLUpsertEntityDataFetcher) GraphQLRemoveEntityDataFetcher(io.jmix.graphql.modifier.GraphQLRemoveEntityDataFetcher) DataFetcher(graphql.schema.DataFetcher) StreamSupport(java.util.stream.StreamSupport) Method(java.lang.reflect.Method) LoadContext(io.jmix.core.LoadContext) EntityImportPlanJsonBuilder(io.jmix.core.impl.importexport.EntityImportPlanJsonBuilder) NamingUtils(io.jmix.graphql.NamingUtils) DataManager(io.jmix.core.DataManager) GraphQLRemoveEntityDataFetcherContext(io.jmix.graphql.modifier.GraphQLRemoveEntityDataFetcherContext) Logger(org.slf4j.Logger) FetchPlan(io.jmix.core.FetchPlan) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) IdentifierService(io.jmix.graphql.service.IdentifierService) AccessManager(io.jmix.core.AccessManager) GraphQLUpsertEntityDataFetcherContext(io.jmix.graphql.modifier.GraphQLUpsertEntityDataFetcherContext) Metadata(io.jmix.core.Metadata) EntityImportPlan(io.jmix.core.EntityImportPlan) Collectors(java.util.stream.Collectors) Component(org.springframework.stereotype.Component) Stream(java.util.stream.Stream) EntityImportExport(io.jmix.core.EntityImportExport) PersistenceException(javax.persistence.PersistenceException) EntityStates(io.jmix.core.EntityStates) EntityValidationException(io.jmix.core.validation.EntityValidationException) Entity(io.jmix.core.Entity) MetaProperty(io.jmix.core.metamodel.model.MetaProperty) MetaClass(io.jmix.core.metamodel.model.MetaClass)

Example 84 with MetaProperty

use of io.jmix.core.metamodel.model.MetaProperty in project jmix by jmix-framework.

the class EntityMutationDataFetcher method assureCompositionInverseLink.

/**
 * Check that inverse link is set correctly in composition relation. If link is null - fix it (assign to parent).
 * If link point to different entity (not equals to parent) - throw exception.
 *
 * @param parent          - parent entity
 * @param parentMetaClass - meta class of parent entity
 * @param metaProperty    - metadata of property which points to child in parent entity
 * @param child           - child entity
 */
protected void assureCompositionInverseLink(Object parent, MetaClass parentMetaClass, MetaProperty metaProperty, Object child) {
    MetaProperty inverseMetaProperty = metaProperty.getInverse();
    if (inverseMetaProperty == null) {
        return;
    }
    Object inverseValue = EntityValues.getValue(child, inverseMetaProperty.getName());
    if (inverseValue == null) {
        // inverse value is null - update it to correct value
        EntityValues.setValue(child, inverseMetaProperty.getName(), parent);
    } else {
        if (!parent.equals(inverseValue)) {
            // parent id doesn't match parent in graph - throw exception
            String message = String.format("Composition attribute '%s' in class '%s' doesn't contain the correct link to parent entity. " + "Please set correct parent ID '%s' in composition relation.", metaProperty.getName(), parentMetaClass.getName(), EntityValues.getId(parent));
            log.error(message);
            throw new GqlEntityValidationException(message);
        }
    }
}
Also used : MetaProperty(io.jmix.core.metamodel.model.MetaProperty)

Example 85 with MetaProperty

use of io.jmix.core.metamodel.model.MetaProperty in project jmix by jmix-framework.

the class MessagesDataFetcher method getEntityMessages.

protected List<MessageDetail> getEntityMessages(MetaClass metaClass, Locale locale) {
    List<MessageDetail> messages = new ArrayList<>();
    CrudEntityContext entityContext = new CrudEntityContext(metaClass);
    accessManager.applyRegisteredConstraints(entityContext);
    String metaClassName = metaClass.getName();
    if (entityContext.isReadPermitted()) {
        String entityCaption = messageTools.getEntityCaption(metaClass, locale);
        messages.add(new MessageDetail(metaClassName, entityCaption));
    }
    for (MetaProperty metaProperty : metaClass.getProperties()) {
        EntityAttributeContext attributeContext = new EntityAttributeContext(metaClass, metaProperty.getName());
        accessManager.applyRegisteredConstraints(attributeContext);
        if (attributeContext.canView()) {
            String propertyCaption = messageTools.getPropertyCaption(metaProperty, locale);
            messages.add(new MessageDetail(metaClassName + "." + metaProperty.getName(), propertyCaption));
        }
    }
    return messages;
}
Also used : CrudEntityContext(io.jmix.core.accesscontext.CrudEntityContext) EntityAttributeContext(io.jmix.core.accesscontext.EntityAttributeContext) ArrayList(java.util.ArrayList) MessageDetail(io.jmix.graphql.schema.messages.MessageDetail) MetaProperty(io.jmix.core.metamodel.model.MetaProperty)

Aggregations

MetaProperty (io.jmix.core.metamodel.model.MetaProperty)267 MetaClass (io.jmix.core.metamodel.model.MetaClass)162 MetaPropertyPath (io.jmix.core.metamodel.model.MetaPropertyPath)53 Nullable (javax.annotation.Nullable)36 Range (io.jmix.core.metamodel.model.Range)23 Autowired (org.springframework.beans.factory.annotation.Autowired)23 Collectors (java.util.stream.Collectors)22 java.util (java.util)20 Component (org.springframework.stereotype.Component)18 Entity (io.jmix.core.Entity)17 EntityValues (io.jmix.core.entity.EntityValues)17 io.jmix.core (io.jmix.core)16 Logger (org.slf4j.Logger)15 LoggerFactory (org.slf4j.LoggerFactory)15 ArrayList (java.util.ArrayList)12 Collection (java.util.Collection)12 EntityValueSource (io.jmix.ui.component.data.meta.EntityValueSource)10 Metadata (io.jmix.core.Metadata)9 KeyValueMetaClass (io.jmix.core.impl.keyvalue.KeyValueMetaClass)9 CollectionDatasource (com.haulmont.cuba.gui.data.CollectionDatasource)8