TableServicesImpl.java
/*
* Copyright 2021 Global Crop Diversity Trust
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gringlobal.service.impl;
import java.lang.reflect.Field;
import java.time.Instant;
import java.util.Calendar;
import java.util.Date;
import java.util.UUID;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.validation.constraints.NotNull;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.text.CaseUtils;
import org.genesys.blocks.model.AuditedVersionedModel;
import org.gringlobal.compatibility.service.DataviewService;
import org.gringlobal.compatibility.service.impl.DataviewServiceImpl;
import org.gringlobal.custom.validation.javax.CodeValueField;
import org.gringlobal.model.CooperatorOwnedModel;
import org.gringlobal.model.SysTable;
import org.gringlobal.model.SysTableField;
import org.gringlobal.model.SysTableFieldLang;
import org.gringlobal.persistence.SysTableFieldLangRepository;
import org.gringlobal.persistence.SysTableFieldRepository;
import org.gringlobal.persistence.SysTableRepository;
import org.gringlobal.service.SysTableFieldTranslationService;
import org.gringlobal.service.SysTableMappingException;
import org.gringlobal.service.TableServices;
import org.gringlobal.service.filter.SysTableFieldFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedBy;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ReflectionUtils;
/**
* The Class TableServicesImpl.
*/
@Service
@Slf4j
public class TableServicesImpl implements TableServices {
/**
* The Class SysDataviewServiceImpl.
*/
@Service
@Transactional(readOnly = true)
public static class SysTableServiceImpl extends CRUDServiceImpl<SysTable, SysTableRepository> implements SysTableService {
@Override
@Transactional
public SysTable create(SysTable source) {
return repository.save(source);
}
@Override
@Transactional
public SysTable update(SysTable updated, SysTable target) {
target.setId(updated.getId());
return repository.save(target);
}
@Override
public SysTable load(String tableName) {
return repository.findByTableName(tableName);
}
}
// /**
// * The Class SysDataviewServiceImpl.
// */
// @Service
// @Transactional(readOnly = true)
// public class SysTableLangServiceImpl extends CRUDServiceImpl<SysTableLang, SysTableLangRepository> implements SysTableLangService {
//
// }
/**
* The Class SysDataviewServiceImpl.
*/
@Service
@Transactional(readOnly = true)
public static class SysTableFieldServiceImpl extends FilteredTranslatedCRUDServiceImpl<SysTableField, SysTableFieldLang, SysTableFieldTranslationService.TranslatedSysTableField, SysTableFieldFilter, SysTableFieldRepository> implements SysTableFieldService {
@Autowired
private DataviewService dataviewService;
@Autowired
private SysTableService sysTableService;
public SysTableFieldServiceImpl() {
super();
}
@Override
public SysTableField get(String tableName, String fieldName) {
return repository.findByTableNameAndFieldName(tableName, fieldName);
}
@Override
@Transactional
public SysTableField create(SysTableField source) {
return repository.save(source);
}
@Override
@Transactional
public SysTableField createFast(SysTableField source) {
return repository.save(source);
}
@Override
@Transactional
public SysTableField update(SysTableField updated, SysTableField target) {
target.apply(updated);
return repository.save(target);
}
@Override
@Transactional
public SysTableField updateFast(SysTableField updated, SysTableField target) {
target.apply(updated);
return repository.save(target);
}
@Override
@Transactional
public SysTableField generateMapping(String tableName, String tableFieldName) throws SysTableMappingException {
var sysTableField = repository.findByTableNameAndFieldName(tableName, tableFieldName);
if (sysTableField != null) {
// repository.delete(sysTableField);
// sysTableField = null;
}
var entityInfo = dataviewService.getEntityInfo(tableName);
if (entityInfo == null) {
throw new SysTableMappingException("Table " + tableName + " is not a GGCE entity.");
}
var sysTable = sysTableService.load(tableName);
if (sysTable == null) {
sysTable = new SysTable();
sysTable.setTableName(tableName);
sysTable.setIsEnabled("Y");
sysTable.setIsReadonly("N");
sysTable.setAuditsCreated("N");
sysTable.setAuditsModified("N");
sysTable.setAuditsOwned("N");
if (CooperatorOwnedModel.class.isAssignableFrom(entityInfo.getTarget())) {
sysTable.setAuditsCreated("Y");
sysTable.setAuditsModified("Y");
sysTable.setAuditsOwned("Y");
} else if (AuditedVersionedModel.class.isAssignableFrom(entityInfo.getTarget())) {
sysTable.setAuditsCreated("Y");
sysTable.setAuditsModified("Y");
}
sysTable = sysTableService.create(sysTable);
}
if (sysTableField == null) {
sysTableField = new SysTableField();
sysTableField.setTable(sysTable);
sysTableField.setIsReadonly("N");
sysTableField.setFieldName(tableFieldName);
}
Field targetField = null;
if (tableFieldName.endsWith("_id")) {
if (tableFieldName.equalsIgnoreCase(tableName + "_id")) {
targetField = ReflectionUtils.findField(entityInfo.getTarget(), "id");
} else {
String camelFieldName = CaseUtils.toCamelCase(tableFieldName.replaceFirst("_id$", ""), false, '_');
targetField = ReflectionUtils.findField(entityInfo.getTarget(), camelFieldName);
}
}
if (targetField == null) {
String camelFieldName = CaseUtils.toCamelCase(tableFieldName, false, '_');
targetField = ReflectionUtils.findField(entityInfo.getTarget(), camelFieldName);
if (targetField == null) {
throw new SysTableMappingException("Field " + camelFieldName + " for " + tableFieldName + " not found in " + tableName);
}
}
sysTableField.setFieldType(getFieldType(targetField.getType()));
sysTableField.setFieldPurpose(getFieldPurpose(targetField));
sysTableField.setIsPrimaryKey(isPrimaryKey(targetField) ? "Y" : "N");
sysTableField.setIsNullable(isNullable(targetField) ? "Y" : "N");
sysTableField.setIsForeignKey(isForeignKey(targetField) ? "Y" : "N");
sysTableField.setIsAutoincrement(isAutoincrement(targetField) ? "Y" : "N");
sysTableField.setMaxLength(getMaxLength(targetField));
sysTableField.setDefaultValue(DataviewServiceImpl.NULLVALUE);
var codeValueField = targetField.getAnnotation(CodeValueField.class);
if (codeValueField != null) {
// Annotated with @CodeValueField
sysTableField.setGuiHint("SMALL_SINGLE_SELECT_CONTROL");
sysTableField.setGroupName(codeValueField.value());
} else if (sysTableField.getGuiHint() == null) {
sysTableField.setGuiHint(getGuiHint(targetField));
}
log.warn("Mapping SysTableField {}.{}", sysTableField.getTable().getTableName(), sysTableField.getFieldName());
return repository.save(sysTableField);
}
private String getGuiHint(Field targetField) {
if (Double.class.isAssignableFrom(targetField.getType())) {
return "DECIMAL_CONTROL";
}
if (Float.class.isAssignableFrom(targetField.getType())) {
return "DECIMAL_CONTROL";
}
if (Number.class.isAssignableFrom(targetField.getType())) {
return "INTEGER_CONTROL";
}
if (Date.class.isAssignableFrom(targetField.getType())) {
return "DATE_CONTROL";
}
if (Calendar.class.isAssignableFrom(targetField.getType())) {
return "DATE_CONTROL";
}
if (targetField.getName().startsWith("is")) {
return "TOGGLE_CONTROL";
}
return "TEXT_CONTROL";
}
@Override
public String getDeclaredFieldName(Field targetField) {
var joinAnno = targetField.getAnnotation(JoinColumn.class);
if (joinAnno != null && joinAnno.name() != null) {
return joinAnno.name();
}
var columnAnno = targetField.getAnnotation(Column.class);
if (columnAnno != null && columnAnno.name() != null) {
return columnAnno.name();
}
return null;
}
@Override
public int getMaxLength(Field targetField) {
var columnAnno = targetField.getAnnotation(Column.class);
if (columnAnno != null) {
return columnAnno.length();
}
return 0;
}
@Override
public boolean isAutoincrement(Field targetField) {
return targetField.getAnnotation(GeneratedValue.class) != null;
}
@Override
public boolean isForeignKey(Field targetField) {
return targetField.getAnnotation(ManyToOne.class) != null;
}
@Override
public boolean isNullable(Field targetField) {
if (targetField.getType().isPrimitive()) {
return false;
}
if (targetField.getAnnotation(NotNull.class) != null) {
return false;
}
var columnAnno = targetField.getAnnotation(Column.class);
if (columnAnno != null) {
return columnAnno.nullable();
}
var joinAnno = targetField.getAnnotation(JoinColumn.class);
if (joinAnno != null) {
return joinAnno.nullable();
}
return true;
}
@Override
public boolean isPrimaryKey(Field targetField) {
return targetField.getAnnotation(Id.class) != null;
}
@Override
public String getFieldPurpose(Field targetField) {
// Map field to fieldPurpose
if (targetField.getAnnotation(Id.class) != null) {
return "PRIMARY_KEY";
} else if (targetField.getAnnotation(LastModifiedDate.class) != null) {
return "AUTO_DATE_MODIFY";
} else if (targetField.getAnnotation(CreatedDate.class) != null) {
return "AUTO_DATE_CREATE";
} else if (targetField.getAnnotation(CreatedBy.class) != null) {
return "AUTO_ASSIGN_CREATE";
} else if (targetField.getAnnotation(LastModifiedBy.class) != null) {
return "AUTO_ASSIGN_MODIFY";
} else if (targetField.getName().equals("ownedBy")) {
return "AUTO_ASSIGN_OWN";
} else if (targetField.getName().equals("ownedDate")) {
return "AUTO_DATE_OWN";
}
return "DATA";
}
@Override
public String getFieldType(Class<?> type) {
if (type == Integer.class) {
return "INTEGER";
} else if (type == String.class) {
return "STRING";
} else if (type == Long.class) {
return "LONG";
} else if (type == Date.class) {
return "DATETIME";
} else if (type == Calendar.class) {
return "DATETIME";
} else if (type == Instant.class) {
return "DATETIME";
} else if (type == UUID.class) {
return "GUID";
} else if (AuditedVersionedModel.class.isAssignableFrom(type)) {
return "LONG";
} else if (CooperatorOwnedModel.class.isAssignableFrom(type)) {
return "INTEGER";
}
log.error("Unmanaged SysTableField type {}", type.getName());
return null;
}
}
@Component
public static class SysTableFieldTranslationSupport extends BaseTranslationSupport<SysTableField, SysTableFieldLang, SysTableFieldTranslationService.TranslatedSysTableField, SysTableFieldFilter, SysTableFieldLangRepository> implements SysTableFieldTranslationService {
public SysTableFieldTranslationSupport() {
super();
}
@Override
protected TranslatedSysTableField toTranslated(SysTableField e, String title, String description) {
return TranslatedSysTableField.from(e, title, description);
}
}
// /**
// * The Class SysDataviewServiceImpl.
// */
// @Service
// @Transactional(readOnly = true)
// public class SysTableFieldLangServiceImpl extends CRUDServiceImpl<SysTableFieldLang, SysTableFieldLangRepository> implements SysTableFieldLangService {
//
// }
}