Пример #1
0
 public void Initialize(PSMSchema psmSchema)
 {
     PSMSchema = psmSchema;
     nodeInfos.Clear();
     Log           = new Log();
     NamingSupport = new NamingSupport {
         Log = Log
     };
     RelaxNGXmlSyntaxWriter = new RelaxNGXmlSyntaxWriter();
 }
Пример #2
0
        public void GenerateSchemaStructure()
        {
            foreach (PSMAssociationMember node in PSMSchema.PSMNodes)
            {
                if (node is PSMSchemaClass)
                {
                    continue;
                }

                RngNodeTranslationInfo nodeInfo = new RngNodeTranslationInfo();
                nodeInfo.Node   = node;
                nodeInfos[node] = nodeInfo;

                nodeInfo.ContentPatternName = NamingSupport.SuggestName(node, topLevelPattern: true);
            }
        }
Пример #3
0
        private void AddReferences(XElement parentElement, RngNodeTranslationInfo nodeInfo)
        {
            #region SR
            if (nodeInfo.Node is PSMClass)
            {
                PSMClass psmClass = (PSMClass)nodeInfo.Node;
                // HACK: nodeInfos.ContainsKey(psmClass.RepresentedClass) -- this prevents references to cross-schema representatives,
                //       for now, but should be fixed in the future
                if (psmClass.IsStructuralRepresentative && nodeInfos.ContainsKey(psmClass.RepresentedClass))
                {
                    RngNodeTranslationInfo srInfo = nodeInfos[psmClass.RepresentedClass];
                    RelaxNGXmlSyntaxWriter.RngRef(parentElement, srInfo.ContentPatternName);
                }
            }

            #endregion

            #region attributes

            if (nodeInfo.Node is PSMClass)
            {
                PSMClass psmClass = (PSMClass)nodeInfo.Node;

                foreach (PSMAttribute psmAttribute in psmClass.PSMAttributes)
                {
                    string attributeName = NamingSupport.SuggestName(psmAttribute, attribute: true);
                    if (psmAttribute.Element)
                    {
                        RelaxNGXmlSyntaxWriter.RngAttributeAsElement(parentElement, attributeName, psmAttribute);
                    }
                    if (!psmAttribute.Element)
                    {
                        RelaxNGXmlSyntaxWriter.RngAttribute(parentElement, attributeName, psmAttribute);
                    }
                    if (psmAttribute.AttributeType == null)
                    {
                        Log.AddWarningFormat("Type of attribute '{0}' is not specified. ", psmAttribute);
                    }
                    else if (!psmAttribute.AttributeType.IsSealed)
                    {
                        if (psmAttribute.AttributeType.BaseType == Guid.Empty || string.IsNullOrEmpty(psmAttribute.AttributeType.XSDDefinition))
                        {
                            Log.AddWarningFormat("Can not translate type of attribute '{0}' - '{1}'. Define base type and XSD definition via Data Type Manager.", psmAttribute, psmAttribute.AttributeType);
                        }
                        else
                        {
                            usedNonDefaultAttribuXElements.AddIfNotContained(psmAttribute.AttributeType);
                        }
                    }
                }
            }

            #endregion

            #region associations

            if (nodeInfo.Node is PSMAssociationMember)
            {
                PSMAssociationMember psmAssociationMember = (PSMAssociationMember)nodeInfo.Node;

                // associations
                foreach (PSMAssociation psmAssociation in psmAssociationMember.ChildPSMAssociations)
                {
                    RngNodeTranslationInfo childInfo       = nodeInfos[psmAssociation.Child];
                    XElement applyCardinalityInThisElement = null;

                    #region class
                    if (childInfo.Node is PSMClass)
                    {
                        PSMClass childClass = (PSMClass)childInfo.Node;
                        XElement elementContainingReference = parentElement;
                        if (psmAssociation.IsNamed)
                        {
                            XElement elementElement = RelaxNGXmlSyntaxWriter.RngElement(parentElement, psmAssociation.Name);
                            elementContainingReference    = elementElement;
                            applyCardinalityInThisElement = elementElement;
                        }

                        XElement referenceElement;
                        IEnumerable <PSMClass> allAllowedClasses = childClass.GetSpecificClasses(true).Where(c => !c.Abstract);
                        if (allAllowedClasses.Count() <= 1)
                        {
                            referenceElement = RelaxNGXmlSyntaxWriter.RngRef(elementContainingReference, childInfo.ContentPatternName);
                        }
                        else
                        {
                            RelaxNGXmlSyntaxWriter.AddComment(elementContainingReference, string.Format("here follows expansion for classes inheriting from '{0}'", childClass.Name));
                            referenceElement = RelaxNGXmlSyntaxWriter.RngChoice(elementContainingReference);
                            foreach (PSMClass allowedClass in allAllowedClasses)
                            {
                                RelaxNGXmlSyntaxWriter.RngRef(referenceElement, nodeInfos[allowedClass].ContentPatternName);
                            }
                            applyCardinalityInThisElement = referenceElement;
                        }

                        if (!psmAssociation.IsNamed)
                        {
                            applyCardinalityInThisElement = referenceElement;
                        }
                    }
                    #endregion

                    #region content model
                    if (childInfo.Node is PSMContentModel)
                    {
                        /*
                         * association name is ignored in this case,
                         * normalized schemas do not have content models
                         * with named parent associations
                         */
                        if (psmAssociation.IsNamed)
                        {
                            Log.AddErrorFormat(
                                "Name of '{0}' is ignored. Associations leading to content models should not have names (this violates rules for normalized schemas).",
                                psmAssociation);
                        }
                        XElement contentModelElement;
                        switch (((PSMContentModel)childInfo.Node).Type)
                        {
                        case PSMContentModelType.Sequence:
                            contentModelElement = RelaxNGXmlSyntaxWriter.RngGroup(parentElement);
                            AddReferences(contentModelElement, childInfo);
                            applyCardinalityInThisElement = contentModelElement;
                            break;

                        case PSMContentModelType.Choice:
                            contentModelElement = RelaxNGXmlSyntaxWriter.RngChoice(parentElement);
                            AddReferences(contentModelElement, childInfo);
                            applyCardinalityInThisElement = contentModelElement;
                            break;

                        case PSMContentModelType.Set:
                            contentModelElement = RelaxNGXmlSyntaxWriter.RngInterleave(parentElement);
                            AddReferences(contentModelElement, childInfo);
                            applyCardinalityInThisElement = contentModelElement;
                            break;

                        default:
                            // never gets here
                            throw new ArgumentOutOfRangeException();
                        }
                    }
                    #endregion

                    RelaxNGXmlSyntaxWriter.HandleCardinality(applyCardinalityInThisElement, psmAssociation);
                }
            }

            #endregion

            // todo: EMPTY content
        }