From 8165e0b756de5434add24e3bee45acecc094b06c Mon Sep 17 00:00:00 2001 From: alaskowski <alaskowski@ethz.ch> Date: Thu, 21 Sep 2023 13:04:42 +0200 Subject: [PATCH] SSDM-55: Improved property converter for multi-value properties --- .../property/PropertyTranslator.java | 102 +++++++++++------- .../dataaccess/EntityPropertiesConverter.java | 30 ++++-- 2 files changed, 89 insertions(+), 43 deletions(-) diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/property/PropertyTranslator.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/property/PropertyTranslator.java index bc908803a2b..f406a320fed 100644 --- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/property/PropertyTranslator.java +++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/property/PropertyTranslator.java @@ -55,66 +55,53 @@ public abstract class PropertyTranslator extends records.stream().filter(r -> r.sample_id != null).map(r -> r.sample_id) .collect(Collectors.toSet())); - Map<Long, Map<String, Serializable>> properties = new HashMap<Long, Map<String, Serializable>>(); + Map<Long, Map<String, Serializable>> properties = + new HashMap<Long, Map<String, Serializable>>(); for (PropertyRecord record : records) { Map<String, Serializable> objectProperties = properties.get(record.objectId); if (objectProperties == null) { - objectProperties = new HashMap<String, Serializable>(); + objectProperties = new HashMap<>(); properties.put(record.objectId, objectProperties); } if (record.propertyValue != null) { - objectProperties.put(record.propertyCode, record.propertyValue); + updateObjectProperty(objectProperties, record.propertyCode, record.propertyValue); } else if (record.materialPropertyValueCode != null) { - objectProperties.put(record.propertyCode, + updateObjectProperty(objectProperties, record.propertyCode, record.materialPropertyValueCode + " (" + record.materialPropertyValueTypeCode + ")"); } else if (record.vocabularyPropertyValue != null) { - if(objectProperties.containsKey(record.propertyCode)) { - Serializable current = objectProperties.get(record.propertyCode); - Serializable newValue = composeMultiValueProperty(current, record.vocabularyPropertyValue); - objectProperties.put(record.propertyCode, newValue); - } else { - objectProperties.put(record.propertyCode, record.vocabularyPropertyValue); - } + updateObjectProperty(objectProperties, record.propertyCode, + record.vocabularyPropertyValue); } else if (record.sample_perm_id != null) { - if (visibaleSamples.contains(record.sample_id)) - { - if(objectProperties.containsKey(record.propertyCode)) { - Serializable current = objectProperties.get(record.propertyCode); - Serializable newValue = composeMultiValueProperty(current, record.sample_perm_id); - objectProperties.put(record.propertyCode, newValue); - } else - { - objectProperties.put(record.propertyCode, record.sample_perm_id); - } - } + updateObjectProperty(objectProperties, record.propertyCode, record.sample_perm_id); } else if (record.integerArrayPropertyValue != null) { - objectProperties.put(record.propertyCode, - convertArrayToString(record.integerArrayPropertyValue)); + updateArrayObjectProperty(objectProperties, record.propertyCode, + record.integerArrayPropertyValue); } else if (record.realArrayPropertyValue != null) { - objectProperties.put(record.propertyCode, - convertArrayToString(record.realArrayPropertyValue)); + updateArrayObjectProperty(objectProperties, record.propertyCode, + record.realArrayPropertyValue); } else if (record.stringArrayPropertyValue != null) { - objectProperties.put(record.propertyCode, - convertArrayToString(record.stringArrayPropertyValue)); + updateArrayObjectProperty(objectProperties, record.propertyCode, + record.stringArrayPropertyValue); } else if (record.timestampArrayPropertyValue != null) { - objectProperties.put(record.propertyCode, - convertArrayToString(record.timestampArrayPropertyValue)); + updateArrayObjectProperty(objectProperties, record.propertyCode, + record.timestampArrayPropertyValue); } else if (record.jsonPropertyValue != null) { - objectProperties.put(record.propertyCode, record.jsonPropertyValue); + updateObjectProperty(objectProperties, record.propertyCode, + record.jsonPropertyValue); } else { // SAMPLE property with deleted sample. Thus, nothing is put to objectProperties @@ -124,15 +111,57 @@ public abstract class PropertyTranslator extends return properties; } - private Serializable composeMultiValueProperty(Serializable current, Serializable newValue) { + private void updateObjectProperty(Map<String, Serializable> objectProperties, + String propertyCode, Serializable propertyValue) + { + if (objectProperties.containsKey(propertyCode)) + { + Serializable current = objectProperties.get(propertyCode); + Serializable newValue = composeMultiValueProperty(current, propertyValue); + objectProperties.put(propertyCode, newValue); + } else + { + objectProperties.put(propertyCode, propertyValue); + } + } + + private void updateArrayObjectProperty(Map<String, Serializable> objectProperties, + String propertyCode, Serializable[] propertyValue) + { + if (objectProperties.containsKey(propertyCode)) + { + Serializable[] current = (Serializable[]) objectProperties.get(propertyCode); + Serializable[] result; + if(current.length > 0) { + if(current[0].getClass().isArray()) { + result = new Serializable[current.length + 1]; + System.arraycopy(current, 0, result, 0, current.length); + result[current.length] = propertyValue; + } else { + result = new Serializable[] {current, propertyValue}; + } + } else { + result = propertyValue; + } + objectProperties.put(propertyCode, result); + } else + { + objectProperties.put(propertyCode, propertyValue); + } + } + + private Serializable composeMultiValueProperty(Serializable current, Serializable newValue) + { Serializable[] result; - if(current.getClass().isArray()) { + if (current.getClass().isArray()) + { Serializable[] values = (Serializable[]) current; result = new Serializable[values.length + 1]; System.arraycopy(values, 0, result, 0, values.length); result[values.length] = newValue; - } else { - result = new Serializable[] {current, newValue}; + } else + { + result = new Serializable[] { current, newValue }; } return result; } @@ -150,7 +179,8 @@ public abstract class PropertyTranslator extends ObjectHolder<Map<String, Serializable>> result, Object relations, PropertyFetchOptions fetchOptions) { - Map<Long, Map<String, Serializable>> properties = (Map<Long, Map<String, Serializable>>) relations; + Map<Long, Map<String, Serializable>> properties = + (Map<Long, Map<String, Serializable>>) relations; Map<String, Serializable> objectProperties = properties.get(objectId); if (objectProperties == null) diff --git a/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/EntityPropertiesConverter.java b/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/EntityPropertiesConverter.java index a08157c3f3c..d8fdb2ef294 100644 --- a/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/EntityPropertiesConverter.java +++ b/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/EntityPropertiesConverter.java @@ -268,7 +268,7 @@ public final class EntityPropertiesConverter implements IEntityPropertiesConvert { final String propertyCode = property.getPropertyType().getCode(); final PropertyTypePE propertyType = getPropertyType(propertyCode); - final String valueOrNull = property.tryGetAsString(); + final Serializable valueOrNull = property.getValue(); ExtendedEntityTypePropertyType extendedETPT = getEntityTypePropertyType(entityTypePE, propertyType); final EntityTypePropertyTypePE entityTypePropertyTypePE = @@ -281,12 +281,26 @@ public final class EntityPropertiesConverter implements IEntityPropertiesConvert if (isNullOrBlank(valueOrNull) == false) { List<T> results = new ArrayList<>(); - String translatedValue = extendedETPT.translate(registrator, valueOrNull); + if(propertyType.isMultiValue() && valueOrNull.getClass().isArray()) { + for (Serializable value : (Serializable[]) valueOrNull) + { + String translatedValue = + extendedETPT.translate(registrator, (String) value); + final String validatedValue = + propertyValueValidator.validatePropertyValue(propertyType, + translatedValue); + results.addAll(createEntityProperty(registrator, propertyType, + entityTypePropertyTypePE, + validatedValue)); + } + } else { + String translatedValue = extendedETPT.translate(registrator, (String) valueOrNull); - final String validatedValue = - propertyValueValidator.validatePropertyValue(propertyType, translatedValue); - results.addAll(createEntityProperty(registrator, propertyType, entityTypePropertyTypePE, - validatedValue)); + final String validatedValue = + propertyValueValidator.validatePropertyValue(propertyType, translatedValue); + results.addAll(createEntityProperty(registrator, propertyType, entityTypePropertyTypePE, + validatedValue)); + } return results; } return null; @@ -299,7 +313,9 @@ public final class EntityPropertiesConverter implements IEntityPropertiesConvert { List<T> entityProperties = new ArrayList<>(); String val = value; - if (propertyType.isMultiValue()) + List<DataTypeCode> arrayTypes = List.of(DataTypeCode.ARRAY_STRING, + DataTypeCode.ARRAY_INTEGER, DataTypeCode.ARRAY_REAL, DataTypeCode.ARRAY_TIMESTAMP); + if (propertyType.isMultiValue() && !arrayTypes.contains(propertyType.getType().getCode())) { if (val.startsWith("[")) { -- GitLab