Пример #1
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);
            }
        }
Пример #2
0
 /// <summary>
 /// Create a cardinality change
 /// </summary>
 private void CreateCardinalityChange(Feature feature, Constraint constraint)
 {
     #region Cardinality Change
     // 1. Validate constraint & target
     CardinalityConstraintValue ccv = constraint.Value as CardinalityConstraintValue;
     ClassContent ccFeature         = feature as ClassContent;
     if (ccFeature == null)
     {
         Trace.WriteLine(String.Format("Delta: Cannot apply cardinality constraint against a feature of type '{0}', skipping...", feature.GetType().Name), "error");
         return;
     }
     // 2. Validate existing data
     if ((ccv.OriginalMaxValue.HasValue ? ccv.OriginalMaxValue.ToString() != ccFeature.MaxOccurs : ccFeature.MaxOccurs != "*") ||
         (ccv.OriginalMinValue.HasValue ? ccv.OriginalMinValue.ToString() != ccFeature.MinOccurs : ccFeature.MaxOccurs != null))
     {
         Trace.WriteLine(String.Format("Delta: Applying cardinality constraint on '{0}' even though original Min/Max occurs do not match!", feature.Name), "warn");
     }
     // 3. Validate that the cardinality doesn't already exist
     if (ccFeature.Annotations.Exists(o => o is CardinalityConstraintAnnotation && (o as CardinalityConstraintAnnotation).RealmCode == this.m_deltaSet.Realm.Code))
     {
         Trace.WriteLine(String.Format("Delta: Cardinality constraint has already been applied to '{0}'", feature.Name), "error");
         return;
     }
     // 4. Append the annotation
     ccFeature.Annotations.Add(new CardinalityConstraintAnnotation()
     {
         ChangeType = ChangeType.Edit,
         RealmCode  = this.m_deltaSet.Realm.Code,
         MaxOccurs  = ccv.NewMaxValue.HasValue ? ccv.NewMaxValue.Value.ToString() : "*",
         MinOccurs  = ccv.NewMinValue.HasValue ? ccv.NewMinValue.Value.ToString() : null,
         RealmName  = this.m_deltaSet.MetaData.Description
     });
     #endregion
 }
Пример #3
0
        public List <String> GetTypes(Schema Schema)
        {
            var Primitives = GetPrimitives(Schema);

            var NamespaceToClasses = new Dictionary <String, List <List <String> > >();

            void AddClass(String ClassNamespaceName, IEnumerable <String> ClassContent)
            {
                if (!NamespaceToClasses.ContainsKey(ClassNamespaceName))
                {
                    NamespaceToClasses.Add(ClassNamespaceName, new List <List <String> >());
                }
                NamespaceToClasses[ClassNamespaceName].Add(ClassContent.ToList());
            }

            foreach (var c in Schema.Types)
            {
                if (c.OnPrimitive)
                {
                    continue;
                }
                else if (c.OnAlias)
                {
                    AddClass(c.NamespaceName(), Alias(c.Alias));
                }
                else if (c.OnRecord)
                {
                    AddClass(c.NamespaceName(), Record(c.Record));
                }
                else if (c.OnTaggedUnion)
                {
                    AddClass(c.NamespaceName(), TaggedUnion(c.TaggedUnion));
                }
                else if (c.OnEnum)
                {
                    AddClass(c.NamespaceName(), Enum(c.Enum));
                }
                else if (c.OnClientCommand)
                {
                }
                else if (c.OnServerCommand)
                {
                }
                else
                {
                    throw new InvalidOperationException();
                }
            }

            if (NamespaceToClasses.Count > 1)
            {
                throw new NotSupportedException("PythonMultipleNamespace"); //Python不支持nested class import
            }

            var Classes = NamespaceToClasses.Select(p => p.Value.Join(new String[] { "" }));

            return((new List <List <String> > {
                Primitives
            }).Concat(Classes).Join(new String[] { "" }).ToList());
        }
Пример #4
0
        /// <summary>
        /// Determine if the class content is a candidate for collapsing
        /// </summary>
        private bool IsCandidateForTypeCollapse(ClassContent cc)
        {
            // Candidates must be a property with 0..1 and must be
            // traversable in nature.
            if (cc.MaxOccurs != "1" || !(cc is Property) ||
                (cc as Property).PropertyType != Property.PropertyTypes.TraversableAssociation ||
                cc.MinOccurs != "0")
            {
                return(false);
            }

            // Determine the conformance meets criteria
            if ((cc.Conformance == ClassContent.ConformanceKind.Optional || cc.Conformance == ClassContent.ConformanceKind.Required) &&
                !QueryConformance((cc as Property).Type, ClassContent.ConformanceKind.Optional | ClassContent.ConformanceKind.Required))
            {
                return(false);
            }
            else if (cc.Conformance == ClassContent.ConformanceKind.Populated)
            {
                return(false);
            }

            // Make sure none of the child member names appear in the parent class they are to be merged with
            bool isCandidate = CountReferences((cc as Property).Type) == 1;

            foreach (ClassContent content in (cc.Container as Class).Content)
            {
                isCandidate &= HasMember((cc as Property).Type, content.Name);
            }
            // Now we must determine if there are no other references to the class to be collapsed
            return(isCandidate);
        }
Пример #5
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;
                    }
                }
            }
        }
Пример #6
0
        public List <String> GetTypes(Schema Schema)
        {
            var NamespaceName = Schema.Types.Concat(Schema.TypeRefs).Where(t => !t.OnPrimitive).FirstOrDefault()?.NamespaceName() ?? "";

            var Primitives = GetPrimitives(Schema);

            var NamespaceToClasses = new Dictionary <String, List <List <String> > >();

            void AddClass(String ClassNamespaceName, IEnumerable <String> ClassContent)
            {
                if (!NamespaceToClasses.ContainsKey(ClassNamespaceName))
                {
                    NamespaceToClasses.Add(ClassNamespaceName, new List <List <String> >());
                }
                NamespaceToClasses[ClassNamespaceName].Add(ClassContent.ToList());
            }

            AddClass(NamespaceName, Streams());

            AddClass(NamespaceName, BinaryTranslator(Schema, NamespaceName));

            if (NamespaceToClasses.Count > 1)
            {
                throw new NotSupportedException("PythonMultipleNamespace"); //Python不支持nested class import
            }

            var Classes = NamespaceToClasses.Select(p => p.Value.Join(new String[] { "" }));

            return((new List <List <String> > {
                Primitives
            }).Concat(Classes).Join(new String[] { "" }).ToList());
        }
Пример #7
0
        /// <summary>
        /// Apply delta against a property
        /// </summary>
        private void ApplyDelta(ClassContent property, RelationshipDeltaData delta)
        {
            Trace.WriteLine(string.Format("Delta: Applying deltas for '{0}.{1}'...", property.Container.Name, property.Name), "debug");

            // Apply constraints
            foreach (var constraint in delta.Constraint)
            {
                ApplyConstraint(property, constraint);
            }
        }
Пример #8
0
        /// <summary>
        /// Create a remove change delta
        /// </summary>
        private void CreateRemoveChange(Feature feature, Constraint constraint)
        {
            #region Remove Change
            // 1. Find the feature that is to be removed
            Feature               removeFeature = null;
            ClassContent          pFeature      = feature as ClassContent;
            RemoveConstraintValue rcv           = constraint.Value as RemoveConstraintValue;
            if (rcv.RelationshipName == feature.Name)
            {
                removeFeature = feature;
            }
            else if (!String.IsNullOrEmpty(rcv.OwnedEntryPoint) && !String.IsNullOrEmpty(rcv.ClassName))
            {
                if (feature is Property)
                {
                    var ssContainer = ((feature as Property).Container as Class).ContainerPackage;
                    if (ssContainer != null && ssContainer.Name.Equals(rcv.OwnedEntryPoint))
                    {
                        removeFeature = ssContainer.OwnedClasses.Find(o => o.Name.Equals(rcv.ClassName));
                    }
                }
            }

            // 2. Validate the feature
            if (removeFeature == null)
            {
                Trace.WriteLine(String.Format("Delta: Cannot apply remove constraint on '{0}.{1}{2}' as the path was not found...",
                                              rcv.OwnedEntryPoint, rcv.ClassName, rcv.RelationshipName == null ? "" : "." + rcv.RelationshipName), "error");
                return;
            }

            // 3. Apply the remove constraint
            if (removeFeature.Annotations.Exists(o => o is RemoveConstraintAnnotation && (o as RemoveConstraintAnnotation).RealmCode == this.m_deltaSet.Realm.Code))
            {
                Trace.WriteLine(String.Format("Delta: Conformance constraint has already been applied to '{0}'", feature.Name), "error");
                return;
            }
            removeFeature.Annotations.Add(
                new RemoveConstraintAnnotation()
            {
                ChangeType = ChangeType.Remove,
                RealmCode  = this.m_deltaSet.Realm.Code,
                RealmName  = this.m_deltaSet.MetaData.Description
            }
                );

            // 4. Remove the supported constraint
            removeFeature.Annotations.RemoveAll(o => o is SupportedConstraintAnnotation && (o as SupportedConstraintAnnotation).RealmCode == this.m_deltaSet.Realm.Code);

            #endregion
        }
Пример #9
0
        public List <String> GetTypes(Schema Schema, String NamespaceName)
        {
            var Primitives = GetPrimitives(Schema);

            var NamespaceToClasses = new List <KeyValuePair <String, List <List <String> > > >();

            void AddClass(String ClassNamespaceName, IEnumerable <String> ClassContent)
            {
                if ((NamespaceToClasses.Count > 0) && (NamespaceToClasses[NamespaceToClasses.Count - 1].Key == ClassNamespaceName))
                {
                    NamespaceToClasses[NamespaceToClasses.Count - 1].Value.Add(ClassContent.ToList());
                }
                else
                {
                    NamespaceToClasses.Add(new KeyValuePair <String, List <List <String> > >(ClassNamespaceName, new List <List <String> > {
                        ClassContent.ToList()
                    }));
                }
            }

            AddClass(NamespaceName, Streams());
            AddClass(NamespaceName, BinaryTranslator(Schema, NamespaceName));

            var Commands = Schema.Types.Where(t => t.OnClientCommand || t.OnServerCommand).ToList();

            if (Commands.Count > 0)
            {
                var SchemaClosureGenerator = Schema.GetSchemaClosureGenerator();
                var Hash = SchemaClosureGenerator.GetSubSchema(Schema.Types.Where(t => (t.OnClientCommand || t.OnServerCommand) && t.Version() == ""), new List <TypeSpec> {
                }).GetNonattributed().Hash();
                if (WithServer)
                {
                    AddClass(NamespaceName, BinarySerializationServer(Hash, Commands, SchemaClosureGenerator, NamespaceName));
                }
                if (WithClient)
                {
                    AddClass(NamespaceName, IBinarySender());
                    AddClass(NamespaceName, BinarySerializationClient(Hash, Commands, SchemaClosureGenerator, NamespaceName));
                }
            }

            var Classes = NamespaceToClasses.Select(p => WrapNamespace(p.Key, p.Value.Join(new String[] { "" })));

            return((new List <List <String> > {
                Primitives
            }).Concat(Classes).Join(new String[] { "" }).ToList());
        }
Пример #10
0
        /// <summary>
        /// Count references of the type in the specified class content
        /// </summary>
        private int CountReferences(ClassContent cc, TypeReference tr)
        {
            int             retVal = 0;
            FeatureComparer fc     = new FeatureComparer();

            if (cc is Property && fc.CompareTypeReference((cc as Property).Type, tr) == 0)
            {
                retVal++;
            }
            else if (cc is Choice)
            {
                foreach (ClassContent scc in (cc as Choice).Content)
                {
                    retVal += CountReferences(scc, tr);
                }
            }
            return(retVal);
        }
Пример #11
0
        /// <summary>
        /// Create a conformance change annotation
        /// </summary>
        private void CreateConformanceChange(Feature feature, Constraint constraint)
        {
            #region Conformance Change
            // 1. Validate the constraint is against a property
            ClassContent pFeature = feature as ClassContent;
            if (pFeature == null)
            {
                Trace.WriteLine(String.Format("Delta: Conformance constraint cannot be applied against a '{1}' named '{0}'", feature.Name, feature.GetType().Name), "error");
                return;
            }

            // 2. Validate the conformance old value is in fact a match
            ConstraintValue <String> stConstraint = constraint.Value as ConstraintValue <string>;
            if (stConstraint == null || stConstraint.Original.ToLower() != pFeature.Conformance.ToString().ToLower())
            {
                Trace.WriteLine(String.Format("Delta: Conformance constraint cannot be applied because the original value of '{0}' does not match the actual original property conformance of '{1}'",
                                              stConstraint.Original.ToLower(), pFeature.Conformance.ToString().ToLower()), "error");
                return;
            }

            // Map the SCREAMING CAPS to ScreamingCaps
            string friendlyValue = String.Format("{0}{1}", stConstraint.New[0], stConstraint.New.Substring(1).ToLower());
            if (friendlyValue == "Not_allowed")
            {
                friendlyValue = "NotAllowed";
            }
            // 3. Verify a constraint for the same jurisdication has not already been added
            if (feature.Annotations.Exists(o => o is ConformanceConstraintAnnotation && (o as ConformanceConstraintAnnotation).RealmCode == this.m_deltaSet.Realm.Code))
            {
                Trace.WriteLine(String.Format("Delta: Conformance constraint has already been applied to '{0}'", feature.Name), "error");
                return;
            }

            feature.Annotations.Add(
                new ConformanceConstraintAnnotation()
            {
                NewValue   = (Property.ConformanceKind)Enum.Parse(typeof(Property.ConformanceKind), friendlyValue),
                ChangeType = ChangeType.Edit,
                RealmCode  = this.m_deltaSet.Realm.Code,
                RealmName  = this.m_deltaSet.MetaData.Description
            }
                );
            #endregion
        }
Пример #12
0
 /// <summary>
 /// Class content comparer
 /// </summary>
 private int CompareContent(ClassContent x, ClassContent y)
 {
     // Name must match
     if (!x.Name.Equals(y.Name))
     {
         return(x.Name.CompareTo(y.Name));
     }
     else if (!x.GetType().Equals(y.GetType())) // must be the same type of content
     {
         return(-1);
     }
     else if (x is Property) // We have already asserted that x and y must be the same type
     {
         return(CompareProperty(x as Property, y as Property));
     }
     else if (x is Choice) // Compare choice
     {
         return(CompareChoice(x as Choice, y as Choice));
     }
     return(0);
 }
Пример #13
0
        /// <summary>
        /// Is this a candidate for collapsing meaningless complexity
        /// </summary>
        private bool IsCandidateForMeaninglessComplexityCollapse(ClassContent cc)
        {
            if (!(cc is Property) || (cc as Property).Type.Class == null)
            {
                return(false);                                                         // 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)
            {
                return(false);                    // can't collapse this relation as there is more than sub-property
            }
            ClassContent candidate = content[0];

            // Is this a generic parameter
            if ((candidate.Container as Class).TypeParameters != null && (cc.Container as Class).TypeParameters.Find(o => o.ParameterName == (candidate as Property).Type.Name) != null)
            {
                return(false);
            }

            // Now determine if we can collapse
            return((candidate.Conformance == ClassContent.ConformanceKind.Mandatory ||
                    candidate.Conformance >= cc.Conformance ||
                    (cc.Conformance <= ClassContent.ConformanceKind.Required &&
                     candidate.Conformance == ClassContent.ConformanceKind.Populated)) && // Experiment: && candidate.Conformance != ClassContent.ConformanceKind.Populated)
                   candidate.MaxOccurs == "1" &&
                   candidate is Property);
        }
Пример #14
0
        public List <String> GetTypes(Schema Schema, String NamespaceName)
        {
            var Primitives = GetPrimitives(Schema);

            var NamespaceToClasses = new Dictionary <String, List <List <String> > >();

            void AddClass(String ClassNamespaceName, IEnumerable <String> ClassContent)
            {
                if (!NamespaceToClasses.ContainsKey(ClassNamespaceName))
                {
                    NamespaceToClasses.Add(ClassNamespaceName, new List <List <String> >());
                }
                NamespaceToClasses[ClassNamespaceName].Add(ClassContent.ToList());
            }

            var Commands = Schema.Types.Where(t => t.OnClientCommand || t.OnServerCommand).ToList();

            if (Commands.Count > 0)
            {
                var SchemaClosureGenerator = Schema.GetSchemaClosureGenerator();
                var Hash = SchemaClosureGenerator.GetSubSchema(Schema.Types.Where(t => (t.OnClientCommand || t.OnServerCommand) && t.Version() == ""), new List <TypeSpec> {
                }).GetNonattributed().Hash();
                AddClass(NamespaceName, JsonSerializationServer(Hash, Commands, SchemaClosureGenerator, NamespaceName));
                AddClass(NamespaceName, IJsonSender());
                AddClass(NamespaceName, JsonSerializationClient(Hash, Commands, SchemaClosureGenerator, NamespaceName));
                AddClass(NamespaceName, JsonLogAspectWrapper(Commands, NamespaceName));
            }

            AddClass(NamespaceName, JsonTranslator(Schema, NamespaceName));

            var Classes = NamespaceToClasses.Select(p => Inner.WrapNamespace(p.Key, p.Value.Join(new String[] { "" })));

            return((new List <List <String> > {
                Primitives
            }).Concat(Classes).Join(new String[] { "" }).ToList());
        }
Пример #15
0
        /// <summary>
        /// Query conformance
        /// </summary>
        private bool QueryConformance(TypeReference typeReference, ClassContent.ConformanceKind p)
        {
            if(typeReference.Class == null) return false;
            bool retVal = true;
            // Class content
            foreach (ClassContent cc in typeReference.Class.GetFullContent())
                if (cc is Property)
                    retVal &= ((cc.Conformance & p) == cc.Conformance);
                else if (cc is Choice)
                    retVal &= QueryConformance(cc as Choice, typeReference, p);

            return retVal;
        }
Пример #16
0
 /// <summary>
 /// Count references of the type in the specified class content
 /// </summary>
 private int CountReferences(ClassContent cc, TypeReference tr)
 {
     int retVal = 0;
     FeatureComparer fc = new FeatureComparer();
     if (cc is Property && fc.CompareTypeReference((cc as Property).Type, tr) == 0)
         retVal++;
     else if (cc is Choice)
         foreach (ClassContent scc in (cc as Choice).Content)
             retVal += CountReferences(scc, tr);
     return retVal;
         
 }
Пример #17
0
 /// <summary>
 /// Query the conformance for a choice
 /// </summary>
 private bool QueryConformance(Choice chc, TypeReference typeReference, ClassContent.ConformanceKind p)
 {
     bool retVal = true;
     foreach (ClassContent cc in chc.Content)
         if (cc is Property)
             retVal &= ((cc.Conformance & p) == cc.Conformance);
         else if (cc is Choice)
             retVal &= QueryConformance(cc as Choice, typeReference, p);
     return retVal;
 }
Пример #18
0
        /// <summary>
        /// Render property attribute
        /// </summary>
        private String RenderPropertyAttribute(ClassContent cc, string ownerPackage, int propertySort)
        {

            StringWriter retBuilder = new StringWriter();

            // Represent as an option
            Choice options = cc as Choice;
            if(options == null)
                options = new Choice() {
                    Content = new List<ClassContent>() { cc as Property }
                };

            // Traversal names already rendered
            List<string> alreadyRendered = new List<string>();


            // Iterate through choices
            foreach (Property property in options.Content)
            {
                // Enumerator for alt-traversals
                List<Property.AlternateTraversalData> altTraversal = new List<Property.AlternateTraversalData>();

                altTraversal.Add(new Property.AlternateTraversalData() { CaseWhen = property.Type, TraversalName = property.Name });
                // Alternatives
                if (property.AlternateTraversalNames != null)
                    foreach (Property.AlternateTraversalData kv in property.AlternateTraversalNames)
                        altTraversal.Add(kv);

                // Write properties
                foreach (Property.AlternateTraversalData kv in altTraversal)
                {

                    // Datatype
                    TypeReference tr = Datatypes.MapDatatype(kv.CaseWhen);

                    string key = string.Format("{0}.{1}.{2}.{3}", ownerPackage, tr.Name, kv.TraversalName, kv.InteractionOwner != null ? kv.InteractionOwner.Name : "");

                    // Already rendered
                    if (!alreadyRendered.Contains(key))
                    {
                        retBuilder.Write("\t@Property(name = \"{0}\", conformance = ConformanceType.{1}, propertyType = PropertyType.{2}, sortKey = {3}",
                            kv.TraversalName, cc.Conformance.ToString().ToUpper(), (options.Content[0] as Property).PropertyType.ToString().ToUpper(), propertySort);

                        // Now a type hint
                        if (tr.Class != null && (property.Container is Choice || property.AlternateTraversalNames != null))
                            retBuilder.Write(", type = {0}.class", CreateDatatypeRef(tr, property, ownerPackage));

                        // Now for an interaction hint
                        if (tr.Class != null && (property.Container is Choice || property.AlternateTraversalNames != null) && kv.InteractionOwner != null)
                            retBuilder.Write(", interactionOwner = {0}.interaction.{1}.class", ownerPackage, kv.InteractionOwner.Name);
                        // Impose a flavor?
                        if (tr.Flavor != null)
                            retBuilder.Write(", imposeFlavorId = \"{0}\"", tr.Flavor);

                        // Is this a set?
                        if (property.MaxOccurs != "1")
                            retBuilder.Write(", minOccurs = {0}, maxOccurs = {1}", property.MinOccurs, property.MaxOccurs == "*" ? "-1" : property.MaxOccurs);
                        if (property.MinLength != null)
                            retBuilder.Write(", minLength = {0}", property.MinLength);
                        if (property.MaxLength != null)
                            retBuilder.Write(", maxLength = {0}", property.MaxLength);

                        // Is there an update mode
                        //if (property.UpdateMode != null)
                        //    retBuilder.Write(", defaultUpdateMode = UpdateMode.{0}", property.UpdateMode);

                        // Is there a supplier domain?
                        if (property.SupplierDomain != null &&
                            property.SupplierStrength == MohawkCollege.EHR.gpmr.COR.Property.CodingStrengthKind.CodedNoExtensions)
                            retBuilder.Write(", supplierDomain = \"{0}\"", (property.SupplierDomain.ContentOid));

                        // Fixed value
                        if (!String.IsNullOrEmpty(property.FixedValue))
                            retBuilder.Write(", fixedValue = \"{0}\"", property.FixedValue);

                        // generic supplier
                        if (property.Type != null && property.Type.GenericSupplier != null &&
                            property.Type.GenericSupplier.Count > 0)
                        {
                            retBuilder.Write(", genericSupplier = {");
                            foreach (var genSupp in property.Type.GenericSupplier)
                                if((property.Container as Class).TypeParameters == null ||
                                    !(property.Container as Class).TypeParameters.Exists(o=>o.Name == genSupp.Name))
                                    retBuilder.Write("{0}.class{1}", CreateDatatypeRef(genSupp, property, ownerPackage, false), genSupp == property.Type.GenericSupplier.Last() ? "" : ",");
                            retBuilder.Write("}");
                        }
                        else if (property.MaxOccurs != "1" && !Datatypes.IsCollectionType(property.Type)) // Array list so we still need to put this in
                        {
                            retBuilder.Write(", genericSupplier = {");
                            CreateDatatypeRef(property.Type, property, ownerPackage);
                            retBuilder.Write("}");
                        }

                        retBuilder.WriteLine("),");
                        alreadyRendered.Add(key);
                    }
                }
            }

            string retVal = retBuilder.ToString();
            retVal = retVal.Substring(0, retVal.LastIndexOf(","));
            retVal += "\r\n";
            if (alreadyRendered.Count > 1)
            {
                if (!s_imports.Contains("org.marc.everest.annotations.Properties"))
                    s_imports.Add("org.marc.everest.annotations.Properties");
                return String.Format("\t@Properties( value = {{\r\n{0}\t }})\r\n", retVal);
            }
            else
                return retVal;
        }
Пример #19
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;
            }
        }
Пример #20
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);
            }
        }
Пример #21
0
 void CreateBook()
 {
     autor   = new ClassAutor();
     content = new ClassContent();
     title   = new ClassTitle();
 }
Пример #22
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;
                    }

            
        }
Пример #23
0
        /// <summary>
        /// Is this a candidate for collapsing meaningless complexity
        /// </summary>
        private bool IsCandidateForMeaninglessComplexityCollapse(ClassContent cc)
        {
            if(!(cc is Property) || (cc as Property).Type.Class == null) return false; // 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) return false; // can't collapse this relation as there is more than sub-property
            
            ClassContent candidate = content[0];

            // Is this a generic parameter
            if ((candidate.Container as Class).TypeParameters != null && (cc.Container as Class).TypeParameters.Find(o => o.ParameterName == (candidate as Property).Type.Name) != null)
                return false;

            // Now determine if we can collapse
            return (candidate.Conformance == ClassContent.ConformanceKind.Mandatory
                || candidate.Conformance >= cc.Conformance
                || (cc.Conformance <= ClassContent.ConformanceKind.Required
                && candidate.Conformance == ClassContent.ConformanceKind.Populated)) // Experiment: && candidate.Conformance != ClassContent.ConformanceKind.Populated) 
                && candidate.MaxOccurs == "1"
                && candidate is Property;
        }
Пример #24
0
        ///-----------------------------------------------------------------

        #region Rule internal
        protected override void GatherVariants(List <FunctionVariant> variants, ScriptContent scriptContent, ClassContent contentSrc, ClassContent contentDst)
        {
            variants.Clear();
            var slots = new int[contentSrc.NameCount / 2];

            GatherVariants(0, slots, variants, scriptContent, contentSrc, contentDst);
        }
Пример #25
0
        ///-----------------------------------------------------------------

        #region Rule internal
        protected override void GatherVariants(List <FunctionVariant> variants, ScriptContent scriptContent, ClassContent contentSrc, ClassContent contentDst)
        {
            var slots = new int[contentDst.VarCount];

            for (var s = 0; s < slots.Length; s++)
            {
                slots[s] = 0;
            }

            variants.Clear();
            GatherVariantsSlots(0, slots, variants, scriptContent, contentSrc, contentDst);
        }
Пример #26
0
        protected override void GatherVariants(List <FunctionVariant> variants, ScriptContent scriptContent, ClassContent contentSrc, ClassContent contentDst)
        {
            variants.Clear();

            for (int r = 0; r < repeatCount; r++)
            {
                var variant = new FunctionVariant(scriptContent.functionContents.Count);
                for (var fc = 0; fc < scriptContent.functionContents.Count; fc++)
                {
                    var functionContent = scriptContent.functionContents[fc];
                    for (var v = 0; v < contentSrc.names.Count; v++)
                    {
                        var functionBody = functionContent.body;

                        if (Defaults[0].CanSwap(functionBody))
                        {
                            var swap = Defaults[0] + scriptContent.classDefaultType;
                            functionBody = swap.Apply(functionBody);
                        }

                        if (Defaults[1].CanSwap(functionBody))
                        {
                            var swap = Defaults[1] + (r + 1).ToString();
                            functionBody = swap.Apply(functionBody);
                        }

                        if (Names.DefaultSymbol.CanSwap(functionBody))
                        {
                            var swap = Names.DefaultSymbol + contentSrc.names[v] + r.ToString();
                            functionBody = swap.Apply(functionBody);
                        }

                        if (Variables.DefaultSymbol.CanSwap(functionBody))
                        {
                            var swap = Variables.DefaultSymbol + r.ToString();
                            functionBody = swap.Apply(functionBody);
                        }

                        variant[fc] = functionBody;
                    }
                }

                variants.Add(variant);
            }
        }
Пример #27
0
        private TypeReference CreateTypeReference(AssociationEnd ae, ClassContent cc)
        {
            
            // Resolve CMET
            ClassElement cel = staticModel.OwnedClass.Find(o => (o.Choice is CommonModelElementRef) && (o.Choice as CommonModelElementRef).Name == ae.ParticipantClassName);
            if (cel != null) // It is a CMET - Note: This is where late binding may occur.. 
                ae.ParticipantClassName = (cel.Choice as CommonModelElementRef).CmetName ?? (cel.Choice as CommonModelElementRef).Name; // Resolve to CMET

            // The type of this end is the type of the association
            TypeReference tr = new TypeReference();
            tr.Container = cc;
            tr.MemberOf = ClassRepository;

            #region Type Reference
            // IS the traversable association referencing a CMET type?
            // if it is, then we require some extra processing to de-reference the CMET
            if (ClassRepository.ContainsKey(ae.ParticipantClassName) &&
                    ClassRepository[ae.ParticipantClassName] is CommonTypeReference)
            {
                // Get the CMET references (which is a CTR in COR)
                CommonTypeReference ctr = (ClassRepository[ae.ParticipantClassName] as CommonTypeReference);
                tr = ctr.Class; // Assign the class type reference
                tr.MemberOf = ClassRepository;

                // Process this class?
                if (!ClassRepository.ContainsKey(tr.Name))
                    PackageParser.ParseClassFromPackage(tr.Name, repository, ClassRepository);

                if (cc is Property)
                {
                    (cc as Property).FixedValue = ctr.ClassifierCode; // Assign a fixed classifier code
                    (cc as Property).Documentation = ctr.Documentation; // Assign the documentation
                }
            }
            else if (cel != null) // Bad CMET ref
            {
                // JF - Bug processing payload models
                //// the --ignore-cmet flag
                if (MifCompiler.hostContext.Mode == Pipeline.OperationModeType.Quirks)
                {
                    System.Diagnostics.Trace.WriteLine(string.Format("can't make type reference to CMET '{0}' as it wasn't found in the classes. The user has specified the --quirks flag so this error won't be classified as fatal...", (cel.Choice as CommonModelElementRef).CmetName), "quirks");
                    tr.Name = null;
                }
                else 
                    throw new InvalidOperationException(string.Format("can't make type reference to CMET '{0}' as it wasn't found anywhere in the repository ({1}).", (cel.Choice as CommonModelElementRef).CmetName, staticModel.PackageLocation.ToString(MifCompiler.NAME_FORMAT)));
            }
            else
            {
                if (templateParameters.ContainsKey(ae.ParticipantClassName))
                    tr.Name = ae.ParticipantClassName;
                else
                    tr.Name = string.Format("{0}.{1}", staticModel.PackageLocation.Artifact == ArtifactKind.RIM ? "RIM" : staticModel.PackageLocation.ToString(MifCompiler.NAME_FORMAT),
                        ae.ParticipantClassName);
            }
            #endregion



            return tr;

        }
Пример #28
0
        /// <summary>
        /// Apply delta against a property
        /// </summary>
        private void ApplyDelta(ClassContent property, RelationshipDeltaData delta)
        {
            Trace.WriteLine(string.Format("Delta: Applying deltas for '{0}.{1}'...", property.Container.Name, property.Name), "debug");

            // Apply constraints
            foreach (var constraint in delta.Constraint)
                ApplyConstraint(property, constraint);
            
        }
Пример #29
0
        /// <summary>
        /// Determine if the class content is a candidate for collapsing
        /// </summary>
        private bool IsCandidateForTypeCollapse(ClassContent cc)
        {
            // Candidates must be a property with 0..1 and must be 
            // traversable in nature.
            if (cc.MaxOccurs != "1" || !(cc is Property) || 
                (cc as Property).PropertyType != Property.PropertyTypes.TraversableAssociation ||
                cc.MinOccurs != "0")
                return false;

            // Determine the conformance meets criteria
            if((cc.Conformance == ClassContent.ConformanceKind.Optional || cc.Conformance == ClassContent.ConformanceKind.Required)
                && !QueryConformance((cc as Property).Type, ClassContent.ConformanceKind.Optional | ClassContent.ConformanceKind.Required))
                        return false;
            else if (cc.Conformance == ClassContent.ConformanceKind.Populated)
                return false;

            // Make sure none of the child member names appear in the parent class they are to be merged with
            bool isCandidate = CountReferences((cc as Property).Type) == 1;
            foreach(ClassContent content in (cc.Container as Class).Content)
                isCandidate &= HasMember((cc as Property).Type, content.Name);
            // Now we must determine if there are no other references to the class to be collapsed
            return isCandidate;
        }
Пример #30
0
        ///-----------------------------------------------------------------

        #region CodeRule abstract
        protected abstract void GatherVariants(List <FunctionVariant> variants, ScriptContent scriptContent, ClassContent contentSrc, ClassContent contentDst);
Пример #31
0
        /// <summary>
        /// Optimize the <paramref name="feature"/>
        /// </summary>
        public MohawkCollege.EHR.gpmr.COR.Feature Optimize(MohawkCollege.EHR.gpmr.COR.Feature f, CombineLog workingLog)
        {
            string qualifiedName = String.Format("{0}.{1}", (f as Class).ContainerName, f.Name);
            // Garbage bin
            List <String>       classGarbageBin   = new List <string>();
            List <ClassContent> contentGarbageBin = new List <ClassContent>();

            // Still valid to process this feature
            if (!Repository.ContainsKey(qualifiedName))
            {
                return(null); // Can't process non-existant class
            }
            // First determine if a class that is identical to this already exists
            FeatureComparer comparer         = new FeatureComparer();
            var             matchingFeatures = from kv in Repository
                                               where comparer.Compare(kv.Value, f) == 0
                                               select kv.Value;

            CombineInfo currentCombinationLog = new CombineInfo();

            // Find matching features in each of the sub-systems
            if (matchingFeatures.Count() > 1 && CorCollapserPipelineTrigger.combine == true)
            {
                System.Diagnostics.Trace.WriteLine(String.Format("{0} other classes can be represented by this class", matchingFeatures.Count()), "debug");
                currentCombinationLog.Destination = qualifiedName;

                foreach (var s in matchingFeatures)
                {
                    string qName = String.Format("{0}.{1}", (s as Class).ContainerName, s.Name);
                    if (qName != qualifiedName)
                    {
                        System.Diagnostics.Trace.WriteLine(String.Format("\tReplaces '{0}'", qName), "debug");
                        currentCombinationLog.Class.Add(qName);

                        // Copy alternate traversal data
                        foreach (ClassContent cc in (s as Class).Content)
                        {
                            if (cc is Property && (cc as Property).AlternateTraversalNames != null)
                            {
                                if (((f as Class).Content.Find(o => o.Name == cc.Name) as Property).AlternateTraversalNames == null)
                                {
                                    ((f as Class).Content.Find(o => o.Name == cc.Name) as Property).AlternateTraversalNames = new List <Property.AlternateTraversalData>();
                                }
                                ((f as Class).Content.Find(o => o.Name == cc.Name) as Property).AlternateTraversalNames.AddRange((cc as Property).AlternateTraversalNames);
                            }
                        }
                        // Replace referneces
                        ReplaceReferences(s as Class, f as Class);

                        // Add an annotation
                        f.Annotations.Add(new CodeCombineAnnotation((s as Class).CreateTypeReference()));

                        // Remove this class (Add it to the garbage bin)
                        classGarbageBin.Add(qName);
                    }
                }
                workingLog.CombineOps.Add(currentCombinationLog);
            }

            // Now collapse members
            if (CorCollapserPipelineTrigger.collapse)
            {
                for (int i = 0; i < (f as Class).Content.Count; i++)
                {
                    ClassContent cc = (f as Class).Content[i];
                    // Determine if it is a candidate for collapsing needless complexity
                    if (IsCandidateForMeaninglessComplexityCollapse(cc))
                    {
                        while (IsCandidateForMeaninglessComplexityCollapse(cc))
                        {
                            System.Diagnostics.Trace.WriteLine(string.Format("\tCollapsing '{0}'", cc.Name), "debug");
                            CollapseMemberType(cc, f as Class);
                        }
                    }
                    // Determine if it is a candidate for collapsing the entire type
                    else if (IsCandidateForTypeCollapse(cc))
                    {
                        System.Diagnostics.Trace.WriteLine(string.Format("\tCollapsing '{0}'", cc.Name), "debug");
                        CopyMembers((cc as Property).Type, f as Class, cc);
                        contentGarbageBin.Add(cc);
                    }
                }

                // Clean up garbage bin
                (f as Class).Content.RemoveAll(a => contentGarbageBin.Contains(a));
                (f as Class).Content.Sort(new ClassContent.Comparator());
            }

            // Clean the garbage bin
            foreach (string s in classGarbageBin)
            {
                Repository.Remove(s);
            }

            return(null);
        }
Пример #32
0
        ///-----------------------------------------------------------------

        #region CodeRule overridable
        public virtual BuildResult Generate(ScriptContent data)
        {
            var variants = new List <FunctionVariant>();

            //If needed, Add the default value as a possible class
            var maxSrc = data.classInfos.Count + (GenerateDefault ? 1 : 0);

            //Only loop through the dst classes if required
            var maxDst  = GenerationMode == GenerationRule.ForeachSrcCrossDest ? data.classInfos.Count : 1;
            var infoSrc = new ClassContent();
            var infoDst = new ClassContent();
            var infoDef = new ClassContent();

            if (GenerateDefault)
            {
                infoDef.className = data.classDefaultType;
            }

            //Loop throught the source classes
            for (var iSrc = 0; iSrc < maxSrc; iSrc++)
            {
                //Add the default value as a possible class
                infoSrc = GenerateDefault && iSrc == 0
                    ? infoDef
                    : data.classInfos[iSrc + (GenerateDefault ? -1 : 0)];

                if (UseOneClassPerSource)
                {
                    data.codeGenerated.Add(new ScriptContent.GeneratedCode {
                        className = infoSrc.className, code = string.Empty
                    });
                }
                else if (data.codeGenerated.Count == 0)
                {
                    data.codeGenerated.Add(new ScriptContent.GeneratedCode {
                        className = string.Empty, code = string.Empty
                    });
                }

                //one pass or as many as the dst classes
                for (var iSDst = 0; iSDst < maxDst; iSDst++)
                {
                    if (GenerationMode == GenerationRule.ForeachSrcCrossDest)
                    {
                        infoDst = data.classInfos[iSDst];
                    }

                    //Gather code variants
                    GatherVariants(variants, data, infoSrc, infoDst);

                    var swapSrc = ClassSrc + infoSrc.className;
                    var swapDst = ClassDst;

                    //Add the Header from the code file
                    if (GenerationMode == GenerationRule.ForeachSrcCrossDest)
                    {
                        swapDst = swapDst + infoDst.className;
                        AddCodeTo(data, data.codeHeader, swapSrc, swapDst);
                    }
                    else
                    {
                        AddCodeTo(data, data.codeHeader, swapSrc);
                    }

                    //Go through all variants and apply them to the code
                    for (var v = 0; v < variants.Count; v++)
                    {
                        var variant  = variants[v];
                        var codeBody = data.codeBody;

                        //Error out if the requested funcs result are not available
                        if (!SwapCodeContent(ref codeBody, Functions, variant.Count, variant.Variants))
                        {
                            return((BuildResult)BuildResult.ValueType.PrateekScriptInsufficientNames + GetType().Name + infoSrc.className);
                        }

                        //Error out if the requested Names are not available
                        if (!SwapCodeContent(ref codeBody, Names, infoSrc.NameCount, infoSrc.names))
                        {
                            return((BuildResult)BuildResult.ValueType.PrateekScriptInsufficientNames + infoSrc.className);
                        }

                        if (GenerationMode == GenerationRule.ForeachSrcCrossDest)
                        {
                            AddCodeTo(data, codeBody, swapSrc, swapDst);
                        }
                        else
                        {
                            AddCodeTo(data, codeBody, swapSrc);
                        }
                    }

                    //Add the Footer from the code file
                    if (GenerationMode == GenerationRule.ForeachSrcCrossDest)
                    {
                        AddCodeTo(data, data.codeFooter, swapSrc, swapDst);
                    }
                    else
                    {
                        AddCodeTo(data, data.codeFooter, swapSrc);
                    }
                }
            }

            for (var c = 0; c < data.codeGenerated.Count; c++)
            {
                var codeGenerated = data.codeGenerated[c];
                codeGenerated.code    = codeGenerated.code.Replace(string.Empty.NewLine(), string.Empty.NewLine() + Glossary.Macros.codeDataTabsTag);
                data.codeGenerated[c] = codeGenerated;
            }

            return(BuildResult.ValueType.Success);
        }
Пример #33
0
        internal static Property Parse(ClassAttribute clsa, String vocabBindingRealm, ClassRepository cr, Dictionary <string, Package> derivationSuppliers)
        {
            // TODO: Support EnumerationValue stuff
            Property retVal = new Property();

            // Name (and busines names)
            retVal.Name = clsa.Name;
            foreach (BusinessName bn in clsa.BusinessName)
            {
                if (bn.Language == MifCompiler.Language || bn.Language == null)
                {
                    retVal.BusinessName = bn.Name;
                }
            }

            // Documentation
            if (clsa.Annotations != null)
            {
                retVal.Documentation = DocumentationParser.Parse(clsa.Annotations.Documentation);
            }

            // Conformance
            retVal.Conformance = clsa.IsMandatory ? ClassContent.ConformanceKind.Mandatory : clsa.Conformance == ConformanceKind.Required ? ClassContent.ConformanceKind.Required :
                                 ClassContent.ConformanceKind.Optional;

            if (retVal.Conformance != Property.ConformanceKind.Mandatory && clsa.MinimumMultiplicity == "1")
            {
                retVal.Conformance = Property.ConformanceKind.Populated;
            }

            // Min / Max occurs
            if (retVal.Conformance == MohawkCollege.EHR.gpmr.COR.Property.ConformanceKind.Mandatory)
            {
                retVal.MinOccurs = "1";
            }
            else
            {
                retVal.MinOccurs = clsa.MinimumMultiplicity;
            }
            retVal.MaxOccurs = clsa.MaximumMultiplicity == "-1" ? "*" : clsa.MaximumMultiplicity;
            retVal.MaxLength = clsa.MaximumLength;
            retVal.MinLength = clsa.MinimumLength;

            // Structural or non?
            retVal.PropertyType = clsa.IsImmutable ? Property.PropertyTypes.Structural : Property.PropertyTypes.NonStructural;

            // Default value
            retVal.DefaultValue = clsa.DefaultValue;
            retVal.Initializor  = clsa.DefaultFrom == DefaultDeterminerKind.ITS ? Property.InitializorTypes.ITS :
                                  clsa.DefaultFrom == DefaultDeterminerKind.Realm ? Property.InitializorTypes.Realm :
                                  clsa.DefaultFrom == DefaultDeterminerKind.ReferencingAttribute ? Property.InitializorTypes.ReferencedAttributes : Property.InitializorTypes.DefaultValue;

            if (clsa.DerivedFrom != null)
            {
                retVal.Realization = new List <ClassContent>();
                foreach (var dei in clsa.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 (!cr.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, cr);
                        // Ditch if still can't find
                        if (!cr.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.AttributeName, dei.StaticModelDerivationId), "warn");
                        }
                    }

                    // Feature was found
                    var f = (ss as MohawkCollege.EHR.gpmr.COR.SubSystem).FindClass(dei.ClassName);
                    if (f != null)
                    {
                        ClassContent cc = f.GetFullContent().Find(o => o.Name == dei.AttributeName);
                        retVal.Realization.Add(cc);
                    }
                    else
                    {
                        System.Diagnostics.Trace.WriteLine(String.Format("Can't find derivation class '{0}' for association '{1}' (derivation supplier {2})", dei.ClassName, dei.AttributeName, dei.StaticModelDerivationId), "warn");
                    }
                }
            }

            // Derived from
            retVal.DerivedFrom = clsa;

            // Fixed Value
            retVal.FixedValue = clsa.FixedValue;

            // Sort key
            retVal.SortKey = clsa.SortKey;

            // Datatype
            retVal.Type = TypeReferenceParser.Parse(clsa.Type);

            // Update Modes
            retVal.UpdateMode = clsa.UpdateModeDefault.ToString();
            if (clsa.UpdateModesAllowed != null)
            {
                retVal.AllowedUpdateModes = new List <string>();
                foreach (string s in clsa.UpdateModesAllowed.Split(','))
                {
                    retVal.AllowedUpdateModes.Add(s);
                }
            }

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

                // JF: If the code system is identified, then bind
                if (clsa.Vocabulary.Code != null && !String.IsNullOrEmpty(clsa.Vocabulary.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"));
                    retVal.SupplierDomain = cr.Find(o => o is CodeSystem && (o as CodeSystem).Name.Equals(clsa.Vocabulary.Code.CodeSystemName)) as Enumeration;
                    if (retVal.SupplierDomain == null)
                    {
                        Trace.WriteLine(String.Format("'{0}' could not be bound to '{1}' as the code system was not found", clsa.Name, clsa.Vocabulary.Code.CodeSystemName), "warn");
                    }
                }
                if (clsa.Vocabulary.ConceptDomain != null)
                {
                    retVal.SupplierDomain = cr.Find(o => o is ConceptDomain && (o as ConceptDomain).Name.Equals(clsa.Vocabulary.ConceptDomain.Name)) as Enumeration;
                    if (retVal.SupplierDomain == null && MifCompiler.hostContext.Mode == Pipeline.OperationModeType.Quirks)
                    {
                        retVal.SupplierDomain = cr.Find(o => o is Enumeration && o.Name.Equals(clsa.Vocabulary.ConceptDomain.Name)) as Enumeration;
                        if (retVal.SupplierDomain != null)
                        {
                            Trace.WriteLine(String.Format("'{0}' couldn't be bound to concept domain '{1}', '{2}' with name '{1}' was located, so the binding was changed", clsa.Name, clsa.Vocabulary.ConceptDomain.Name, retVal.SupplierDomain.EnumerationType), "quirks");
                        }
                    }
                    if (retVal.SupplierDomain == null)
                    {
                        Trace.WriteLine(String.Format("'{0}' could not be bound to '{1}' as the concept domain was not found", clsa.Name, clsa.Vocabulary.ConceptDomain.Name), "warn");
                    }
                }
                if (clsa.Vocabulary.ValueSet != null)
                {
                    retVal.SupplierDomain = cr.Find(o => o is ValueSet && (o as ValueSet).Name.Equals(clsa.Vocabulary.ValueSet.Name)) as Enumeration;
                    if (retVal.SupplierDomain == null)
                    {
                        Trace.WriteLine(String.Format("'{0}' could not be bound to '{1}' as the value set was not found", clsa.Name, clsa.Vocabulary.ValueSet.Name), "warn");
                    }

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

                // Supplier strength(s)
                if (clsa.Vocabulary.ValueSet != null)
                {
                    retVal.SupplierStrength = clsa.Vocabulary.ValueSet.CodingStrength == CodingStrengthKind.CNE ? (Property.CodingStrengthKind?)Property.CodingStrengthKind.CodedNoExtensions:
                                              clsa.Vocabulary.ValueSet.CodingStrength == CodingStrengthKind.CWE ? (Property.CodingStrengthKind?)Property.CodingStrengthKind.CodedNoExtensions : null;
                }

                // Supplier domain strength
                if (retVal.SupplierDomain != null)
                {
                    if (defaultCodingStrengths.ContainsKey(retVal.SupplierDomain.Name ?? "") && !retVal.SupplierStrength.HasValue)
                    {
                        retVal.SupplierStrength = defaultCodingStrengths[retVal.SupplierDomain.Name];
                    }
                    else
                    {
                        retVal.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");
                    }
                }
            }

            return(retVal);
        }
Пример #34
0
        public Dictionary <String, IEnumerable <String> > GetPackageFiles(Schema Schema, String NamespaceName)
        {
            var NamespaceToClasses = new Dictionary <String, List <KeyValuePair <String, List <String> > > >();

            void AddClass(String ClassNamespaceName, String ClassName, IEnumerable <String> ClassContent)
            {
                if (!NamespaceToClasses.ContainsKey(ClassNamespaceName))
                {
                    NamespaceToClasses.Add(ClassNamespaceName, new List <KeyValuePair <String, List <String> > >());
                }
                NamespaceToClasses[ClassNamespaceName].Add(new KeyValuePair <String, List <String> >(ClassName, ClassContent.ToList()));
            }

            var Commands = Schema.Types.Where(t => t.OnClientCommand || t.OnServerCommand).Where(t => t.Version() == "").ToList();

            if (Commands.Count > 0)
            {
                var SchemaClosureGenerator = Schema.GetSchemaClosureGenerator();
                var Hash = SchemaClosureGenerator.GetSubSchema(Schema.Types.Where(t => (t.OnClientCommand || t.OnServerCommand) && t.Version() == ""), new List <TypeSpec> {
                }).GetNonattributed().Hash();
                AddClass(NamespaceName, "IJsonSender", IJsonSender());
                AddClass(NamespaceName, "JsonSerializationClient", JsonSerializationClient(Hash, Commands, SchemaClosureGenerator, NamespaceName));
            }

            AddClass(NamespaceName, "JsonTranslator", JsonTranslator(Schema, NamespaceName));

            return(NamespaceToClasses.SelectMany(p => p.Value.Select(v => new KeyValuePair <String, IEnumerable <String> >(String.Join("/", p.Key.Split('.').Where(NamespacePart => NamespacePart != "").Select(NamespacePart => LowercaseCamelize(NamespacePart)).Concat(new String[] { v.Key })), WrapModule(p.Key, Schema.Imports, v.Value)))).ToDictionary(p => p.Key, p => p.Value));
        }
Пример #35
0
        public List <String> GetTypes(Schema Schema, String NamespaceName)
        {
            var Primitives = GetPrimitives(Schema);

            var NamespaceToClasses = new Dictionary <String, List <List <String> > >();

            void AddClass(String ClassNamespaceName, IEnumerable <String> ClassContent)
            {
                if (!NamespaceToClasses.ContainsKey(ClassNamespaceName))
                {
                    NamespaceToClasses.Add(ClassNamespaceName, new List <List <String> >());
                }
                NamespaceToClasses[ClassNamespaceName].Add(ClassContent.ToList());
            }

            foreach (var c in Schema.Types)
            {
                if (c.OnPrimitive)
                {
                    if (c.VersionedName() == "Unit")
                    {
                        AddClass(c.NamespaceName(), Primitive_Unit());
                    }
                    else if (c.VersionedName() == "Optional")
                    {
                        AddClass(c.NamespaceName(), Primitive_Optional());
                    }
                    else
                    {
                        continue;
                    }
                }
                else if (c.OnAlias)
                {
                    AddClass(c.NamespaceName(), Alias(c.Alias));
                }
                else if (c.OnRecord)
                {
                    AddClass(c.NamespaceName(), Record(c.Record));
                }
                else if (c.OnTaggedUnion)
                {
                    AddClass(c.NamespaceName(), TaggedUnion(c.TaggedUnion));
                }
                else if (c.OnEnum)
                {
                    AddClass(c.NamespaceName(), Enum(c.Enum));
                }
                else if (c.OnClientCommand)
                {
                    AddClass(c.NamespaceName(), ClientCommand(c.ClientCommand));
                }
                else if (c.OnServerCommand)
                {
                    AddClass(c.NamespaceName(), ServerCommand(c.ServerCommand));
                }
                else
                {
                    throw new InvalidOperationException();
                }
            }

            var Commands = Schema.Types.Where(t => t.OnClientCommand || t.OnServerCommand).ToList();

            if (Commands.Count > 0)
            {
                AddClass(NamespaceName, IApplicationServer(Commands, NamespaceName));
                AddClass(NamespaceName, IApplicationClient(Commands, NamespaceName));
                AddClass(NamespaceName, IEventPump(Commands, NamespaceName));
            }

            var Classes = NamespaceToClasses.Select(p => WrapNamespace(p.Key, p.Value.Join(new String[] { "" })));

            return((new List <List <String> > {
                Primitives
            }).Concat(Classes).Join(new String[] { "" }).ToList());
        }
Пример #36
0
        /// <summary>
        /// Render class content to class file
        /// </summary>
        private string RenderClassContent(ClassContent cc, string ownerPackage, int propertySort)
        {

            StringWriter sw = new StringWriter();

            // Render the backing field
            TypeReference backingFieldType = null;
            if (cc is Property)
            {
                // HACK: Java can't hide members, so what we need to do 
                //       is detect if the model changes data types between overridden
                //       classes.
                backingFieldType = GetBackingFieldTypeThroughChildren((cc as Property), cc.Container as Class);
            //    backingFieldType = (cc as Property).Type;

            }
            else
            {


                backingFieldType = ((cc as Choice).Content[0] as Property).Type;
                if (backingFieldType != null && backingFieldType.Class != null)
                    backingFieldType = backingFieldType.Class.BaseClass;
                else
                    backingFieldType = new TypeReference() { Name = null };
                foreach (var chc in (cc as Choice).Content)
                {
                    if (backingFieldType.Name == null) break; // Just going to use System.Object Anyways

                    Property chcProperty = chc as Property; // Cast a property

                    // This line ensures that a common root class can be used across all the choices
                    if (chcProperty.Type == null || chcProperty.Type.Class == null || chcProperty.Type.Class.BaseClass.Name != backingFieldType.Name)
                        backingFieldType = new TypeReference() { Name = null };
                }
            }
            
            
            // Backing field write
            sw.WriteLine("\t// Backing field for {0}", cc.Name);
            sw.Write("\tprivate ");
            
            // Fixed value?
            //if (cc is Property && !String.IsNullOrEmpty((cc as Property).FixedValue))
            //    sw.Write("final ");

            // Datatype reference
            string dtr = CreateDatatypeRef(backingFieldType, cc as Property, ownerPackage);
            bool initialize = false,
                isNativeCollection = false;
            if (cc.MaxOccurs != "1" &&
                    !Datatypes.IsCollectionType(backingFieldType))
            {
                dtr = string.Format("ArrayList<{0}>", dtr);
                initialize = true;
                isNativeCollection = true;
            }

            sw.Write("{0} m_{1}", dtr, Util.Util.MakeFriendly(cc.Name));

            if (initialize)
                sw.Write(" = new {0}()", dtr);

            string setterName = "set";

            // TODO: Fixed Values here
            var property = cc as Property;
            // Only render fixed values when:
            // 1. The property is a property
            // 2. The property has a fixed value
            // 3. The property is mandatory or populated
            // 4. The property is not a traversable association.
            if (property != null && !String.IsNullOrEmpty(property.FixedValue) && (property.Conformance == ClassContent.ConformanceKind.Populated || property.Conformance == ClassContent.ConformanceKind.Mandatory) &&
                property.PropertyType != Property.PropertyTypes.TraversableAssociation)
            {
                // Get the real supplier (value set, or code system if concept domain)
                var splrCd = property.SupplierDomain as ConceptDomain;
                var bindingDomain = property.SupplierDomain;
                Enumeration.EnumerationValue ev = null;
                if (splrCd != null && splrCd.ContextBinding != null &&
                    splrCd.ContextBinding.Count == 1)
                    bindingDomain = splrCd.ContextBinding[0];

                if(bindingDomain != null)
                    ev = bindingDomain.GetEnumeratedLiterals().Find(o => o.Name == (property.FixedValue ?? property.DefaultValue));

                bool wontRenderBd = bindingDomain != null ? String.IsNullOrEmpty(EnumerationRenderer.WillRender(bindingDomain)) : true;

                if (bindingDomain == null)
                    sw.Write(" = ({2})org.marc.everest.formatters.FormatterUtil.fromWireFormat(\"{1}\", {0}.class);",
                        backingFieldType.Name, property.FixedValue, dtr);
                else if (ev == null || wontRenderBd) // Enumeration value is not known in the enumeration, fixed value fails
                {
                    System.Diagnostics.Trace.WriteLine(String.Format("Can't find literal '{0}' in supplier domain for property '{1}'", property.FixedValue, property.Name), "error");
                    if (wontRenderBd) // wont be rendering binding domain, so best to just emit it
                    {
                        if(Datatypes.GetOverrideSetters(backingFieldType, property, ownerPackage).FirstOrDefault(o=>o.Parameters.Count == 2) != null)
                            sw.Write(" = new {0}(\"{1}\", {2})",
                                dtr, property.FixedValue, ev == null ? "null" : String.Format("\"{0}\"", ev.CodeSystem));
                        else
                            sw.Write(" = new {0}(\"{1}\")",
                                dtr, property.FixedValue, ev == null ? "null" : String.Format("\"{0}\"", ev.CodeSystem));
                    }
                    else
                        sw.Write(" = new {0}(new {2}(\"{3}\"))",
                            dtr, ownerPackage, Util.Util.MakeFriendly(EnumerationRenderer.WillRender(property.SupplierDomain)), property.FixedValue);
                }
                else // Fixed value is known
                    sw.Write(" = new {2}({0}.{1})",
                    Util.Util.MakeFriendly(EnumerationRenderer.WillRender(bindingDomain)), Util.Util.PascalCase(ev.BusinessName ?? ev.Name), dtr, ownerPackage);

                // Update setter name so the output method has the right naming convention
                setterName = "override";

            }

            sw.WriteLine(";");

            // Render the documentation
            sw.Write(DocumentationRenderer.Render(cc.Documentation, 1));

            // Render the property attribute
            sw.Write(RenderPropertyAttribute(cc, ownerPackage, propertySort));

            // JF: Are there any members in the parent that we're overriding?
            String modifier = "";
            if (cc.Container != null && cc.Container is Class)
            {
                var containerClassRef = (cc.Container as Class).BaseClass;
                while (containerClassRef != null && containerClassRef.Class != null)
                {
                    foreach (var content in containerClassRef.Class.Content)
                    {
                        if (content.ToString() == property.ToString())
                            modifier = "@Override";
                        //else if (content is Property && CreatePascalCasedName(content as Property) == pName ||
                        //    content is Choice && CreatePascalCasedName(content as Choice) == pName)
                        //    modifier = "new virtual";

                    }
                    containerClassRef = containerClassRef.Class.BaseClass;
                }

            }
            // Render the getter
            sw.Write(modifier);
            sw.WriteLine("\tpublic {0} get{1}() {{ return this.m_{2}; }}", dtr, Util.Util.PascalCase(cc.Name), Util.Util.MakeFriendly(cc.Name));

            // Render setters
            // Default setter
            sw.Write(DocumentationRenderer.Render(cc.Documentation, 1));

            sw.Write(modifier);
            sw.WriteLine("\tpublic void {3}{1}({0} value) {{ this.m_{2} = value; }}", dtr, Util.Util.PascalCase(cc.Name), Util.Util.MakeFriendly(cc.Name), setterName);

            // Now to render the helper methods that can set the backing property, these are convenience methods
            if (cc is Choice && !isNativeCollection)
            {
                // Now, return getAsMethods

                StringBuilder getTraversalFor = new StringBuilder();

                foreach (Property p in (cc as Choice).Content)
                {
                    if (p.Type.Class != null && p.Type.Class.IsAbstract) continue; // don't output abstract classes
                    getTraversalFor.AppendFormat("\t\tif(this.m_{0} instanceof {1}) return \"{2}\";\r\n", Util.Util.MakeFriendly(cc.Name), CreateDatatypeRef(p.Type, p, ownerPackage, false), p.Name);
                    sw.WriteLine("\t/** Gets the {0} property cast to {1} or null if {0} is not an instance of {1}. This happens when the traversal name is {2}. This convenience method saves the developer from casting */", Util.Util.PascalCase(cc.Name), Util.Util.MakeFriendly(p.Type.Name), p.Name);
                    sw.WriteLine("\tpublic {0} get{1}If{4}() {{ if(this.m_{3} instanceof {0}) return ({0})this.m_{3}; else return null; }}",
                        CreateDatatypeRef(p.Type, p, ownerPackage), Util.Util.PascalCase(cc.Name), Util.Util.MakeFriendly(p.Type.Name), Util.Util.MakeFriendly(cc.Name), Util.Util.PascalCase(p.Name));
                    sw.WriteLine("\t/** Sets the {0} property given the specified instance of {1}. */", Util.Util.PascalCase(cc.Name), Util.Util.MakeFriendly(p.Type.Name));
                    sw.WriteLine("\tpublic void {3}{1}({0} value) {{ this.m_{2} = value; }}", CreateDatatypeRef(p.Type, p, ownerPackage), Util.Util.PascalCase(cc.Name), Util.Util.MakeFriendly(cc.Name), setterName);
                }

                sw.WriteLine("\t/** Gets the actual traversal name used for the choice element {0}, null if traversal was not provided **/", Util.Util.PascalCase(cc.Name));
                sw.WriteLine("\tpublic String get{0}TraversalName() {{", Util.Util.PascalCase(cc.Name));
                sw.WriteLine(getTraversalFor);
                sw.WriteLine("\t\treturn null;");
                sw.WriteLine("\t}");
                ; // TODO: Factory methods and etc
            }
            else if (!isNativeCollection)
            {
                foreach (var sod in MohawkCollege.EHR.gpmr.Pipeline.Renderer.Java.HeuristicEngine.Datatypes.GetOverrideSetters(backingFieldType, cc as Property, ownerPackage))
                {
                    sw.Write(DocumentationRenderer.Render(cc.Documentation, 1));
                    sw.Write("\tpublic void {1}{0}(", Util.Util.PascalCase(cc.Name), setterName);
                    foreach (var parm in sod.Parameters)
                    {
                        sw.Write("{0} {1}", parm.DataType, parm.Name);
                        if (sod.Parameters.Last() != parm)
                            sw.Write(", ");
                    }
                    sw.Write(")");
                    if (sod.Throws != null && sod.Throws.Count > 0)
                    {
                        sw.Write(" throws ");
                        foreach (var thrw in sod.Throws)
                            sw.Write("{0} {1}", thrw.Type, thrw == sod.Throws.Last() ? "" : ",");
                    }
                    sw.WriteLine("{");
                    sw.WriteLine("\t\t{0}", sod.SetterText);
                    sw.WriteLine("\t\tthis.m_{0} = {1};", Util.Util.MakeFriendly(cc.Name), sod.ValueInstance.Name);
                    sw.WriteLine("\t}");
                }
            }

            return sw.ToString();

        }
        ///-----------------------------------------------------------------

        #region Rule internal
        protected override void GatherVariants(List <FunctionVariant> variants, ScriptContent scriptContent, ClassContent contentSrc, ClassContent contentDst)
        {
            infos.Clear();
            Glossary.Macros.GetTags(this);

            variants.Clear();
            if (scriptContent.functionContents.Count == 0)
            {
                return;
            }

            var result  = string.Empty;
            var variant = new FunctionVariant(result);

            for (var k = 0; k < infos.Count; k++)
            {
                result += scriptContent.functionContents[0].body;
                result  = (Variables[0] + infos[k].name).Apply(result);
            }

            variant[0] = result;
            variants.Add(variant);
        }
Пример #38
0
        private string CreateProperty(ClassContent cc, String ownerNs, int propertySort)
        {

            // JF: Supporting CeRX
            // There are some things where there is a choice that has no choices .. ?
            if (cc is Choice && (cc as Choice).Content.Count == 0)
            {
                Trace.WriteLine(String.Format("Choice '{0}' has no content, property will not be rendered!", cc.Name), "warn");
                return String.Empty;
            }

            StringWriter sw = new StringWriter();
            
            // Output documentation
            if (cc.Documentation != null)
                sw.Write(DocumentationRenderer.Render(cc.Documentation, 2).Replace("<summary>",String.Format("<summary>({0}) ", cc.Conformance)));
            else if (cc is Property && (cc as Property).Type.ClassDocumentation != null)
                sw.Write(DocumentationRenderer.Render((cc as Property).Type.ClassDocumentation, 2).Replace("<summary>", String.Format("<summary>({0}) ", cc.Conformance)));

            // Correct documentation
            if (sw.ToString().Length == 0)
                sw.WriteLine("\t\t/// <summary>({0}) {1}</summary>", cc.Conformance, cc.BusinessName == null ? "Documentation was not found" : cc.BusinessName.Replace("\r", "").Replace("\n","").Replace("&", "&amp;"));

            // Markers
            foreach (String s in Enum.GetNames(typeof(MarkerAttribute.MarkerAttributeType)))
                if (Util.Util.PascalCase(cc.Name) == s)
                    sw.Write(CreateMarkerAttribute((MarkerAttribute.MarkerAttributeType)Enum.Parse(typeof(MarkerAttribute.MarkerAttributeType), s), 2));

            // Determine property attributes
            if (cc is Property)
            {
                #region Properties
                Property property = cc as Property;

                // JF - 19/04/10 : This code is used to support the collapsing of C# classes
                foreach(var annotation in property.Annotations)
                    if (annotation is CodeCollapseAnnotation)
                    {
                        CodeCollapseAnnotation cca = annotation as CodeCollapseAnnotation;
                        sw.Write("\t\t[PropertyCollapse(Name = \"{0}\", Order = {1}", cca.Name, cca.Order);

                        string fixedValueString = ""; // Create the fixed value string
                        if(cca.OriginalType != null && cca.OriginalType.Class != null)
                            foreach(var originalContent in cca.OriginalType.Class.Content) // Iterate through the original type's members
                                if (originalContent is Property && (originalContent as Property).PropertyType == MohawkCollege.EHR.gpmr.COR.Property.PropertyTypes.Structural &&
                                    !String.IsNullOrEmpty((originalContent as Property).FixedValue)) // If the member is a structural property and the value is fixed then add
                                    fixedValueString += String.Format("{0}={1}|", originalContent.Name, (originalContent as Property).FixedValue);

                        if (!String.IsNullOrEmpty(fixedValueString)) // Set the fixed value string
                            sw.Write(", FixedAttributeValues = \"{0}\"", fixedValueString.Substring(0, fixedValueString.Length - 1));

                        // Now end the property
                        sw.WriteLine(")]");
                    }


                // Property attribute
                sw.Write(CreatePropertyAttribute(cc as Property, ownerNs, 2, propertySort));

                sw.WriteLine("#if !WINDOWS_PHONE");
                // Set browsing off for fixed values
                if (property.FixedValue != null && property.PropertyType != Property.PropertyTypes.TraversableAssociation)
                {
                    sw.WriteLine("\t\t[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]");
                    sw.WriteLine("\t\t[System.ComponentModel.ReadOnly(true)]");
                    sw.WriteLine("\t\t[System.ComponentModel.Browsable(false)]");
                }

                // Designer category, etc
                sw.WriteLine("\t\t[System.ComponentModel.Category(\"{0}\")]", property.Conformance);
                sw.WriteLine("\t\t[System.ComponentModel.Description(\"{0}\")]", Util.Util.StringEscape(property.BusinessName != null ? property.BusinessName.Replace("\n","").Replace("\r","") : property.Name));
                // Which type converter?
                TypeReference tr = Datatypes.MapDatatype((cc as Property).Type);

                if (property.SupplierDomain != null)
                    sw.WriteLine("\t\t[System.ComponentModel.TypeConverter(typeof(MARC.Everest.Design.DataTypeConverter))]");
                else
                {
                    sw.WriteLine("\t\t[System.ComponentModel.TypeConverter(typeof(System.ComponentModel.ExpandableObjectConverter))]");
                    if (!(property.MaxOccurs != "1" &&
                    (!Datatypes.IsCollectionType(tr))))
                        sw.WriteLine("\t\t[System.ComponentModel.Editor(typeof(MARC.Everest.Design.NewInstanceTypeEditor), typeof(System.Drawing.Design.UITypeEditor))]");
                }
                // Default value
                if (property.DefaultValue != null)
                    sw.WriteLine("\t\t[System.ComponentModel.DefaultValue(\"{0}\")]", property.DefaultValue);
                sw.WriteLine("#endif");

                // Determine the datatype
                string dt = "";
                dt = CreateDatatypeRef(tr, property);

                sw.Write("\t\tpublic ");

               
                // Property name
                // IF the property name is equal to the generic parameter, we don't pascal case it
                // IF the property name is equal to the containing class name, we use the name of the datatype it references as the property name

                // Is this a backing property
                string pName = CreatePascalCasedName(cc as Property);

                // JF: Are there any members in the parent that we're overriding?
                string modifier = "virtual";

                if (property.Container != null && property.Container is Class)
                {
                    var containerClassRef = (property.Container as Class).BaseClass;
                    while (containerClassRef != null && containerClassRef.Class != null)
                    {
                        foreach (var content in containerClassRef.Class.Content)
                        {
                            if (content.ToString() == property.ToString())
                                modifier = "override";
                            else if (content is Property && CreatePascalCasedName(content as Property) == pName ||
                                content is Choice && CreatePascalCasedName(content as Choice) == pName)
                                modifier = "new virtual";

                        }
                        containerClassRef = containerClassRef.Class.BaseClass;
                    }

                }
                sw.Write("{0} ", modifier);
                
                // Is it a list?
                if (property.MaxOccurs != "1" &&
                    (!Datatypes.IsCollectionType(tr)))
                    sw.Write("List<{0}>", dt);
                else
                    sw.Write(dt);

                sw.Write(" {0} {{", pName);

                // Property fixed
                if ((property.FixedValue != null || (property.DefaultValue != null && (property.Conformance == ClassContent.ConformanceKind.Populated || property.Conformance == ClassContent.ConformanceKind.Mandatory))) && property.PropertyType != Property.PropertyTypes.TraversableAssociation
                    ) // Type Reference for default value
                {
                    if (property.SupplierDomain != null &&
                        dt.Contains(Util.Util.MakeFriendly(property.SupplierDomain.Name) + ">") &&
                        property.SupplierStrength == MohawkCollege.EHR.gpmr.COR.Property.CodingStrengthKind.CodedNoExtensions) // supplier domain is known
                    {
                        // Get the real supplier (value set, or code system if concept domain)
                        var splrCd = property.SupplierDomain as ConceptDomain;
                        var bindingDomain = property.SupplierDomain;
                        Enumeration.EnumerationValue ev = null;
                        if (splrCd != null && splrCd.ContextBinding != null &&
                            splrCd.ContextBinding.Count == 1)
                            bindingDomain = splrCd.ContextBinding[0];

                        ev = bindingDomain.GetEnumeratedLiterals().Find(o => o.Name == (property.FixedValue ?? property.DefaultValue));

                        if (ev == null) // Enumeration value is not known in the enumeration, fixed value fails
                        {
                            System.Diagnostics.Trace.WriteLine(String.Format("Can't find literal '{0}' in supplier domain for property '{1}'", property.FixedValue ?? property.DefaultValue, property.Name), "error");
                            sw.WriteLine(" get; set; }");
                        }
                        else if(!Datatypes.IsCollectionType(tr)) // Fixed value is known
                            sw.WriteLine(" get {{ return __{3}; }} set {{ __{3} = value; }} }}\r\n\t\tprivate {2} __{3} = {0}.{1};",
                            Util.Util.MakeFriendly(EnumerationRenderer.WillRender(bindingDomain)), Util.Util.PascalCase(ev.BusinessName ?? ev.Name), dt, Util.Util.MakeFriendly(cc.Name));
                        else // Fixed value is known but it is some sort of collection
                            sw.WriteLine(" get {{ return __{2}; }} set {{ __{2} = value; }} }}\r\n\t\tprivate {1} __{2} = MARC.Everest.Connectors.Util.Convert<{1}>(\"{0}\", false);",
                            property.FixedValue ?? property.DefaultValue, CreateDatatypeRef(property.Type, property), Util.Util.MakeFriendly(cc.Name));
                    }
                    else if (property.Type.Class == null)
                        sw.WriteLine(" get {{ return __{2}; }} set {{ __{2} = value; }} }}\r\n\t\tprivate {1} __{2} = MARC.Everest.Connectors.Util.Convert<{1}>(\"{0}\", false);",
                            property.FixedValue ?? property.DefaultValue, CreateDatatypeRef(property.Type, property), Util.Util.MakeFriendly(cc.Name));
                    else
                        sw.Write(" get; set; }");  // Can't be cast
                }
                else if (property.MaxOccurs != "1" &&
                    (!Datatypes.IsCollectionType(tr)))
                    sw.WriteLine(" get {{ return __{0}; }} set {{ __{0} = value; }} }}\r\n\t\tprivate List<{1}> __{0} = new List<{1}>();", Util.Util.MakeFriendly(cc.Name), dt);
                else
                    sw.WriteLine(" get; set; }");
                #endregion
            }  // cc is property
            else // cc is choice
            {
                // Find the base type 
                TypeReference tr = new TypeReference();
                Choice choice = cc as Choice;

                if (cc.Documentation != null)
                    sw.Write(DocumentationRenderer.Render(cc.Documentation, 2));
                else
                {
                    sw.WriteLine("\t\t/// <summary>\r\n\t\t/// Choice Of: <list><listheader><term>Traversal</term><description>Class</description></listheader>");
                    foreach (Property p in choice.Content)
                        sw.WriteLine("\t\t/// <item><term>{1}</term><description>When class is <see cref=\"T:{2}.{0}\"/></description></item>", p.Type, p.Name, ownerNs);
                    sw.WriteLine("\t\t/// </list></summary>");
                }

                // Create property attributes
                foreach (Property p in choice.Content)
                    sw.Write(CreatePropertyAttribute(p, ownerNs, 2, propertySort));


                // Write editor attributes
                sw.WriteLine("#if !WINDOWS_PHONE");
                sw.WriteLine("\t\t[System.ComponentModel.TypeConverter(typeof(System.ComponentModel.ExpandableObjectConverter))]");
                if (!(cc.MaxOccurs != "1" && !Datatypes.IsCollectionType(tr)))
                    sw.WriteLine("\t\t[System.ComponentModel.Editor(typeof(MARC.Everest.Design.NewInstanceTypeEditor), typeof(System.Drawing.Design.UITypeEditor))]");
                sw.WriteLine("#endif");
                // Get the type reference
                tr = (choice.Content[0] as Property).Type.Class.BaseClass;
                List<String> methods = new List<string>();
                StringBuilder getTraversalFor = new StringBuilder();

                foreach (Property p in choice.Content)
                {

                    // Set the property
                    if (p.Type.Class.BaseClass != null && tr != null && p.Type.Class.BaseClass.Name != tr.Name)
                        tr = null;

                    if (p.Type.Class != null && p.Type.Class.IsAbstract) continue; // don't output abstract classes

                    getTraversalFor.AppendFormat("\t\tif(this.$$pcName$$ is {0}) return \"{1}\";\r\n", CreateDatatypeRef(p.Type, p), p.Name);

                    // Generate getter

                    // Generate a SETProperty method that sets for this permutation
                    StringBuilder method_sb = new StringBuilder("\t\t");
                    method_sb.AppendFormat("/// <summary> Get <see cref=\"P:$$pcName$$\"/> cast as an instance of <see cref=\"T:{0}\"/>. This occurs when $$pcName$$ is represented as {1}. Null if <see cref=\"P:$$pcName$$\"/> is not an instance of <see cref=\"T:{0}\"/></summary>\r\n", CreateDatatypeRef(p.Type, p), p.Name);
                    method_sb.AppendFormat("public {0} Get$$pcName$$If{2}() {{ return this.$$pcName$$ as {0}; }}\r\n", CreateDatatypeRef(p.Type, p), Util.Util.MakeFriendly(p.Type.Name), Util.Util.PascalCase(p.Name));
                    method_sb.AppendFormat("/// <summary> Set <see cref=\"P:$$pcName$$\"/> to an instance of <see cref=\"T:{0}\"/> </summary>\r\n", CreateDatatypeRef(p.Type, p));
                    method_sb.AppendFormat("\t\t/// <param name=\"value\">The value to set $$pcName$$ to</param>\r\n");
                    method_sb.AppendFormat("\t\tpublic void Set$$pcName$$({0} value) {{ this.$$pcName$$ = value; }}\r\n", CreateDatatypeRef(p.Type, p));
                    methods.Add(method_sb.ToString());

                    // Generate a shortcut SETProperty method
                    if (factoryMethods.ContainsKey(p.Type.Name))
                    {
                        foreach (FactoryMethodInfo mi in factoryMethods[p.Type.Name])
                        {
                            method_sb = new StringBuilder();
                            StringBuilder methodSig = new StringBuilder();
                            method_sb.AppendFormat("\r\n\t\tpublic void Set{0}(", Util.Util.PascalCase(cc.Name));
                            methodSig.AppendFormat("public void Set{0}(", Util.Util.PascalCase(cc.Name));
                            // Get the parameters
                            foreach (string parm in mi.parameters)
                                if (parm.Length > 0)
                                {
                                    string mParm = parm;
                                    method_sb.AppendFormat("{0},", mParm);
                                    methodSig.AppendFormat("{0},", mParm.Substring(0, mParm.LastIndexOf(" ")));
                                }

                            method_sb.Remove(method_sb.Length - 1, 1);

                            // Ensure that we don't declare the same method signature twice
                            if (m_methodDeclarations.Contains(methodSig.ToString()))
                                continue;

                            // Add a declaration
                            m_methodDeclarations.Add(methodSig.ToString());

                            // Insert the documentation
                            method_sb.Insert(0, mi.documentation);
                            method_sb.Insert(0, String.Format("/// <summary> Set <see cref=\"P:{0}\"/> to an instance of <see cref=\"T:{1}\"/> using the parameters specified</summary>\r\n", Util.Util.PascalCase(cc.Name), p.Type.Name));


                            method_sb.AppendFormat(") {{ this.$$pcName$$ = {0}(", mi.name);
                            foreach (var parm in mi.parameters)
                                if (parm.Length > 0) method_sb.AppendFormat("{0},", parm.Split(' ')[1]);
                            method_sb.Remove(method_sb.Length - 1, 1);
                            method_sb.Append("); }");
                            methods.Add(method_sb.ToString());
                        }
                    }
                }


                // If no type reference is agreed to, then the type reference is Object!
                string dt = tr == null ? "System.Object" : CreateDatatypeRef(tr, choice.Content[0] as Property);

                sw.Write("\t\tpublic ");

                // Is it a list?
                if (cc.MaxOccurs != "1" &&
                    (!Datatypes.IsCollectionType(tr)))
                    sw.Write("List<{0}>", dt);
                else
                    sw.Write(dt);

                // Property name
                // IF the property name is equal to the generic parameter, we don't pascal case it
                // IF the property name is equal to the containing class name, we use the name of the datatype it references as the property name
                string pName = CreatePascalCasedName(choice);

                sw.WriteLine(" {0} {{ get; set; }}", pName);

                // Get traversal name
                sw.WriteLine("\t/// <summary>Gets the actual traversal name used for the choice property <see cref=\"P:{0}\"/>, null if traversal was not provided </summary>", Util.Util.PascalCase(cc.Name));
                sw.WriteLine("\tpublic String Get{0}TraversalName() {{", Util.Util.PascalCase(cc.Name));
                sw.WriteLine(getTraversalFor.Replace("$$pcName$$", pName));
                sw.WriteLine("\t\treturn null;");
                sw.WriteLine("\t}");

                // Write the setters
                foreach (string s in methods)
                    sw.WriteLine(s.Replace("$$pcName$$", pName));
            }
                
            return sw.ToString(); 
        }
Пример #39
0
        ///-----------------------------------------------------------------
        private void GatherVariants(int s, int[] slots, List <FunctionVariant> variants, ScriptContent data, ClassContent contentSrc, ClassContent contentDst)
        {
            if (s < slots.Length)
            {
                for (var p = 0; p < 2; p++)
                {
                    slots[s] = p;
                    GatherVariants(s + 1, slots, variants, data, contentSrc, contentDst);
                }
            }
            else
            {
                var variant = new FunctionVariant(2);
                for (var sv = 0; sv < slots.Length; sv++)
                {
                    if (slots[sv] == 0)
                    {
                        for (var i = 0; i < data.functionContents.Count; i++)
                        {
                            var info = data.functionContents[i].body;
                            info       = (Names[0] + contentSrc.names[sv * 2 + 0]).Apply(info);
                            info       = (Names[1] + contentSrc.names[sv * 2 + 1]).Apply(info);
                            variant[i] = info;
                        }
                    }
                }

                if (variant.Call != string.Empty)
                {
                    variants.Add(variant);
                }
            }
        }
Пример #40
0
        public Dictionary <String, IEnumerable <String> > GetPackageFiles(Schema Schema, String NamespaceName)
        {
            var NamespaceToClasses = new Dictionary <String, List <KeyValuePair <String, List <String> > > >();

            void AddClass(String ClassNamespaceName, String ClassName, IEnumerable <String> ClassContent)
            {
                if (!NamespaceToClasses.ContainsKey(ClassNamespaceName))
                {
                    NamespaceToClasses.Add(ClassNamespaceName, new List <KeyValuePair <String, List <String> > >());
                }
                NamespaceToClasses[ClassNamespaceName].Add(new KeyValuePair <String, List <String> >(ClassName, ClassContent.ToList()));
            }

            foreach (var c in Schema.Types)
            {
                if (c.OnPrimitive)
                {
                    if (c.VersionedName() == "Unit")
                    {
                        AddClass(c.NamespaceName(), "Unit", Primitive_Unit());
                    }
                    else if (c.VersionedName() == "Set")
                    {
                        AddClass(c.NamespaceName(), "Set", Primitive_Set());
                    }
                    else
                    {
                        var p = c.Primitive;
                        if (PrimitiveMapping.ContainsKey(p.VersionedName()))
                        {
                            var Name         = p.VersionedName();
                            var PlatformName = PrimitiveMapping[Name];
                            if (Name != PlatformName && p.GenericParameters.Count() == 0 && PlatformName != "Error")
                            {
                                AddClass(c.NamespaceName(), Name, Primitive(Name, PlatformName));
                            }
                            else
                            {
                                continue;
                            }
                        }
                    }
                }
                else if (c.OnAlias)
                {
                    AddClass(c.NamespaceName(), c.DefinitionName(), Alias(c.Alias));
                }
                else if (c.OnRecord)
                {
                    AddClass(c.NamespaceName(), c.DefinitionName(), Record(c.Record));
                }
                else if (c.OnTaggedUnion)
                {
                    AddClass(c.NamespaceName(), c.DefinitionName(), TaggedUnion(c.TaggedUnion));
                }
                else if (c.OnEnum)
                {
                    AddClass(c.NamespaceName(), c.DefinitionName(), Enum(c.Enum));
                }
                else if (c.OnClientCommand)
                {
                    var tc         = c.ClientCommand;
                    var RequestRef = GetSuffixedTypeRef(tc.Name, tc.Version, "Request");
                    var Request    = new RecordDef {
                        Name = RequestRef.Name, Version = RequestRef.Version, GenericParameters = new List <VariableDef> {
                        }, Fields = tc.OutParameters, Attributes = tc.Attributes, Description = tc.Description
                    };
                    var ReplyRef = GetSuffixedTypeRef(tc.Name, tc.Version, "Reply");
                    var Reply    = new TaggedUnionDef {
                        Name = ReplyRef.Name, Version = ReplyRef.Version, GenericParameters = new List <VariableDef> {
                        }, Alternatives = tc.InParameters, Attributes = tc.Attributes, Description = tc.Description
                    };
                    AddClass(c.NamespaceName(), Request.DefinitionName(), Record(Request));
                    AddClass(c.NamespaceName(), Reply.DefinitionName(), TaggedUnion(Reply));
                }
                else if (c.OnServerCommand)
                {
                    var tc       = c.ServerCommand;
                    var EventRef = GetSuffixedTypeRef(tc.Name, tc.Version, "Event");
                    var Event    = new RecordDef {
                        Name = EventRef.Name, Version = EventRef.Version, GenericParameters = new List <VariableDef> {
                        }, Fields = tc.OutParameters, Attributes = tc.Attributes, Description = tc.Description
                    };
                    AddClass(c.NamespaceName(), Event.DefinitionName(), Record(Event));
                }
                else
                {
                    throw new InvalidOperationException();
                }
            }

            var scg    = Schema.GetSchemaClosureGenerator();
            var sc     = scg.GetClosure(Schema.TypeRefs.Concat(Schema.Types), new List <TypeSpec> {
            });
            var Tuples = sc.TypeSpecs.Where(t => t.OnTuple).ToList();

            foreach (var t in Tuples)
            {
                AddClass(NamespaceName, t.SimpleName(NamespaceName), Tuple(t, NamespaceName));
            }

            var Commands = Schema.Types.Where(t => t.OnClientCommand || t.OnServerCommand).Where(t => t.Version() == "").ToList();

            if (Commands.Count > 0)
            {
                AddClass(NamespaceName, "IApplicationClient", IApplicationClient(Commands, NamespaceName));
            }

            return(NamespaceToClasses.SelectMany(p => p.Value.Select(v => new KeyValuePair <String, IEnumerable <String> >(String.Join("/", p.Key.Split('.').Where(NamespacePart => NamespacePart != "").Select(NamespacePart => LowercaseCamelize(NamespacePart)).Concat(new String[] { v.Key })), WrapModule(p.Key, Schema.Imports, v.Value)))).ToDictionary(p => p.Key, p => p.Value));
        }
Пример #41
0
        ///-----------------------------------------------------------------
        private void GatherVariantsSlots(int s, int[] slots, List <FunctionVariant> variants, ScriptContent data, ClassContent contentSrc, ClassContent contentDst)
        {
            var varCount = contentSrc.VarCount + 1;

            for (var c = 0; c < varCount; c++)
            {
                slots[s] = c;
                if (s + 1 < slots.Length)
                {
                    GatherVariantsSlots(s + 1, slots, variants, data, contentSrc, contentDst);
                }
                else
                {
                    if (data.classDefaultExportOnly)
                    {
                        var foundValid = false;
                        for (var exp = 0; exp < slots.Length; exp++)
                        {
                            if (slots[exp] >= contentSrc.VarCount)
                            {
                                foundValid = true;
                                break;
                            }
                        }

                        if (!foundValid)
                        {
                            continue;
                        }
                    }

                    var sn      = 0;
                    var variant = new FunctionVariant(3);
                    variant[1] += Glossary.Code.argsV;
                    for (var v = 0; v < slots.Length; v++)
                    {
                        var sv = slots[v];
                        if (sv < contentSrc.VarCount)
                        {
                            var name = sv < contentSrc.NameCount ? contentSrc.names[sv] : contentSrc.variables[sv];
                            variant.Call = name;
                            var variable = contentSrc.variables[sv];
                            variant[2] = string.Format(Glossary.Code.varsV, variable);
                        }
                        else
                        {
                            variant.Call = Glossary.Code.callN;
                            variant[1]   = string.Format(Glossary.Code.argsNOpt, data.classDefaultType, sn, data.classDefaultValue);
                            variant[2]   = string.Format(Glossary.Code.varsN, sn);
                            sn++;
                        }
                    }

                    if (sn != slots.Length)
                    {
                        variants.Add(variant);
                    }
                }
            }
        }
Пример #42
0
        public void AddContent(ClassContent c)
        {
            c.Container = this;
            content.Add(c);

            // Sort, any structural properties come before non structural props.
            content.Sort(new ClassContent.Comparator());
        }
        ///-----------------------------------------------------------------

        #region Rule internal
        protected override void GatherVariants(List <FunctionVariant> variants, ScriptContent scriptContent, ClassContent contentSrc, ClassContent contentDst)
        {
            keywords.Clear();
            identifiers.Clear();
            Glossary.Macros.GetTags(this);

            variants.Clear();
            if (scriptContent.functionContents.Count == 0)
            {
                return;
            }

            var result = string.Empty;

            for (var k = 0; k < keywords.Count; k++)
            {
                result += scriptContent.functionContents[0].body;
                result  = (Variables[0] + keywords[k]).Apply(result);
            }

            var variant = new FunctionVariant(result, 1);

            result = string.Empty;
            for (var i = 0; i < identifiers.Count; i++)
            {
                result += scriptContent.functionContents[0].body;
                result  = (Variables[0] + identifiers[i]).Apply(result);
            }

            variant[1] = result;
            variants.Add(variant);
        }
Пример #44
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;

        }