/// <summary> /// Write inline when condition /// </summary> private void WriteInlineWhenConditionCollapse(XmlWriter xw, Property p, List <TypeReference> genericSupplier, string interactionName) { // Resolve the type reference TypeReference tr = p.Type; if (ResolveTypeReference(tr.Name, genericSupplier) != null) { tr = ResolveTypeReference(p.Type.Name, genericSupplier); } // Annotations if (p.Annotations != null && p.Annotations.Count > 0) { // Get the root of the collapsing CodeCollapseAnnotation cca = p.Annotations.Find(o => o is CodeCollapseAnnotation && (o as CodeCollapseAnnotation).Order == 0) as CodeCollapseAnnotation; xw.WriteStartElement("when", NS_XSLT); xw.WriteAttributeString("test", string.Format("name() = '{0}'", cca.Name)); xw.WriteStartElement("for-each", NS_XSLT); string xpath = "."; // Annotations foreach (CodeCollapseAnnotation annot in p.Annotations.FindAll(o => o is CodeCollapseAnnotation && (o as CodeCollapseAnnotation).Order > 0)) { if (annot.Property != null && (annot.Property as Property).AlternateTraversalNames != null) { Property.AlternateTraversalData altTraversal = (annot.Property as Property).AlternateTraversalNames.Find(o => o.CaseWhen.Name == ResolveTypeReference(p.Type.Name, genericSupplier).Name&& o.InteractionOwner.Name == interactionName); if (altTraversal.TraversalName != null) { xpath += string.Format("/hl7:{0}", altTraversal.TraversalName); } } else { xpath += string.Format("/hl7:{0}", annot.Name); } } xw.WriteAttributeString("select", xpath); // Inline element map collapse WriteInlineElementMapCollapse(xw, p, p.Type, genericSupplier, interactionName); xw.WriteEndElement(); // for-each xw.WriteEndElement(); // test } else if (p.AlternateTraversalNames == null || p.AlternateTraversalNames.Count == 0) // Alternate traversal names { xw.WriteStartElement("when", NS_XSLT); xw.WriteAttributeString("test", String.Format("name() = '{0}'", p.Name)); // Write structural property if (p.PropertyType == Property.PropertyTypes.Structural) { WriteInlineAttributeMapCollapse(xw, p); } else { WriteInlineElementMapCollapse(xw, p, p.Type, genericSupplier, interactionName); } xw.WriteEndElement(); // when } else if (tr.Class != null && tr.Class.IsAbstract) { WriteInlineAbstractWhenCondition(xw, tr, p, genericSupplier, interactionName); } else { xw.WriteStartElement("when", NS_XSLT); // Find the altTraversal Property.AlternateTraversalData altTraversal = p.AlternateTraversalNames.Find(o => o.CaseWhen.Name == tr.Name); // Alternate traversal // Alternate traversal if (altTraversal.TraversalName != null) { xw.WriteAttributeString("test", string.Format("name() = '{0}'", altTraversal.TraversalName)); } else { xw.WriteAttributeString("test", string.Format("name() = '{0}'", p.Name)); } // Write the taversing WriteInlineElementMapCollapse(xw, p, p.Type, genericSupplier, interactionName); xw.WriteEndElement(); } }
/// <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; } }