diff --git a/modules/global/src/com/haulmont/cuba/core/entity/BaseGenericIdEntity.java b/modules/global/src/com/haulmont/cuba/core/entity/BaseGenericIdEntity.java index 1a53df499d..9930d52025 100644 --- a/modules/global/src/com/haulmont/cuba/core/entity/BaseGenericIdEntity.java +++ b/modules/global/src/com/haulmont/cuba/core/entity/BaseGenericIdEntity.java @@ -13,6 +13,7 @@ import com.haulmont.cuba.core.global.AppBeans; import com.haulmont.cuba.core.global.Metadata; import com.haulmont.cuba.core.global.PersistenceHelper; import com.haulmont.cuba.core.global.TimeSource; +import org.apache.commons.lang.ObjectUtils; import javax.annotation.Nullable; import javax.persistence.Column; @@ -151,48 +152,52 @@ public abstract class BaseGenericIdEntity extends AbstractInstance implements } @Override - public void setValue(String property, Object obj, boolean checkEquals) { + public void setValue(String property, Object newValue, boolean checkEquals) { if (DynamicAttributesUtils.isDynamicAttribute(property)) { Preconditions.checkState(dynamicAttributes != null, "Dynamic attributes should be loaded explicitly"); String attributeCode = DynamicAttributesUtils.decodeAttributeCode(property); CategoryAttributeValue categoryAttributeValue = dynamicAttributes.get(attributeCode); - if (categoryAttributeValue != null) { - if (obj != null) { - categoryAttributeValue.setValue(obj); - categoryAttributeValue.setDeleteTs(null); - } else { + Object oldValue = categoryAttributeValue != null ? categoryAttributeValue.getValue() : null; + + if (newValue == null) { + if (categoryAttributeValue != null) { categoryAttributeValue.setValue(null); categoryAttributeValue.setDeleteTs(AppBeans.get(TimeSource.class).currentTimestamp()); + propertyChanged(property, oldValue, null); } - } else if (obj != null) { - categoryAttributeValue = new CategoryAttributeValue(); - categoryAttributeValue.setValue(obj); - categoryAttributeValue.setEntityId(getUuid()); - categoryAttributeValue.setCode(attributeCode); - DynamicAttributes dynamicAttributesBean = AppBeans.get(DynamicAttributes.NAME); - categoryAttributeValue.setCategoryAttribute( - dynamicAttributesBean.getAttributeForMetaClass(getMetaClass(), attributeCode)); - dynamicAttributes.put(attributeCode, categoryAttributeValue); + } else if (!ObjectUtils.equals(oldValue, newValue)) { + if (categoryAttributeValue != null) { + categoryAttributeValue.setValue(newValue); + categoryAttributeValue.setDeleteTs(null); + } else { + categoryAttributeValue = new CategoryAttributeValue(); + categoryAttributeValue.setValue(newValue); + categoryAttributeValue.setEntityId(getUuid()); + categoryAttributeValue.setCode(attributeCode); + DynamicAttributes dynamicAttributesBean = AppBeans.get(DynamicAttributes.NAME); + categoryAttributeValue.setCategoryAttribute( + dynamicAttributesBean.getAttributeForMetaClass(getMetaClass(), attributeCode)); + dynamicAttributes.put(attributeCode, categoryAttributeValue); + } + propertyChanged(property, null, newValue); } - - propertyChanged(property, null, obj); } else { - super.setValue(property, obj, checkEquals); + super.setValue(property, newValue, checkEquals); } } @Override @SuppressWarnings("unchecked") - public V getValue(String property) { + public T getValue(String property) { if (DynamicAttributesUtils.isDynamicAttribute(property)) { if (PersistenceHelper.isNew(this) && dynamicAttributes == null) { - dynamicAttributes = new HashMap<>(); + dynamicAttributes = new HashMap<>(); } Preconditions.checkState(dynamicAttributes != null, "Dynamic attributes should be loaded explicitly"); CategoryAttributeValue categoryAttributeValue = dynamicAttributes.get(DynamicAttributesUtils.decodeAttributeCode(property)); if (categoryAttributeValue != null) { - return (V) categoryAttributeValue.getValue(); + return (T) categoryAttributeValue.getValue(); } else { return null; } @@ -209,20 +214,4 @@ public abstract class BaseGenericIdEntity extends AbstractInstance implements public Map getDynamicAttributes() { return dynamicAttributes; } - - @Override - public String toString() { - String state = ""; - if (__new) - state += "new,"; - if (__managed) - state += "managed,"; - if (__detached) - state += "detached,"; - if (__removed) - state += "removed,"; - if (state.length() > 0) - state = state.substring(0, state.length() - 1); - return super.toString() + " [" + state + "]"; - } } \ No newline at end of file diff --git a/modules/gui/src/com/haulmont/cuba/gui/components/RuntimePropertiesFrame.java b/modules/gui/src/com/haulmont/cuba/gui/components/RuntimePropertiesFrame.java index 251176e7ea..4f2965b91b 100644 --- a/modules/gui/src/com/haulmont/cuba/gui/components/RuntimePropertiesFrame.java +++ b/modules/gui/src/com/haulmont/cuba/gui/components/RuntimePropertiesFrame.java @@ -12,10 +12,10 @@ import com.haulmont.chile.core.model.MetaProperty; import com.haulmont.chile.core.model.MetaPropertyPath; import com.haulmont.chile.core.model.Range; import com.haulmont.cuba.core.app.dynamicattributes.DynamicAttributes; +import com.haulmont.cuba.core.app.dynamicattributes.DynamicAttributesMetaProperty; import com.haulmont.cuba.core.app.dynamicattributes.DynamicAttributesUtils; import com.haulmont.cuba.core.app.dynamicattributes.PropertyType; import com.haulmont.cuba.core.entity.CategoryAttribute; -import com.haulmont.cuba.core.entity.CategoryAttributeValue; import com.haulmont.cuba.core.global.AppBeans; import com.haulmont.cuba.core.global.DevelopmentException; import com.haulmont.cuba.core.global.View; @@ -26,7 +26,10 @@ import com.haulmont.cuba.gui.components.validators.DoubleValidator; import com.haulmont.cuba.gui.components.validators.IntegerValidator; import com.haulmont.cuba.gui.components.validators.LongValidator; import com.haulmont.cuba.gui.config.WindowConfig; -import com.haulmont.cuba.gui.data.*; +import com.haulmont.cuba.gui.data.CollectionDatasource; +import com.haulmont.cuba.gui.data.Datasource; +import com.haulmont.cuba.gui.data.DsBuilder; +import com.haulmont.cuba.gui.data.RuntimePropsDatasource; import com.haulmont.cuba.gui.xml.layout.ComponentsFactory; import org.apache.commons.lang.StringUtils; @@ -158,12 +161,11 @@ public class RuntimePropertiesFrame extends AbstractWindow { protected java.util.List createFieldsForAttributes() { @SuppressWarnings("unchecked") - Collection metaProperties = rds.getPropertiesFilteredByCategory(); + Collection metaProperties = rds.getPropertiesFilteredByCategory(); java.util.List fields = new ArrayList<>(); - for (MetaProperty property : metaProperties) { + for (DynamicAttributesMetaProperty property : metaProperties) { FieldGroup.FieldConfig field = new FieldGroup.FieldConfig(property.getName()); - CategoryAttribute attribute = dynamicAttributes - .getAttributeForMetaClass(rds.resolveCategorizedEntityClass(), property.getName()); + CategoryAttribute attribute = property.getAttribute(); field.setCaption(attribute != null ? attribute.getName() : property.getName()); field.setWidth(fieldWidth); fields.add(field); @@ -204,16 +206,15 @@ public class RuntimePropertiesFrame extends AbstractWindow { protected void initCustomFields(FieldGroup component, java.util.List fields, final Datasource ds) { @SuppressWarnings("unchecked") - Collection metaProperties = rds.getPropertiesFilteredByCategory(); - for (final MetaProperty metaProperty : metaProperties) { + Collection metaProperties = rds.getPropertiesFilteredByCategory(); + for (final DynamicAttributesMetaProperty metaProperty : metaProperties) { Range range = metaProperty.getRange(); if (!range.isDatatype()) { component.addCustomField(metaProperty.getName(), new FieldGroup.CustomFieldGenerator() { @Override public Component generateField(Datasource datasource, String propertyId) { final PickerField pickerField; - Boolean lookup = ((DynamicAttributesEntity) datasource.getItem()) - .getCategoryValue(metaProperty.getName()).getCategoryAttribute().getLookup(); + Boolean lookup = metaProperty.getAttribute().getLookup(); if (lookup != null && lookup) { pickerField = componentsFactory.createComponent(LookupPickerField.class); @@ -236,16 +237,12 @@ public class RuntimePropertiesFrame extends AbstractWindow { pickerField.setDatasource(ds, propertyId); LookupAction lookupAction = (LookupAction) pickerField.getAction(LookupAction.NAME); if (lookupAction != null) { - DynamicAttributesEntity dynamicAttributesEntity = (DynamicAttributesEntity) ds.getItem(); - CategoryAttributeValue categoryAttributeValue = dynamicAttributesEntity.getCategoryValue(metaProperty.getName()); - if (categoryAttributeValue != null) { - String screen = categoryAttributeValue.getCategoryAttribute().getScreen(); - if (StringUtils.isBlank(screen)) { - WindowConfig windowConfig = AppBeans.get(WindowConfig.NAME); - screen = windowConfig.getBrowseScreenId(pickerField.getMetaClass()); - } - lookupAction.setLookupScreen(screen); + String screen = metaProperty.getAttribute().getScreen(); + if (StringUtils.isBlank(screen)) { + WindowConfig windowConfig = AppBeans.get(WindowConfig.NAME); + screen = windowConfig.getBrowseScreenId(pickerField.getMetaClass()); } + lookupAction.setLookupScreen(screen); } pickerField.addOpenAction(); pickerField.setWidth(fieldWidth); @@ -312,15 +309,16 @@ public class RuntimePropertiesFrame extends AbstractWindow { } protected void loadRequired(FieldGroup fieldGroup, FieldGroup.FieldConfig field) { - DynamicAttributesEntity dynamicAttributesEntity = (DynamicAttributesEntity) rds.getItem(); - CategoryAttributeValue categoryAttributeValue = dynamicAttributesEntity.getCategoryValue(field.getId()); - String requiredMessage = messages.formatMessage( - AppConfig.getMessagesPack(), - "validation.required.defaultMsg", - categoryAttributeValue.getCategoryAttribute().getName() - ); - fieldGroup.setRequired(field, - Boolean.TRUE.equals(categoryAttributeValue.getCategoryAttribute().getRequired()) && requiredControlEnabled, requiredMessage); + CategoryAttribute attribute = dynamicAttributes.getAttributeForMetaClass(rds.getMainDs().getMetaClass(), field.getId()); + if (attribute != null) { + String requiredMessage = messages.formatMessage( + AppConfig.getMessagesPack(), + "validation.required.defaultMsg", + attribute.getName() + ); + fieldGroup.setRequired(field, + Boolean.TRUE.equals(attribute.getRequired()) && requiredControlEnabled, requiredMessage); + } } public void setCategoryFieldVisible(boolean visible) { diff --git a/modules/gui/src/com/haulmont/cuba/gui/data/DynamicAttributesEntity.java b/modules/gui/src/com/haulmont/cuba/gui/data/DynamicAttributesEntity.java index bc09c643a5..e876ae0923 100644 --- a/modules/gui/src/com/haulmont/cuba/gui/data/DynamicAttributesEntity.java +++ b/modules/gui/src/com/haulmont/cuba/gui/data/DynamicAttributesEntity.java @@ -5,51 +5,36 @@ package com.haulmont.cuba.gui.data; import com.haulmont.chile.core.common.ValueListener; -import com.haulmont.chile.core.common.compatibility.InstancePropertyChangeListenerWrapper; +import com.haulmont.chile.core.model.Instance; import com.haulmont.chile.core.model.MetaClass; import com.haulmont.cuba.core.app.dynamicattributes.DynamicAttributesUtils; -import com.haulmont.cuba.core.app.dynamicattributes.PropertyType; import com.haulmont.cuba.core.entity.BaseEntity; -import com.haulmont.cuba.core.entity.CategoryAttribute; +import com.haulmont.cuba.core.entity.BaseGenericIdEntity; import com.haulmont.cuba.core.entity.CategoryAttributeValue; -import com.haulmont.cuba.core.entity.Entity; import com.haulmont.cuba.core.global.UuidProvider; -import org.apache.commons.lang.ObjectUtils; -import org.apache.commons.lang.StringUtils; -import java.lang.ref.WeakReference; -import java.util.*; +import java.util.Date; +import java.util.Map; +import java.util.UUID; /** - * The entity, that contains a set of dynamic attributes. + * Specific entity, delegating all calls to internal BaseGenericIdEntity. + * + * Obsolete. Will be removed in future releases. * * @author devyatkin * @version $Id$ */ public class DynamicAttributesEntity implements BaseEntity { - private static final long serialVersionUID = -8091230910619941201L; - - protected MetaClass metaClass; + protected BaseGenericIdEntity mainItem; protected UUID id; - protected Map changed = new HashMap<>(); - protected Collection> __valueListeners; - - protected Map categoryValues = new HashMap<>(); - protected Map values = new HashMap<>(); - - public DynamicAttributesEntity(MetaClass metaClass) { - this.metaClass = metaClass; + public DynamicAttributesEntity(BaseGenericIdEntity mainItem) { + this.mainItem = mainItem; this.id = UuidProvider.createUuid(); } - public void addAttributeValue(CategoryAttribute attribute, CategoryAttributeValue categoryAttributeValue, Object value) { - String attributeCode = DynamicAttributesUtils.encodeAttributeCode(attribute.getCode()); - categoryValues.put(attributeCode, categoryAttributeValue); - values.put(attributeCode, value); - } - @Override public UUID getId() { return id; @@ -80,7 +65,7 @@ public class DynamicAttributesEntity implements BaseEntity { @Override public MetaClass getMetaClass() { - return metaClass; + return mainItem.getMetaClass(); } @Override @@ -90,142 +75,54 @@ public class DynamicAttributesEntity implements BaseEntity { @Override public void addListener(com.haulmont.chile.core.common.ValueListener listener) { - addPropertyChangeListener(new InstancePropertyChangeListenerWrapper(listener)); + mainItem.addListener(listener); } @Override public void removeListener(ValueListener listener) { - removePropertyChangeListener(new InstancePropertyChangeListenerWrapper(listener)); + mainItem.removeListener(listener); } @Override public void addPropertyChangeListener(PropertyChangeListener listener) { - if (__valueListeners == null) { - __valueListeners = new ArrayList<>(); - } - __valueListeners.add(new WeakReference<>(listener)); + mainItem.addPropertyChangeListener(listener); } @Override public void removePropertyChangeListener(PropertyChangeListener listener) { - if (__valueListeners != null) { - for (Iterator> it = __valueListeners.iterator(); it.hasNext(); ) { - PropertyChangeListener iteratorListener = it.next().get(); - if (iteratorListener == null || iteratorListener.equals(listener)) { - it.remove(); - } - } - } + mainItem.removePropertyChangeListener(listener); } @Override public void removeAllListeners() { - if (__valueListeners != null) { - __valueListeners.clear(); - } - } - - protected void propertyChanged(String s, Object prev, Object curr) { - if (__valueListeners != null) { - for (WeakReference reference : new ArrayList<>(__valueListeners)) { - PropertyChangeListener listener = reference.get(); - if (listener == null) { - __valueListeners.remove(reference); - } else { - listener.propertyChanged(new PropertyChangeEvent(this, s, prev, curr)); - } - } - } + mainItem.removeAllListeners(); } @Override + @SuppressWarnings("unchecked") public T getValue(String name) { - return (T) values.get(name); + return (T) mainItem.getValue(name); } @Override public void setValue(String name, Object value) { - Object oldValue = values.get(name); - if (!ObjectUtils.equals(oldValue, value)) { - values.put(name, value); - changed.put(name, value); - CategoryAttributeValue categoryValue = categoryValues.get(name); - if (value != null) { - if (BaseEntity.class.isAssignableFrom(value.getClass())) { - categoryValue.setEntityValue(((Entity) value).getUuid()); - } else { - setValue(categoryValue, value); - } - } else { - setValue(categoryValue, null); - } - - propertyChanged(name, oldValue, value); - } + mainItem.setValue(name, value); } @Override + @SuppressWarnings("unchecked") public T getValueEx(String propertyPath) { - return (T) values.get(propertyPath); + return (T) mainItem.getValueEx(propertyPath); } @Override public void setValueEx(String propertyPath, Object value) { - Object oldValue = values.get(propertyPath); - if (!ObjectUtils.equals(oldValue, value)) { - values.put(propertyPath, value); - changed.put(propertyPath, value); - CategoryAttributeValue attrValue = categoryValues.get(propertyPath); - if (value != null) { - if (Entity.class.isAssignableFrom(value.getClass())) { - attrValue.setEntityValue(((Entity) value).getUuid()); - } else { - setValue(attrValue, value); - } - } else { - setValue(attrValue, null); - } - - propertyChanged(propertyPath, oldValue, value); - } + mainItem.setValueEx(propertyPath, value); } + @SuppressWarnings("unchecked") public CategoryAttributeValue getCategoryValue(String name) { - return categoryValues.get(name); - } - - private void setValue(CategoryAttributeValue attrValue, Object value) { - if (attrValue.getCategoryAttribute().getIsEntity()) { - attrValue.setEntityValue((UUID) value); - } else { - PropertyType propertyType = attrValue.getCategoryAttribute().getDataType(); - switch (propertyType) { - case INTEGER: - attrValue.setIntValue((Integer) value); - break; - case DOUBLE: - attrValue.setDoubleValue((Double) value); - break; - case BOOLEAN: - attrValue.setBooleanValue((Boolean) value); - break; - case DATE: - attrValue.setDateValue((Date) value); - break; - case STRING: - case ENUMERATION: - attrValue.setStringValue(StringUtils.trimToNull((String) value)); - break; - case ENTITY: - attrValue.setEntityValue((UUID) value); - break; - } - } - } - - public void updateAttributeValue(CategoryAttributeValue attributeValue) { - CategoryAttribute attribute = attributeValue.getCategoryAttribute(); - String attributeCode = DynamicAttributesUtils.encodeAttributeCode(attribute.getCode()); - categoryValues.put(attributeCode, attributeValue); + Map dynamicAttributes = mainItem.getDynamicAttributes(); + return dynamicAttributes != null ? dynamicAttributes.get(DynamicAttributesUtils.decodeAttributeCode(name)) : null; } } \ No newline at end of file diff --git a/modules/gui/src/com/haulmont/cuba/gui/data/RuntimePropsDatasource.java b/modules/gui/src/com/haulmont/cuba/gui/data/RuntimePropsDatasource.java index 51ac4956e7..3c85eaf81a 100644 --- a/modules/gui/src/com/haulmont/cuba/gui/data/RuntimePropsDatasource.java +++ b/modules/gui/src/com/haulmont/cuba/gui/data/RuntimePropsDatasource.java @@ -7,6 +7,7 @@ package com.haulmont.cuba.gui.data; import com.haulmont.chile.core.model.MetaClass; import com.haulmont.chile.core.model.MetaProperty; +import com.haulmont.cuba.core.app.dynamicattributes.DynamicAttributesMetaProperty; import com.haulmont.cuba.core.entity.Entity; import com.haulmont.cuba.core.global.View; @@ -20,9 +21,7 @@ public interface RuntimePropsDatasource extends Datasource Datasource getMainDs(); - Collection getPropertiesFilteredByCategory(); - - View getAttributeValueView(); + Collection getPropertiesFilteredByCategory(); MetaClass resolveCategorizedEntityClass(); } \ No newline at end of file diff --git a/modules/gui/src/com/haulmont/cuba/gui/data/impl/DsContextImpl.java b/modules/gui/src/com/haulmont/cuba/gui/data/impl/DsContextImpl.java index 188118628f..fb826cc13b 100644 --- a/modules/gui/src/com/haulmont/cuba/gui/data/impl/DsContextImpl.java +++ b/modules/gui/src/com/haulmont/cuba/gui/data/impl/DsContextImpl.java @@ -288,10 +288,6 @@ public class DsContextImpl implements DsContextImplementation { entities.add(entity); views.put(entity, datasource.getView()); - - if (datasource instanceof RuntimePropsDatasource) { - views.put(entity, ((RuntimePropsDatasource) datasource).getAttributeValueView()); - } } // Replace the reference to master entity with actual entity containing in the master datasource, diff --git a/modules/gui/src/com/haulmont/cuba/gui/data/impl/RuntimePropsDatasourceImpl.java b/modules/gui/src/com/haulmont/cuba/gui/data/impl/RuntimePropsDatasourceImpl.java index b47692e1c8..c0bf447169 100644 --- a/modules/gui/src/com/haulmont/cuba/gui/data/impl/RuntimePropsDatasourceImpl.java +++ b/modules/gui/src/com/haulmont/cuba/gui/data/impl/RuntimePropsDatasourceImpl.java @@ -10,13 +10,15 @@ import com.haulmont.chile.core.model.MetaClass; import com.haulmont.chile.core.model.MetaProperty; import com.haulmont.cuba.core.app.dynamicattributes.DynamicAttributes; import com.haulmont.cuba.core.app.dynamicattributes.DynamicAttributesMetaClass; +import com.haulmont.cuba.core.app.dynamicattributes.DynamicAttributesMetaProperty; import com.haulmont.cuba.core.app.dynamicattributes.DynamicAttributesUtils; -import com.haulmont.cuba.core.app.dynamicattributes.PropertyType; import com.haulmont.cuba.core.entity.*; -import com.haulmont.cuba.core.global.*; +import com.haulmont.cuba.core.global.AppBeans; +import com.haulmont.cuba.core.global.DevelopmentException; +import com.haulmont.cuba.core.global.PersistenceHelper; +import com.haulmont.cuba.core.global.View; import com.haulmont.cuba.gui.data.*; -import org.apache.commons.lang.BooleanUtils; -import org.apache.commons.lang.StringUtils; +import com.haulmont.cuba.gui.dynamicattributes.DynamicAttributesGuiTools; import javax.annotation.Nullable; import java.util.*; @@ -34,6 +36,7 @@ public class RuntimePropsDatasourceImpl protected DsContext dsContext; protected DataSupplier dataSupplier; + protected DynamicAttributesGuiTools dynamicAttributesGuiTools; protected DynamicAttributesMetaClass metaClass; protected View view; protected Datasource mainDs; @@ -47,39 +50,23 @@ public class RuntimePropsDatasourceImpl protected Category category; protected final Collection attributes; - protected final View attributeValueView; public RuntimePropsDatasourceImpl(DsContext dsContext, DataSupplier dataSupplier, String id, String mainDsId, @Nullable MetaClass categorizedEntityClass) { this.categorizedEntityClass = categorizedEntityClass; this.id = id; this.dsContext = dsContext; this.dataSupplier = dataSupplier; + this.dynamicAttributesGuiTools = AppBeans.get(DynamicAttributesGuiTools.NAME); + this.metaClass = new DynamicAttributesMetaClass(); this.setMainDs(mainDsId); this.setCommitMode(CommitMode.DATASTORE); - attributes = AppBeans.get(DynamicAttributes.class).getAttributesForMetaClass(resolveCategorizedEntityClass()); + this.attributes = AppBeans.get(DynamicAttributes.NAME, DynamicAttributes.class).getAttributesForMetaClass(resolveCategorizedEntityClass()); for (CategoryAttribute attribute : attributes) { MetaProperty metaProperty = DynamicAttributesUtils.getMetaPropertyPath(mainDs.getMetaClass(), attribute).getMetaProperty(); this.metaClass.addProperty(metaProperty, attribute); } - - //noinspection unchecked - mainDs.addItemPropertyChangeListener(e -> { - if (e.getProperty().equals("category")) { - categoryChanged = true; - initMetaClass(); - } - }); - mainDs.setLoadDynamicAttributes(true); - - ViewRepository viewRepository = AppBeans.get(ViewRepository.NAME); - - View baseAttributeValueView = viewRepository.getView(CategoryAttributeValue.class, View.LOCAL); - View baseAttributeView = viewRepository.getView(CategoryAttribute.class, View.LOCAL); - - attributeValueView = new View(baseAttributeValueView, null, false) - .addProperty("categoryAttribute", new View(baseAttributeView, null, false).addProperty("category")); } @Override @@ -88,88 +75,6 @@ public class RuntimePropsDatasourceImpl throw new UnsupportedOperationException(); } - protected void initMetaClass() { - Entity entity = mainDs.getItem(); - if (!(entity instanceof BaseGenericIdEntity)) { - throw new IllegalStateException("This datasource can contain only entity with subclass of BaseGenericIdEntity"); - } - BaseGenericIdEntity baseGenericIdEntity = (BaseGenericIdEntity) entity; - if (PersistenceHelper.isNew(baseGenericIdEntity)) { - baseGenericIdEntity.setDynamicAttributes(new HashMap<>()); - } - @SuppressWarnings("unchecked") - Map dynamicAttributes = baseGenericIdEntity.getDynamicAttributes(); - Preconditions.checkNotNullArgument(dynamicAttributes, "Dynamic attributes should be loaded explicitly"); - - if (entity instanceof Categorized) { - category = ((Categorized) entity).getCategory(); - } - if (!initializedBefore && category == null) { - category = getDefaultCategory(); - if (entity.getMetaClass().getProperty("category") != null) { - entity.setValue("category", category); - } - } - - item = new DynamicAttributesEntity(metaClass); - Collection entityValues = dynamicAttributes.values(); - TimeSource timeSource = AppBeans.get(TimeSource.NAME); - for (CategoryAttribute attribute : attributes) { - if (!attribute.getCategory().equals(category)) { - continue; - } - - CategoryAttributeValue attributeValue = getValue(attribute, entityValues); - Object value; - if (attributeValue == null) { - attributeValue = new CategoryAttributeValue(); - dynamicAttributes.put(attribute.getCode(), attributeValue); - - attributeValue.setCode(DynamicAttributesUtils.decodeAttributeCode(attribute.getCode())); - attributeValue.setCategoryAttribute(attribute); - attributeValue.setEntityId(entity.getUuid()); - - if (PersistenceHelper.isNew(entity) || categoryChanged) { - attributeValue.setStringValue(StringUtils.trimToNull(attribute.getDefaultString())); - attributeValue.setIntValue(attribute.getDefaultInt()); - attributeValue.setDoubleValue(attribute.getDefaultDouble()); - attributeValue.setBooleanValue(attribute.getDefaultBoolean()); - attributeValue.setDateValue(BooleanUtils.isTrue(attribute.getDefaultDateIsCurrent()) ? - timeSource.currentTimestamp() : attribute.getDefaultDate()); - attributeValue.setEntityValue(attribute.getDefaultEntityId()); - value = parseValue(attribute, attributeValue); - } else { - value = null; - } - } else { - value = parseValue(attribute, attributeValue); - } - - item.addAttributeValue(attribute, attributeValue, value); - } - - view = new View(DynamicAttributesEntity.class); - Collection properties = metaClass.getProperties(); - for (MetaProperty property : properties) { - view.addProperty(property.getName()); - } - - item.addPropertyChangeListener(listener); - item.addPropertyChangeListener(e -> { - modified = true; - //noinspection unchecked - itemsToUpdate.add(item.getCategoryValue(e.getProperty())); - }); - - this.valid(); - initializedBefore = true; - if (!itemsToDelete.isEmpty()) { - modified = true; - } - fireItemChanged(null); - } - - @Override public MetaClass resolveCategorizedEntityClass() { if (categorizedEntityClass == null) { return mainDs.getMetaClass(); @@ -178,60 +83,6 @@ public class RuntimePropsDatasourceImpl } } - protected CategoryAttributeValue getValue(CategoryAttribute attribute, Collection entityValues) { - for (CategoryAttributeValue attrValue : entityValues) { - if (attrValue.getCategoryAttribute().equals(attribute)) - return attrValue; - } - return null; - } - - protected Object parseValue(CategoryAttribute attribute, CategoryAttributeValue attrValue) { - PropertyType dataType = attribute.getDataType(); - - if (BooleanUtils.isTrue(attribute.getIsEntity())) { - if (attrValue != null) { - UUID entityId = attrValue.getEntityValue(); - return parseEntity(attribute.getEntityClass(), entityId); - } else { - UUID entityId = attribute.getDefaultEntityId(); - return parseEntity(attribute.getEntityClass(), entityId); - } - } else { - switch (dataType) { - case STRING: - case ENUMERATION: - return attrValue != null ? attrValue.getStringValue() : attribute.getDefaultString(); - case INTEGER: - return attrValue != null ? attrValue.getIntValue() : attribute.getDefaultInt(); - case DOUBLE: - return attrValue != null ? attrValue.getDoubleValue() : attribute.getDefaultDouble(); - case BOOLEAN: - return attrValue != null ? attrValue.getBooleanValue() : attribute.getDefaultBoolean(); - case DATE: - return attrValue != null ? attrValue.getDateValue() : attribute.getDefaultDate(); - } - - } - return attrValue.getStringValue(); - } - - protected Entity parseEntity(String entityType, UUID uuid) { - try { - Class clazz = Class.forName(entityType); - String entityClassName = metadata.getSession().getClassNN(clazz).getName(); - LoadContext entitiesContext = LoadContext.create(clazz) - .setQuery(LoadContext.createQuery("select a from " + entityClassName + " a where a.id =:e") - .setParameter("e", uuid)) - .setView(View.LOCAL) - .setSoftDeletion(false); - Entity entity = dataSupplier.load(entitiesContext); - return entity; - } catch (ClassNotFoundException e) { - throw new RuntimeException("can't parse entity " + entityType + " " + uuid, e); - } - } - @Override public DsContext getDsContext() { return dsContext; @@ -244,24 +95,7 @@ public class RuntimePropsDatasourceImpl @Override public void commit() { - if (!allowCommit) - return; - - if (Datasource.CommitMode.DATASTORE.equals(getCommitMode())) { - Set commitInstances = new HashSet<>(); - Set deleteInstances = new HashSet<>(); - - commitInstances.addAll(itemsToCreate); - commitInstances.addAll(itemsToUpdate); - deleteInstances.addAll(itemsToDelete); - - CommitContext cc = new CommitContext(commitInstances, deleteInstances); - - Set entities = getDataSupplier().commit(cc); - committed(entities); - } else { - throw new UnsupportedOperationException(); - } + //just do nothing } @Override @@ -301,7 +135,7 @@ public class RuntimePropsDatasourceImpl @Override public void refresh() { - initMetaClass(); + initMetaClass(mainDs.getItem()); } @Override @@ -314,11 +148,6 @@ public class RuntimePropsDatasourceImpl return null; // null is correct } - @Override - public View getAttributeValueView() { - return attributeValueView; - } - @Override public void initialized() { final State prev = state; @@ -335,55 +164,29 @@ public class RuntimePropsDatasourceImpl @Override public void committed(Set entities) { - if (state != State.VALID) { + if (!State.VALID.equals(state)) { return; } for (Entity entity : entities) { - if (entity instanceof CategoryAttributeValue) { - CategoryAttributeValue attributeValue = (CategoryAttributeValue) entity; - item.updateAttributeValue(attributeValue); - Entity mainItem = mainDs.getItem(); - if (mainItem instanceof BaseGenericIdEntity) { - BaseGenericIdEntity baseGenericIdEntity = (BaseGenericIdEntity) mainItem; - if (baseGenericIdEntity.getDynamicAttributes() == null) { - baseGenericIdEntity.setDynamicAttributes(new HashMap<>()); - } - - baseGenericIdEntity.getDynamicAttributes().put(attributeValue.getCode(), attributeValue); - } + if (entity.equals(mainDs.getItem())) { + initMetaClass(entity); } } modified = false; clearCommitLists(); } - protected void setMainDs(String name) { - mainDs = dsContext.get(name); - if (mainDs == null) { - throw new DevelopmentException("runtimePropsDatasource initialization error: mainDs '" + name + "' does not exists"); - } - - //noinspection unchecked - mainDs.addStateChangeListener(e -> { - if (e.getState() == State.VALID) { - if (e.getPrevState() != State.VALID) { - initMetaClass(); - } else { - valid(); - } - } - }); - } - @Override public Datasource getMainDs() { return mainDs; } @Override - public Collection getPropertiesFilteredByCategory() { - return metaClass.getPropertiesFilteredByCategory(category); + @SuppressWarnings("unchecked") + public Collection getPropertiesFilteredByCategory() { + Collection propertiesFilteredByCategory = metaClass.getPropertiesFilteredByCategory(category); + return (Collection) propertiesFilteredByCategory; } @Nullable @@ -398,4 +201,80 @@ public class RuntimePropsDatasourceImpl return null; } + + protected void setMainDs(String name) { + mainDs = dsContext.get(name); + if (mainDs == null) { + throw new DevelopmentException("runtimePropsDatasource initialization error: mainDs '" + name + "' does not exists"); + } + mainDs.setLoadDynamicAttributes(true); + + dynamicAttributesGuiTools.listenDynamicAttributesChanges(mainDs); + + //noinspection unchecked + mainDs.addListener( + new DsListenerAdapter() { + @Override + public void stateChanged(Datasource ds, State prevState, State state) { + if (State.VALID.equals(state)) { + if (!State.VALID.equals(prevState)) + initMetaClass(mainDs.getItem()); + else + valid(); + } + } + + @Override + public void valueChanged(Entity source, String property, Object prevValue, Object value) { + if (property.equals("category")) { + categoryChanged = true; + initMetaClass(mainDs.getItem()); + } + } + + @Override + public void itemChanged(Datasource ds, @Nullable Entity prevItem, @Nullable Entity item) { + initMetaClass(item); + } + } + ); + } + + protected void initMetaClass(Entity entity) { + if (!(entity instanceof BaseGenericIdEntity)) { + throw new IllegalStateException("This datasource can contain only entity with subclass of BaseGenericIdEntity"); + } + + BaseGenericIdEntity baseGenericIdEntity = (BaseGenericIdEntity) entity; + if (PersistenceHelper.isNew(baseGenericIdEntity) && baseGenericIdEntity.getDynamicAttributes() == null) { + baseGenericIdEntity.setDynamicAttributes(new HashMap<>()); + } + + @SuppressWarnings("unchecked") + Map dynamicAttributes = baseGenericIdEntity.getDynamicAttributes(); + Preconditions.checkNotNullArgument(dynamicAttributes, "Dynamic attributes should be loaded explicitly"); + + if (baseGenericIdEntity instanceof Categorized) { + category = ((Categorized) baseGenericIdEntity).getCategory(); + } + if (!initializedBefore && category == null) { + category = getDefaultCategory(); + if (baseGenericIdEntity.getMetaClass().getProperty("category") != null) { + baseGenericIdEntity.setValue("category", category); + } + } + + item = new DynamicAttributesEntity(baseGenericIdEntity); + dynamicAttributesGuiTools.initDefaultAttributeValues(baseGenericIdEntity); + + view = new View(DynamicAttributesEntity.class); + Collection properties = metaClass.getProperties(); + for (MetaProperty property : properties) { + view.addProperty(property.getName()); + } + + valid(); + initializedBefore = true; + fireItemChanged(null); + } } \ No newline at end of file