Search in sources :

Example 1 with ReferenceFieldMetadata

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;
}
Also used : ComplexTypeMetadata(org.talend.mdm.commmon.metadata.ComplexTypeMetadata) SimpleTypeMetadata(org.talend.mdm.commmon.metadata.SimpleTypeMetadata) TypeMetadata(org.talend.mdm.commmon.metadata.TypeMetadata) ContainedComplexTypeMetadata(org.talend.mdm.commmon.metadata.ContainedComplexTypeMetadata) FieldMetadata(org.talend.mdm.commmon.metadata.FieldMetadata) EnumerationFieldMetadata(org.talend.mdm.commmon.metadata.EnumerationFieldMetadata) ContainedTypeFieldMetadata(org.talend.mdm.commmon.metadata.ContainedTypeFieldMetadata) ReferenceFieldMetadata(org.talend.mdm.commmon.metadata.ReferenceFieldMetadata) SimpleTypeFieldMetadata(org.talend.mdm.commmon.metadata.SimpleTypeFieldMetadata) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) ReferenceFieldMetadata(org.talend.mdm.commmon.metadata.ReferenceFieldMetadata) MetadataVisitable(org.talend.mdm.commmon.metadata.MetadataVisitable) ComplexTypeMetadata(org.talend.mdm.commmon.metadata.ComplexTypeMetadata) ContainedComplexTypeMetadata(org.talend.mdm.commmon.metadata.ContainedComplexTypeMetadata) ContainedComplexTypeMetadata(org.talend.mdm.commmon.metadata.ContainedComplexTypeMetadata)

Aggregations

ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 ComplexTypeMetadata (org.talend.mdm.commmon.metadata.ComplexTypeMetadata)1 ContainedComplexTypeMetadata (org.talend.mdm.commmon.metadata.ContainedComplexTypeMetadata)1 ContainedTypeFieldMetadata (org.talend.mdm.commmon.metadata.ContainedTypeFieldMetadata)1 EnumerationFieldMetadata (org.talend.mdm.commmon.metadata.EnumerationFieldMetadata)1 FieldMetadata (org.talend.mdm.commmon.metadata.FieldMetadata)1 MetadataVisitable (org.talend.mdm.commmon.metadata.MetadataVisitable)1 ReferenceFieldMetadata (org.talend.mdm.commmon.metadata.ReferenceFieldMetadata)1 SimpleTypeFieldMetadata (org.talend.mdm.commmon.metadata.SimpleTypeFieldMetadata)1 SimpleTypeMetadata (org.talend.mdm.commmon.metadata.SimpleTypeMetadata)1 TypeMetadata (org.talend.mdm.commmon.metadata.TypeMetadata)1