예제 #1
0
 private string CreateStructureAttribute(Class cls)
 {
     StringBuilder sb = new StringBuilder("[Structure(");
     sb.AppendFormat("Name = \"{0}\", StructureType = StructureAttribute.StructureAttributeType.MessageType, IsEntryPoint = {1}, Model=\"{2}\", Publisher={3} )]", cls.Name,
         cls.ContainerPackage.EntryPoint.Exists(o => o.Name == cls.Name) ? "true" : "false", cls.ContainerName, cls.Documentation != null ? "\"" + cls.Documentation.Copyright + "\"" : "null");
     return sb.ToString();
 }
예제 #2
0
        private void CascadeGenerics(MohawkCollege.EHR.gpmr.COR.Class cls, Stack <string> CurrentlyProcessing)
        {
            if (cls == null || CurrentlyProcessing.Contains(cls.Name)) // Something to process and we aren't already processing it
            {
                return;
            }

            // Push on the current class
            CurrentlyProcessing.Push(cls.Name);

            foreach (ClassContent cc in cls.Content)
            {
                if (cc is Property)
                {
                    // Now set the generics of the class to this
                    if ((cc as Property).Type.Class == null)
                    {
                        continue;                                      // Base datatype so don't worry
                    }
                    CascadeGenerics((cc as Property).Type.Class, CurrentlyProcessing);

                    foreach (TypeParameter p in (cc as Property).Type.Class.TypeParameters ?? new List <TypeParameter>())
                    {
                        cls.AddTypeParameter(p);
                        (cc as Property).Type.AddGenericSupplier(p.ParameterName, p);
                    }
                }
            }

            CurrentlyProcessing.Pop(); // Pop off the current class
        }
예제 #3
0
        internal static MohawkCollege.EHR.gpmr.COR.Class Parse(ClassBase cls, string vocabularyBindingRealm, ClassRepository cr, Dictionary <string, Package> derivationSuppliers)
        {
            // Return value
            MohawkCollege.EHR.gpmr.COR.Class retVal = new MohawkCollege.EHR.gpmr.COR.Class();

            // Name of the class
            retVal.Name = cls.Name;

            // Identify where this class came from
            retVal.DerivedFrom = cls;

            // Set the business name
            foreach (BusinessName bn in cls.BusinessName)
            {
                if (bn.Language == MifCompiler.Language || bn.Language == null)
                {
                    retVal.BusinessName = bn.Name;
                }
            }

            // Set the documentation & Copyright
            retVal.Documentation = new MohawkCollege.EHR.gpmr.COR.Documentation();
            if (cls.Annotations != null)
            {
                retVal.Documentation = DocumentationParser.Parse(cls.Annotations.Documentation);
            }
            if (cls.Container.Header.Copyright != null)
            {
                retVal.Documentation.Copyright = string.Format("Copyright (C){0}, {1}", cls.Container.Header.Copyright.Year,
                                                               cls.Container.Header.Copyright.Owner);
            }

            // Set abstractiveness of the class
            retVal.IsAbstract = cls.IsAbstract;

            // Sort the properties and add them to the class
            cls.Attribute.Sort(new ClassAttribute.Comparator());
            retVal.Content = new List <ClassContent>();
            foreach (ClassAttribute ca in cls.Attribute)
            {
                if (ca.Conformance == ConformanceKind.NotPermitted)
                {
                    continue;
                }
                MohawkCollege.EHR.gpmr.COR.Property prp = PropertyParser.Parse(ca, vocabularyBindingRealm, cr, derivationSuppliers);
                prp.Container = retVal;
                retVal.AddContent(prp);
            }

            // Set sort key
            retVal.SortKey = cls.SortKey;

            // Return
            return(retVal);
        }
예제 #4
0
        internal static MohawkCollege.EHR.gpmr.COR.Class Parse(ClassBase cls, string vocabularyBindingRealm, ClassRepository cr, Dictionary<string, Package> derivationSuppliers)
        {
            // Return value
            MohawkCollege.EHR.gpmr.COR.Class retVal = new MohawkCollege.EHR.gpmr.COR.Class();

            // Name of the class
            retVal.Name = cls.Name;

            // Identify where this class came from
            retVal.DerivedFrom = cls;

            // Set the business name
            foreach (BusinessName bn in cls.BusinessName)
                if (bn.Language == MifCompiler.Language || bn.Language == null)
                    retVal.BusinessName = bn.Name;

            // Set the documentation & Copyright
            retVal.Documentation = new MohawkCollege.EHR.gpmr.COR.Documentation();
            if(cls.Annotations != null)
                retVal.Documentation = DocumentationParser.Parse(cls.Annotations.Documentation);
            if (cls.Container.Header.Copyright != null)
                retVal.Documentation.Copyright = string.Format("Copyright (C){0}, {1}", cls.Container.Header.Copyright.Year,
                    cls.Container.Header.Copyright.Owner);

            // Set abstractiveness of the class
            retVal.IsAbstract = cls.IsAbstract;

            // Sort the properties and add them to the class
            cls.Attribute.Sort(new ClassAttribute.Comparator());
            retVal.Content = new List<ClassContent>();
            foreach (ClassAttribute ca in cls.Attribute)
            {
                if (ca.Conformance == ConformanceKind.NotPermitted) continue;
                MohawkCollege.EHR.gpmr.COR.Property prp = PropertyParser.Parse(ca, vocabularyBindingRealm, cr,derivationSuppliers);
                prp.Container = retVal;
                retVal.AddContent(prp);
            }

            // Set sort key
            retVal.SortKey = cls.SortKey;

            // Return
            return retVal;
        }
예제 #5
0
        public static List<String> MapInterfaces(Class c, string ownerNs)
        {
            List<String> retVal = new List<string>();

            // Find which interfaces this class implements
            foreach(var iface in s_heuristicData.Interfaces)
            {
                bool matches = true;
                Enumeration supplierDomain = null;
                foreach (var prop in iface.Properties)
                {
                    Property p = c.Content.Find(o => (o is Property) && (o as Property).Type.Name != null &&
                        (o as Property).Type.Name.ToLower() + "." + o.Name.ToLower() == prop.DataType.ToLower() + "." + prop.Name.ToLower() &&
                        (o.MaxOccurs == "1" || o.MaxOccurs != "1" && prop.Name.StartsWith("LIST"))) as Property;
                    matches &= p != null;
                    if(matches)
                        supplierDomain = p.SupplierDomain;
                }

                // Determine if match was found
                if (matches)
                {
                    if (!String.IsNullOrEmpty(iface.GenericParameter))
                    {
                        string rv = iface.Name;
                        if (supplierDomain != null && 
                            !String.IsNullOrEmpty(EnumerationRenderer.WillRender(supplierDomain)))
                        {
                            if (retVal.Contains(rv))
                                retVal.Remove(rv);

                            rv += String.Format("<{1}>", ownerNs, EnumerationRenderer.WillRender(supplierDomain));
                            retVal.Add(rv);
                        }
                    }
                    else
                        retVal.Add(iface.Name);
                }
            }

            return retVal;
        }
예제 #6
0
        /// <summary>
        /// Generate the complex type
        /// </summary>
        /// <param name="cls">The class to generate the complex type for</param>
        /// <param name="prefix">The prefix namespace for the class</param>
        /// <param name="genericParameters">Generic parameters</param>
        private XmlSchemaComplexType GenerateComplexType(Class cls, string prefix, List<TypeReference> genericParameters, List<String> includedModels, List<TypeReference> additionalCompileTargets)
        {

            if (cls != null && genericParameters != null && cls.TypeParameters != null && cls.TypeParameters.Count != genericParameters.Count)
                return null;
            if (cls == null)
            {
                Trace.WriteLine("Cannot generate complex type for null class", "error");
                return null;
            }

            // Create the complex type
            XmlSchemaComplexType complexType = new XmlSchemaComplexType()
            {
                Name = prefix != null ? String.Format("{0}.{1}.{2}", prefix, cls.ContainerName, cls.Name) : String.Format("{0}.{1}", cls.ContainerName, cls.Name),
                IsAbstract = cls.IsAbstract
            };

            // Populate documentation for the type
            if (!Documentation.IsEmpty(cls.Documentation))
            {
                XmlSchemaDocumentation documentation = new XmlSchemaDocumentation();
                XmlDocument documentationMarkup = new XmlDocument();
                documentationMarkup.LoadXml("<div xmlns=\"http://www.w3.org/1999/xhtml\">" + cls.Documentation.ToString() + "</div>");
                documentation.Markup = new List<XmlNode>(documentationMarkup.ChildNodes.Cast<XmlNode>()).ToArray();
                complexType.Annotation = new XmlSchemaAnnotation();
                complexType.Annotation.Items.Add(documentation);
            }

            // Complex Content
            XmlSchemaComplexContentExtension content = new XmlSchemaComplexContentExtension();

            // Null flavors and stuff
            if (cls.BaseClass != null)
            {
                // Add the import for model
                if (!includedModels.Contains(cls.BaseClass.Class.ContainerName))
                    includedModels.Add(cls.BaseClass.Class.ContainerName);

                // Set the extension
                content.BaseTypeName = new XmlQualifiedName(cls.BaseClass.Name, targetNs);
            }
            else if(cls.CreateTypeReference().Name != baseClass)
                content.BaseTypeName = new XmlQualifiedName(baseClass, targetNs);

            // Sequence
            XmlSchemaSequence sequence = new XmlSchemaSequence();
            
            // Iterate through content
            foreach (ClassContent cc in cls.Content)
            {
                if (cc is Property)
                {
                    Property property = cc as Property;

                    TypeReference realReference = property.Type.Class == null && genericParameters != null ? genericParameters.Find(o => o is TypeParameter && (o as TypeParameter).ParameterName == property.Type.Name) : property.Type;

                    // Is this a property that really represents a choice?
                    // This sometimes happens when a property (namely ACT) points to an
                    // abstract class that has many different sub-traversals...
                    if (realReference != null && 
                        realReference.Class != null &&
                        realReference.Class.IsAbstract) // Choice
                    {
                        XmlSchemaChoice propertyChoice = new XmlSchemaChoice()
                            {
                                MinOccursString = property.MinOccurs,
                                MaxOccursString = property.MaxOccurs == "*" ? "unbounded" : property.MaxOccurs
                            };
                        List<XmlSchemaElement> elements = CreateChoice(property, realReference.Class, genericParameters, prefix, includedModels, additionalCompileTargets);
                        foreach (XmlSchemaElement ele in elements)
                            propertyChoice.Items.Add(ele);
                        sequence.Items.Add(propertyChoice);
                    }
                    else // The property is really a property
                        switch (property.PropertyType)
                        {
                            case Property.PropertyTypes.Structural:
                                content.Attributes.Add(CreateAttribute(property));
                                break;
                            default:
                                sequence.Items.Add(CreateElement(property, genericParameters, prefix, includedModels, additionalCompileTargets));
                                break;
                        }
                }
                else if (cc is Choice)
                {
                    // Render the choice
                    XmlSchemaChoice choice = new XmlSchemaChoice()
                    {
                        MinOccursString = cc.MinOccurs,
                        MaxOccursString = cc.MaxOccurs == "*" ? "unbounded" : cc.MaxOccurs
                    };

                    List<XmlSchemaElement> elements = CreateChoice(cc as Choice, genericParameters, prefix, includedModels, additionalCompileTargets);
                    foreach (XmlSchemaElement element in elements)
                        choice.Items.Add(element);
                    sequence.Items.Add(choice);
                }
            }

            // Now for the inherited classes, these could also be sent
            if (cls.SpecializedBy.Count > 0)
            {
                XmlSchemaChoice childChoice = new XmlSchemaChoice();
                //// Generate a choice for all child elements
                //List<XmlSchemaElement> elements = GenerateChildChoices(cls, genericParameters, prefix, includedModels, additionalCompileTargets);
                //foreach (XmlSchemaElement ele in elements)
                //    childChoice.Items.Add(ele);
            }

            content.Particle = sequence; // Sequence
            // Add the sequence to the content
            if (sequence.Items.Count > 0)
            {
                if (content.BaseTypeName != null && !String.IsNullOrEmpty(content.BaseTypeName.Name))
                    complexType.ContentModel = new XmlSchemaComplexContent() { Content = content };
                else
                    complexType.Particle = sequence;
            }

            return complexType;

        }
예제 #7
0
        public static List<String> MapInterfaces(Class c)
        {
            List<String> retVal = new List<string>();

            // Find which interfaces this class implements
            foreach(KeyValuePair<Type, List<String>> kv in interfaces)
            {
                bool matches = true;
                Enumeration supplierDomain = null;
                foreach (String s in kv.Value)
                {
                    Property p = c.Content.Find(o => (o is Property) &&
                        ((o as Property).Type.Name != null && (o as Property).Type.Name.ToLower() + "." + o.Name.ToLower() == s.ToLower()) &&
                        (o.MaxOccurs == "1" || o.MaxOccurs != "1" && s.StartsWith("LIST"))) as Property;
                    matches &= p != null;
                    if(matches && p.SupplierStrength == Property.CodingStrengthKind.CodedNoExtensions)
                        supplierDomain = p.SupplierDomain;
                }

                // Determine if match was found
                if (matches)
                {
                    if (kv.Key.FullName.Contains("`"))
                    {
                        string rv = kv.Key.FullName.Substring(0, kv.Key.FullName.IndexOf("`"));
                        if (supplierDomain != null &&
                            !String.IsNullOrEmpty((EnumerationRenderer.WillRender(supplierDomain))))
                        {
                            if (retVal.Contains(rv))
                                retVal.Remove(rv);

                            rv += "<" + EnumerationRenderer.WillRender(supplierDomain) + ">";
                            retVal.Add(rv);
                        }
                    }
                    else
                        retVal.Add(kv.Key.FullName);
                }
            }

            return retVal;
        }
예제 #8
0
        /// <summary>
        /// Copy members from <paramref name="typeReference"/> into the class <paramref name="p"/> in the context of the 
        /// <paramref name="context"/>
        /// </summary>
        private void CopyMembers(TypeReference typeReference, Class p, ClassContent context)
        {
            if(typeReference.Class == null) throw new InvalidOperationException("Impossible condition to proceed");
            foreach (ClassContent cc in typeReference.Class.Content)
            {
                // Can't use AddContent as that sorts the content and would mess up the outer loops
                ClassContent newCc = cc.Clone() as ClassContent;
                newCc.Container = p;
                newCc.MemberOf = p.MemberOf;
                newCc.Annotations.Add(new CodeCollapseAnnotation() { Name = context.Name, Order = 0, Property = context });
                newCc.Annotations.Add(new CodeCollapseAnnotation() { Name = newCc.Name, Order = 1, Property =  newCc});

                // Assign code collapse attributes
                p.Content.Add(newCc);
            }
        }
예제 #9
0
        private string CreateCollapsedConstructor(Class cls, String ownerNs)
        {
            // Is there only one useful thing in this class?
            Property pseudoProperty = new Property();
            pseudoProperty.Name = "this";
            pseudoProperty.Type = cls.CreateTypeReference();

            // Determine the collapsed name
            Stack<KeyValuePair<String, TypeReference>> collapseData = DetermineCollapsedName(pseudoProperty);
            if (collapseData.Count > 0)
            {
                StringWriter sw = new StringWriter();

                StringBuilder methodBody  = new StringBuilder();
                String methodParms = "", methodHelp = "";

                // Create datatypes that will be used
                string path = "this";
                while (collapseData.Count > 0)
                {
                    KeyValuePair<String, TypeReference> current = collapseData.Pop();

                    string dt = CreateDatatypeRef(current.Value, current.Value.Container as Property);
                        string pCasedName = Util.Util.PascalCase(current.Key) == dt ? current.Key :
                        Util.Util.PascalCase(current.Key) == Util.Util.PascalCase(cls.Name) ? Util.Util.PascalCase(current.Key) + (current.Value.Container as Property).Type.Class.Name : Util.Util.PascalCase(current.Key);

                    path += "." + pCasedName;

                    if (current.Key != "this")
                        methodBody.AppendFormat("\t\t\t{0} = new {1}();\r\n", path, CreateDatatypeRef(current.Value, new Property()));
                    if (collapseData.Count == 0) // Last item, generate factory method data
                    {
                        Dictionary<String, String[]> childFactoryMethod = CreateFactoryMethod(current.Value, path);
                        // Get mandatory stuff
                        methodBody.Append(childFactoryMethod["mandatory"][1]);
                        methodParms = childFactoryMethod["mandatory"][0];
                        methodHelp = childFactoryMethod["mandatory"][2];
                    }
                }

                if (String.IsNullOrEmpty(methodParms)) return "";

                // Now generate the constructor
                sw.WriteLine("\t\t/// <summary> CTOR Populates {0} </summary>", path);
                sw.WriteLine(methodHelp);
                sw.WriteLine("\t\tpublic {0}({1}) {{ ", Util.Util.PascalCase(cls.Name), methodParms.Remove(methodParms.Length - 1));
                sw.WriteLine(methodBody.ToString());
                sw.WriteLine("\t\t}");
                return sw.ToString();
            }

            return "";
        }
예제 #10
0
        /// <summary>
        /// Create the equality method
        /// </summary>
        private string CreateEqualityMethod(Class cls)
        {

            string genericString = "";
            foreach (TypeParameter tp in cls.TypeParameters ?? new List<TypeParameter>())
                genericString += tp + ",";
            if(!String.IsNullOrEmpty(genericString))
                genericString = genericString.Substring(0, genericString.Length - 1);

            string dataReference = String.Format("{0}{1}",
                    Util.Util.PascalCase(cls.Name),
                    String.IsNullOrEmpty(genericString) ? "" : String.Format("<{0}>", genericString)
                );

            StringWriter swEquals = new StringWriter(),
                swHash = new StringWriter();

            // Method signatures
            swEquals.WriteLine("\t\t/// <summary>Overload of the equality determiner</summary>\r\n\t\tpublic bool Equals({0} other)\r\n\t\t{{\r\n\t\t\tbool equal = true;",
                dataReference
            );
            swHash.WriteLine("\t\t/// <summary>Overload of hash code</summary>\r\n\t\tpublic override int GetHashCode()\r\n\t\t{");
            swHash.WriteLine("\t\tint result = 1;");
            
            swEquals.WriteLine("\t\t\tif(other != null) {");
            foreach (var prop in cls.Content)
            {
                if (prop is Property)
                {
                    if (prop.MaxOccurs == "1" ||
                        (prop as Property).Type.CoreDatatypeName != null && Datatypes.IsCollectionType((prop as Property).Type))
                        swEquals.WriteLine("\t\t\t\tequal &= this.{0} != null ? this.{0}.Equals(other.{0}) : other.{0} == null;", CreatePascalCasedName(prop as Property));
                    else
                    {
                        swEquals.WriteLine("\t\t\t\tequal &= this.{0}.Count == other.{0}.Count;", CreatePascalCasedName(prop as Property));
                        swEquals.WriteLine("\t\t\t\tfor(int i = 0; i < (equal ? this.{0}.Count : 0); i++) equal &= this.{0}[i] != null ? this.{0}[i].Equals(other.{0}[i]) : other.{0}[i] == null;", CreatePascalCasedName(prop as Property));
                    }
                    swHash.WriteLine("result = 17 * result + ((this.{0} == null) ? 0 : this.{0}.GetHashCode());", CreatePascalCasedName(prop as Property));
                }
                else
                {
                    if ((prop as Choice).Content.Count == 0)
                    {
                        Trace.WriteLine("Skipping equality check for choice with 0 choice elements", "warn");
                        continue;
                    }
                    swEquals.WriteLine("\t\t\t\tequal &= this.{0} != null ? this.{0}.Equals(other.{0}) : other.{0} == null;", CreatePascalCasedName(prop as Choice));
                    swHash.WriteLine("result = 17 * result + ((this.{0} == null) ? 0 : this.{0}.GetHashCode());", CreatePascalCasedName(prop as Choice));
                }
            }
            swEquals.WriteLine("\t\t\t\treturn equal;");
            swEquals.WriteLine("\t\t\t}");
            swEquals.WriteLine("\t\t\treturn false;");
            swEquals.WriteLine("\t\t}");
            swEquals.WriteLine("\t\t/// <summary>Overload of the equality determiner</summary>\r\n\t\tpublic override bool Equals(Object obj)\r\n\t\t{");
            swEquals.WriteLine("\t\t\tif(obj is {0}) return Equals(obj as {0});", dataReference);
            swEquals.WriteLine("\t\t\treturn base.Equals(obj);");
            swEquals.WriteLine("\t\t}");

             
            swHash.WriteLine("\t\t\treturn result;\r\n\t\t}");

            return String.Format("{0}\r\n{1}", swEquals.ToString(), swHash.ToString());
        }
예제 #11
0
        public virtual void Compile()
        {
            string modelName = staticModel.PackageLocation.ToString(MifCompiler.NAME_FORMAT);

            System.Diagnostics.Trace.WriteLine(string.Format("Compiling static model package '{0}'...", modelName), "debug");

            // Check if the package has already been "compiled"
            if (ClassRepository.ContainsKey(staticModel.PackageLocation.ToString(MifCompiler.NAME_FORMAT)))
            {
                return; // Already compiled
            }
            // Create a COR namespace or package area based on the static model
            MohawkCollege.EHR.gpmr.Pipeline.Compiler.Mif20.Parsers.SubsystemParser.Parse(staticModel);

            // Static Model Derivation Suppliers
            Dictionary <string, Package> derivationSuppliers = new Dictionary <string, Package>();

            foreach (StaticModelDerivation smd in staticModel.DerivedFrom)
            {
                derivationSuppliers.Add(smd.StaticModelDerivationId, this.repository.Find(smd.TargetStaticModel) as Package);
            }

            // Compile owned entry points first
            foreach (var ep in staticModel.OwnedEntryPoint)
            {
                var cls = staticModel.OwnedClass.Find(o => o.Choice is MohawkCollege.EHR.HL7v3.MIF.MIF20.StaticModel.Flat.Class && (o.Choice as MohawkCollege.EHR.HL7v3.MIF.MIF20.StaticModel.Flat.Class).Name == ep.ClassName);
                if (cls != null)
                {
                    ProcessClassElement(cls, derivationSuppliers);
                }
            }

            // Compile all contained classes in the package
            foreach (ClassElement c in staticModel.OwnedClass)
            {
                ProcessClassElement(c, derivationSuppliers);
            }

            // Get a ref to the current sub-system
            MohawkCollege.EHR.gpmr.COR.SubSystem ss = (ClassRepository[staticModel.PackageLocation.Artifact == ArtifactKind.RIM ? "RIM" : staticModel.PackageLocation.ToString(MifCompiler.NAME_FORMAT)]
                                                       as MohawkCollege.EHR.gpmr.COR.SubSystem);

            // Compile all contained associations
            foreach (Association a in staticModel.OwnedAssociation)
            {
                ParseAssociation(a, derivationSuppliers);
            }

            // Process entry points
            foreach (EntryPoint ep in staticModel.OwnedEntryPoint)
            {
                // Find the class
                MohawkCollege.EHR.gpmr.COR.Class cls = ss.FindClass(ep.ClassName);

                // The ProcStack keeps track of the properties the CascadeGenerics is
                // processing so that we don't get a stack overflow
                Stack <string> procStack = new Stack <string>();
                // Process any generic providers that need to be cascaded down to child properties
                // This is required for interactions to function properly.
                CascadeGenerics(cls, procStack);

                // Assign as the ep
                if (ss.EntryPoint == null)
                {
                    ss.EntryPoint = new List <MohawkCollege.EHR.gpmr.COR.Class>();                       // Have to do this here so we don't have E/P array with 0 elements
                }
                ss.EntryPoint.Add(cls);
            }
        }
예제 #12
0
        public void ParseAssociation(Association asc, Dictionary <string, Package> derivationSuppliers)
        {
            // There are two scenarios
            // A: Two traversable connections
            // B: A traversable and non traversable end


            // Case A: Two traversable connections, this means that the connection appears in both classes
            if (asc.Ends[0] is AssociationEnd && asc.Ends[1] is AssociationEnd)
            {
                // Make processing a little easier
                AssociationEnd[] ends = new AssociationEnd[] {
                    asc.Ends[0] as AssociationEnd,
                    asc.Ends[1] as AssociationEnd
                };


                // Loop so we write the code once
                for (int i = 0; i < 2; i++)
                {
                    Property p = new Property();
                    p.Name = ends[i].Name;

                    // Business Name
                    foreach (BusinessName bn in ends[i].BusinessName ?? new List <BusinessName>())
                    {
                        if (bn.Language == MifCompiler.Language || bn.Language == null)
                        {
                            p.BusinessName = bn.Name;
                        }
                    }

                    // The multiplicity of the opposing end influences the property on this end of the
                    // association
                    p.MinOccurs   = ends[1 - i].MinimumMultiplicity;
                    p.MaxOccurs   = ends[1 - i].MaximumMultiplicity;
                    p.Conformance = ends[1 - i].IsMandatory ? ClassContent.ConformanceKind.Mandatory :
                                    ends[1 - i].Conformance == ConformanceKind.Required ? ClassContent.ConformanceKind.Required :
                                    ends[1 - i].MinimumMultiplicity == "1" ? ClassContent.ConformanceKind.Populated :
                                    ClassContent.ConformanceKind.Optional;

                    // The type of this end is the type of the association
                    p.Type = CreateTypeReference(ends[i], p);

                    if (p.Type.Name == null)
                    {
                        if (p.Documentation == null)
                        {
                            p.Documentation = new MohawkCollege.EHR.gpmr.COR.Documentation();
                        }
                        if (p.Documentation.Description == null)
                        {
                            p.Documentation.Description = new List <string>();
                        }

                        p.Documentation.Description.Add(String.Format("GPMR: Association to type '{0}' was ignored and set as nothing as '{0}' could not be found. You should consider revising this", ends[i].ParticipantClassName));
                    }

                    // Traversable association
                    p.PropertyType = Property.PropertyTypes.TraversableAssociation;

                    // Annotations
                    if (asc.Annotations != null)
                    {
                        p.Documentation = MohawkCollege.EHR.gpmr.Pipeline.Compiler.Mif20.Parsers.DocumentationParser.Parse(asc.Annotations.Documentation);
                    }

                    // Find the class this end belongs in
                    if (!ClassRepository.ContainsKey(string.Format("{0}.{1}", staticModel.PackageLocation.Artifact == ArtifactKind.RIM ? "RIM" : staticModel.PackageLocation.ToString(MifCompiler.NAME_FORMAT),
                                                                   ends[1 - i].ParticipantClassName)))
                    {
                        throw new Exception(string.Format("Can't bind property '{0}' to class '{1}'... Class does not exist", p.Name, ends[1 - i].ParticipantClassName));
                    }

                    // Set derivation
                    p.DerivedFrom = asc;
                    p.SortKey     = asc.SortKey;

                    try
                    {
                        if (ends[i].DerivedFrom != null)
                        {
                            p.Realization = new List <ClassContent>();
                            foreach (var dei in ends[i].DerivedFrom)
                            {
                                MohawkCollege.EHR.gpmr.COR.Feature f = null;
                                if (!ClassRepository.TryGetValue(string.Format("{0}.{1}", derivationSuppliers[dei.StaticModelDerivationId].PackageLocation.Artifact == ArtifactKind.RIM ? "RIM" : derivationSuppliers[dei.StaticModelDerivationId].PackageLocation.ToString(MifCompiler.NAME_FORMAT),
                                                                               dei.ClassName), out f))
                                {
                                    System.Diagnostics.Trace.WriteLine(String.Format("Can't find derivation class '{0}' for association '{1}'", dei.ClassName, ends[i].Name), "debug");
                                }
                                else
                                {
                                    ClassContent cc = (f as MohawkCollege.EHR.gpmr.COR.Class).GetFullContent().Find(o => o.Name == dei.AssociationEndName);
                                    p.Realization.Add(cc);
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Trace.WriteLine(String.Format("Cannot append derivation information to {0} (reason:{1})", ends[i].Name, ex.ToString()), "error");
                    }

                    // Add to repository
                    if (ends[1 - i].Conformance != ConformanceKind.NotPermitted)
                    {
                        (ClassRepository[string.Format("{0}.{1}", staticModel.PackageLocation.Artifact == ArtifactKind.RIM ? "RIM" : staticModel.PackageLocation.ToString(MifCompiler.NAME_FORMAT),
                                                       ends[1 - i].ParticipantClassName)] as MohawkCollege.EHR.gpmr.COR.Class).AddContent(p);
                    }
                }
            }
            else // Case 2: A traversable and non-traversable connection,
            {
                AssociationEnd ae = (asc.Ends[0] as AssociationEnd) ?? (asc.Ends[1] as AssociationEnd);
                NonTraversableAssociationEnd ntae = (asc.Ends[0] as NonTraversableAssociationEnd) ?? (asc.Ends[1] as NonTraversableAssociationEnd);

                // Start to process the property.
                ClassContent cc;
                if (ae.ChoiceItem != null && ae.ChoiceItem.Count > 0)
                {
                    cc = new Choice();
                }
                else
                {
                    cc = new Property();
                }

                cc.Name = ae.Name;

                // Business Name
                foreach (BusinessName bn in ae.BusinessName ?? new List <BusinessName>())
                {
                    if (bn.Language == MifCompiler.Language || bn.Language == null)
                    {
                        cc.BusinessName = bn.Name;
                    }
                }

                // The multiplicity of the opposing end influences the property on this end of the
                // association
                cc.MinOccurs   = ae.MinimumMultiplicity;
                cc.MaxOccurs   = ae.MaximumMultiplicity;
                cc.Conformance = ae.IsMandatory ? ClassContent.ConformanceKind.Mandatory :
                                 ae.Conformance == ConformanceKind.Required && ae.MinimumMultiplicity == "1" ? ClassContent.ConformanceKind.Populated :
                                 ae.Conformance == ConformanceKind.Required ? ClassContent.ConformanceKind.Required :
                                 ClassContent.ConformanceKind.Optional;

                #region Bind To Class
                // Find the class on the traversable end, we'll need to append the property to it
                if (!ClassRepository.ContainsKey(string.Format("{0}.{1}", staticModel.PackageLocation.Artifact == ArtifactKind.RIM ? "RIM" : staticModel.PackageLocation.ToString(MifCompiler.NAME_FORMAT),
                                                               ntae.ParticipantClassName)))
                {
                    System.Diagnostics.Trace.WriteLine(string.Format("Can't bind property '{0}' to class '{1}'... Class does not exist", cc.Name, ntae.ParticipantClassName), "error");
                }
                //throw new Exception(string.Format("Can't bind property '{0}' to class '{1}'... Class does not exist", p.Name, ae.ParticipantClassName));
                else if (ae.Conformance != ConformanceKind.NotPermitted) // Append the property to the class
                {
                    MohawkCollege.EHR.gpmr.COR.Class cls = ClassRepository[string.Format("{0}.{1}", staticModel.PackageLocation.Artifact == ArtifactKind.RIM ? "RIM" : staticModel.PackageLocation.ToString(MifCompiler.NAME_FORMAT),
                                                                                         ntae.ParticipantClassName)] as MohawkCollege.EHR.gpmr.COR.Class;
                    cls.AddContent(cc);
                    // Add template parameter
                    if (templateParameters.ContainsKey(ae.ParticipantClassName))
                    {
                        cls.AddTypeParameter(templateParameters[ae.ParticipantClassName]);
                    }
                }
                else
                {
                    return;
                }

                #endregion

                // Choice or property?
                if (cc is Property)
                {
                    Property p = cc as Property;
                    p.Type = CreateTypeReference(ae, p);
                    if (p.Type.Name == null)
                    {
                        if (p.Documentation == null)
                        {
                            p.Documentation = new MohawkCollege.EHR.gpmr.COR.Documentation();
                        }
                        if (p.Documentation.Description == null)
                        {
                            p.Documentation.Description = new List <string>();
                        }
                        p.Documentation.Description.Add(String.Format("GPMR: Association to type '{0}' was ignored and set as nothing as '{0}' could not be found. You should consider revising this", ae.ParticipantClassName));
                    }
                    // Traversable association
                    p.PropertyType = Property.PropertyTypes.TraversableAssociation;
                }
                else // Choice
                {
                    Choice chc = cc as Choice;
                    chc.MemberOf = ClassRepository;
                    chc.Content  = new List <ClassContent>();

                    // Get a type reference to the CMET or main type to be used
                    TypeReference trf = CreateTypeReference(ae, cc);

                    // Cannot find association
                    if (trf.Name == null)
                    {
                        if (chc.Documentation == null)
                        {
                            chc.Documentation = new MohawkCollege.EHR.gpmr.COR.Documentation();
                        }
                        if (chc.Documentation.Description == null)
                        {
                            chc.Documentation.Description = new List <string>();
                        }

                        chc.Documentation.Description.Add(String.Format("GPMR: Association to type '{0}' was ignored and set as nothing as '{0}' could not be found. You should consider revising this", ae.ParticipantClassName));
                    }

                    // Warn
                    if (trf.Class == null)
                    {
                        throw new InvalidOperationException(String.Format("Cannot make association to class '{0}' as it was not defined!", ae.ParticipantClassName));
                    }
                    if (ae.ChoiceItem.Count != trf.Class.SpecializedBy.Count)
                    {
                        System.Diagnostics.Trace.WriteLine(string.Format("Number of choices on property does not match the number of child classes for its data type for association '{0}'", cc.Name), "warn");
                    }

                    chc.Content.AddRange(ProcessAssociations(ae, ae.ChoiceItem, trf, chc));

                    /*
                     * // Specializations
                     * List<TypeReference> specializations = new List<TypeReference>(trf.Class.SpecializedBy);
                     *
                     * // Flatten choice members
                     * for (int i = 0; i < ae.ChoiceItem.Count ; i++)
                     *  if (ae.ChoiceItem[i].Specialization != null && ae.ChoiceItem[i].Specialization.Count > 0)
                     *  {
                     *      AssociationEndSpecialization aes = ae.ChoiceItem[i]; // Get local reference
                     *      // Remove redundant data
                     *      ae.ChoiceItem.RemoveAt(i); // Remove the redundant choice item
                     *      i--; // redo this item
                     *      // is this a cmet?
                     *      if (ClassRepository.ContainsKey(aes.ClassName) && ClassRepository[aes.ClassName] is CommonTypeReference)
                     *      {
                     *          specializations.RemoveAll(o => o.Name == (ClassRepository[aes.ClassName] as CommonTypeReference).Class.Name);
                     *          specializations.AddRange((ClassRepository[aes.ClassName] as CommonTypeReference).Class.Class.SpecializedBy);
                     *      }
                     *
                     *      ae.ChoiceItem.AddRange(aes.Specialization); // Now add the choices
                     *  }
                     *
                     * int ip = 0;
                     *
                     * // Add choice members
                     * foreach (AssociationEndSpecialization aes in ae.ChoiceItem)
                     * {
                     *  Property p = new Property();
                     *
                     *  // Now, construct the properties from the CMET entries
                     *  // Try ...
                     *
                     *  var rClassName = specializations.Find(o => o.Class != null && o.Class.Name.Equals(aes.ClassName));
                     *
                     *  // Determine if this is a CMET
                     *  if (ClassRepository.ContainsKey(aes.ClassName) && ClassRepository[aes.ClassName] is CommonTypeReference)
                     *      p.Type = (ClassRepository[aes.ClassName] as CommonTypeReference).Class;
                     *  else if (rClassName != null) // Try using the inheritence method
                     *      p.Type = rClassName;
                     *  else if (ClassRepository.ContainsKey(String.Format("{0}.{1}", staticModel.PackageLocation.ToString(MifCompiler.NAME_FORMAT), aes.ClassName)))
                     *      p.Type = ((ClassRepository[String.Format("{0}.{1}", staticModel.PackageLocation.ToString(MifCompiler.NAME_FORMAT), aes.ClassName)] as MohawkCollege.EHR.gpmr.COR.Class).CreateTypeReference());
                     *  else
                     *  {
                     *      System.Diagnostics.Trace.WriteLine(string.Format("Class '{2}' of CMET '{1}' could not be found or was not processed. The processing of the property '{0}' in '{3}.{4}' will NOT continue", cc.Name, aes.ClassName, ae.ParticipantClassName, staticModel.PackageLocation.ToString(MifCompiler.NAME_FORMAT), ntae.ParticipantClassName), "error");
                     *      break;
                     *  }
                     *
                     *  p.PropertyType = Property.PropertyTypes.TraversableAssociation;
                     *
                     *  // Fix bug with optional choice
                     *  p.MinOccurs = chc.MinOccurs;
                     *  p.MaxOccurs = chc.MaxOccurs;
                     *  p.Conformance = chc.Conformance;
                     *
                     *  p.DerivedFrom = aes;
                     *  p.Documentation = p.Type.ClassDocumentation;
                     *
                     *  p.MemberOf = ClassRepository;
                     *  p.Container = chc;
                     *
                     *  // Traversal names
                     *  p.Name = aes.TraversalName;
                     *
                     *  chc.Content.Add(p);
                     *
                     *  ip++;
                     * }
                     */
                }


                // Annotations
                if (asc.Annotations != null)
                {
                    cc.Documentation = MohawkCollege.EHR.gpmr.Pipeline.Compiler.Mif20.Parsers.DocumentationParser.Parse(asc.Annotations.Documentation);
                }

                // Set derivation
                cc.DerivedFrom = asc;
                cc.SortKey     = ae.SortKey;

                try
                {
                    if (ae.DerivedFrom != null)
                    {
                        cc.Realization = new List <ClassContent>();
                        foreach (var dei in ae.DerivedFrom)
                        {
                            MohawkCollege.EHR.gpmr.COR.Feature ss = null;
                            Package derivationPkg = null;
                            if (!derivationSuppliers.TryGetValue(dei.StaticModelDerivationId, out derivationPkg) || derivationPkg == null)
                            {
                                continue;
                            }

                            // Has the package been compiled?
                            if (!ClassRepository.TryGetValue(string.Format("{0}", derivationPkg.PackageLocation.Artifact == ArtifactKind.RIM ? "RIM" : derivationPkg.PackageLocation.ToString(MifCompiler.NAME_FORMAT)), out ss))
                            {
                                // Attempt to parse
                                PackageParser.Parse(derivationPkg.PackageLocation.ToString(MifCompiler.NAME_FORMAT), derivationPkg.MemberOfRepository, ClassRepository);
                                // Ditch if still can't find
                                if (!ClassRepository.TryGetValue(string.Format("{0}", derivationPkg.PackageLocation.Artifact == ArtifactKind.RIM ? "RIM" : derivationPkg.PackageLocation.ToString(MifCompiler.NAME_FORMAT)), out ss))
                                {
                                    System.Diagnostics.Trace.WriteLine(String.Format("Can't find derivation class '{0}' for association '{1}' (derivation supplier {2})", dei.ClassName, dei.AssociationEndName, dei.StaticModelDerivationId), "warn");
                                }
                            }

                            // Feature was found
                            var f = (ss as MohawkCollege.EHR.gpmr.COR.SubSystem).FindClass(dei.ClassName);
                            if (f != null)
                            {
                                // Realized Class content
                                ClassContent rcc = f.GetFullContent().Find(o => o.Name == dei.AssociationEndName);
                                cc.Realization.Add(rcc);
                            }
                            else
                            {
                                System.Diagnostics.Trace.WriteLine(String.Format("Can't find derivation class '{0}' for association '{1}' (derivation supplier {2})", dei.ClassName, dei.AssociationEndName, dei.StaticModelDerivationId), "warn");
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    Trace.WriteLine(String.Format("Cannot append derivation information to {0} (reason:{1})", ae.Name, ex.ToString()), "error");
                }

                (cc.Container as MohawkCollege.EHR.gpmr.COR.Class).Content.Sort(new ClassContent.Comparator());
            }
        }
예제 #13
0
        internal static MohawkCollege.EHR.gpmr.COR.Class Parse(ClassParameterInfo classInfo)
        {
            // Has this been processed?
            if (classInfo.CompilerRepository.ContainsKey(string.Format("{0}.{1}", classInfo.ScopedPackageName, classInfo.Class.Name)))
            {
                return(null);
            }

            // Get the vocabulary realm that this package is bound to
            string vocabularyRealm = classInfo.MifContainer is StaticModel && (classInfo.MifContainer as StaticModel).ImportedVocabularyModelPackage != null ? (classInfo.MifContainer as StaticModel).ImportedVocabularyModelPackage.Realm : null;

            // Parse the common (class base) portion of the classes
            MohawkCollege.EHR.gpmr.COR.Class retVal = Parse(classInfo.Class as ClassBase, vocabularyRealm, classInfo.CompilerRepository, classInfo.DerivationSuppliers);

            // Base class
            retVal.BaseClass = classInfo.EnforcedBaseClass;

            // Containing subsystem
            retVal.ContainerPackage = classInfo.CompilerRepository[classInfo.ScopedPackageName] as MohawkCollege.EHR.gpmr.COR.SubSystem;

            // Fire parsed event
            retVal.FireParsed();

            #region Specializations

            retVal.SpecializedBy = new List <TypeReference>();

            // Iterate through each child class and process where neccessary
            foreach (ClassGeneralization cg in (classInfo.Class as MohawkCollege.EHR.HL7v3.MIF.MIF20.StaticModel.Flat.Class).SpecializationChild)
            {
                TypeReference tr = new TypeReference();
                tr.Name     = string.Format("{0}.{1}", classInfo.ScopedPackageName, cg.ChildClassName); // Make a ref to the child class
                tr.MemberOf = classInfo.CompilerRepository;

                bool isCMET = false;
                // Get the child class
                if (classInfo.MifContainer is GlobalStaticModel)
                {
                    // Get the CMET reference from the MIF class hierarchy
                    ClassElement ce = (classInfo.MifContainer as GlobalStaticModel).OwnedClass.Find(delegate(ClassElement c)
                    {
                        if (c != null && c.Choice != null && c.Choice is CommonModelElementRef)
                        {
                            return((c.Choice as CommonModelElementRef).Name == cg.ChildClassName);
                        }
                        else
                        {
                            return(false);
                        }
                    });

                    string cmetName = ce != null ? (ce.Choice as CommonModelElementRef).CmetName ?? (ce.Choice as CommonModelElementRef).Name : "";

                    // Determine if the reference is a cmet and gathe t
                    isCMET = cmetName != null && ce != null && classInfo.CompilerRepository.ContainsKey(cmetName) &&
                             classInfo.CompilerRepository[cmetName] is CommonTypeReference;

                    if (isCMET) // A CMET was successfully resolved
                    {
                        tr = (classInfo.CompilerRepository[cmetName] as CommonTypeReference).Class;
                    }
                    else if (ce != null && MifCompiler.cmetBindings.ContainsKey(cmetName)) // A CMET was not resolved, but a binding exists!
                    {
                        string boundModel = MifCompiler.cmetBindings[cmetName];
                        MohawkCollege.EHR.gpmr.COR.Feature boundSubSystem = null;
                        if (classInfo.CompilerRepository.TryGetValue(boundModel, out boundSubSystem))
                        {
                            tr = (boundSubSystem as MohawkCollege.EHR.gpmr.COR.SubSystem).EntryPoint[0].CreateTypeReference();
                        }
                        else
                        {
                            PackageParser.Parse(boundModel, classInfo.MifContainer.MemberOfRepository, classInfo.CompilerRepository);
                        }
                    }
                    else if (ce != null) // MIF References a CMET but one was never processed? This is odd!
                    {
                        System.Diagnostics.Trace.WriteLine(string.Format("CMET '{0}' was never processed, therefore CommonModelElementRef can't be processed in file '{1}'", cmetName, classInfo.ScopedPackageName), "warn");
                        continue;
                    }
                }

                // The child class has not been processed yet
                if (!classInfo.CompilerRepository.ContainsKey(tr.Name))
                {
                    if (isCMET) // Explicit, have to process another model
                    {
                        PackageParser.ParseClassFromPackage(tr.Name, classInfo.MifContainer.MemberOfRepository, classInfo.CompilerRepository);
                        // Assign the base class
                        //if ((classInfo.CompilerRepository[tr.Name] as MohawkCollege.EHR.gpmr.COR.Class).BaseClass != null)
                        //    System.Diagnostics.Debugger.Break();
                    }
                    else
                    {
                        ClassParameterInfo parm2 = new ClassParameterInfo();
                        parm2.Class = (classInfo.MifContainer as StaticModel).OwnedClass.Find(o => (o.Choice is MohawkCollege.EHR.HL7v3.MIF.MIF20.StaticModel.Flat.Class && string.Format("{0}.{1}", classInfo.ScopedPackageName, (o.Choice as MohawkCollege.EHR.HL7v3.MIF.MIF20.StaticModel.Flat.Class).Name) == tr.Name)).Choice as ClassBase;
                        parm2.CompilerRepository  = classInfo.CompilerRepository;
                        parm2.DerivationSuppliers = classInfo.DerivationSuppliers;
                        parm2.MifContainer        = classInfo.MifContainer;
                        parm2.ScopedPackageName   = classInfo.ScopedPackageName;
                        parm2.EnforcedBaseClass   = retVal.CreateTypeReference();
                        ClassParser.Parse(parm2);
                    }
                }


                // Add to specialization list
                MohawkCollege.EHR.gpmr.COR.Feature f = null;
                if (classInfo.CompilerRepository.TryGetValue(tr.Name, out f))
                {
                    retVal.SpecializedBy.Add((f as MohawkCollege.EHR.gpmr.COR.Class).CreateTypeReference());
                    (f as MohawkCollege.EHR.gpmr.COR.Class).BaseClass = retVal.CreateTypeReference();
                }
                else
                {
                    Trace.WriteLine(String.Format("Cannot find base class '{0}' for '{1}'. Base class must exist before it can be specialized", tr.Name, retVal.Name), "error");
                }
            }


            #endregion

            // Assign Temporary Membership to the compiler class repository so the
            // locating of a structural member will succeed
            retVal.MemberOf = classInfo.CompilerRepository;

            // Is a classCode enforcement placed on this class?
            #region Supplier Structural Domain
            if (classInfo.Class.SupplierStructuralDomain != null && classInfo.Class.SupplierStructuralDomain.Code != null)
            {
                MohawkCollege.EHR.gpmr.COR.Property clsa = retVal.FindMember("classCode", false, MohawkCollege.EHR.gpmr.COR.Property.PropertyTypes.Structural);

                if (clsa == null)// Class code is derived... we need to override it
                {
                    clsa = retVal.FindMember("classCode", true, MohawkCollege.EHR.gpmr.COR.Property.PropertyTypes.Structural);
                    // Any class code defined?
                    if (clsa != null)
                    {
                        clsa = PropertyParser.Parse(clsa.DerivedFrom as ClassAttribute, vocabularyRealm, classInfo.CompilerRepository, classInfo.DerivationSuppliers);
                        retVal.AddContent(clsa);
                    }
                    else // Makes no sense, we have a class code enforcement but no class code?
                    {
                        if (MifCompiler.hostContext.Mode == Pipeline.OperationModeType.Quirks)
                        {
                            Trace.WriteLine(String.Format("Supplier domain is specified on class '{0}' which has class code. Since GPMR is in quirks mode, the classCode attribute will be created", retVal.Name), "quirks");
                            clsa              = new Property();
                            clsa.Name         = "classCode";
                            clsa.PropertyType = Property.PropertyTypes.Structural;
                            clsa.Conformance  = ClassContent.ConformanceKind.Mandatory;
                            retVal.AddContent(clsa);
                        }
                        else
                        {
                            throw new InvalidOperationException("Shouldn't be here. Supplier domain specified on a class with no classCode");
                        }
                    }
                }

                #region Now populate the code domain
                // Supplier domains
                if (classInfo.Class.SupplierStructuralDomain != null)
                {
                    var supplierStruct = classInfo.Class.SupplierStructuralDomain;

                    if (supplierStruct.Code != null && !String.IsNullOrEmpty(supplierStruct.Code.Code)) // Fixed code
                    {
                        clsa.FixedValue = string.Format("{0}", supplierStruct.Code.Code);
                    }

                    // JF: If the code system is identified, then bind
                    if (supplierStruct.Code != null && !String.IsNullOrEmpty(supplierStruct.Code.CodeSystemName)) // Very odd thing that is present in UV mifs
                    {
                        Trace.WriteLine(String.Format("'{0}' is specified as fixed code's code system, however no fixed code is present. Assuming this is a bound code system instead", "assumption"));
                        clsa.SupplierDomain = classInfo.CompilerRepository.Find(o => o is CodeSystem && (o as CodeSystem).Name.Equals(supplierStruct.Code.CodeSystemName)) as Enumeration;
                        if (clsa.SupplierDomain == null)
                        {
                            Trace.WriteLine(String.Format("'{0}' could not be bound to '{1}' as the code system was not found", clsa.Name, supplierStruct.Code.CodeSystemName), "warn");
                        }
                    }
                    if (supplierStruct.ConceptDomain != null)
                    {
                        clsa.SupplierDomain = classInfo.CompilerRepository.Find(o => o is ConceptDomain && (o as ConceptDomain).Name.Equals(supplierStruct.ConceptDomain.Name)) as Enumeration;
                        if (clsa.SupplierDomain == null)
                        {
                            Trace.WriteLine(String.Format("'{0}' could not be bound to '{1}' as the concept domain was not found", clsa.Name, supplierStruct.ConceptDomain.Name), "warn");
                        }
                    }
                    if (supplierStruct.ValueSet != null)
                    {
                        clsa.SupplierDomain = classInfo.CompilerRepository.Find(o => o is ValueSet && (o as ValueSet).Name.Equals(supplierStruct.ValueSet.Name)) as Enumeration;
                        if (clsa.SupplierDomain == null)
                        {
                            Trace.WriteLine(String.Format("'{0}' could not be bound to '{1}' as the value set was not found", clsa.Name, supplierStruct.ValueSet.Name), "warn");
                        }

                        bool shouldFix = false;
                        if (clsa.SupplierDomain != null)
                        {
                            var enumLiteral = clsa.SupplierDomain.Literals.Find(o => o.Name == supplierStruct.ValueSet.RootCode);
                            shouldFix = enumLiteral != null && enumLiteral.RelatedCodes != null && enumLiteral.RelatedCodes.Count == 0;
                        }
                        if (shouldFix)
                        {
                            clsa.FixedValue = String.Format("{0}", supplierStruct.ValueSet.RootCode);
                        }
                    }

                    // Supplier strength(s)
                    if (supplierStruct.ValueSet != null)
                    {
                        clsa.SupplierStrength = supplierStruct.ValueSet.CodingStrength == CodingStrengthKind.CNE ? (Property.CodingStrengthKind?)Property.CodingStrengthKind.CodedNoExtensions:
                                                supplierStruct.ValueSet.CodingStrength == CodingStrengthKind.CWE ? (Property.CodingStrengthKind?)Property.CodingStrengthKind.CodedNoExtensions : null;
                    }
                    else
                    {
                        clsa.SupplierStrength = Property.CodingStrengthKind.CodedNoExtensions;
                        System.Diagnostics.Trace.WriteLine(string.Format("No vocabulary value set on property {0}! Defaulting to CNE for supplier strength", retVal.Name), "assumption");
                    }
                }



                //if (classInfo.Class.SupplierStructuralDomain.Code != null)
                //    clsa.FixedValue = string.Format("{0}{1}", classInfo.Class.SupplierStructuralDomain.Code.CodeSystem == null ? "" : classInfo.Class.SupplierStructuralDomain.Code.CodeSystem + ":", classInfo.Class.SupplierStructuralDomain.Code.Code);

                //if (classInfo.Class.SupplierStructuralDomain.ConceptDomain != null)
                //    clsa.SupplierDomain = classInfo.Class.SupplierStructuralDomain.ConceptDomain.Name;
                //if (classInfo.Class.SupplierStructuralDomain.ValueSet != null)
                //{
                //    clsa.SupplierStrength = classInfo.Class.SupplierStructuralDomain.ValueSet.CodingStrength == CodingStrengthKind.CNE ? (Property.CodingStrengthKind?)Property.CodingStrengthKind.CodedNoExtensions :
                //        classInfo.Class.SupplierStructuralDomain.ValueSet.CodingStrength == CodingStrengthKind.CWE ? (Property.CodingStrengthKind?)Property.CodingStrengthKind.CodedNoExtensions : null;
                //    clsa.SupplierDomainValueSet = classInfo.Class.SupplierStructuralDomain.ValueSet.Id;
                //}
                //else
                //{
                //    clsa.SupplierStrength = Property.CodingStrengthKind.CodedNoExtensions;
                //    System.Diagnostics.Trace.WriteLine(string.Format("No vocabulary value set on property {0}! Defaulting to CNE for supplier strength", retVal.Name), "assumption");
                //}
                #endregion
            }
            #endregion

            // All specifications
            #region Specializations

            //if ((classInfo.Class as MohawkCollege.EHR.HL7v3.MIF.MIF20.StaticModel.Flat.Class).SpecializationChild != null && (classInfo.Class as MohawkCollege.EHR.HL7v3.MIF.MIF20.StaticModel.Flat.Class).SpecializationChild.Count > 0)
            //{
            //    retVal.SpecializedBy = new List<MohawkCollege.EHR.gpmr.COR.TypeReference>();
            //    foreach (ClassGeneralization cg in (classInfo.Class as MohawkCollege.EHR.HL7v3.MIF.MIF20.StaticModel.Flat.Class).SpecializationChild)
            //    {
            //        MohawkCollege.EHR.gpmr.COR.TypeReference specRef = new MohawkCollege.EHR.gpmr.COR.TypeReference();
            //        specRef.Name = string.Format("{0}.{1}", classInfo.ScopedPackageName, cg.ChildClassName);
            //        MohawkCollege.EHR.gpmr.COR.Property noProp = new MohawkCollege.EHR.gpmr.COR.Property();
            //        noProp.Container = retVal;
            //        specRef.Container = noProp;
            //        retVal.SpecializedBy.Add(specRef);
            //    }
            //}

            #endregion

            #region Behaviors

            // State machine on the class
            if (classInfo.Class.Behavior != null)
            {
                // Find the property that this state machine acts on

                Property stateProperty = retVal.FindMember(classInfo.Class.Behavior.SupplierStateAttributeName, false, Property.PropertyTypes.NonStructural | Property.PropertyTypes.Structural);

                stateProperty.StateMachine = StateMachineParser.Parse(classInfo.Class.Behavior);
            }

            #endregion

            #region Derivation Supplier
            if (classInfo.Class.DerivedFrom != null)
            {
                // Init retVal projection
                retVal.Realizations = new List <MohawkCollege.EHR.gpmr.COR.TypeReference>();

                // Iterate through each class this class is a projection of (is based on)
                foreach (ClassDerivation cd in classInfo.Class.DerivedFrom)
                {
                    try
                    {
                        // See if this class has been parsed
                        Package derivationPackage = null;
                        if (!classInfo.DerivationSuppliers.TryGetValue(cd.StaticModelDerivationId, out derivationPackage) || derivationPackage == null)
                        {
                            continue;
                        }

                        MohawkCollege.EHR.gpmr.COR.Feature ss = null;

                        // Has the package been compiled?
                        if (!classInfo.CompilerRepository.TryGetValue(string.Format("{0}", derivationPackage.PackageLocation.Artifact == ArtifactKind.RIM ? "RIM" : derivationPackage.PackageLocation.ToString(MifCompiler.NAME_FORMAT)), out ss))
                        {
                            // Attempt to parse
                            PackageParser.Parse(derivationPackage.PackageLocation.ToString(MifCompiler.NAME_FORMAT), derivationPackage.MemberOfRepository, classInfo.CompilerRepository);
                            // Ditch if still can't find
                            if (!classInfo.CompilerRepository.TryGetValue(string.Format("{0}", derivationPackage.PackageLocation.Artifact == ArtifactKind.RIM ? "RIM" : derivationPackage.PackageLocation.ToString(MifCompiler.NAME_FORMAT)), out ss) || ss == null)
                            {
                                System.Diagnostics.Trace.WriteLine(String.Format("Can't find derivation class '{0}' (derivation supplier {1})", cd.ClassName, cd.StaticModelDerivationId), "warn");
                            }
                        }


                        // Attempt to parse
                        MohawkCollege.EHR.gpmr.COR.SubSystem supplierSubSystem = ss as MohawkCollege.EHR.gpmr.COR.SubSystem;

                        // Find the class
                        MohawkCollege.EHR.gpmr.COR.Class supplierClass = classInfo.CompilerRepository[string.Format("{0}.{1}", supplierSubSystem.Name, cd.ClassName)] as MohawkCollege.EHR.gpmr.COR.Class;

                        // Add a realization
                        retVal.Realizations.Add(supplierClass.CreateTypeReference());

                        // Now do some processing
                        foreach (ClassContent cc in supplierClass.Content)
                        {
                            ClassContent rcc = null;

                            // Find the class content we are talking about
                            if (cc is Property)
                            {
                                rcc = retVal.FindMember(cc.Name, true, (cc as MohawkCollege.EHR.gpmr.COR.Property).PropertyType);
                            }
                            else
                            {
                                ; //TODO: Clean up choices so they match the realization class. Not sure if this supposed to be done
                            }
                            // Correct Items
                            if (rcc != null)
                            {
                                if (MohawkCollege.EHR.gpmr.COR.Documentation.IsEmpty(rcc.Documentation))// Correct documentation
                                {
                                    rcc.Documentation = cc.Documentation;
                                }
                                // Removed: This was supposed to correct missing supplier domains from the RMIMs using the RIM data, however it does
                                // cause some issues.
                                //    if (rcc is MohawkCollege.EHR.gpmr.COR.Property && (rcc as MohawkCollege.EHR.gpmr.COR.Property).SupplierDomain == null &&
                                //        (cc as MohawkCollege.EHR.gpmr.COR.Property).SupplierDomain != null)
                                //    {
                                //        (rcc as MohawkCollege.EHR.gpmr.COR.Property).SupplierDomain = (cc as MohawkCollege.EHR.gpmr.COR.Property).SupplierDomain;
                                //        (rcc as MohawkCollege.EHR.gpmr.COR.Property).SupplierStrength = (cc as MohawkCollege.EHR.gpmr.COR.Property).SupplierStrength;
                                //    }
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        System.Diagnostics.Trace.WriteLine(string.Format("Could not find derivation supplier information for {0}", retVal.Name), "warn");
                    }
                }
            }
            #endregion

            #region Correct Vocabulary

            // This is quite a problem, when a property is bound to a value set, and that value set
            // is merely a pointer to other value sets of data we need to correct the pointer
            foreach (var property in retVal.Content)
            {
                // If the content is a property and it has a supplier domain, try to find the supplier domain
                if (property is Property && (property as Property).SupplierDomain != null)
                {
                    // Now to correct the reference
                    if ((property as Property).SupplierDomain.EnumerationReference != null &&
                        (property as Property).SupplierDomain.EnumerationReference.Count == 1)
                    {
                        (property as Property).SupplierDomain = (property as Property).SupplierDomain.EnumerationReference[0];
                    }
                }
            }

            #endregion

            // Sort the class content
            retVal.Content.Sort(new ClassContent.Comparator());

            // Return
            return(retVal);
        }
예제 #14
0
        /// <summary>
        /// Replace references in the class content <paramref name="cc"/> from <paramref name="s"/>
        /// to <paramref name="f"/>
        /// </summary>
        private void ReplaceReferences(Class s, Class f, ClassContent cc)
        {
            string fqnF = String.Format("{0}.{1}", f.ContainerName, f.Name),
                fqnS = String.Format("{0}.{1}", s.ContainerName, s.Name);
            if (cc is Property && (cc as Property).Type.Name == fqnS)
                UpdateReference((cc as Property).Type, fqnS, fqnF);
            else if (cc is Choice)
                foreach (var c in (cc as Choice).Content)
                    ReplaceReferences(s, f, c);

            // Alternate traversals
            if(cc is Property)
                foreach (var alt in (cc as Property).AlternateTraversalNames ?? new List<Property.AlternateTraversalData>())
                    if (alt.CaseWhen.Name.Equals(fqnS))
                    {
                        alt.CaseWhen.Name = fqnF;
                        alt.CaseWhen.MemberOf = s.MemberOf;
                    }

            
        }
예제 #15
0
        /// <summary>
        /// Replace references in the repository from <paramref name="s"/> to 
        /// <paramref name="f"/>
        /// </summary>
        private void ReplaceReferences(Class s, Class f)
        {
            // Get all classes
            var classes = from cls in Repository
                          where cls.Value is Class
                          select cls.Value as Class;
            string fqnF = String.Format("{0}.{1}", f.ContainerName, f.Name),
                fqnS = String.Format("{0}.{1}", s.ContainerName, s.Name);

            // Iterate through classes and update the references
            foreach (var cls in classes)
            {
                // Replace the base class
                if (cls.BaseClass != null && cls.BaseClass.Name == fqnS)
                    cls.BaseClass.Name = fqnF;

                // Replace all references
                foreach (ClassContent cc in cls.Content)
                    ReplaceReferences(s, f, cc);

                // Replace sub classes
                if (cls.SpecializedBy != null)
                {
                    foreach (TypeReference tr in cls.SpecializedBy)
                        UpdateReference(tr, fqnS, fqnF);
                }
            }

            // Iterate through interactions and update any references
            var interactions = from cls in Repository
                               where cls.Value is Interaction 
                               select cls.Value as Interaction;
            foreach (var interaction in interactions)
                UpdateReference(interaction.MessageType, fqnS, fqnF);

            // Iterate through type references (CMETS) and update any referneces
            var cmets = from cls in Repository
                        where cls.Value is CommonTypeReference && (cls.Value as CommonTypeReference).Class.Name == fqnS
                        select cls.Value as CommonTypeReference;
            foreach (var cmet in cmets)
                UpdateReference(cmet.Class, fqnS, fqnF);
                
        }
예제 #16
0
        /// <summary>
        /// Generate a choice structure for all child classes of <paramref name="property"/>
        /// </summary>
        private List<XmlSchemaElement> CreateChoice(Property property, Class cls, List<TypeReference> genericParameters, string prefix, List<string> includedModels, List<TypeReference> additionalCompileTargets)
        {
            List<XmlSchemaElement> retVal = new List<XmlSchemaElement>();

            // Iterate through the child classes
            foreach (TypeReference tr in cls.SpecializedBy)
            {
                if (tr.Class == null) continue; // Not interested in non-implementable classes!
                else if (tr.Class.IsAbstract && tr.Class.SpecializedBy.Count > 0) retVal.AddRange(CreateChoice(property, tr.Class, genericParameters, prefix, includedModels, additionalCompileTargets));

                // Clone the property and set the type reference to what we really want to set it up as
                Property choiceProperty = property.Clone() as Property;
                choiceProperty.MemberOf = property.MemberOf;
                choiceProperty.Type = tr;

                // Generate a choice element for this option
                XmlSchemaElement element = CreateElement(choiceProperty, genericParameters, prefix, includedModels, additionalCompileTargets);
                // Find the correct name for this element
                if (element.Name == property.Name && property.AlternateTraversalNames != null && property.AlternateTraversalNames.Count > 0)
                {
                    MohawkCollege.EHR.gpmr.COR.Property.AlternateTraversalData name = property.AlternateTraversalNames.Find(o => o.CaseWhen.Name == tr.Name &&
                                                                                       (o.InteractionOwner.Name == prefix || prefix == null));
                    if (name.TraversalName != null) element.Name = name.TraversalName;
                }
                else
                    element.Name = tr.Class.Name; 

                retVal.Add(element);
            }

            return retVal;
        }
예제 #17
0
        private string CreateValidateFunction(Class cls)
        {
            StringWriter sw = new StringWriter(),
                swEx = new StringWriter();

            sw.WriteLine("\t\t/// <summary> Validates that the current instance meets conformance rules specified in the model </summary>");
            sw.WriteLine("\t\t/// <returns>True if this instance is valid, false otherwise</returns>");
            sw.WriteLine("\t\t/// <remarks>Provides only basic validation functionality</remarks>");
            sw.WriteLine("\t\tpublic {0} bool Validate() {{\r\n\t\t\tbool isValid = {1};\r\n\t\t\tif(!isValid) return false;",
                "RIM." + Util.Util.PascalCase(cls.Name) == RimbaCsRenderer.RootClass ? "virtual" : "override", "RIM." + Util.Util.PascalCase(cls.Name) == RimbaCsRenderer.RootClass ? "true" : "base.Validate()");

            
            swEx.WriteLine("\t\t/// <summary> Validates that the current instance meets conformance rules specified in the model returning the detected errors</summary>");
            swEx.WriteLine("\t\t/// <returns>A list of detected errors</returns>");
            swEx.WriteLine("\t\t/// <remarks>Provides only basic validation functionality</remarks>");
            swEx.WriteLine("\t\tpublic {0} IEnumerable<MARC.Everest.Connectors.IResultDetail> ValidateEx() {{\r\n\t\t\tList<MARC.Everest.Connectors.IResultDetail> retVal = {1};",
                "RIM." + Util.Util.PascalCase(cls.Name) == RimbaCsRenderer.RootClass ? "virtual" : "override", "RIM." + Util.Util.PascalCase(cls.Name) == RimbaCsRenderer.RootClass ? "new List<MARC.Everest.Connectors.IResultDetail>()" : "base.ValidateEx() as List<MARC.Everest.Connectors.IResultDetail>");

            // Write the validation function
            foreach (ClassContent cc in cls.Content)
            {
                string pCasedName = String.Empty;
                if (cc is Property)
                {
                    pCasedName = CreatePascalCasedName(cc as Property);

                    TypeReference tr = Datatypes.MapDatatype((cc as Property).Type);
                    string dt = CreateDatatypeRef(tr, cc as Property);

                }
                else
                {
                    if ((cc as Choice).Content.Count == 0)
                    {
                        Trace.WriteLine("Skipping validation for choice element with no choices", "warn");
                        continue;
                    }
                    
                    pCasedName = CreatePascalCasedName(cc as Choice);
                }

                // If this property is mandatory or populated then it must have a valid value
                if (cc.Conformance == ClassContent.ConformanceKind.Mandatory || cc.Conformance == ClassContent.ConformanceKind.Populated)
                {
                    if (cc.MaxOccurs != "1")
                    {
                        sw.WriteLine("\t\t\tisValid &= this.{0} != null && this.{0}.Count <= {1} && this.{0}.Count >= {2};", pCasedName, cc.MaxOccurs == "*" ? "int.MaxValue" : cc.MaxOccurs, cc.MinOccurs);
                        swEx.WriteLine("\t\t\tif(!(this.{0} != null && this.{0}.Count <= {1} && this.{0}.Count >= {2}))  retVal.Add(new MARC.Everest.Connectors.InsufficientRepetitionsResultDetail(MARC.Everest.Connectors.ResultDetailType.Error, \"{0} must have between {2} and {1} elements\", \"{0}\")); ", pCasedName, cc.MaxOccurs == "*" ? "int.MaxValue" : cc.MaxOccurs, cc.MinOccurs);
                    }
                    else
                    {
                        sw.WriteLine("\t\t\t#region Validate {0}", pCasedName);
                        sw.WriteLine("\t\t\tif(this.{0} == null) return false; // automatically not valid", pCasedName);
                        sw.WriteLine("\t\t\telse {");
                        sw.WriteLine("\t\t\t\tSystem.Reflection.MethodInfo mi = this.{0}.GetType().GetMethod(\"Validate\");", pCasedName);
                        sw.WriteLine("\t\t\t\tisValid &= (mi != null) ? ((bool)mi.Invoke(this.{0}, null)) : true;", pCasedName);
                        sw.WriteLine("\t\t\t}");
                        sw.WriteLine("\t\t\t#endregion");

                        swEx.WriteLine("\t\t\t#region Validate {0}", pCasedName); 
                        swEx.WriteLine("\t\t\tif(this.{0} == null) retVal.Add(new MARC.Everest.Connectors.MandatoryElementMissingResultDetail(MARC.Everest.Connectors.ResultDetailType.Error, \"{0} does not meet criteria for {1} element\", \"{0}\"));", pCasedName, cc.Conformance);
                        swEx.WriteLine("\t\t\telse {");
                        swEx.WriteLine("\t\t\t\tSystem.Reflection.MethodInfo mi = this.{0}.GetType().GetMethod(\"ValidateEx\");", pCasedName);
                        swEx.WriteLine("\t\t\t\tif(mi != null) {{ foreach(var res in (IEnumerable<MARC.Everest.Connectors.IResultDetail>)mi.Invoke(this.{0}, null)) {{ \r\n\t\t\t\t if(res.Location != null) res.Location = \"{0}.\" + res.Location; \r\n\t\t\t\t else res.Location = \"{0}\"; \r\n\t\t\t\t retVal.Add(res); \r\n\t\t\t }} \r\n\t\t\t }} ", pCasedName);
                        swEx.WriteLine("\t\t\t}");
                        swEx.WriteLine("\t\t\t#endregion");

                    }
                }
            }

            sw.WriteLine("\t\t\treturn isValid;\r\n\t\t}");
            swEx.WriteLine("\t\t\treturn retVal;\r\n\t\t}");
            sw.WriteLine("\r\n\r\n{0}", swEx);
            return sw.ToString();
        }
예제 #18
0
 /// <summary>
 /// Gets a common backing type for a particular property type reference through children
 /// Handles when data types change through child implementations ( handled by .NET via NEW )
 /// </summary>
 private TypeReference GetBackingFieldTypeThroughChildren(Property property, Class searchClass)
 {
     TypeReference initialType = property.Type;
     foreach (var child in searchClass.SpecializedBy) // iterate through children
     {
         var childProp = child.Class.Content.Find(o => o.Name == property.Name);
         if (childProp is Property)
         {
             TypeReference candidate = GetBackingFieldTypeThroughChildren(childProp as Property, child.Class);
             if (!candidate.Name.Equals(initialType.Name))
                 initialType = new TypeReference() { Name = null };
         }
     }
     return initialType;
 }
예제 #19
0
 /// <summary>
 /// Create the structure annotation
 /// </summary>
 private string CreateStructureAnnotation(Class cls)
 {
     return String.Format("@Structure(name = \"{0}\", structureType = StructureType.MESSAGETYPE, isEntryPoint = {1}, model =\"{2}\", publisher = {3})", cls.Name, cls.ContainerPackage.EntryPoint.Exists(o => o.Name == cls.Name) ? "true" : "false", cls.ContainerName, cls.Documentation != null ? "\"" + cls.Documentation.Copyright + "\"" : "Structure.NULL");
 }
예제 #20
0
        /// <summary>
        /// Create the equality method
        /// </summary>
        private string CreateEqualityMethod(Class cls)
        {

            string genericString = "";
            foreach (TypeParameter tp in cls.TypeParameters ?? new List<TypeParameter>())
                genericString += tp + ",";
            if (!String.IsNullOrEmpty(genericString))
                genericString = genericString.Substring(0, genericString.Length - 1);

            string dataReference = String.Format("{0}{1}",
                    Util.Util.PascalCase(cls.Name),
                    String.IsNullOrEmpty(genericString) ? "" : String.Format("<{0}>", genericString)
                );

            StringWriter swEquals = new StringWriter(),
                swHash = new StringWriter();

            // Method signatures
            swEquals.WriteLine("\t\t/** Overload of the equality determiner */\r\n\t\tpublic boolean equals({0} other)\r\n\t\t{{\r\n\t\t\tboolean equal = true;",
                dataReference
            );
            swHash.WriteLine("\t\t/** Overload of hash code */\r\n\t\t@Override\r\n\t\tpublic int hashCode()\r\n\t\t{");
            swHash.WriteLine("\t\tint result = 31;");

            swEquals.WriteLine("\t\t\tif(other != null) {");
            foreach (var prop in cls.Content)
            {
                if (prop is Property)
                {
                    if (prop.MaxOccurs == "1" ||
                        (prop as Property).Type.CoreDatatypeName != null && Datatypes.IsCollectionType((prop as Property).Type))
                        swEquals.WriteLine("\t\t\t\tequal &= this.get{0}() != null ? this.get{0}().equals(other.get{0}()) : other.get{0}() == null;", Util.Util.PascalCase(prop.Name));
                    else
                    {
                        swEquals.WriteLine("\t\t\t\tequal &= this.get{0}().size() == other.get{0}().size();", Util.Util.PascalCase(prop.Name));
                        swEquals.WriteLine("\t\t\t\tfor(int i = 0; i < (equal ? this.get{0}().size() : 0); i++) equal &= this.get{0}().get(i) != null ? this.get{0}().get(i).equals(other.get{0}().get(i)) : other.get{0}().get(i) == null;", Util.Util.PascalCase(prop.Name));
                    }
                    swHash.WriteLine("result = 17 * result + ((this.get{0}() == null) ? 0 : this.get{0}().hashCode());", Util.Util.PascalCase(prop.Name));
                }
                else
                {
                    if ((prop as Choice).Content.Count == 0)
                    {
                        Trace.WriteLine("Skipping equality check for choice with 0 choice elements", "warn");
                        continue;
                    }
                    swEquals.WriteLine("\t\t\t\tequal &= this.get{0}() != null ? this.get{0}().equals(other.get{0}()) : other.get{0}() == null;", Util.Util.PascalCase(prop.Name));
                    swHash.WriteLine("result = 17 * result + ((this.get{0}() == null) ? 0 : this.get{0}().hashCode());", Util.Util.PascalCase(prop.Name));
                }
            }
            swEquals.WriteLine("\t\t\t\treturn equal;");
            swEquals.WriteLine("\t\t\t}");
            swEquals.WriteLine("\t\t\treturn false;");
            swEquals.WriteLine("\t\t}");
            swEquals.WriteLine("\t\t/** Overload of the equality determiner*/\r\n\t\t@Override\r\n\t\tpublic boolean equals(Object obj)\r\n\t\t{");

            // Replace Subject<Act> with Subject<?>
            if (cls.TypeParameters != null && cls.TypeParameters.Count > 0)
                dataReference = Util.Util.PascalCase(cls.Name);

            swEquals.WriteLine("\t\t\tif(obj instanceof {0}) return this.equals(({0})obj);", dataReference);
            swEquals.WriteLine("\t\t\treturn super.equals(obj);");
            swEquals.WriteLine("\t\t}");


            swHash.WriteLine("\t\t\treturn result;\r\n\t\t}");

            return String.Format("{0}\r\n{1}", swEquals.ToString(), swHash.ToString());
        }
예제 #21
0
        private TypeReference GenerateCombinedType(List<TypeReference> matching)
        {
            Class generatedClass = new Class();
            generatedClass.Name = "";
            generatedClass.MemberOf = matching[0].Class.MemberOf;
            generatedClass.ContainerPackage = (matching[0].Class as Class).ContainerPackage;
            generatedClass.Content = new List<ClassContent>();

            // Combine everything
            foreach (var t in matching)
            {
                generatedClass.Name += t.Class.Name;
                List<Property> elements = FlattenPropertyHierarchy(t.Class.Content);
                int order = 0;
                foreach (var ele in elements)
                {
                    Property clonedElement = ele.Clone() as Property, 
                        currentGeneratedElement = generatedClass.Content.Find(o => o.Name == ele.Name) as Property; // clone the property
                    clonedElement.Container = generatedClass;
                    if (ele.Container is Choice)
                        clonedElement.Realization = (ele.Container as Choice).Realization;


                    if (currentGeneratedElement == null) // Doesn't already exist!
                        generatedClass.Content.Insert(order, clonedElement);
                    else if (currentGeneratedElement != null && currentGeneratedElement.Type.Name != ele.Type.Name && ele.Type.Class != null) // a property with the same name but with different type exists
                        // Combine those classes
                        currentGeneratedElement.Type = GenerateCombinedType(new List<TypeReference>() { currentGeneratedElement.Type, ele.Type });
                    order++;
                }
            }
            return generatedClass.CreateTypeReference();
        }
예제 #22
0
        /// <summary>
        /// Collapse the data type of <paramref name="cc"/> so that it is the only meaningful data type provided by its 
        /// natural type
        /// </summary>
        private void CollapseMemberType(ClassContent cc, Class context)
        {
            if(!(cc is Property)) throw new InvalidOperationException("Can't collapse this member type"); // Not a candidate

            // The condition for this type of collection is that the referenced type:
            //  1. Provides only ONE property (after --collapse-ignore are removed)
            //  2. The ONE property is mandatory (must be provided)
            List<ClassContent> content = (cc as Property).Type.Class.GetFullContent();
            content.RemoveAll(a => CorCollapserPipelineTrigger.collapseIgnore.Contains(a.Name)); // Remove the ignore

            if (CorCollapserPipelineTrigger.collapseIgnoreFixed)
                content.RemoveAll(o => o is Property && !String.IsNullOrEmpty((o as Property).FixedValue) && (o as Property).PropertyType == Property.PropertyTypes.Structural);

            if(content.Count != 1) throw new InvalidOperationException("Can't collapse type with more than one meaningful content"); // can't collapse this relation as there is more than sub-property
            ClassContent candidate = content[0];

            cc.Annotations.Add(new CodeCollapseAnnotation() { Name = cc.Name, Order = 0, Property = cc as Property });

            // Has this collapsed member had any collapsing
            if (candidate.Annotations.Count > 0)
            {
                // Get all code collapse annotations from the candidate
                List<Annotation> collapseAnnotations = candidate.Annotations.FindAll(o => o is CodeCollapseAnnotation);
                // Find one that links it to the candidate

                //collapseAnnotations.RemoveAll(o => candidate.Annotations.Count(ca => (ca as CodeCollapseAnnotation).Property == (o as CodeCollapseAnnotation).Property) != 1);

                CodeCollapseAnnotation oldCca = null;
                foreach (CodeCollapseAnnotation cca in collapseAnnotations)
                {
                    cca.Order = cc.Annotations.Count;
                    if (cc.Annotations.Count(ca =>ca is CodeCollapseAnnotation && (ca as CodeCollapseAnnotation).Property == cca.Property) == 0)
                        cc.Annotations.Add(cca);
                    oldCca = cca;
                }
                
            }
            else
                cc.Annotations.Add(new CodeCollapseAnnotation() { Name = candidate.Name, Order = 1, Property = candidate as Property });


            // Determine a better name
            if (CorCollapserPipelineTrigger.collapseSpecialNaming)
            {
                // We collapse the collapsee's name into the parent by default.
                string preferredName = candidate.Name;

                // If the container for the property already has an element by the name we prefer, we must 
                // or the collapsee's name is in the useless words list we must keep the current name, or if the 
                // parent's name is in the structurally important collection
                if((cc.Container as Class).GetFullContent().Find(o=>o.Name == preferredName) != null || CorCollapserPipelineTrigger.uselessWords.Contains(preferredName)
                    || CorCollapserPipelineTrigger.importantWords.Contains(cc.Name))
                    preferredName = cc.Name;

                cc.Name = preferredName;
            }

            // Now determine if we can collapse
            (cc as Property).Type = (candidate as Property).Type.Clone() as TypeReference;
            (cc as Property).SupplierDomain = (candidate as Property).SupplierDomain;
            (cc as Property).SupplierStrength = (candidate as Property).SupplierStrength;
            (cc as Property).Type.Container = cc;
            (cc as Property).Type.MemberOf = cc.MemberOf;

            // Update documentation
            if((cc as Property).Documentation == null && 
                candidate.Documentation != null)
                (cc as Property).Documentation = candidate.Documentation;

        }