try {
Map<String, FieldMetadata> ceilingMergedProperties = getSimpleMergedProperties(entity.getType()[0],
persistencePerspective);
String mapKey = entity.findProperty(mapStructure.getKeyPropertyName()).getValue();
if (ceilingMergedProperties.containsKey(mapStructure.getMapProperty() + FieldManager.MAPFIELDSEPARATOR + mapKey)) {
throw new ServiceException("\"" + mapKey + "\" is a reserved property name.");
}
Serializable instance = persistenceManager.getDynamicEntityDao().retrieve(Class.forName(entity.getType()[0]), Long.valueOf(entity.findProperty("symbolicId").getValue()));
Assert.isTrue(instance != null, "Entity not found");
FieldManager fieldManager = getFieldManager();
Map map = (Map) fieldManager.getFieldValue(instance, mapStructure.getMapProperty());
PersistentClass persistentClass = persistenceManager.getDynamicEntityDao().getPersistentClass(mapStructure.getValueClassName());
Map<String, FieldMetadata> valueUnfilteredMergedProperties;
if (persistentClass == null) {
valueUnfilteredMergedProperties = persistenceManager.getDynamicEntityDao().getPropertiesForPrimitiveClass(
((SimpleValueMapStructure) mapStructure).getValuePropertyName(),
((SimpleValueMapStructure) mapStructure).getValuePropertyFriendlyName(),
Class.forName(mapStructure.getValueClassName()),
Class.forName(entity.getType()[0]),
MergedPropertyType.MAPSTRUCTUREVALUE
);
} else {
valueUnfilteredMergedProperties = persistenceManager.getDynamicEntityDao().getMergedProperties(
mapStructure.getValueClassName(),
new Class[]{Class.forName(mapStructure.getValueClassName())},
null,
new String[]{},
new ForeignKey[]{},
MergedPropertyType.MAPSTRUCTUREVALUE,
persistencePerspective.getPopulateToOneFields(),
persistencePerspective.getIncludeFields(),
persistencePerspective.getExcludeFields(),
persistencePerspective.getConfigurationKey(),
""
);
}
Map<String, FieldMetadata> valueMergedProperties = filterOutCollectionMetadata(valueUnfilteredMergedProperties);
if (StringUtils.isEmpty(mapKey)) {
entity.addValidationError(mapStructure.getKeyPropertyName(), RequiredPropertyValidator.ERROR_MESSAGE);
LOG.debug("No key property passed in for map, failing validation");
}
populate: {
if (persistentClass != null) {
Serializable valueInstance = (Serializable) map.get(entity.findProperty("priorKey").getValue());
if (valueInstance == null) {
valueInstance = procureSandBoxMapValue(mapStructure, entity);
if (valueInstance == null) {
break populate;
}
}
if (map.get(mapKey) != null && !map.get(mapKey).equals(valueInstance)) {
entity.addValidationError(mapStructure.getKeyPropertyName(), "keyExistsValidationError");
}
if (StringUtils.isNotBlank(mapStructure.getMapKeyValueProperty())) {
Property p = entity.findProperty("key");
Property newP = new Property();
newP.setName(mapStructure.getMapKeyValueProperty());
newP.setValue(p.getValue());
newP.setIsDirty(p.getIsDirty());
entity.addProperty(newP);
}
//allow validation on other properties in order to show key validation errors along with all the other properties
//validation errors
valueInstance = createPopulatedInstance(valueInstance, entity, valueMergedProperties, false);
if (StringUtils.isNotEmpty(mapKey) && !entity.isValidationFailure()) {
if (!entity.findProperty("priorKey").getValue().equals(mapKey)) {
map.remove(entity.findProperty("priorKey").getValue());
}
/*
* TODO this map manipulation code currently assumes the key value is a String. This should be widened to accept
* additional types of primitive objects.
*/
map.put(entity.findProperty(mapStructure.getKeyPropertyName()).getValue(), valueInstance);
}
} else {
if (StringUtils.isNotEmpty(mapKey) && !entity.isValidationFailure()) {
map.put(entity.findProperty(mapStructure.getKeyPropertyName()).getValue(), entity.findProperty(((SimpleValueMapStructure) mapStructure).getValuePropertyName()).getValue());
}
}
}
instance = persistenceManager.getDynamicEntityDao().merge(instance);
Entity[] responses = getMapRecords(instance, mapStructure, ceilingMergedProperties, valueMergedProperties, entity.findProperty("symbolicId"));
for (Entity response : responses) {
if (response.findProperty(mapStructure.getKeyPropertyName()).getValue().equals(persistencePackage.getEntity().findProperty(mapStructure.getKeyPropertyName()).getValue())) {
return response;
}
}
//could be empty if reverting a sandbox item that has experienced a deletion. make sure to at least return an empty instance of Entity.
return ArrayUtils.isEmpty(responses)?new Entity():responses[0];
} catch (Exception e) {
throw new ServiceException("Problem updating entity : " + e.getMessage(), e);
}
}