use of org.talend.mdm.commmon.metadata.ReferenceFieldMetadata 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;
}
Aggregations