use of org.meveo.model.customEntities.CustomModelObject in project meveo by meveo-org.
the class CustomTableService method importData.
/**
* Import data into custom table
*
* @param customModelObject Custom table definition
* @param values A list of records to import. Each record is a map of values with field name as a map key and field value as a value.
* @param append True if data should be appended to the existing data
* @return Number of records imported
* @throws BusinessException General business exception
*/
public int importData(String sqlConnectionCode, String tableName, CustomModelObject customModelObject, List<Map<String, Object>> values, boolean append) throws BusinessException {
// Custom table fields. Fields will be sorted by their GUI 'field' position.
Map<String, CustomFieldTemplate> cfts = customFieldTemplateService.findByAppliesTo(customModelObject.getAppliesTo());
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>> valuesPartial = new ArrayList<>();
// Delete current data first if in override mode
if (!append) {
remove(sqlConnectionCode, (CustomEntityTemplate) customModelObject);
}
// By default will update ES immediately. If more than 100 records are being updated, ES will be updated in batch way - reconstructed from a table
boolean updateESImediately = append;
if (values.size() > 100) {
updateESImediately = false;
}
try {
CustomEntityTemplate cet = customEntityTemplateService.findByCodeOrDbTablename(tableName);
for (Map<String, Object> value : values) {
// Save to DB every 1000 records
if (importedLines >= 1000) {
valuesPartial = convertValues(valuesPartial, cfts, false);
customTableService.get().createInNewTx(sqlConnectionCode, cet, updateESImediately, valuesPartial);
valuesPartial.clear();
importedLines = 0;
}
valuesPartial.add(value);
importedLines++;
importedLinesTotal++;
}
// Save to DB remaining records
valuesPartial = convertValues(valuesPartial, cfts, false);
customTableService.get().createInNewTx(sqlConnectionCode, cet, updateESImediately, valuesPartial);
// Repopulate ES index
if (!updateESImediately) {
elasticClient.populateAll(currentUser, CustomTableRecord.class, customModelObject.getCode());
}
} catch (Exception e) {
throw new BusinessException(e);
}
return importedLinesTotal;
}
use of org.meveo.model.customEntities.CustomModelObject in project meveo by meveo-org.
the class NativePersistenceService method findIdByUniqueValues.
/**
* Find a record uuid in table using its exact values
*
* @param sqlConnectionCode Code of the sql configuration
* @param customTemplate Template related to the table
* @param queryValues Values used to filter the result
* @param fields
* @return The uuid of the record if it was found or null if it was not
*/
public String findIdByUniqueValues(String sqlConnectionCode, CustomModelObject customTemplate, Map<String, Object> queryValues, Collection<CustomFieldTemplate> fields) {
String result = null;
String tableName = PostgresReserverdKeywords.escapeAndFormat(customTemplate.getDbTableName());
if (queryValues.isEmpty()) {
throw new IllegalArgumentException("Query values should not be empty");
}
StringBuilder q = new StringBuilder();
q.append("SELECT uuid FROM {h-schema}" + tableName + " as a\n");
Map<Integer, Object> queryParamers = new HashMap<>();
Map<String, Object> uniqueValues = new HashMap<>();
for (CustomFieldTemplate cft : fields) {
if (cft.isUnique()) {
Object uniqueValue = Optional.ofNullable(queryValues.get(cft.getCode())).orElse(queryValues.get(cft.getDbFieldname()));
// Don't use inherited values
if (uniqueValue != null && cft.getAppliesTo().equals(customTemplate.getAppliesTo())) {
uniqueValues.put(cft.getDbFieldname(), uniqueValue);
}
}
}
if (uniqueValues.isEmpty()) {
result = null;
} else {
AtomicInteger i = new AtomicInteger(1);
uniqueValues.forEach((key, value) -> {
key = PostgresReserverdKeywords.escapeAndFormat(key);
if (!(value instanceof Collection) && !(value instanceof File) && !(value instanceof Map)) {
if (value instanceof EntityReferenceWrapper) {
value = ((EntityReferenceWrapper) value).getUuid();
}
if (i.get() == 1) {
q.append("WHERE a." + key + " = ?\n");
} else {
q.append("AND a." + key + " = ?\n");
}
queryParamers.put(i.getAndIncrement(), value);
}
});
QueryBuilder builder = new QueryBuilder();
builder.setSqlString(q.toString());
Session session = crossStorageTransaction.getHibernateSession(sqlConnectionCode);
NativeQuery<Map<String, Object>> query = builder.getNativeQuery(session, true);
queryParamers.forEach((k, v) -> query.setParameter(k, v));
try {
Map<String, Object> singleResult = query.getSingleResult();
result = (String) singleResult.get("uuid");
} catch (NoResultException | NonUniqueResultException e) {
result = null;
} catch (Exception e) {
log.error("Error executing query {}", query.getQueryString());
throw e;
}
}
if (result == null && customTemplate instanceof CustomEntityTemplate) {
CustomEntityTemplate cet = (CustomEntityTemplate) customTemplate;
CustomEntityTemplate superTemplate = cet.getSuperTemplate();
if (superTemplate != null) {
if (HibernateUtils.isLazyLoaded(superTemplate)) {
superTemplate = customEntityTemplateService.findById(superTemplate.getId(), List.of("superTemplate"));
}
result = findIdByUniqueValues(sqlConnectionCode, superTemplate, queryValues, fields);
}
}
return result;
}
use of org.meveo.model.customEntities.CustomModelObject in project meveo by meveo-org.
the class JSONSchemaIntoJavaClassParser method parseFields.
private void parseFields(Map<String, Object> jsonMap, CompilationUnit compilationUnit, CustomModelObject template, Map<String, CustomFieldTemplate> fieldsDefinition) {
compilationUnit.setPackageDeclaration("org.meveo.model.customEntities");
ClassOrInterfaceDeclaration classDeclaration = compilationUnit.addClass((String) jsonMap.get("id")).setPublic(true);
Collection<FieldDeclaration> fds = new ArrayList<>();
// Generate default constructor
classDeclaration.addConstructor(Modifier.Keyword.PUBLIC);
if (template instanceof CustomEntityTemplate) {
CustomEntityTemplate cet = (CustomEntityTemplate) template;
if (cet.getNeo4JStorageConfiguration() != null && cet.getNeo4JStorageConfiguration().isPrimitiveEntity()) {
// Handle primitive entity if value field is not defined
FieldDeclaration fd = new FieldDeclaration();
VariableDeclarator variableDeclarator = new VariableDeclarator();
variableDeclarator.setName("value");
switch(cet.getNeo4JStorageConfiguration().getPrimitiveType()) {
case DATE:
variableDeclarator.setType("Instant");
compilationUnit.addImport(Instant.class);
break;
case DOUBLE:
variableDeclarator.setType("Double");
compilationUnit.addImport(Double.class);
break;
case LONG:
variableDeclarator.setType("Long");
compilationUnit.addImport(Long.class);
break;
case STRING:
variableDeclarator.setType("String");
compilationUnit.addImport(String.class);
break;
default:
variableDeclarator.setType("Object");
break;
}
if (fieldsDefinition.get("value") == null) {
fd.setModifiers(Modifier.Keyword.PRIVATE);
fd.addVariable(variableDeclarator);
fd.addSingleMemberAnnotation(JsonProperty.class, "required = true");
compilationUnit.addImport(JsonProperty.class);
classDeclaration.addMember(fd);
((ArrayList<FieldDeclaration>) fds).add(fd);
}
// Generate constructor with the value
classDeclaration.addConstructor(Modifier.Keyword.PUBLIC).addParameter(new Parameter(variableDeclarator.getType(), "value")).setBody(JavaParser.parseBlock("{\n this.value = value; \n}"));
} else {
VariableDeclarator variableDeclarator = new VariableDeclarator();
variableDeclarator.setType("String");
// Generate constructor with the value
classDeclaration.addConstructor(Modifier.Keyword.PUBLIC).addParameter(new Parameter(variableDeclarator.getType(), "uuid")).setBody(JavaParser.parseBlock("{\n this.uuid = uuid; \n}"));
}
}
if (classDeclaration != null) {
FieldDeclaration field = new FieldDeclaration();
VariableDeclarator variable = new VariableDeclarator();
variable.setName("uuid");
variable.setType("String");
field.setModifiers(Modifier.Keyword.PRIVATE);
field.addVariable(variable);
classDeclaration.addMember(field);
((ArrayList<FieldDeclaration>) fds).add(field);
if (jsonMap.containsKey("storages")) {
compilationUnit.addImport(DBStorageType.class);
FieldDeclaration fd = new FieldDeclaration();
fd.addAnnotation(JsonIgnore.class);
VariableDeclarator variableDeclarator = new VariableDeclarator();
variableDeclarator.setName("storages");
variableDeclarator.setType("DBStorageType");
fd.setModifiers(Modifier.Keyword.PRIVATE);
fd.addVariable(variableDeclarator);
classDeclaration.addMember(fd);
((ArrayList<FieldDeclaration>) fds).add(fd);
}
Map<String, Object> items = (Map<String, Object>) jsonMap.get("properties");
if (items != null) {
for (Map.Entry<String, Object> item : items.entrySet()) {
String code = item.getKey();
Map<String, Object> values = (Map<String, Object>) item.getValue();
FieldDeclaration fd = new FieldDeclaration();
VariableDeclarator vd = new VariableDeclarator();
vd.setName(code);
CustomFieldTemplate cft = fieldsDefinition.get(code);
if (cft.getStorageType().equals(CustomFieldStorageTypeEnum.MATRIX)) {
fd = getMatrixField(cft, compilationUnit);
fds.add(fd);
classDeclaration.addMember(fd);
continue;
}
// Add @JsonProperty annotation
if (values.containsKey("nullable") && !Boolean.parseBoolean(values.get("nullable").toString())) {
fd.addSingleMemberAnnotation(JsonProperty.class, "required = true");
compilationUnit.addImport(JsonProperty.class);
}
if (values.get("type") != null) {
if (values.get("type").equals("array")) {
compilationUnit.addImport("java.util.List");
Map<String, Object> value = (Map<String, Object>) values.get("items");
if (value.containsKey("$ref")) {
// Handle entity references
var fieldDefinition = fieldsDefinition.get(code);
if (fieldDefinition != null && fieldDefinition.getRelationship() != null) {
String crtCode = fieldDefinition.getRelationship().getCode();
var relationFields = customFieldService.findByAppliesTo(fieldDefinition.getRelationship().getAppliesTo());
// If CRT has no relation, directly use the target node as field type
if (relationFields == null || relationFields.isEmpty()) {
fd.addSingleMemberAnnotation(Relation.class, '"' + crtCode + '"');
compilationUnit.addImport(Relation.class);
} else {
var fieldDeclaration = classDeclaration.addPrivateField("List<" + crtCode + ">", code);
((ArrayList<FieldDeclaration>) fds).add(fieldDeclaration);
continue;
}
}
String ref = (String) value.get("$ref");
if (ref != null) {
String[] data = ref.split("/");
if (data.length > 0) {
String name = data[data.length - 1];
try {
Class.forName(name);
compilationUnit.addImport(name);
String[] className = name.split("\\.");
name = className[className.length - 1];
} catch (ClassNotFoundException e) {
compilationUnit.addImport("org.meveo.model.customEntities." + name);
}
vd.setType("List<" + name + ">");
}
}
} else if (value.containsKey("type")) {
if (value.get("type").equals("integer")) {
vd.setType("List<Long>");
} else if (value.get("type").equals("number")) {
vd.setType("List<Double>");
} else {
String typeItem = (String) value.get("type");
typeItem = Character.toUpperCase(typeItem.charAt(0)) + typeItem.substring(1);
vd.setType("List<" + typeItem + ">");
}
} else if (value.containsKey("enum")) {
vd.setType("List<String>");
}
vd.setInitializer(JavaParser.parseExpression("new ArrayList<>()"));
compilationUnit.addImport(ArrayList.class);
} else if (values.get("type").equals("object")) {
compilationUnit.addImport("java.util.Map");
Map<String, Object> patternProperties = (Map<String, Object>) values.get("patternProperties");
Map<String, Object> properties = (Map<String, Object>) (patternProperties != null ? patternProperties.get("^.*$") : values.get("properties"));
if (properties.containsKey("$ref")) {
String ref = (String) properties.get("$ref");
if (ref != null) {
String[] data = ref.split("/");
if (data.length > 0) {
String name = data[data.length - 1];
try {
Class.forName(name);
compilationUnit.addImport(name);
String[] className = name.split("\\.");
name = className[className.length - 1];
} catch (ClassNotFoundException e) {
compilationUnit.addImport("org.meveo.model.customEntities." + name);
}
vd.setType("Map<String, " + name + ">");
}
}
} else if (properties.containsKey("type")) {
if (properties.get("type").equals("string")) {
vd.setType("Map<String, String>");
} else {
vd.setType("Map<String, Object>");
}
}
vd.setInitializer(JavaParser.parseExpression("new HashMap<>()"));
compilationUnit.addImport(HashMap.class);
} else if (values.get("type").equals("integer")) {
if (code.equals("count")) {
vd.setType("Integer");
} else {
vd.setType("Long");
}
} else if (values.get("type").equals("number")) {
vd.setType("Double");
} else if ((values.get("format") != null)) {
if (values.get("format").equals("date-time")) {
compilationUnit.addImport("java.time.Instant");
vd.setType("Instant");
}
} else if (values.get("default") != null && (values.get("default").equals("true") || values.get("default").equals("false"))) {
vd.setType("Boolean");
} else {
String type = (String) values.get("type");
type = Character.toUpperCase(type.charAt(0)) + type.substring(1);
vd.setType(type);
}
} else if (values.get("$ref") != null) {
var fieldDefinition = fieldsDefinition.get(code);
if (fieldDefinition != null && fieldDefinition.getRelationship() != null) {
var relationFields = customFieldService.findByAppliesTo(fieldDefinition.getRelationship().getAppliesTo());
String crtCode = fieldDefinition.getRelationship().getCode();
// If CRT has no relation, directly use the target node as field type
if (relationFields == null || relationFields.isEmpty()) {
// Add @Relation annotation
fd.addSingleMemberAnnotation(Relation.class, '"' + crtCode + '"');
compilationUnit.addImport(Relation.class);
} else {
var fieldDeclaration = classDeclaration.addPrivateField(crtCode, code);
((ArrayList<FieldDeclaration>) fds).add(fieldDeclaration);
continue;
}
}
String[] data = ((String) values.get("$ref")).split("/");
if (data.length > 0) {
String name = data[data.length - 1];
// Handle cases where prefixed by 'org.meveo.model.customEntities.CustomEntityTemplate -'
name = CustomFieldTemplate.retrieveCetCode(name);
try {
Class.forName(name);
compilationUnit.addImport(name);
String[] className = name.split("\\.");
name = className[className.length - 1];
} catch (ClassNotFoundException e) {
compilationUnit.addImport("org.meveo.model.customEntities." + name);
}
vd.setType(name);
}
} else if (values.get("enum") != null && values.get("type") == null) {
vd.setType("String");
}
fd.addVariable(vd);
fd.setModifiers(Modifier.Keyword.PRIVATE);
classDeclaration.addMember(fd);
((ArrayList<FieldDeclaration>) fds).add(fd);
}
}
for (FieldDeclaration fieldDeclaration : fds) {
if (fieldDeclaration != null) {
fieldDeclaration.createGetter();
fieldDeclaration.createSetter();
}
}
}
}
use of org.meveo.model.customEntities.CustomModelObject in project meveo by meveo-org.
the class CrossStorageService method fetchEntityReferences.
public void fetchEntityReferences(Repository repository, CustomModelObject customModelObject, Map<String, Object> values, Map<String, Set<String>> subFields) throws EntityDoesNotExistsException {
for (Map.Entry<String, Object> entry : new HashSet<>(values.entrySet())) {
CustomFieldTemplate cft = cache.getCustomFieldTemplate(entry.getKey(), customModelObject.getAppliesTo());
if (cft != null && cft.getFieldType() == CustomFieldTypeEnum.ENTITY) {
// Check if target is not JPA entity
try {
var session = transaction.getHibernateSession(repository.getSqlConfigurationCode());
Class<?> clazz = Class.forName(cft.getEntityClazzCetCode());
values.put(entry.getKey(), session.find(clazz, entry.getValue()));
continue;
} catch (ClassNotFoundException e) {
// NOOP
} catch (Exception e) {
log.error("Cannot find referenced entity {}", e.getMessage());
throw new RuntimeException(e);
}
CustomEntityTemplate cet = cache.getCustomEntityTemplate(cft.getEntityClazzCetCode());
var nConf = cet.getNeo4JStorageConfiguration();
// Don't fetch primitive entities
if (nConf != null && nConf.isPrimitiveEntity()) {
continue;
}
Set<String> fetchFields = subFields.get(cft.getCode());
if (fetchFields == null) {
continue;
}
fetchFields = new HashSet<>(fetchFields);
Map<String, Set<String>> subSubFields = extractSubFields(fetchFields);
if (fetchFields.contains("*")) {
fetchFields = cache.getCustomFieldTemplates(cet.getAppliesTo()).keySet();
}
if (cft.getStorageType() == CustomFieldStorageTypeEnum.SINGLE) {
if (entry.getValue() instanceof String) {
Map<String, Object> refValues = find(repository, cet, (String) entry.getValue(), fetchFields, subSubFields, false);
values.put(cft.getCode(), refValues);
} else if (entry.getValue() instanceof Map) {
values.put(cft.getCode(), entry.getValue());
}
} else if (cft.getStorageType() == CustomFieldStorageTypeEnum.LIST) {
if (entry.getValue() instanceof Collection) {
Collection<?> collection = (Collection<?>) entry.getValue();
if (!collection.isEmpty()) {
var firstItem = collection.iterator().next();
if (firstItem instanceof String) {
// List list = find(repository, cet, null);
// TODO
}
}
}
}
}
}
}
use of org.meveo.model.customEntities.CustomModelObject in project meveo by meveo-org.
the class SqlConfigurationService method initializeModuleDatabase.
public List<CustomModelObject> initializeModuleDatabase(String moduleCode, String sqlConfCode) throws BusinessException {
List<CustomModelObject> initializedItems = new ArrayList<>();
MeveoModule module = meveoModuleService.findByCode(moduleCode);
Set<MeveoModuleItem> moduleItems = module.getModuleItems();
List<String> moduleCrtCodes = moduleItems.stream().filter(item -> item.getItemClass().equals(CustomRelationshipTemplate.class.getName())).distinct().map(item -> item.getItemCode()).collect(Collectors.toList());
List<String> moduleCetCodes = moduleItems.stream().filter(item -> item.getItemClass().equals(CustomEntityTemplate.class.getName())).distinct().map(item -> item.getItemCode()).collect(Collectors.toList());
List<CustomEntityTemplate> moduleCets = new ArrayList<CustomEntityTemplate>();
moduleCetCodes.forEach(moduleCetCode -> {
moduleCets.add(customEntityTemplateService.findByCode(moduleCetCode));
});
List<CustomRelationshipTemplate> moduleCrts = new ArrayList<CustomRelationshipTemplate>();
moduleCrtCodes.forEach(moduleCrtCode -> {
moduleCrts.add(customRelationshipTemplateService.findByCode(moduleCrtCode));
});
initializedItems.addAll(moduleCets);
initializedItems.addAll(moduleCrts);
for (CustomEntityTemplate moduleCet : moduleCets) {
customTableCreatorService.createTable(sqlConfCode, moduleCet);
}
for (CustomRelationshipTemplate moduleCrt : moduleCrts) {
try {
customTableCreatorService.createCrtTable(sqlConfCode, moduleCrt);
} catch (BusinessException e) {
log.error("Couldn't create CRT table", e);
throw e;
}
}
return initializedItems;
}
Aggregations