use of org.broadleafcommerce.openadmin.server.service.persistence.validation.PopulateValueRequestValidator in project BroadleafCommerce by BroadleafCommerce.
the class BasicPersistenceModule method createPopulatedInstance.
@Override
public Serializable createPopulatedInstance(Serializable instance, Entity entity, Map<String, FieldMetadata> unfilteredProperties, Boolean setId, Boolean validateUnsubmittedProperties) throws ValidationException {
final Map<String, FieldMetadata> mergedProperties = filterOutCollectionMetadata(unfilteredProperties);
FieldManager fieldManager = getFieldManager();
boolean handled = false;
for (FieldPersistenceProvider fieldPersistenceProvider : fieldPersistenceProviders) {
MetadataProviderResponse response = fieldPersistenceProvider.filterProperties(new AddFilterPropertiesRequest(entity), unfilteredProperties);
if (MetadataProviderResponse.NOT_HANDLED != response) {
handled = true;
}
if (MetadataProviderResponse.HANDLED_BREAK == response) {
break;
}
}
if (!handled) {
defaultFieldPersistenceProvider.filterProperties(new AddFilterPropertiesRequest(entity), unfilteredProperties);
}
// Order media field, map field and rule builder fields last, as they will have some validation components that depend on previous values
Property[] sortedProperties = entity.getProperties();
Arrays.sort(sortedProperties, new Comparator<Property>() {
@Override
public int compare(Property o1, Property o2) {
BasicFieldMetadata mo1 = (BasicFieldMetadata) mergedProperties.get(o1.getName());
BasicFieldMetadata mo2 = (BasicFieldMetadata) mergedProperties.get(o2.getName());
boolean isLate1 = mo1 != null && mo1.getFieldType() != null && mo1.getName() != null && (SupportedFieldType.RULE_SIMPLE == mo1.getFieldType() || SupportedFieldType.RULE_WITH_QUANTITY == mo1.getFieldType() || SupportedFieldType.RULE_SIMPLE_TIME == mo1.getFieldType() || SupportedFieldType.MEDIA == mo1.getFieldType() || o1.getName().contains(FieldManager.MAPFIELDSEPARATOR));
boolean isLate2 = mo2 != null && mo2.getFieldType() != null && mo2.getName() != null && (SupportedFieldType.RULE_SIMPLE == mo2.getFieldType() || SupportedFieldType.RULE_WITH_QUANTITY == mo2.getFieldType() || SupportedFieldType.RULE_SIMPLE_TIME == mo2.getFieldType() || SupportedFieldType.MEDIA == mo2.getFieldType() || o2.getName().contains(FieldManager.MAPFIELDSEPARATOR));
if (isLate1 && !isLate2) {
return 1;
} else if (!isLate1 && isLate2) {
return -1;
}
return 0;
}
});
Session session = getPersistenceManager().getDynamicEntityDao().getStandardEntityManager().unwrap(Session.class);
FlushMode originalFlushMode = session.getFlushMode();
try {
session.setFlushMode(FlushMode.MANUAL);
RuntimeException entityPersistenceException = null;
for (Property property : sortedProperties) {
BasicFieldMetadata metadata = (BasicFieldMetadata) mergedProperties.get(property.getName());
Class<?> returnType;
if (!property.getName().contains(FieldManager.MAPFIELDSEPARATOR) && !property.getName().startsWith("__")) {
Field field = fieldManager.getField(instance.getClass(), property.getName());
if (field == null) {
LOG.debug("Unable to find a bean property for the reported property: " + StringUtil.sanitize(property.getName()) + ". Ignoring property.");
continue;
}
returnType = field.getType();
} else {
if (metadata == null) {
LOG.debug("Unable to find a metadata property for the reported property: " + StringUtil.sanitize(property.getName()) + ". Ignoring property.");
continue;
}
returnType = getMapFieldType(instance, fieldManager, property);
if (returnType == null) {
returnType = getBasicBroadleafType(metadata.getFieldType());
}
}
if (returnType == null) {
throw new IllegalAccessException("Unable to determine the value type for the property (" + property.getName() + ")");
}
String value = property.getValue();
if (metadata != null) {
if (metadata.getFieldType().equals(SupportedFieldType.BOOLEAN)) {
if (value == null) {
value = "false";
}
}
if (attemptToPopulateValue(property, fieldManager, instance, setId, metadata, entity, value)) {
boolean isValid = true;
PopulateValueRequest request = new PopulateValueRequest(setId, fieldManager, property, metadata, returnType, value, persistenceManager, this, entity.isPreAdd());
handled = false;
if (value != null) {
for (PopulateValueRequestValidator validator : populateValidators) {
PropertyValidationResult validationResult = validator.validate(request, instance);
if (!validationResult.isValid()) {
entity.addValidationError(property.getName(), validationResult.getErrorMessage());
isValid = false;
}
}
}
if (isValid) {
try {
boolean isBreakDetected = false;
for (FieldPersistenceProvider fieldPersistenceProvider : fieldPersistenceProviders) {
if ((!isBreakDetected || fieldPersistenceProvider.alwaysRun()) && (value != null || fieldPersistenceProvider.canHandlePopulateNull())) {
MetadataProviderResponse response = fieldPersistenceProvider.populateValue(request, instance);
if (MetadataProviderResponse.NOT_HANDLED != response) {
handled = true;
}
if (MetadataProviderResponse.HANDLED_BREAK == response) {
isBreakDetected = true;
}
}
}
if (!handled) {
if (value == null) {
property.setIsDirty(true);
}
defaultFieldPersistenceProvider.populateValue(new PopulateValueRequest(setId, fieldManager, property, metadata, returnType, value, persistenceManager, this, entity.isPreAdd()), instance);
if (value == null) {
fieldManager.setFieldValue(instance, property.getName(), null);
}
}
} catch (ParentEntityPersistenceException | javax.validation.ValidationException e) {
entityPersistenceException = e;
cleanupFailedPersistenceAttempt(instance);
break;
}
}
}
}
}
// Only check validation if not the initial add
if (!entity.isPreAdd()) {
validate(entity, instance, mergedProperties, validateUnsubmittedProperties);
}
// if validation failed, refresh the current instance so that none of the changes will be persisted
if (entity.isValidationFailure()) {
// only refresh the instance if it was managed to begin with
if (persistenceManager.getDynamicEntityDao().getStandardEntityManager().contains(instance)) {
persistenceManager.getDynamicEntityDao().refresh(instance);
}
// re-initialize the valid properties for the entity in order to deal with the potential of not
// completely sending over all checkbox/radio fields
List<Serializable> entityList = new ArrayList<Serializable>(1);
entityList.add(instance);
Entity invalid = getRecords(mergedProperties, entityList, null, null, null)[0];
invalid.setPropertyValidationErrors(entity.getPropertyValidationErrors());
invalid.overridePropertyValues(entity);
String message = ValidationUtil.buildErrorMessage(invalid.getPropertyValidationErrors(), invalid.getGlobalValidationErrors());
throw new ValidationException(invalid, message);
} else if (entityPersistenceException != null) {
throw ExceptionHelper.refineException(entityPersistenceException.getCause());
} else {
fieldManager.persistMiddleEntities();
}
} catch (IllegalAccessException e) {
throw new PersistenceException(e);
} catch (InstantiationException e) {
throw new PersistenceException(e);
} finally {
session.setFlushMode(originalFlushMode);
}
return instance;
}
Aggregations