public Param(Builder builder) { name = builder.name; setJavaClass(builder.javaClass); entityWhere = builder.entityWhere; entityView = (builder.entityView != null) ? builder.entityView : View.MINIMAL; property = builder.property; inExpr = builder.inExpr; required = builder.required; categoryAttrId = builder.categoryAttrId; isDateInterval = builder.isDateInterval; useUserTimeZone = builder.useUserTimeZone; if (DynamicAttributesUtils.isDynamicAttribute(builder.property)) { CategoryAttribute categoryAttribute = DynamicAttributesUtils.getCategoryAttribute(builder.property); if (categoryAttribute.getDataType() == PropertyType.ENUMERATION) { type = Type.RUNTIME_ENUM; } } }
protected MetaPropertyPath resolveMetaPropertyPath(MetaClass metaClass, String property) { MetaPropertyPath mpp = metaClass.getPropertyPath(property); if (mpp == null && DynamicAttributesUtils.isDynamicAttribute(property)) { mpp = DynamicAttributesUtils.getMetaPropertyPath(metaClass, property); } return mpp; }
public DynamicAttributesMetaProperty(MetaClass metaClass, CategoryAttribute attribute) { this.attribute = attribute; this.javaClass = DynamicAttributesUtils.getAttributeClass(attribute); this.metaClass = metaClass; this.name = DynamicAttributesUtils.encodeAttributeCode(attribute.getCode()); this.mandatory = attribute.getRequired(); Metadata metadata = AppBeans.get(Metadata.NAME); Session metadataSession = metadata.getSession(); if (Entity.class.isAssignableFrom(javaClass)) { range = new ClassRange(metadataSession.getClass(javaClass)); this.type = Type.ASSOCIATION; } else { this.range = new DatatypeRange(Datatypes.getNN(javaClass)); this.type = Type.DATATYPE; } }
/** * Get special meta property path object for dynamic attribute by code */ @Nullable public MetaPropertyPath getMetaPropertyPath(MetaClass metaClass, String attributeCode) { attributeCode = decodeAttributeCode(attributeCode); CategoryAttribute attribute = dynamicAttributes.getAttributeForMetaClass(metaClass, attributeCode); if (attribute != null) { return DynamicAttributesUtils.getMetaPropertyPath(metaClass, attribute); } else { return null; } }
protected Set<String> filterRemovedAttributes(MetaClass metaClass, Set<String> attributes) { // filter attributes that do not exists in entity anymore return attributes.stream() .filter(attributeName -> { if (DynamicAttributesUtils.isDynamicAttribute(attributeName)) { return dynamicAttributesTools.getMetaPropertyPath(metaClass, attributeName) != null; } else { return metaClass.getPropertyPath(attributeName) != null; } }) .collect(Collectors.toSet()); }
/** * Creates ListEditor component. * * @param valueSource value source * @param propertyId property id of dynamic attribute * @return list editor component or null */ @Nullable public Component generateComponent(ValueSource valueSource, String propertyId) { if (valueSource instanceof EntityValueSource) { MetaClass metaClass = ((EntityValueSource) valueSource).getEntityMetaClass(); MetaPropertyPath metaPropertyPath = DynamicAttributesUtils.getMetaPropertyPath(metaClass, propertyId); if (metaPropertyPath == null) { log.error("MetaPropertyPath for dynamic attribute {} not found", propertyId); return null; } return generateComponent(valueSource, metaPropertyPath); } return null; }
@Override @SuppressWarnings("unchecked") public <V> V getValue(String property) { if (DynamicAttributesUtils.isDynamicAttribute(property)) { if (PersistenceHelper.isNew(this) && dynamicAttributes == null) { 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(); } else { return null; } } else { return super.getValue(property); } }
@Override public String getLocCaption() { if (isBlank(caption) && !isBlank(propertyPath)) { MessageTools messageTools = AppBeans.get(MessageTools.class); String propertyCaption = messageTools.getPropertyCaption(metaClass, propertyPath); if (!isBlank(propertyCaption)) { return propertyCaption + "." + locCaption; } } else if (isNotBlank(caption)) { MessageTools messageTools = AppBeans.get(MessageTools.class); return messageTools.loadString(messagesPack, caption); } MetaPropertyPath mpp = DynamicAttributesUtils.getMetaPropertyPath(metaClass, getCategoryAttributeId()); if (mpp != null) { return DynamicAttributesUtils.getCategoryAttribute(mpp.getMetaProperty()).getLocaleName(); } return super.getLocCaption(); } }
protected Set<EntityLogAttr> createDynamicLogAttribute(CategoryAttributeValue entity, @Nullable EntityAttributeChanges changes, boolean registerDeleteOp) { Set<EntityLogAttr> result = new HashSet<>(); EntityLogAttr attr = metadata.create(EntityLogAttr.class); attr.setName(DynamicAttributesUtils.encodeAttributeCode(entity.getCode())); MetaProperty valueMetaProperty = entity.getMetaClass().getProperty(getCategoryAttributeValueName(entity)); Object value = entity.getValue(); attr.setValue(stringify(value, valueMetaProperty)); Object valueId = getValueId(value); if (valueId != null) attr.setValueId(valueId.toString()); if (changes != null || registerDeleteOp) { Object oldValue = getOldCategoryAttributeValue(entity, changes); attr.setOldValue(stringify(oldValue, valueMetaProperty)); Object oldValueId = getValueId(oldValue); if (oldValueId != null) { attr.setOldValueId(oldValueId.toString()); } } result.add(attr); return result; }
Op op = operationLookup.getValue(); Class javaClass = DynamicAttributesUtils.getAttributeClass(attribute); String propertyPath = Strings.isNullOrEmpty(condition.getPropertyPath()) ? "" : "." + condition.getPropertyPath(); ConditionParamBuilder paramBuilder = AppBeans.get(ConditionParamBuilder.class); .setJavaClass(paramJavaClass) .setMetaClass(condition.getEntityMetaClass()) .setProperty(DynamicAttributesUtils.getMetaPropertyPath(null, attribute).getMetaProperty()) .setInExpr(condition.getInExpr()) .setRequired(condition.getRequired())
/** * For collection dynamic attributes the method returns a list of formatted collection items joined with the comma, * for non-collection dynamic attribute a formatted value is returned */ @SuppressWarnings("unchecked") public String getDynamicAttributeValueAsString(MetaProperty metaProperty, Object value) { CategoryAttribute categoryAttribute = getCategoryAttribute(metaProperty); if (categoryAttribute.getIsCollection()) { if (value instanceof Collection) { List<String> valuesList = ((Collection<Object>) value).stream() .map(item -> metadataTools.format(item, metaProperty)) .collect(Collectors.toList()); return Joiner.on(", ").join(valuesList); } } return metadataTools.format(value, metaProperty); } }
@Nullable public CategoryAttribute getAttributeForMetaClass(MetaClass metaClass, String code) { code = DynamicAttributesUtils.decodeAttributeCode(code); MetaClass targetMetaClass = resolveTargetMetaClass(metaClass); Map<String, CategoryAttribute> attributes = attributesCache.get(targetMetaClass.getName()); if (attributes != null) { return attributes.get(code); } return null; }
protected void fillOperationSelect(CategoryAttribute categoryAttribute) { Class clazz = DynamicAttributesUtils.getAttributeClass(categoryAttribute); OpManager opManager = AppBeans.get(OpManager.class); EnumSet<Op> availableOps = BooleanUtils.isTrue(categoryAttribute.getIsCollection()) ? opManager.availableOpsForCollectionDynamicAttribute() : opManager.availableOps(clazz); List<Op> ops = new LinkedList<>(availableOps); operationLookup.setOptionsList(ops); Op operator = condition.getOperator(); if (operator != null) { operationLookup.setValue(operator); } } }
protected MetaPropertyPath resolveMetaPropertyPath(MetaClass metaClass, String property) { MetaPropertyPath mpp = metaClass.getPropertyPath(property); if (mpp == null && DynamicAttributesUtils.isDynamicAttribute(property)) { mpp = dynamicAttributesTools.getMetaPropertyPath(metaClass, property); } return mpp; }
/** * Get special meta property path object for dynamic attribute id */ @Nullable public MetaPropertyPath getMetaPropertyPath(MetaClass metaClass, UUID attributeId) { Collection<CategoryAttribute> attributes = dynamicAttributes.getAttributesForMetaClass(metaClass); CategoryAttribute attribute = null; for (CategoryAttribute theAttribute : attributes) { if (theAttribute.getId().equals(attributeId)) { attribute = theAttribute; break; } } if (attribute != null) { return DynamicAttributesUtils.getMetaPropertyPath(metaClass, attribute); } else { return null; } }
if (isDynamicAttribute(property)) { @SuppressWarnings("unchecked") Map<String, CategoryAttributeValue> entityDynamicAttributes = String attributeCode = decodeAttributeCode(property); return entityDynamicAttributes.containsKey(attributeCode) || dynamicAttributes.getAttributeForMetaClass(metaClass, property) != null;
protected void internalRegisterModifyAttributeValue(CategoryAttributeValue entity, @Nullable EntityAttributeChanges changes, Set<String> attributes) { String propertyName = DynamicAttributesUtils.encodeAttributeCode(entity.getCode()); if (!attributes.contains(propertyName)) { return; } Date ts = timeSource.currentTimestamp(); EntityManager em = persistence.getEntityManager(); Set<String> dirty = changes == null ? persistence.getTools().getDirtyFields(entity) : changes.getOwnAttributes(); boolean registerDeleteOp = dirty.contains("deleteTs") && entity.isDeleted(); boolean hasChanges = dirty.stream().anyMatch(s -> s.endsWith("Value")); if (hasChanges) { EntityLogItem item = metadata.create(EntityLogItem.class); item.setEventTs(ts); item.setUser(findUser(em)); item.setType(EntityLogItem.Type.MODIFY); item.setEntity(getEntityName(entity)); item.setObjectEntityId(entity.getObjectEntityId()); item.setAttributes(createDynamicLogAttribute(entity, changes, registerDeleteOp)); enqueueItem(item); } }
/** * Creates ListEditor component. * * @param valueSource value source * @param metaPropertyPath meta property path of dynamic attribute * @return list editor component or null */ @Nullable public Component generateComponent(ValueSource valueSource, MetaPropertyPath metaPropertyPath) { CategoryAttribute categoryAttribute = DynamicAttributesUtils.getCategoryAttribute(metaPropertyPath.getMetaProperty()); if (categoryAttribute == null) { log.error("Dynamic attribute {} not found", metaPropertyPath.getMetaProperty().getName()); return null; } return generateComponent(valueSource, categoryAttribute); }
@Override @SuppressWarnings("unchecked") public void setValue(String name, Object value) { mainItem.setValue(name, value); //if we set an attribute from another type of entity, we need to set reference to CategoryAttribute manually //this is workaround to make #PL-5770 logic works with modern RuntimePropertiesDatasource String attributeCode = DynamicAttributesUtils.decodeAttributeCode(name); Map<String, CategoryAttributeValue> dynamicAttributes = mainItem.getDynamicAttributes(); if (dynamicAttributes != null) { CategoryAttributeValue categoryAttributeValue = dynamicAttributes.get(attributeCode); if (categoryAttributeValue != null && categoryAttributeValue.getCategoryAttribute() == null) { categoryAttributeValue.setCategoryAttribute(attributesMap.get(attributeCode)); } } }
protected boolean isCollectionDynamicAttribute(MetaProperty metaProperty) { if (DynamicAttributesUtils.isDynamicAttribute(metaProperty.getName())) { CategoryAttribute attribute = DynamicAttributesUtils.getCategoryAttribute(metaProperty); return attribute != null && BooleanUtils.isTrue(attribute.getIsCollection()); } return false; } }