use of org.meveo.admin.exception.ValidationException in project meveo by meveo-org.
the class CustomTableService method importData.
/**
* Import data into custom table
*
* @param cet Custom table definition
* @param inputStream Data stream
* @param append True if data should be appended to the existing data. If false, data will be added in batch. One by one otherwise.
* @return Number of records imported
* @throws BusinessException General business exception
*/
public int importData(String sqlConnectionCode, CustomEntityTemplate cet, InputStream inputStream, boolean append) throws BusinessException {
final String dbTableName = SQLStorageConfiguration.getDbTablename(cet);
// Custom table fields. Fields will be sorted by their GUI 'field' position.
Map<String, CustomFieldTemplate> cfts = customFieldTemplateService.findByAppliesTo(cet.getAppliesTo());
if (cfts == null || cfts.isEmpty()) {
throw new ValidationException("No fields are defined for custom table " + dbTableName, "customTable.noFields");
}
List<CustomFieldTemplate> fields = new ArrayList<>(cfts.values());
fields.sort((cft1, cft2) -> {
int pos1 = cft1.getGUIFieldPosition();
int pos2 = cft2.getGUIFieldPosition();
return pos1 - pos2;
});
int importedLines = 0;
int importedLinesTotal = 0;
List<Map<String, Object>> values = new ArrayList<>();
ObjectReader oReader = getCSVReader(fields);
try (Reader reader = new InputStreamReader(inputStream)) {
// Cache used to avoid fetching multiple time the same data
Map<String, Map<String, String>> entityReferencesCache = new HashMap<>();
MappingIterator<Map<String, Object>> mappingIterator = oReader.readValues(reader);
while (mappingIterator.hasNext()) {
Map<String, Object> lineValues = mappingIterator.next();
lineValues.remove("uuid");
if (append) {
lineValues = convertValue(lineValues, cfts, true, null);
replaceEntityreferences(sqlConnectionCode, fields, entityReferencesCache, lineValues);
String uuid = findIdByUniqueValues(sqlConnectionCode, cet, lineValues, fields);
if (uuid == null) {
final String tablename = SQLStorageConfiguration.getDbTablename(cet);
super.createInNewTx(sqlConnectionCode, tablename, lineValues);
importedLines++;
importedLinesTotal++;
}
} else {
// Save to DB every 500 records
if (importedLines >= 500) {
saveBatch(sqlConnectionCode, cfts, fields, cet.getCode(), values, entityReferencesCache);
values.clear();
importedLines = 0;
}
importedLines++;
importedLinesTotal++;
values.add(lineValues);
}
if (importedLinesTotal % 30000 == 0) {
log.trace("Imported {} lines to {} table", importedLinesTotal, dbTableName);
}
}
if (!append) {
// Save remaining records
saveBatch(sqlConnectionCode, cfts, fields, cet.getCode(), values, entityReferencesCache);
}
// Re-populate ES index
elasticClient.populateAll(currentUser, CustomTableRecord.class, cet.getCode());
log.info("Imported {} lines to {} table", importedLinesTotal, dbTableName);
} catch (RuntimeJsonMappingException e) {
throw new ValidationException("Invalid file format", "message.upload.fail.invalidFormat", e);
} catch (IOException e) {
throw new BusinessException(e);
}
return importedLinesTotal;
}
use of org.meveo.admin.exception.ValidationException in project meveo by meveo-org.
the class MeveoModuleApi method release.
public void release(String moduleCode, String nextVersion) throws MeveoApiException, BusinessException {
MeveoModule module = meveoModuleService.findByCode(moduleCode);
if (module == null) {
throw new EntityDoesNotExistsException(MeveoModule.class, moduleCode);
}
Integer version = Integer.parseInt(nextVersion.replace(".", ""));
Integer versionModule = Integer.parseInt(module.getCurrentVersion().replace(".", ""));
if (version > versionModule) {
if (module.getScript() != null) {
boolean checkRelease = meveoModuleService.checkTestSuites(module.getScript().getCode());
if (!checkRelease) {
throw new ValidationException("There some test suits failed", "meveoModule.checkTestSuitsReleaseFailed");
}
}
meveoModuleService.releaseModule(module, nextVersion);
} else {
throw new ValidationException("Failed to release module. Next version is less than the current version " + module.getCurrentVersion());
}
}
use of org.meveo.admin.exception.ValidationException in project meveo by meveo-org.
the class NativePersistenceService method castValue.
/**
* Convert value of unknown data type to a target data type. A value of type
* list is considered as already converted value, as would come only from WS.
*
* @param value Value to convert
* @param targetClass Target data type class to convert to
* @param expectedList Is return value expected to be a list. If value is not a
* list and is a string a value will be parsed as comma
* separated string and each value will be converted
* accordingly. If a single value is passed, it will be
* added to a list.
* @param datePatterns Optional. Date patterns to apply to a date type field.
* Conversion is attempted in that order until a valid date
* is matched.If no values are provided, a standard date and
* time and then date only patterns will be applied.
* @return A converted data type
* @throws ValidationException Value can not be cast to a target class
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
protected Object castValue(Object value, Class targetClass, boolean expectedList, String[] datePatterns) throws ValidationException {
if (StringUtils.isBlank(value)) {
return null;
}
if (value.equals(true)) {
return 1;
} else if (value.equals(false)) {
return 0;
}
// Nothing to cast - same data type
if (targetClass.isAssignableFrom(value.getClass()) && !expectedList) {
return value;
}
// separated string and convert each value separately
if (expectedList) {
if (value instanceof Collection) {
Collection<?> collectionValue = (Collection<?>) value;
// Convert entity references wrapper list to list of string
{
List<String> entityReferences = collectionValue.stream().filter(EntityReferenceWrapper.class::isInstance).map(EntityReferenceWrapper.class::cast).map(EntityReferenceWrapper::getUuid).filter(Objects::nonNull).collect(Collectors.toList());
if (!entityReferences.isEmpty()) {
return entityReferences;
}
}
// Convert entity references wrapper list to list of long
{
List<Long> entityReferences = collectionValue.stream().filter(EntityReferenceWrapper.class::isInstance).map(EntityReferenceWrapper.class::cast).map(EntityReferenceWrapper::getId).filter(Objects::nonNull).collect(Collectors.toList());
if (!entityReferences.isEmpty()) {
return entityReferences;
}
}
return value;
} else if (value instanceof String) {
try {
// First try to parse json
return JacksonUtil.fromString((String) value, List.class);
} catch (Exception e) {
// If it fails, parse comma separated string
List valuesConverted = new ArrayList<>();
String[] valueItems = ((String) value).split(",");
for (String valueItem : valueItems) {
Object valueConverted = castValue(valueItem, targetClass, false, datePatterns);
if (valueConverted != null) {
valuesConverted.add(valueConverted);
} else {
throw new ValidationException("Filter value " + value + " does not match " + targetClass.getSimpleName());
}
}
return valuesConverted;
}
} else {
// A single value list
Object valueConverted = castValue(value, targetClass, false, datePatterns);
if (valueConverted != null) {
return Collections.singletonList(valueConverted);
} else {
throw new ValidationException("Filter value " + value + " does not match " + targetClass.getSimpleName());
}
}
} else {
if (value instanceof Collection) {
return JacksonUtil.toString(value);
}
}
Number numberVal = null;
BigDecimal bdVal = null;
String stringVal = null;
Boolean booleanVal = null;
Date dateVal = null;
List listVal = null;
if (value instanceof BigDecimal) {
bdVal = (BigDecimal) value;
} else if (value instanceof Number) {
numberVal = (Number) value;
} else if (value instanceof Boolean) {
booleanVal = (Boolean) value;
} else if (value instanceof Date) {
dateVal = (Date) value;
} else if (value instanceof String) {
stringVal = (String) value;
} else if (value instanceof List) {
listVal = (List) value;
} else if (value instanceof Map) {
stringVal = JacksonUtil.toString(value);
} else if (value instanceof File) {
stringVal = ((File) value).getAbsolutePath();
} else {
throw new ValidationException("Unrecognized data type for value " + value + " type " + value.getClass());
}
try {
if (targetClass == String.class) {
if (value instanceof Map) {
return stringVal;
}
if (stringVal != null || listVal != null) {
return value;
} else {
return value.toString();
}
} else if (targetClass == Boolean.class || (targetClass.isPrimitive() && targetClass.getName().equals("boolean"))) {
if (booleanVal != null) {
return value;
} else {
return Boolean.parseBoolean(value.toString());
}
} else if (targetClass == Date.class || targetClass == Instant.class) {
if (dateVal != null || listVal != null) {
return value;
} else if (numberVal != null) {
return Instant.ofEpochMilli(numberVal.longValue());
} else if (stringVal != null) {
// Use provided date patterns or try default patterns if they were not provided
if (datePatterns != null) {
for (String datePattern : datePatterns) {
Instant date = DateUtils.parseDateWithPattern(stringVal, datePattern);
if (date != null) {
return date;
}
}
} else {
// first try with date and time and then only with date format
Instant date = DateUtils.parseDateWithPattern(stringVal, DateUtils.DATE_TIME_PATTERN);
if (date == null) {
date = DateUtils.parseDateWithPattern(stringVal, paramBean.getDateTimeFormat());
}
if (date == null) {
date = DateUtils.parseDateWithPattern(stringVal, DateUtils.DATE_PATTERN);
}
if (date == null) {
date = DateUtils.parseDateWithPattern(stringVal, paramBean.getDateFormat());
}
return date;
}
}
} else if (targetClass.isEnum()) {
if (listVal != null || targetClass.isAssignableFrom(value.getClass())) {
return value;
} else if (stringVal != null) {
Enum enumVal = ReflectionUtils.getEnumFromString((Class<? extends Enum>) targetClass, stringVal);
if (enumVal != null) {
return enumVal;
}
}
} else if (targetClass == Integer.class || (targetClass.isPrimitive() && targetClass.getName().equals("int"))) {
if (numberVal != null || bdVal != null || listVal != null) {
return value;
} else if (stringVal != null) {
return Integer.parseInt(stringVal);
}
} else if (targetClass == Long.class || (targetClass.isPrimitive() && targetClass.getName().equals("long"))) {
if (numberVal != null || bdVal != null || listVal != null) {
return value;
} else if (stringVal != null) {
return Long.parseLong(stringVal);
}
} else if (targetClass == Byte.class || (targetClass.isPrimitive() && targetClass.getName().equals("byte"))) {
if (numberVal != null || bdVal != null || listVal != null) {
return value;
} else if (stringVal != null) {
return Byte.parseByte(stringVal);
}
} else if (targetClass == Short.class || (targetClass.isPrimitive() && targetClass.getName().equals("short"))) {
if (numberVal != null || bdVal != null || listVal != null) {
return value;
} else if (stringVal != null) {
return Short.parseShort(stringVal);
}
} else if (targetClass == Double.class || (targetClass.isPrimitive() && targetClass.getName().equals("double"))) {
if (numberVal != null || bdVal != null || listVal != null) {
return value;
} else if (stringVal != null) {
return Double.parseDouble(stringVal);
}
} else if (targetClass == Float.class || (targetClass.isPrimitive() && targetClass.getName().equals("float"))) {
if (numberVal != null || bdVal != null || listVal != null) {
return value;
} else if (stringVal != null) {
return Float.parseFloat(stringVal);
}
} else if (targetClass == BigDecimal.class) {
if (numberVal != null || bdVal != null || listVal != null) {
return value;
} else if (stringVal != null) {
return new BigDecimal(stringVal);
}
}
} catch (NumberFormatException e) {
// Swallow - validation will take care of it later
}
return value;
}
use of org.meveo.admin.exception.ValidationException in project meveo by meveo-org.
the class NativePersistenceService method convertValue.
/**
* Convert values to a data type matching field definition. Cannot be converted
* to CEI as map is filtered per key not per CEI.
*
* @param values A map of values with customFieldTemplate code or db field
* name as a key and field value as a value.
* @param fields Field definitions
* @param discardNull If True, null values will be discarded
* @param datePatterns Optional. Date patterns to apply to a date type field.
* Conversion is attempted in that order until a valid date
* is matched.If no values are provided, a standard date and
* time and then date only patterns will be applied.
* @return Converted values with db field name as a key and field value as
* value.
*/
@SuppressWarnings("rawtypes")
public Map<String, Object> convertValue(Map<String, Object> values, Map<String, CustomFieldTemplate> fields, boolean discardNull, String[] datePatterns) throws ValidationException {
if (values == null) {
return null;
}
Map<String, Object> valuesConverted = new HashMap<>();
// Handle ID field
Object uuid = values.get(FIELD_ID);
if (uuid != null) {
valuesConverted.put(FIELD_ID, castValue(uuid, String.class, false, datePatterns));
}
// Convert field based on data type
if (fields != null) {
for (Entry<String, Object> valueEntry : values.entrySet()) {
String key = valueEntry.getKey();
if (key.equals(FIELD_ID)) {
// Was handled before already
continue;
}
if (valueEntry.getValue() == null && !discardNull) {
valuesConverted.put(key, null);
} else if (valueEntry.getValue() != null) {
String[] fieldInfo = key.split(" ");
// String condition = fieldInfo.length == 1 ? null : fieldInfo[0];
// field name here can be a db field name or a custom field code
String fieldName = fieldInfo.length == 1 ? fieldInfo[0] : fieldInfo[1];
Optional<CustomFieldTemplate> customFieldTemplateOpt = fields.values().stream().filter(f -> f.getDbFieldname().equals(fieldName) || f.getCode().equals(fieldName)).findFirst();
if (!customFieldTemplateOpt.isPresent()) {
continue;
}
CustomFieldTemplate customFieldTemplate = customFieldTemplateOpt.get();
final CustomFieldTypeEnum fieldType = customFieldTemplate.getFieldType();
Class dataClass = fieldType.getDataClass();
if (dataClass == null) {
throw new ValidationException("No field definition " + fieldName + " was found");
}
boolean isList = customFieldTemplate.getStorageType() == CustomFieldStorageTypeEnum.LIST;
if (isList && fieldType.isStoredSerializedList()) {
isList = false;
}
Object value = castValue(valueEntry.getValue(), dataClass, isList, datePatterns);
if (!customFieldTemplate.isPersisted()) {
value = null;
}
// Replace cft code with db field name if needed
String dbFieldname = CustomFieldTemplate.getDbFieldname(fieldName);
if (!fieldName.equalsIgnoreCase(dbFieldname)) {
key = key.replaceAll(fieldName, dbFieldname);
}
valuesConverted.put(key, value);
}
}
}
return valuesConverted;
}
use of org.meveo.admin.exception.ValidationException in project meveo by meveo-org.
the class CustomFieldTemplateService method copyCustomFieldTemplate.
/**
* Copy and associate a given custom field template to a given target entity type.
*
* @param cft Custom field template to copy
* @param targetAppliesTo Target CFT.appliesTo value associate custom field template with
* @return custom field template
* @throws BusinessException business exception.
*/
public CustomFieldTemplate copyCustomFieldTemplate(CustomFieldTemplate cft, String targetAppliesTo) throws BusinessException {
if (findByCodeAndAppliesTo(cft.getCode(), targetAppliesTo) != null) {
throw new ValidationException("Custom field template " + cft.getCode() + " already exists in targe entity " + targetAppliesTo, "customFieldTemplate.copyCFT.alreadyExists");
}
// Load calendar for lazy loading
if (cft.getCalendar() != null) {
cft.setCalendar(PersistenceUtils.initializeAndUnproxy(cft.getCalendar()));
if (cft.getCalendar() instanceof CalendarDaily) {
((CalendarDaily) cft.getCalendar()).setHours(PersistenceUtils.initializeAndUnproxy(((CalendarDaily) cft.getCalendar()).getHours()));
cft.getCalendar().nextCalendarDate(new Date());
} else if (cft.getCalendar() instanceof CalendarYearly) {
((CalendarYearly) cft.getCalendar()).setDays(PersistenceUtils.initializeAndUnproxy(((CalendarYearly) cft.getCalendar()).getDays()));
cft.getCalendar().nextCalendarDate(new Date());
} else if (cft.getCalendar() instanceof CalendarInterval) {
((CalendarInterval) cft.getCalendar()).setIntervals(PersistenceUtils.initializeAndUnproxy(((CalendarInterval) cft.getCalendar()).getIntervals()));
cft.getCalendar().nextCalendarDate(new Date());
}
}
if (cft.getListValues() != null) {
cft.getListValues().values().toArray(new String[] {});
}
if (cft.getMatrixColumns() != null) {
cft.getMatrixColumns().toArray(new CustomFieldMatrixColumn[] {});
}
detach(cft);
CustomFieldTemplate cftCopy = SerializationUtils.clone(cft);
cftCopy.setId(null);
cftCopy.setVersion(null);
cftCopy.setAppliesTo(targetAppliesTo);
if (cft.getListValues() != null) {
cftCopy.setListValues(new HashMap<>());
cftCopy.getListValues().putAll(cft.getListValues());
}
if (cft.getMatrixColumns() != null) {
cftCopy.setMatrixColumns(new ArrayList<>());
cftCopy.getMatrixColumns().addAll(cft.getMatrixColumns());
}
create(cftCopy);
return cftCopy;
}
Aggregations