use of org.talend.mdm.commmon.metadata.FieldMetadata in project tmdm-common by Talend.
the class Compare method compare.
/**
* Compare two {@link org.talend.mdm.commmon.metadata.MetadataRepository repositories} and return the differences
* between them.
*
* @param left The original {@link org.talend.mdm.commmon.metadata.MetadataRepository repository}.
* @param right The new {@link org.talend.mdm.commmon.metadata.MetadataRepository repository}.
* @return The {@link org.talend.mdm.commmon.metadata.compare.Compare.DiffResults differences} between the two
* repositories.
* @see org.talend.mdm.commmon.metadata.compare.Compare.DiffResults
*/
public static DiffResults compare(MetadataRepository left, MetadataRepository right) {
Collection<ComplexTypeMetadata> leftEntityTypes = left.getUserComplexTypes();
DiffResults diffResults = new DiffResults();
compareEntitiesChange(left, right, diffResults);
DumpContent dumpContent = new DumpContent();
for (ComplexTypeMetadata leftType : leftEntityTypes) {
ComplexTypeMetadata rightType = right.getComplexType(leftType.getName());
if (rightType != null) {
// Read left content
List<MetadataVisitable> leftContent = new ArrayList<MetadataVisitable>(leftType.accept(dumpContent));
dumpContent.reset();
// Read right content
List<MetadataVisitable> rightContent = new ArrayList<MetadataVisitable>(rightType.accept(dumpContent));
dumpContent.reset();
// Compare contents
Map<String, FieldMetadata> removedElementNames = new HashMap<String, FieldMetadata>();
for (MetadataVisitable leftVisitable : leftContent) {
int index = rightContent.indexOf(leftVisitable);
if (index < 0) {
// Different (right does not exist, but might be removed or modified).
if (leftVisitable instanceof FieldMetadata) {
FieldMetadata field = (FieldMetadata) leftVisitable;
if (field.getContainingType() instanceof ContainedComplexTypeMetadata) {
removedElementNames.put(field.getContainingType().getContainer().getName() + "/" + field.getContainingType().getName() + "/" + field.getName(), field);
} else {
removedElementNames.put(field.getContainingType().getName() + "/" + field.getName(), field);
}
}
} else {
// Field exists on both sides, but checks max length
MetadataVisitable rightElement = rightContent.get(index);
if (leftVisitable instanceof FieldMetadata) {
TypeMetadata leftVisitableType = ((FieldMetadata) leftVisitable).getType();
TypeMetadata rightVisitableType = ((FieldMetadata) rightElement).getType();
if (leftVisitable instanceof ReferenceFieldMetadata) {
compareReferenceFieldMetadata(diffResults.modifyChanges, (ReferenceFieldMetadata) leftVisitable, (ReferenceFieldMetadata) rightElement);
}
// TMDM-9909: Increase the length of a string element should be low impact
Object leftLength = CommonUtil.getSuperTypeMaxLength(leftVisitableType, leftVisitableType);
Object rightLength = CommonUtil.getSuperTypeMaxLength(rightVisitableType, rightVisitableType);
if (!ObjectUtils.equals(leftLength, rightLength)) {
diffResults.modifyChanges.add(new ModifyChange(leftVisitable, rightElement));
}
// TMDM-8022: issues about custom decimal type totalDigits/fractionDigits.
Object leftTotalDigits = leftVisitableType.getData(MetadataRepository.DATA_TOTAL_DIGITS);
Object rightTotalDigits = rightVisitableType.getData(MetadataRepository.DATA_TOTAL_DIGITS);
if (!ObjectUtils.equals(leftTotalDigits, rightTotalDigits)) {
diffResults.modifyChanges.add(new ModifyChange(leftVisitable, rightElement));
}
Object leftFractionDigits = leftVisitableType.getData(MetadataRepository.DATA_FRACTION_DIGITS);
Object rightFractionDigits = rightVisitableType.getData(MetadataRepository.DATA_FRACTION_DIGITS);
if (!ObjectUtils.equals(leftFractionDigits, rightFractionDigits)) {
diffResults.modifyChanges.add(new ModifyChange(leftVisitable, rightElement));
}
}
// Same or already marked as diff, so remove from things to compare
rightContent.remove(index);
}
}
if (!rightContent.isEmpty()) {
Iterator<MetadataVisitable> addedElements = rightContent.iterator();
while (addedElements.hasNext()) {
MetadataVisitable current = addedElements.next();
MetadataVisitable modifiedElement = null;
if (current instanceof FieldMetadata) {
FieldMetadata field = (FieldMetadata) current;
if (field.getContainingType() instanceof ContainedComplexTypeMetadata) {
modifiedElement = removedElementNames.get(field.getContainingType().getContainer().getName() + "/" + field.getContainingType().getName() + "/" + field.getName());
} else {
modifiedElement = removedElementNames.get(field.getContainingType().getName() + "/" + field.getName());
}
}
if (modifiedElement != null) {
// Modified element (only exist in right, not in left).
diffResults.modifyChanges.add(new ModifyChange(modifiedElement, current));
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("[MODIFIED] " + current + " was modified" + "\t was " + modifiedElement + "\t now " + current);
}
if (current instanceof FieldMetadata) {
FieldMetadata field = (FieldMetadata) current;
if (field.getContainingType() instanceof ContainedComplexTypeMetadata) {
removedElementNames.remove(field.getContainingType().getContainer().getName() + "/" + field.getContainingType().getName() + "/" + field.getName());
} else {
modifiedElement = removedElementNames.get(field.getContainingType().getName() + "/" + field.getName());
removedElementNames.remove(field.getContainingType().getName() + "/" + field.getName());
}
}
} else {
// Added element (only exist in right, not in left).
diffResults.addChanges.add(new AddChange(current));
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("[ADDED] " + current + " was added.");
}
}
addedElements.remove();
}
}
// Process removed elements
for (FieldMetadata fieldMetadata : removedElementNames.values()) {
// Different (right does not exist).
diffResults.removeChanges.add(new RemoveChange(fieldMetadata));
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("[REMOVED] " + fieldMetadata + " no longer exist.");
}
}
if (!rightContent.isEmpty()) {
// Not expected at all -> likely a bug
throw new IllegalStateException("Elements remain for comparison.");
}
}
}
List<ComplexTypeMetadata> instantiableTypes = left.getNonInstantiableTypes();
compareTypesChange(left, right, diffResults);
for (ComplexTypeMetadata leftType : instantiableTypes) {
TypeMetadata rightType = right.getNonInstantiableType(leftType.getNamespace(), leftType.getName());
if (rightType != null) {
if (!leftType.getClass().equals(rightType.getClass())) {
// This is a very strange case (e.g. leftType was a simple type and new is a complex one...)
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("[MODIFY] Type '" + leftType.getName() + "' changed (parsed object is different).");
}
diffResults.removeChanges.add(new RemoveChange(leftType));
diffResults.addChanges.add(new AddChange(rightType));
}
}
}
return diffResults;
}
use of org.talend.mdm.commmon.metadata.FieldMetadata in project tmdm-common by Talend.
the class PermissionValidationRule method getFieldMetadata.
private FieldMetadata getFieldMetadata(Element appInfo, String fieldName) {
FieldMetadata fieldMetadata = new SoftFieldRef(null, fieldName, "");
fieldMetadata.setData(MetadataRepository.XSD_LINE_NUMBER, XSDParser.getStartLine(appInfo));
fieldMetadata.setData(MetadataRepository.XSD_COLUMN_NUMBER, XSDParser.getStartColumn(appInfo));
fieldMetadata.setData(MetadataRepository.XSD_DOM_ELEMENT, appInfo);
return fieldMetadata;
}
use of org.talend.mdm.commmon.metadata.FieldMetadata in project tmdm-common by Talend.
the class PermissionValidationRule method validateFieldRefPermission.
private boolean validateFieldRefPermission(FieldMetadata fieldMetadata, ValidationHandler handler) {
fieldMetadata.setData(PermissionConstants.VALIDATION_PERMISSION_MARKER, true);
String name = fieldMetadata.getName();
XSDElementDeclaration element = fieldMetadata.getData(MetadataRepository.XSD_ELEMENT);
if (element == null) {
return true;
}
boolean valid = true;
XSDAnnotation annotation = element.getAnnotation();
if (annotation != null) {
EList<Element> appInfoElements = annotation.getApplicationInformation();
List<FieldMetadata> writeUsers = new ArrayList<FieldMetadata>();
List<FieldMetadata> hideUsers = new ArrayList<FieldMetadata>();
List<FieldMetadata> denyCreate = new ArrayList<FieldMetadata>();
List<FieldMetadata> workflowAccessRights = new ArrayList<FieldMetadata>();
for (Element appInfo : appInfoElements) {
// $NON-NLS-1$
String source = appInfo.getAttribute("source");
String permissionRole = appInfo.getTextContent();
if ("X_Write".equals(source)) {
// $NON-NLS-1$
writeUsers.add(getFieldMetadata(appInfo, permissionRole));
} else if ("X_Hide".equals(source)) {
// $NON-NLS-1$
hideUsers.add(getFieldMetadata(appInfo, permissionRole));
} else if ("X_Deny_Create".equals(source)) {
// $NON-NLS-1$ )
denyCreate.add(getFieldMetadata(appInfo, permissionRole));
} else if ("X_Workflow".equals(source)) {
// $NON-NLS-1$
// $NON-NLS-1$
permissionRole = permissionRole.substring(0, permissionRole.indexOf("#"));
workflowAccessRights.add(getFieldMetadata(appInfo, permissionRole));
}
}
valid = doValidation(handler, ELEMENT_TYPE_FIELD, name, PermissionConstants.PERMISSIONTYPE_WRITE, writeUsers);
valid &= doValidation(handler, ELEMENT_TYPE_FIELD, name, PermissionConstants.PERMISSIONTYPE_HIDE, hideUsers);
valid &= doValidation(handler, ELEMENT_TYPE_FIELD, name, PermissionConstants.PERMISSIONTYPE_DENY_CREATE, denyCreate);
valid &= doValidation(handler, ELEMENT_TYPE_FIELD, name, PermissionConstants.PERMISSIONTYPE_WORKFLOW_ACCESS, workflowAccessRights);
}
if (fieldMetadata instanceof ContainedTypeFieldMetadata) {
ContainedTypeFieldMetadata containedField = (ContainedTypeFieldMetadata) fieldMetadata;
ComplexTypeMetadata cTypeMetadata = containedField.getContainedType();
Collection<FieldMetadata> fieldMetadatas = cTypeMetadata.getFields();
for (FieldMetadata fMetadata : fieldMetadatas) {
boolean validateMarked = BooleanUtils.isTrue(fMetadata.<Boolean>getData(PermissionConstants.VALIDATION_PERMISSION_MARKER));
if (!validateMarked) {
valid &= validateFieldRefPermission(fMetadata, handler);
}
}
}
return valid;
}
use of org.talend.mdm.commmon.metadata.FieldMetadata in project tmdm-common by Talend.
the class ForeignKeyProcessor method handleForeignKeyInfo.
private void handleForeignKeyInfo(MetadataRepository repository, XmlSchemaAnnotationProcessorState state, Element appInfo) {
String path = appInfo.getTextContent();
FieldMetadata fieldMetadata = getFieldMetadata(repository, (ComplexTypeMetadata) state.getReferencedType(), appInfo, path, true);
state.setForeignKeyInfo(fieldMetadata);
}
use of org.talend.mdm.commmon.metadata.FieldMetadata in project tmdm-common by Talend.
the class ForeignKeyProcessor method getFieldMetadata.
private static FieldMetadata getFieldMetadata(MetadataRepository repository, ComplexTypeMetadata type, Element appInfo, String path, boolean isFKInfo) {
String typeName = getTypeName(type, path);
// $NON-NLS-1$
String fieldPath = StringUtils.substringAfter(path, "/").trim();
FieldMetadata fieldMetadata;
if (!fieldPath.isEmpty() && isFKInfo) {
fieldMetadata = new SoftFieldRef(repository, fieldPath, typeName);
} else {
if (!fieldPath.isEmpty() && (repository.getComplexType(typeName) == null || repository.getComplexType(typeName).getKeyFields().size() == 1)) {
fieldMetadata = new SoftFieldRef(repository, fieldPath, typeName);
} else {
// If the reference entity has composite key, the foreign key field should be set as entity not its ID.
fieldMetadata = new SoftIdFieldRef(repository, typeName);
}
}
fieldMetadata.setData(MetadataRepository.XSD_LINE_NUMBER, XSDParser.getStartLine(appInfo));
fieldMetadata.setData(MetadataRepository.XSD_COLUMN_NUMBER, XSDParser.getStartColumn(appInfo));
fieldMetadata.setData(MetadataRepository.XSD_DOM_ELEMENT, appInfo);
return fieldMetadata;
}
Aggregations