Search in sources :

Example 1 with FieldMetadata

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;
}
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)

Example 2 with FieldMetadata

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;
}
Also used : SoftFieldRef(org.talend.mdm.commmon.metadata.SoftFieldRef) FieldMetadata(org.talend.mdm.commmon.metadata.FieldMetadata) ContainedTypeFieldMetadata(org.talend.mdm.commmon.metadata.ContainedTypeFieldMetadata)

Example 3 with 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;
}
Also used : FieldMetadata(org.talend.mdm.commmon.metadata.FieldMetadata) ContainedTypeFieldMetadata(org.talend.mdm.commmon.metadata.ContainedTypeFieldMetadata) XSDElementDeclaration(org.eclipse.xsd.XSDElementDeclaration) Element(org.w3c.dom.Element) ArrayList(java.util.ArrayList) ContainedTypeFieldMetadata(org.talend.mdm.commmon.metadata.ContainedTypeFieldMetadata) XSDAnnotation(org.eclipse.xsd.XSDAnnotation) ComplexTypeMetadata(org.talend.mdm.commmon.metadata.ComplexTypeMetadata)

Example 4 with FieldMetadata

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);
}
Also used : FieldMetadata(org.talend.mdm.commmon.metadata.FieldMetadata)

Example 5 with 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;
}
Also used : SoftFieldRef(org.talend.mdm.commmon.metadata.SoftFieldRef) FieldMetadata(org.talend.mdm.commmon.metadata.FieldMetadata) SoftIdFieldRef(org.talend.mdm.commmon.metadata.SoftIdFieldRef)

Aggregations

FieldMetadata (org.talend.mdm.commmon.metadata.FieldMetadata)8 ContainedTypeFieldMetadata (org.talend.mdm.commmon.metadata.ContainedTypeFieldMetadata)5 ArrayList (java.util.ArrayList)3 Element (org.w3c.dom.Element)3 XSDAnnotation (org.eclipse.xsd.XSDAnnotation)2 XSDElementDeclaration (org.eclipse.xsd.XSDElementDeclaration)2 ComplexTypeMetadata (org.talend.mdm.commmon.metadata.ComplexTypeMetadata)2 SoftFieldRef (org.talend.mdm.commmon.metadata.SoftFieldRef)2 HashMap (java.util.HashMap)1 ContainedComplexTypeMetadata (org.talend.mdm.commmon.metadata.ContainedComplexTypeMetadata)1 EnumerationFieldMetadata (org.talend.mdm.commmon.metadata.EnumerationFieldMetadata)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 SoftIdFieldRef (org.talend.mdm.commmon.metadata.SoftIdFieldRef)1 SoftTypeRef (org.talend.mdm.commmon.metadata.SoftTypeRef)1 TypeMetadata (org.talend.mdm.commmon.metadata.TypeMetadata)1