Search in sources :

Example 1 with XmlSchemaAnnotationProcessorState

use of org.talend.mdm.commmon.metadata.annotation.XmlSchemaAnnotationProcessorState in project tmdm-common by Talend.

the class MetadataRepository method createFieldMetadata.

// TODO Refactor!
private FieldMetadata createFieldMetadata(XSDElementDeclaration element, ComplexTypeMetadata containingType, int minOccurs, int maxOccurs) {
    String fieldName = element.getName();
    if (maxOccurs > 0 && minOccurs > maxOccurs) {
        // Eclipse XSD does not check this
        throw new IllegalArgumentException("Can not parse information on field '" + element.getQName() + "' of type '" + containingType + "' (maxOccurs > minOccurs)");
    }
    boolean isMany = maxOccurs == -1 || maxOccurs > 1;
    XmlSchemaAnnotationProcessorState state = new XmlSchemaAnnotationProcessorState();
    try {
        XSDAnnotation annotation = element.getAnnotation();
        for (XmlSchemaAnnotationProcessor processor : XML_ANNOTATIONS_PROCESSORS) {
            processor.process(this, containingType, annotation, state);
        }
    } catch (Exception e) {
        throw new RuntimeException("Annotation processing exception while parsing info for field '" + fieldName + "' in type '" + containingType.getName() + "'", e);
    }
    boolean isMandatory = minOccurs > 0;
    boolean isContained = false;
    boolean isReference = state.isReference();
    boolean fkIntegrity = state.isFkIntegrity();
    boolean fkIntegrityOverride = state.isFkIntegrityOverride();
    List<FieldMetadata> foreignKeyInfo = state.getForeignKeyInfo();
    String foreignKeyInfoFormat = state.getForeignKeyInfoFormat();
    TypeMetadata fieldType = state.getFieldType();
    FieldMetadata referencedField = state.getReferencedField();
    TypeMetadata referencedType = state.getReferencedType();
    List<String> hideUsers = state.getHide();
    List<String> allowWriteUsers = state.getAllowWrite();
    List<String> workflowAccessRights = state.getWorkflowAccessRights();
    String visibilityRule = state.getVisibilityRule();
    XSDTypeDefinition schemaType = element.getType();
    if (schemaType instanceof XSDSimpleTypeDefinition) {
        XSDSimpleTypeDefinition simpleSchemaType = (XSDSimpleTypeDefinition) schemaType;
        XSDSimpleTypeDefinition content = simpleSchemaType.getBaseTypeDefinition();
        if (schemaType.getQName() != null) {
            fieldType = new SoftTypeRef(this, schemaType.getTargetNamespace(), schemaType.getName(), false);
        } else {
            // Null QNames may happen for anonymous types extending other types.
            fieldType = new SimpleTypeMetadata(targetNamespace, ANONYMOUS_PREFIX + String.valueOf(anonymousCounter++));
            if (content != null) {
                fieldType.addSuperType(new SoftTypeRef(this, content.getTargetNamespace(), content.getName(), false));
            }
        }
        setFieldData(simpleSchemaType, fieldType);
        fieldType.setData(XSD_LINE_NUMBER, XSDParser.getStartLine(element.getElement()));
        fieldType.setData(XSD_COLUMN_NUMBER, XSDParser.getStartColumn(element.getElement()));
        fieldType.setData(XSD_DOM_ELEMENT, element.getElement());
        fieldType.setData(MIN_OCCURS, minOccurs);
        fieldType.setData(MAX_OCCURS, maxOccurs);
        if (isReference) {
            ReferenceFieldMetadata referenceField = new ReferenceFieldMetadata(containingType, false, isMany, isMandatory, fieldName, (ComplexTypeMetadata) referencedType, referencedField, foreignKeyInfo, foreignKeyInfoFormat, fkIntegrity, fkIntegrityOverride, fieldType, allowWriteUsers, hideUsers, workflowAccessRights, state.getForeignKeyFilter(), visibilityRule);
            referenceField.setData(XSD_LINE_NUMBER, XSDParser.getStartLine(element.getElement()));
            referenceField.setData(XSD_COLUMN_NUMBER, XSDParser.getStartColumn(element.getElement()));
            referenceField.setData(XSD_ELEMENT, element);
            referenceField.setData(XSD_DOM_ELEMENT, element.getElement());
            referenceField.setData(MIN_OCCURS, minOccurs);
            referenceField.setData(MAX_OCCURS, maxOccurs);
            setLocalizedNames(referenceField, state.getLocaleToLabel());
            setLocalizedDescriptions(referenceField, state.getLocaleToDescription());
            setDefaultValueRule(referenceField, state.getDefaultValueRule());
            setFieldData(simpleSchemaType, referenceField);
            return referenceField;
        }
        if (content != null) {
            if (content.getFacets().size() > 0) {
                boolean isEnumeration = false;
                for (int i = 0; i < content.getFacets().size(); i++) {
                    XSDConstrainingFacet item = content.getFacets().get(i);
                    if (item instanceof XSDEnumerationFacet) {
                        isEnumeration = true;
                    }
                }
                if (isEnumeration) {
                    EnumerationFieldMetadata enumField = new EnumerationFieldMetadata(containingType, false, isMany, isMandatory, fieldName, fieldType, allowWriteUsers, hideUsers, workflowAccessRights, visibilityRule);
                    enumField.setData(XSD_LINE_NUMBER, XSDParser.getStartLine(element.getElement()));
                    enumField.setData(XSD_COLUMN_NUMBER, XSDParser.getStartColumn(element.getElement()));
                    enumField.setData(XSD_ELEMENT, element);
                    enumField.setData(XSD_DOM_ELEMENT, element.getElement());
                    enumField.setData(MIN_OCCURS, minOccurs);
                    enumField.setData(MAX_OCCURS, maxOccurs);
                    setLocalizedNames(enumField, state.getLocaleToLabel());
                    setLocalizedDescriptions(enumField, state.getLocaleToDescription());
                    setDefaultValueRule(enumField, state.getDefaultValueRule());
                    setFieldData(simpleSchemaType, enumField);
                    return enumField;
                } else {
                    FieldMetadata field = new SimpleTypeFieldMetadata(containingType, false, isMany, isMandatory, fieldName, fieldType, allowWriteUsers, hideUsers, workflowAccessRights, visibilityRule);
                    field.setData(XSD_LINE_NUMBER, XSDParser.getStartLine(element.getElement()));
                    field.setData(XSD_COLUMN_NUMBER, XSDParser.getStartColumn(element.getElement()));
                    field.setData(XSD_ELEMENT, element);
                    field.setData(XSD_DOM_ELEMENT, element.getElement());
                    field.setData(MIN_OCCURS, minOccurs);
                    field.setData(MAX_OCCURS, maxOccurs);
                    setLocalizedNames(field, state.getLocaleToLabel());
                    setLocalizedDescriptions(field, state.getLocaleToDescription());
                    setDefaultValueRule(field, state.getDefaultValueRule());
                    setFieldData(simpleSchemaType, field);
                    return field;
                }
            } else {
                FieldMetadata field = new SimpleTypeFieldMetadata(containingType, false, isMany, isMandatory, fieldName, fieldType, allowWriteUsers, hideUsers, workflowAccessRights, visibilityRule);
                field.setData(XSD_LINE_NUMBER, XSDParser.getStartLine(element.getElement()));
                field.setData(XSD_COLUMN_NUMBER, XSDParser.getStartColumn(element.getElement()));
                field.setData(XSD_ELEMENT, element);
                field.setData(XSD_DOM_ELEMENT, element.getElement());
                field.setData(MIN_OCCURS, minOccurs);
                field.setData(MAX_OCCURS, maxOccurs);
                setLocalizedNames(field, state.getLocaleToLabel());
                setLocalizedDescriptions(field, state.getLocaleToDescription());
                setDefaultValueRule(field, state.getDefaultValueRule());
                setFieldData(simpleSchemaType, field);
                return field;
            }
        }
    }
    if (fieldType == null) {
        String qName = element.getType() == null ? null : element.getType().getQName();
        if (qName != null) {
            TypeMetadata metadata = getType(element.getType().getTargetNamespace(), element.getType().getName());
            if (metadata != null) {
                fieldType = new SoftTypeRef(this, targetNamespace, schemaType.getName(), false);
                isContained = true;
            } else {
                if (schemaType instanceof XSDComplexTypeDefinition) {
                    fieldType = new SoftTypeRef(this, schemaType.getTargetNamespace(), schemaType.getName(), false);
                    isContained = true;
                } else {
                    throw new NotImplementedException("Support for '" + schemaType.getClass() + "'.");
                }
            }
        } else {
            // Ref & anonymous complex type
            isContained = true;
            XSDElementDeclaration refName = element.getResolvedElementDeclaration();
            if (schemaType != null) {
                fieldType = new ComplexTypeMetadataImpl(targetNamespace, ANONYMOUS_PREFIX + String.valueOf(anonymousCounter++), false);
                isContained = true;
            } else if (refName != null) {
                // Reference being an element, consider references as references to entity type.
                fieldType = new SoftTypeRef(this, refName.getTargetNamespace(), refName.getName(), true);
            } else {
                throw new NotImplementedException();
            }
        }
    }
    if (isContained) {
        ContainedTypeFieldMetadata containedField = new ContainedTypeFieldMetadata(containingType, isMany, isMandatory, fieldName, (ComplexTypeMetadata) fieldType, isReference, allowWriteUsers, hideUsers, workflowAccessRights, visibilityRule);
        containedField.setData(XSD_LINE_NUMBER, XSDParser.getStartLine(element.getElement()));
        containedField.setData(XSD_COLUMN_NUMBER, XSDParser.getStartColumn(element.getElement()));
        containedField.setData(XSD_ELEMENT, element);
        containedField.setData(XSD_DOM_ELEMENT, element.getElement());
        containedField.setData(MIN_OCCURS, minOccurs);
        containedField.setData(MAX_OCCURS, maxOccurs);
        if (fieldType.getName().startsWith(ANONYMOUS_PREFIX)) {
            currentTypeStack.push((ComplexTypeMetadata) containedField.getType());
            {
                XmlSchemaWalker.walk(schemaType, this);
            }
            currentTypeStack.pop();
        }
        setLocalizedNames(containedField, state.getLocaleToLabel());
        setLocalizedDescriptions(containedField, state.getLocaleToDescription());
        return containedField;
    } else {
        FieldMetadata field = new SimpleTypeFieldMetadata(containingType, false, isMany, isMandatory, fieldName, fieldType, allowWriteUsers, hideUsers, workflowAccessRights, visibilityRule);
        field.setData(XSD_LINE_NUMBER, XSDParser.getStartLine(element.getElement()));
        field.setData(XSD_COLUMN_NUMBER, XSDParser.getStartColumn(element.getElement()));
        field.setData(XSD_ELEMENT, element);
        field.setData(XSD_DOM_ELEMENT, element.getElement());
        field.setData(MIN_OCCURS, minOccurs);
        field.setData(MAX_OCCURS, maxOccurs);
        setLocalizedNames(field, state.getLocaleToLabel());
        setLocalizedDescriptions(field, state.getLocaleToDescription());
        return field;
    }
}
Also used : NotImplementedException(org.apache.commons.lang.NotImplementedException) XSDTypeDefinition(org.eclipse.xsd.XSDTypeDefinition) XmlSchemaAnnotationProcessorState(org.talend.mdm.commmon.metadata.annotation.XmlSchemaAnnotationProcessorState) XSDEnumerationFacet(org.eclipse.xsd.XSDEnumerationFacet) XSDComplexTypeDefinition(org.eclipse.xsd.XSDComplexTypeDefinition) XSDSimpleTypeDefinition(org.eclipse.xsd.XSDSimpleTypeDefinition) NotImplementedException(org.apache.commons.lang.NotImplementedException) XSDElementDeclaration(org.eclipse.xsd.XSDElementDeclaration) XSDConstrainingFacet(org.eclipse.xsd.XSDConstrainingFacet) XSDAnnotation(org.eclipse.xsd.XSDAnnotation) XmlSchemaAnnotationProcessor(org.talend.mdm.commmon.metadata.annotation.XmlSchemaAnnotationProcessor)

Example 2 with XmlSchemaAnnotationProcessorState

use of org.talend.mdm.commmon.metadata.annotation.XmlSchemaAnnotationProcessorState in project tmdm-common by Talend.

the class MetadataRepository method visitElement.

@Override
public void visitElement(XSDElementDeclaration element) {
    if (currentTypeStack.isEmpty()) {
        // "top level" elements means new MDM entity type
        String typeName = element.getName();
        if (getComplexType(typeName) != null) {
            // Don't process twice type
            return;
        }
        // If entity's type is abstract
        boolean isAbstract = false;
        XSDTypeDefinition typeDefinition = element.getTypeDefinition();
        if (typeDefinition != null && typeDefinition instanceof XSDComplexTypeDefinition) {
            isAbstract = ((XSDComplexTypeDefinition) typeDefinition).isAbstract();
        }
        // Id fields
        Map<String, XSDXPathDefinition> idFields = new LinkedHashMap<String, XSDXPathDefinition>();
        EList<XSDIdentityConstraintDefinition> constraints = element.getIdentityConstraintDefinitions();
        for (XSDIdentityConstraintDefinition constraint : constraints) {
            EList<XSDXPathDefinition> fields = constraint.getFields();
            for (XSDXPathDefinition field : fields) {
                idFields.put(field.getValue(), field);
            }
        }
        XmlSchemaAnnotationProcessorState state;
        try {
            XSDAnnotation annotation = element.getAnnotation();
            state = new XmlSchemaAnnotationProcessorState();
            for (XmlSchemaAnnotationProcessor processor : XML_ANNOTATIONS_PROCESSORS) {
                processor.process(this, null, annotation, state);
            }
        } catch (Exception e) {
            throw new RuntimeException("Annotation processing exception while parsing info for type '" + typeName + "'.", e);
        }
        // If write is not allowed for everyone, at least add "administration".
        if (state.getAllowWrite().isEmpty()) {
            state.getAllowWrite().add(ICoreConstants.ADMIN_PERMISSION);
        }
        ComplexTypeMetadata type = new ComplexTypeMetadataImpl(targetNamespace, typeName, state.getAllowWrite(), state.getDenyCreate(), state.getHide(), state.getDenyPhysicalDelete(), state.getDenyLogicalDelete(), state.getSchematron(), state.getPrimaryKeyInfo(), state.getLookupFields(), true, isAbstract, state.getWorkflowAccessRights());
        // Register parsed localized labels
        Map<Locale, String> localeToLabel = state.getLocaleToLabel();
        for (Map.Entry<Locale, String> entry : localeToLabel.entrySet()) {
            type.registerName(entry.getKey(), entry.getValue());
        }
        // Register parsed localized descriptions
        Map<Locale, String> localeToDescription = state.getLocaleToDescription();
        for (Map.Entry<Locale, String> entry : localeToDescription.entrySet()) {
            type.registerDescription(entry.getKey(), entry.getValue());
        }
        // Keep line and column of definition
        type.setData(XSD_LINE_NUMBER, XSDParser.getStartLine(element.getElement()));
        type.setData(XSD_COLUMN_NUMBER, XSDParser.getStartColumn(element.getElement()));
        type.setData(XSD_ELEMENT, element);
        type.setData(XSD_DOM_ELEMENT, element.getElement());
        addTypeMetadata(type);
        // Keep usage information
        entityTypeUsage.get(element.getType()).add(type);
        // Walk the fields
        currentTypeStack.push(type);
        {
            XmlSchemaWalker.walk(element.getType(), this);
        }
        currentTypeStack.pop();
        // Super types
        XSDElementDeclaration substitutionGroup = element.getSubstitutionGroupAffiliation();
        if (substitutionGroup != null && !XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(substitutionGroup.getTargetNamespace()) && !Types.ANY_TYPE.equals(substitutionGroup.getName())) {
            if (!substitutionGroup.getResolvedElementDeclaration().equals(element)) {
                SoftTypeRef superType = new SoftTypeRef(this, substitutionGroup.getTargetNamespace(), substitutionGroup.getName(), true);
                type.addSuperType(superType);
            }
        }
        // Register keys (TMDM-4470).
        for (Map.Entry<String, XSDXPathDefinition> unresolvedId : idFields.entrySet()) {
            SoftIdFieldRef keyField = new SoftIdFieldRef(this, type.getName(), unresolvedId.getKey());
            // Keep line and column of definition
            keyField.setData(XSD_LINE_NUMBER, XSDParser.getStartLine(unresolvedId.getValue().getElement()));
            keyField.setData(XSD_COLUMN_NUMBER, XSDParser.getStartColumn(unresolvedId.getValue().getElement()));
            keyField.setData(XSD_DOM_ELEMENT, unresolvedId.getValue().getElement());
            type.registerKey(keyField);
        }
        // entity.
        if (type.getKeyFields().isEmpty() && type.getSuperTypes().isEmpty()) {
            Map<String, TypeMetadata> userEntityTypes = entityTypes.get(getUserNamespace());
            if (userEntityTypes != null) {
                userEntityTypes.remove(type.getName());
            }
        }
    } else {
        // Non "top level" elements means fields for the MDM entity type being parsed
        FieldMetadata fieldMetadata;
        int minOccurs = ((XSDParticle) element.getContainer()).getMinOccurs();
        int maxOccurs = ((XSDParticle) element.getContainer()).getMaxOccurs();
        if (element.isElementDeclarationReference() && currentTypeStack.peek().getName().equals(element.getResolvedElementDeclaration().getName())) {
            return;
        }
        if (element.getResolvedElementDeclaration() != null && element.getResolvedElementDeclaration().getTargetNamespace() == null) {
            fieldMetadata = createFieldMetadata(element.getResolvedElementDeclaration(), currentTypeStack.peek(), minOccurs, maxOccurs);
        } else {
            fieldMetadata = createFieldMetadata(element, currentTypeStack.peek(), minOccurs, maxOccurs);
        }
        currentTypeStack.peek().addField(fieldMetadata);
    }
}
Also used : Locale(java.util.Locale) XSDTypeDefinition(org.eclipse.xsd.XSDTypeDefinition) LinkedHashMap(java.util.LinkedHashMap) XmlSchemaAnnotationProcessorState(org.talend.mdm.commmon.metadata.annotation.XmlSchemaAnnotationProcessorState) XSDComplexTypeDefinition(org.eclipse.xsd.XSDComplexTypeDefinition) XSDXPathDefinition(org.eclipse.xsd.XSDXPathDefinition) XSDParticle(org.eclipse.xsd.XSDParticle) NotImplementedException(org.apache.commons.lang.NotImplementedException) XSDElementDeclaration(org.eclipse.xsd.XSDElementDeclaration) XSDIdentityConstraintDefinition(org.eclipse.xsd.XSDIdentityConstraintDefinition) XSDAnnotation(org.eclipse.xsd.XSDAnnotation) XmlSchemaAnnotationProcessor(org.talend.mdm.commmon.metadata.annotation.XmlSchemaAnnotationProcessor) Map(java.util.Map) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) TreeMap(java.util.TreeMap)

Aggregations

NotImplementedException (org.apache.commons.lang.NotImplementedException)2 XSDAnnotation (org.eclipse.xsd.XSDAnnotation)2 XSDComplexTypeDefinition (org.eclipse.xsd.XSDComplexTypeDefinition)2 XSDElementDeclaration (org.eclipse.xsd.XSDElementDeclaration)2 XSDTypeDefinition (org.eclipse.xsd.XSDTypeDefinition)2 XmlSchemaAnnotationProcessor (org.talend.mdm.commmon.metadata.annotation.XmlSchemaAnnotationProcessor)2 XmlSchemaAnnotationProcessorState (org.talend.mdm.commmon.metadata.annotation.XmlSchemaAnnotationProcessorState)2 HashMap (java.util.HashMap)1 LinkedHashMap (java.util.LinkedHashMap)1 Locale (java.util.Locale)1 Map (java.util.Map)1 TreeMap (java.util.TreeMap)1 XSDConstrainingFacet (org.eclipse.xsd.XSDConstrainingFacet)1 XSDEnumerationFacet (org.eclipse.xsd.XSDEnumerationFacet)1 XSDIdentityConstraintDefinition (org.eclipse.xsd.XSDIdentityConstraintDefinition)1 XSDParticle (org.eclipse.xsd.XSDParticle)1 XSDSimpleTypeDefinition (org.eclipse.xsd.XSDSimpleTypeDefinition)1 XSDXPathDefinition (org.eclipse.xsd.XSDXPathDefinition)1