Search in sources :

Example 1 with ValidationException

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;
}
Also used : ValidationException(org.meveo.admin.exception.ValidationException) InputStreamReader(java.io.InputStreamReader) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) ObjectReader(com.fasterxml.jackson.databind.ObjectReader) Reader(java.io.Reader) InputStreamReader(java.io.InputStreamReader) IOException(java.io.IOException) BusinessException(org.meveo.admin.exception.BusinessException) CustomFieldTemplate(org.meveo.model.crm.CustomFieldTemplate) ObjectReader(com.fasterxml.jackson.databind.ObjectReader) CustomModelObject(org.meveo.model.customEntities.CustomModelObject) Map(java.util.Map) HashMap(java.util.HashMap) RuntimeJsonMappingException(com.fasterxml.jackson.databind.RuntimeJsonMappingException)

Example 2 with ValidationException

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());
    }
}
Also used : EntityDoesNotExistsException(org.meveo.api.exception.EntityDoesNotExistsException) ValidationException(org.meveo.admin.exception.ValidationException) MeveoModule(org.meveo.model.module.MeveoModule)

Example 3 with ValidationException

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;
}
Also used : IdentifiableEnum(org.meveo.model.IdentifiableEnum) CustomFieldStorageTypeEnum(org.meveo.model.crm.custom.CustomFieldStorageTypeEnum) CustomFieldTypeEnum(org.meveo.model.crm.custom.CustomFieldTypeEnum) ValidationException(org.meveo.admin.exception.ValidationException) Instant(java.time.Instant) ArrayList(java.util.ArrayList) NoResultException(javax.persistence.NoResultException) NonUniqueResultException(javax.persistence.NonUniqueResultException) NotImplementedException(org.apache.commons.lang.NotImplementedException) ValidationException(org.meveo.admin.exception.ValidationException) BusinessException(org.meveo.admin.exception.BusinessException) PersistenceException(javax.persistence.PersistenceException) SQLException(java.sql.SQLException) BigDecimal(java.math.BigDecimal) Date(java.util.Date) LocalDate(java.time.LocalDate) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) BigInteger(java.math.BigInteger) EntityReferenceWrapper(org.meveo.model.crm.EntityReferenceWrapper) Objects(java.util.Objects) Collection(java.util.Collection) List(java.util.List) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) CustomModelObject(org.meveo.model.customEntities.CustomModelObject) Map(java.util.Map) HashMap(java.util.HashMap) File(java.io.File)

Example 4 with ValidationException

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;
}
Also used : ValidationException(org.meveo.admin.exception.ValidationException) Optional(java.util.Optional) HashMap(java.util.HashMap) CustomFieldTemplate(org.meveo.model.crm.CustomFieldTemplate) CustomFieldTypeEnum(org.meveo.model.crm.custom.CustomFieldTypeEnum) CustomModelObject(org.meveo.model.customEntities.CustomModelObject)

Example 5 with ValidationException

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;
}
Also used : ValidationException(org.meveo.admin.exception.ValidationException) CalendarYearly(org.meveo.model.catalog.CalendarYearly) CalendarDaily(org.meveo.model.catalog.CalendarDaily) CalendarInterval(org.meveo.model.catalog.CalendarInterval) CustomFieldTemplate(org.meveo.model.crm.CustomFieldTemplate) Date(java.util.Date)

Aggregations

ValidationException (org.meveo.admin.exception.ValidationException)14 CustomFieldTemplate (org.meveo.model.crm.CustomFieldTemplate)8 EntityDoesNotExistsException (org.meveo.api.exception.EntityDoesNotExistsException)6 BusinessException (org.meveo.admin.exception.BusinessException)5 CustomEntityTemplate (org.meveo.model.customEntities.CustomEntityTemplate)5 ArrayList (java.util.ArrayList)4 HashMap (java.util.HashMap)4 Map (java.util.Map)4 SQLException (java.sql.SQLException)3 Date (java.util.Date)3 CustomModelObject (org.meveo.model.customEntities.CustomModelObject)3 ObjectReader (com.fasterxml.jackson.databind.ObjectReader)2 RuntimeJsonMappingException (com.fasterxml.jackson.databind.RuntimeJsonMappingException)2 File (java.io.File)2 IOException (java.io.IOException)2 InputStreamReader (java.io.InputStreamReader)2 Reader (java.io.Reader)2 BigInteger (java.math.BigInteger)2 Collection (java.util.Collection)2 List (java.util.List)2