public static TypeReference MapDatatype(TypeReference t) { var m = t.MemberOf; var g = t.Container; t = t.Clone() as TypeReference; t.MemberOf = m; t.Container = g; TypeReference retVal = t.Clone() as TypeReference; // Create a type reference var type = s_heuristicData.Datatypes.Find(o => o.MifDatatype == t.Name + (t.Flavor != null ? "." + t.Flavor : "")); if(type == null && !String.IsNullOrEmpty(t.Flavor )) type = s_heuristicData.Datatypes.Find(o => o.MifDatatype == t.Name); if (t is TypeParameter) return t; else if (t.Name == null) retVal.Name = "java.lang.Object"; else if (type != null) { retVal.Name = type.JavaType; //if (!String.IsNullOrEmpty(type.TemplateParameter)) // retVal.Name = String.Format("{0}.datatypes.generic.{1}", s_apiNs, retVal.Name); //else // retVal.Name = String.Format("{0}.datatypes.{1}", s_apiNs, retVal.Name); retVal.MemberOf = t.MemberOf; retVal.GenericSupplier = t.GenericSupplier; if (t.Name != retVal.Name) retVal.Flavor = null; // Clear flavors if pointing to a new type // Default binding information var tParm = type.DefaultBind; if ((t.GenericSupplier == null || t.GenericSupplier.Count == 0) && !String.IsNullOrEmpty(tParm)) { retVal.AddGenericSupplier("def", MapDatatype(new TypeReference() { Name = tParm })); } } // Default member? return retVal; }
private string GenerateFactoryMethod(TypeReference tr, string ownerNs) { StringWriter sw = new StringWriter(); Dictionary<string, string[]> cfm = ClassRenderer.CreateFactoryMethod(tr, "retVal", true); if (tr.Class != null && tr.Class.IsAbstract) { foreach (var chld in tr.Class.SpecializedBy) sw.WriteLine(GenerateFactoryMethod(chld, ownerNs)); } else { string factoryName = String.Format("Create{0}", tr.Class.Name), tfact = factoryName; if (generatedFactoryMethods.Contains(factoryName)) factoryName = String.Format("Create{0}", Util.Util.MakeFriendly(tr.Name)); generatedFactoryMethods.Add(factoryName); // Iterate and create shortcuts List<String> wroteParms = new List<string>(); // Keep track of the parameters used foreach (KeyValuePair<String, String[]> kv in cfm) { if (kv.Value[0].Length == 0 || wroteParms.Contains(kv.Value[0])) continue; wroteParms.Add(kv.Value[0]); // Correct generic children // TODO: Turn these into regexes //if (tr.Class.TypeParameters != null) // for (int i = 0; i < tr.Class.TypeParameters.Count; i++) // { // List<TypeReference> filler = tr.GenericSupplier == null ? new List<TypeReference>() : tr.GenericSupplier.FindAll(o => (o as TypeParameter).ParameterName == tr.Class.TypeParameters[i].ParameterName); // for(int f = 0; f< 2; f++) // if (filler.Count == 1) // foreach(string replacement in replaceMe) // kv.Value[f] = kv.Value[f].Replace(String.Format(replacement, tr.Class.TypeParameters[i].ParameterName), String.Format(replacement, filler[0].Name)); // else // foreach (string replacement in replaceMe) // kv.Value[f] = kv.Value[f].Replace(String.Format(replacement, tr.Class.TypeParameters[i].ParameterName), String.Format(replacement, "System.Object")); // } // Generate method(s) Class cls = tr.Class; sw.WriteLine("\t\t/// <summary> Create a new instance of {0} to populate {1} </summary>", tr.Name, tr is TypeParameter ? (tr as TypeParameter).ParameterName : ""); sw.Write(kv.Value[2]); sw.WriteLine("\t\tpublic static {0} {1} ({2}) {{ \r\n\t\t\t{0} retVal = new {0}();\r\n{3}", ClassRenderer.CreateDatatypeRef(tr, new Property()), factoryName, kv.Value[0].Substring(0, kv.Value[0].Length - 1), kv.Value[1]); sw.WriteLine("\t\t\treturn retVal;\r\n\t\t}"); if (!wroteParms.Contains("")) { wroteParms.Add(""); sw.WriteLine("\t\t/// <summary> Create a new instance of {0} to populate {1} </summary>", tr.Name, tr.Class.Name); sw.WriteLine("\t\tpublic static {0} {1} () {{ \r\n\t\t\treturn new {0}();\r\n\t\t}}", ClassRenderer.CreateDatatypeRef(tr, new Property()), factoryName); } } foreach (TypeReference tpr in tr.GenericSupplier ?? new List<TypeReference>()) sw.WriteLine(GenerateFactoryMethod(tpr, ownerNs)); } return sw.ToString(); }
/// <summary> /// Add a generic supplier to the type reference /// </summary> public void AddGenericSupplier(string parameterName, TypeReference typeReference, bool throwOnError) { if (GenericSupplier == null) GenericSupplier = new List<TypeReference>(); // Sanity check if (Class != null && (Class.TypeParameters == null || Class.TypeParameters.Find(o => o.ParameterName == parameterName) == null)) throw new InvalidOperationException(string.Format("Can't assign type parameter '{0}' on class '{1}' as no such parameter exists", parameterName, Name)); TypeParameter tp = new TypeParameter(); tp.ParameterName = parameterName; tp.Name = typeReference.name; tp.container = typeReference.container; tp.MemberOf = typeReference.MemberOf; tp.GenericSupplier = typeReference.GenericSupplier; tp.Flavor = typeReference.Flavor; // Turns out that the generic supplier can in fact contain more than one traversal name // for different types that are placed at the point of contact... soo... // this can cause if (GenericSupplier.Exists(o => (o as TypeParameter).ParameterName.Equals(tp.ParameterName)) && throwOnError) throw new ArgumentException(String.Format("More than one supplier is provided for the same type parameter '{0}' on class '{1}'. This is not permitted!", tp.ParameterName, Name)); GenericSupplier.Add(tp); }
/// <summary> /// Make a schema friendly CORE datatype name (ie: Convert IVL<TS> to IVL_TS) /// </summary> /// <param name="typeReference"></param> /// <returns></returns> private string MakeSchemaFriendlyCoreType(TypeReference typeReference) { string retVal = typeReference.CoreDatatypeName; foreach (TypeReference tr in typeReference.GenericSupplier ?? new List<TypeReference>()) retVal += "_" + tr.CoreDatatypeName; return retVal; }
/// <summary> /// Write inline apply template call /// </summary> private void WriteInlineApplyTemplate(XmlWriter xw, Property p, TypeReference tr, List<TypeReference> genericSupplier) { if(!requiredTemplates.Contains(tr.Name)) requiredTemplates.Add(tr.Name); // Write the xsl:apply-template xw.WriteStartElement("call-template", NS_XSLT); xw.WriteAttributeString("name", tr.Name); xw.WriteEndElement(); // call-template }
/// <summary> /// Write an inline abstract when condition /// </summary> private void WriteInlineAbstractWhenCondition(XmlWriter xw, TypeReference tr, Property p, List<TypeReference> genericSupplier, string interactionName) { foreach (TypeReference child in tr.Class.SpecializedBy) { if (child.Class.IsAbstract) WriteInlineAbstractWhenCondition(xw, child, p, genericSupplier, interactionName); else { xw.WriteStartElement("when", NS_XSLT); // Find the altTraversal Property.AlternateTraversalData altTraversal = p.AlternateTraversalNames.Find(o => o.CaseWhen.Name == child.Name); // Alternate traversal // Traversal was found if (altTraversal.TraversalName != null) xw.WriteAttributeString("test", string.Format("name() = '{0}'", altTraversal.TraversalName)); else throw new InvalidOperationException(String.Format("Can't find traversal for alternative data for '{0}' when type is '{1}'...", p.Name, child.Name)); // Perform the inline element map if (p.AlternateTraversalNames == null || p.AlternateTraversalNames.Count == 0) xw.WriteStartElement(p.Name, TargetNamespace); // p.name else { Property.AlternateTraversalData traversal = p.AlternateTraversalNames.Find(o => o.CaseWhen.Name == child.Name); if (traversal.TraversalName != null) // found an alt traversal xw.WriteStartElement(traversal.TraversalName, TargetNamespace); else xw.WriteStartElement(p.Name, TargetNamespace); // fall back to the property name } WriteInlineApplyTemplate(xw, p, child, genericSupplier); xw.WriteEndElement(); // p.name xw.WriteEndElement(); // when } } }
/// <summary> /// Get overridden setters /// </summary> public static SetterOverrideData[] GetOverrideSetters(TypeReference tr, Property p, string ownerPackage) { // Not a datatype so we won't need overrides if(tr.Class != null) return new SetterOverrideData[0]; // Get all the setter overrides var dataType = s_heuristicData.Datatypes.Find(o => o.MifDatatype == tr.Name); // Sanity check if(dataType == null || dataType.SetterOverride.Count == 0) return new SetterOverrideData[0]; // Set generic paramaters Dictionary<String, String> bind = new Dictionary<string, string>(); string fillParameter = dataType.TemplateParameter; if (!String.IsNullOrEmpty(dataType.TemplateParameter)) { int i = 0; foreach (string s in dataType.TemplateParameter.Split(',')) { TypeReference bindTypeRef = null; if (tr.GenericSupplier != null) // Generic Supplier { bindTypeRef = tr.GenericSupplier.Find(o => o is TypeParameter && (o as TypeParameter).ParameterName == s); if (bindTypeRef == null) bindTypeRef = tr.GenericSupplier[i++]; } else if (p != null && p.SupplierDomain != null && !String.IsNullOrEmpty(EnumerationRenderer.WillRender(p.SupplierDomain))) { string vocabName = Util.Util.MakeFriendly(EnumerationRenderer.WillRender(p.SupplierDomain)); string containerName = p.Container is Choice ? (p.Container as Choice).Container.Name : p.Container.Name; if(vocabName.Equals(containerName)) vocabName = String.Format("{0}.vocabulary.{1}", ownerPackage, vocabName); bindTypeRef = new TypeReference() { Name = String.Format("{0}", vocabName) }; } else bindTypeRef = new TypeReference() { Name = dataType.DefaultBind }; // Add Binding bind.Add(s, ClassRenderer.CreateDatatypeRef(bindTypeRef ?? new TypeReference() { Name = null }, null, ownerPackage)); fillParameter = fillParameter.Replace(s, bind[s]); } } // Create setter override and return List<SetterOverrideData> overrides = new List<SetterOverrideData>(dataType.SetterOverride.Count); foreach (var sod in dataType.SetterOverride) { // Correct parameters SetterOverrideData templatedSod = new SetterOverrideData(); templatedSod.Parameters = new List<PropertyInfoData>(); foreach (var parameterData in sod.Parameters) { string dt = String.Empty; if (!bind.TryGetValue(parameterData.DataType, out dt)) dt = parameterData.DataType; templatedSod.Parameters.Add(new PropertyInfoData() { Name = parameterData.Name, DataType = dt.Replace(string.Format("<{0}>", dataType.TemplateParameter), String.Format("<{0}>", fillParameter)) }); } // Correct Body templatedSod.Throws = new List<ThrowsData>(sod.Throws); templatedSod.SetterText = sod.SetterText.Replace(string.Format("<{0}>", dataType.TemplateParameter), String.Format("<{0}>", fillParameter)); templatedSod.ValueInstance = sod.ValueInstance; overrides.Add(templatedSod); } return overrides.ToArray(); }
/// <summary> /// Write an inline for-each element that expands /// </summary> private void WriteInlineForeachExpand(XmlWriter xw, TypeReference tr, List<TypeReference> genericSupplier, string interactionName) { // Clone the class Class clsTr = tr.Class.Clone() as Class; clsTr.MemberOf = tr.Class.MemberOf; // Correct the inheritence if (clsTr.BaseClass == null && clsTr.Name != "InfrastructureRoot") clsTr.BaseClass = (clsTr.MemberOf["RIM.InfrastructureRoot"] as Class).CreateTypeReference(); List<ClassContent> elements = clsTr.GetFullContent(); // Write any attributes // JF- To Support proper ordering //xw.WriteStartElement("for-each", NS_XSLT); //xw.WriteAttributeString("select", String.Format("@* | child::node()[namespace-uri() = '{0}']", NS_SRC)); //xw.WriteStartElement("choose", NS_XSLT); int nc = 0; // Write the element data foreach (ClassContent cc in elements) { if (cc is Property) { Property p = cc as Property; nc += Convert.ToUInt16(WriteInlineWhenConditionExpand(xw, p, genericSupplier, interactionName)); } else if (cc is Choice) // JF: Bug with choice selection { Choice c = cc as Choice; WriteInlineChooseWhenExpand(xw, c, genericSupplier, interactionName); } } // HACK: As an XS:Choose element must have at least one when element //if (nc == 0) //{ // xw.WriteStartElement("when", NS_XSLT); // xw.WriteAttributeString("test", "1=2"); // xw.WriteEndElement(); // when //} // JF- To support proper ordering //xw.WriteEndElement(); // choose //xw.WriteEndElement(); // foreach }
/// <summary> /// Generates a deep condition string for the specified property and type reference /// </summary> private string GenerateDeepConditionString(Property p, TypeReference tr, List<string> properties, List<TypeReference> genericSupplier) { // Get the RIM Realization Property rimName = null; // Is this representative of some sort of RIM structure? if ((p.Container is Class) && (p.Container as Class).ContainerName == "RIM") // This is a rim property rimName = p; else if (p.Container is Choice && (p.Container as Choice).Realization != null && (p.Container as Choice).Realization.Count > 0) rimName = (p.Container as Choice).Realization[0] as Property; else if (p.Realization == null || p.Realization.Count == 0) return ""; else rimName = p.Realization[0] as Property; // Get fixed elements List<Property> fixedElements = FlattenPropertyHierarchy(tr.Class.Content).FindAll(o => o.Realization != null && (o.MinOccurs != "0" || o.FixedValue != null)); string retVal = "", root = "", currentLevelSelector = ""; if (properties.Count == 0) // Initial node { retVal = String.Format("local-name() = '{0}' {1}", rimName.Name, GenerateConditionString(p, tr, ".", genericSupplier)); properties.Add("."); } // Generate the root foreach(var property in properties) root += String.Format("{0}/", property); foreach (var element in fixedElements.FindAll(o=>o.PropertyType != Property.PropertyTypes.Structural)) { string tStr = GenerateConditionString(element, null, ".", genericSupplier); retVal += string.Format(" and {0}hl7:{1}[{2}]", root, element.Realization[0].Name, string.IsNullOrEmpty(tStr) ? "1" : tStr.Substring(4)); // Recurse if (element.Type.Class != null) { properties.Add(String.Format("hl7:{0}[{1}]", element.Realization[0].Name, string.IsNullOrEmpty(tStr) ? "1" : tStr.Substring(4))); string tStrNested = GenerateDeepConditionString(element, element.Type, properties, genericSupplier); if(!String.IsNullOrEmpty(tStrNested)) retVal += String.Format(" {0}", tStrNested); properties.RemoveAt(properties.Count - 1); // Pop the current properties } } return retVal; }
/// <summary> /// Write inline element map collapse /// </summary> private void WriteInlineElementMapCollapse(XmlWriter xw, Property p, TypeReference tr, List<TypeReference> genericSupplier, string interactionName) { Property rimName = null; // Is this representative of some sort of RIM structure? if ((p.Container is Class) && (p.Container as Class).ContainerName == "RIM") // This is a rim property rimName = p; else if (p.Container is Choice && (p.Container as Choice).Realization != null && (p.Container as Choice).Realization.Count > 0) rimName = (p.Container as Choice).Realization[0] as Property; else if (p.Realization == null || p.Realization.Count == 0) { xw.WriteElementString("comment", NS_XSLT, String.Format("TODO: Can't realize property '{0}' in the RIM as no realization data was found", p.Name)); //rimName = p; return; } else rimName = p.Realization[0] as Property; if (ResolveTypeReference(tr.Name, genericSupplier) != null) tr = ResolveTypeReference(p.Type.Name, genericSupplier); if (rimName.AlternateTraversalNames == null || rimName.AlternateTraversalNames.Count == 0) { xw.WriteStartElement(rimName.Name, NS_SRC); // p.name if (tr.Class != null) { //xw.WriteStartElement("attribute", NS_XSLT); //xw.WriteAttributeString("name", "type"); //xw.WriteAttributeString("namespace", "urn:marc-hi:ca/hial"); //xw.WriteString(tr.Name); //xw.WriteEndElement(); // attribute } } else { xw.WriteElementString("comment", NS_XSLT, "TODO: Alternate traversal names aren't represented! Perhaps this will be a choice?"); //Property.AlternateTraversalData traversal = p.AlternateTraversalNames.Find(o => o.CaseWhen.Name == tr.Name); //if (traversal.TraversalName != null) // found an alt traversal // xw.WriteStartElement(traversal.TraversalName, TargetNamespace); //else // xw.WriteStartElement(p.Name, TargetNamespace); // fall back to the property name } // HACK: Need to know what the semantics text of the type is if (p.Type.Class != null && p.Type.Class.Realizations != null && p.Type.Class.Realizations.Count > 0 && p.Type.Class.Realizations[0].Class != null && p.Type.Class.Realizations[0].Class.Content.Find(o => o.Name == "semanticsText") != null && tr.Class != null && tr.Class.Content.Find(o => o.Name == "semText") == null) tr.Class.AddContent(new Property() { Name = "semText", PropertyType = Property.PropertyTypes.Structural, Type = new TypeReference() { Name = "ST" }, FixedValue = p.Name, MinOccurs = "1", MaxOccurs = "1" }); // Determine if this should be a genericized parameter WriteInlineTypeMap(xw, tr, genericSupplier, interactionName, p.PropertyType, rimName.PropertyType); xw.WriteEndElement(); // p.name }
/// <summary> /// Write an inline type mapping for the TypeReference specified /// </summary> private void WriteInlineTypeMap(XmlWriter xw, TypeReference tr, List<TypeReference> genericSupplier, string interactionName, Property.PropertyTypes srcType, Property.PropertyTypes destType) { List<String> collectionTypes = new List<string>() { "SET", "LIST", "QSET", "DSET", "HIST", "BAG" }; if (collectionTypes.Contains(tr.CoreDatatypeName ?? "") && tr.GenericSupplier.Count == 1) // Collection tr = tr.GenericSupplier[0]; else if (collectionTypes.Contains(tr.CoreDatatypeName ?? "")) { System.Diagnostics.Trace.WriteLine(String.Format("Can't handle a collection ({0}) with more than one generic parameter", tr.ToString()), "warn"); return; } string schemaFriendlyName = MakeSchemaFriendlyCoreType(tr); // Map the type if (dataTypeMaps.ContainsKey(schemaFriendlyName ?? "")) // simple map { if (dataTypeMaps[schemaFriendlyName ?? ""].LocalName == "for-each") { // Call the template for strait map only if the property type hasn't changed if (srcType.Equals(destType)) { xw.WriteStartElement("call-template", NS_XSLT); xw.WriteAttributeString("name", "dtMap"); //xw.WriteStartElement("copy-of", NS_XSLT); //xw.WriteAttributeString("select", "."); //xw.WriteEndElement(); xw.WriteEndElement(); // call-template } else { xw.WriteStartElement("value-of", NS_XSLT); xw.WriteAttributeString("select", "."); xw.WriteEndElement(); // value-of } } else dataTypeMaps[schemaFriendlyName ?? ""].WriteTo(xw); } else if (IsRecursiveReference(tr, tr, new List<string>())) // complex map WriteInlineApplyTemplate(xw, tr.Container as Property, tr, genericSupplier); else if (tr.Class != null) WriteInlineForeachCollapse(xw, tr, genericSupplier, interactionName); //else //System.Diagnostics.Debugger.Break(); }
public void AddTraversalName(string TraversalName, TypeReference CaseWhen, Interaction InteractionOwner) { if (CaseWhen != null && CaseWhen.MemberOf == null) CaseWhen.MemberOf = this.MemberOf ?? this.Container.MemberOf; if (AlternateTraversalNames == null) AlternateTraversalNames = new List<AlternateTraversalData>(); AlternateTraversalNames.Add(new AlternateTraversalData() { CaseWhen = CaseWhen, TraversalName = TraversalName, InteractionOwner = InteractionOwner }); }
public void AddTraversalName(string TraversalName, TypeReference CaseWhen) { if (AlternateTraversalNames == null) AlternateTraversalNames = new List<AlternateTraversalData>(); AlternateTraversalNames.Add(new AlternateTraversalData() { CaseWhen = CaseWhen, TraversalName = TraversalName}); }
public TypeReference CreateTypeReference() { TypeReference tr = new TypeReference(); tr.Name = string.Format("{0}.{1}", this.ContainerName, Name); tr.Container = new Property(); tr.Container.Container = this; tr.Flavor = null; tr.GenericSupplier = null; tr.cachedClassRef = this; tr.MemberOf = this.MemberOf ?? this.ContainerPackage.MemberOf; return tr; }
private void ProcessSpecializations(ParameterModel p, List<AssociationEndSpecialization> list, TypeReference baseRef, MohawkCollege.EHR.gpmr.COR.Interaction interactionModel, TypeReference hint) { TypeReference parmRef = null; foreach (var specialization in list) // This shouldn't ever be done ... ever, but this is v3 land { Class specClass = (ClassRepository[p.ToString(MifCompiler.NAME_FORMAT)] as MohawkCollege.EHR.gpmr.COR.SubSystem).OwnedClasses.Find(c => c.Name == specialization.ClassName); if(specClass == null && hint != null) { // Find all sub-classes and see if the hint contains them TypeReference specClassRef = hint.Class.SpecializedBy.Find(o => o.Class.Name == specialization.ClassName); // Make the reference a concreate COR class if (specClassRef != null) specClass = specClassRef.Class; } if (specClass == null) // Do a CMET lookup { MohawkCollege.EHR.gpmr.COR.Feature cmetFeature = null; if (ClassRepository.TryGetValue(specialization.ClassName, out cmetFeature)) specClass = (cmetFeature as CommonTypeReference).Class.Class; else { System.Diagnostics.Trace.WriteLine(string.Format("Can't find specialization '{0}' for parameter '{1}' this traversal will be ignored.", specialization.ClassName, p.ParameterName), "warn"); continue; } } parmRef = specClass.CreateTypeReference(); // Append the traversal name AppendTraversalName(baseRef, p.ParameterName, specialization.TraversalName, parmRef, interactionModel, new Stack<string>()); if (specialization.Specialization.Count > 0) ProcessSpecializations(p, specialization.Specialization, baseRef, interactionModel, parmRef); } }
/// <summary> /// Write an inline abstract when condition for expansion /// </summary> private void WriteInlineAbstractWhenConditionExpand(XmlWriter xw, TypeReference tr, Property p, List<TypeReference> genericSupplier, string interactionName) { List<String> currentConditions = new List<string>(); foreach (TypeReference child in tr.Class.SpecializedBy) { if (child.Class.IsAbstract) WriteInlineAbstractWhenConditionExpand(xw, child, p, genericSupplier, interactionName); else { // Perform the inline element map Property rimName = null; // Is this representative of some sort of RIM structure? if ((p.Container is Class) && (p.Container as Class).ContainerName == "RIM") // This is a rim property rimName = p; else if (p.Realization == null || p.Realization.Count == 0) { // xw.WriteElementString("comment", NS_XSLT, String.Format("TODO: Can't realize property '{0}' in the RIM as no realization data was found", p.Name)); rimName = p; //return; } else rimName = p.Realization[0] as Property; // Calculate the test condition string s = String.Format("local-name() = '{0}' {1} and ./@*[local-name() = 'type'] = '{2}'", rimName.Name, GenerateConditionString(p, child, ".", genericSupplier), child.Name); //s = CascadeConditionString(s, child, null, genericSupplier); if (currentConditions.Contains(s)) continue; // break out as we have already processed this. // JF- Support Ordering //xw.WriteStartElement("when", NS_XSLT); //xw.WriteAttributeString("test", s); xw.WriteStartElement("for-each", NS_XSLT); xw.WriteAttributeString("select", String.Format("./*[{0}]", s)); // Write the apply template if (p.AlternateTraversalNames == null || p.AlternateTraversalNames.Count == 0) xw.WriteStartElement(p.Name, NS_SRC); // p.name else { Property.AlternateTraversalData traversal = p.AlternateTraversalNames.Find(o => o.CaseWhen.Name == child.Name && interactionName == o.InteractionOwner.Name); if (traversal.TraversalName != null) // found an alt traversal xw.WriteStartElement(traversal.TraversalName, NS_SRC); else { traversal = p.AlternateTraversalNames.Find(o => o.CaseWhen.Name == child.Name && o.InteractionOwner == null); if (traversal.TraversalName != null) xw.WriteStartElement(traversal.TraversalName, NS_SRC); else xw.WriteStartElement(p.Name, NS_SRC); // fall back to the property name } } // Determine if there are any other sibling classes that have the same classification as this List<TypeReference> matching = tr.Class.SpecializedBy.FindAll(o => String.Format("local-name() = '{0}' {1}", rimName.Name, GenerateConditionString(p, o, ".", genericSupplier)) == s); currentConditions.Add(s); TypeReference trGenerated = child; if (matching.Count > 1) // There are members that can be combined! // Now the dangerous part trGenerated = GenerateCombinedType(matching); // Perform the inline element map WriteInlineApplyTemplate(xw, p, trGenerated, genericSupplier); xw.WriteEndElement(); // p.name xw.WriteEndElement(); // when } } }
public void Compile() { // Already processing? if (interactionModel == null || processingStack.Contains(interactionModel.PackageLocation.ToString(MifCompiler.NAME_FORMAT))) return; // Add to the processing stack processingStack.Add(interactionModel.PackageLocation.ToString(MifCompiler.NAME_FORMAT)); // Otput the name of the package. System.Diagnostics.Trace.WriteLine(string.Format("Compiling interaction model package '{0}'...", interactionModel.PackageLocation.ToString(MifCompiler.NAME_FORMAT)), "debug"); // Check if the package has already been "compiled" if (ClassRepository.ContainsKey(interactionModel.PackageLocation.ToString(MifCompiler.NAME_FORMAT))) return; // Already compiled // Process the interaction MohawkCollege.EHR.gpmr.COR.Interaction interaction = new MohawkCollege.EHR.gpmr.COR.Interaction(); interaction.Name = interactionModel.PackageLocation.ToString(MifCompiler.NAME_FORMAT); //interaction.Realm = interactionModel.PackageLocation.Realm; // Process business names foreach (BusinessName bn in interactionModel.BusinessName ?? new List<BusinessName>()) if (bn.Language == MifCompiler.Language || bn.Language == null) interaction.BusinessName = bn.Name; // Process documentation if(interactionModel.Annotations != null) interaction.Documentation = DocumentationParser.Parse(interactionModel.Annotations.Documentation); // Set the derivation from pointer interaction.DerivedFrom = interactionModel; // Trigger event interaction.TriggerEvent = interactionModel.InvokingTriggerEvent.ToString(MifCompiler.NAME_FORMAT); // Types TypeReference tr = new TypeReference(); // Has the entry class been created yet? if (!ClassRepository.ContainsKey(interactionModel.ArgumentMessage.ToString(MifCompiler.NAME_FORMAT))) // Process PackageParser.Parse(interactionModel.ArgumentMessage.ToString(MifCompiler.NAME_FORMAT), repository, ClassRepository); var entry = (ClassRepository[interactionModel.ArgumentMessage.ToString(MifCompiler.NAME_FORMAT)] as MohawkCollege.EHR.gpmr.COR.SubSystem); // Could we even find the model? if (entry == null) { System.Diagnostics.Trace.WriteLine(string.Format("Could not find the argument message '{0}', interaction '{1}' can't be processed", interactionModel.ArgumentMessage.ToString(MifCompiler.NAME_FORMAT), interaction.Name), "error"); return; } else if (entry.EntryPoint.Count == 0) { System.Diagnostics.Trace.WriteLine(string.Format("Argument message '{0}' must have an entry point, interaction '{1}' can't be processed", entry.Name, interaction.Name), "error"); return; } else if (entry.EntryPoint.Count != 1) { System.Diagnostics.Trace.WriteLine(string.Format("Ambiguous entry point for argument message '{0}', interaction '{1}' can't be processed", entry.Name, interaction.Name), "error"); return; } // Set the entry class tr = entry.EntryPoint[0].CreateTypeReference(); tr.MemberOf = ClassRepository; // Set member of property ProcessTypeParameters(interactionModel.ArgumentMessage.ParameterModel, tr, interaction); interaction.MessageType = tr; #region Response types if (interactionModel.ReceiverResponsibilities != null) { // Create the array interaction.Responses = new List<MohawkCollege.EHR.gpmr.COR.Interaction>(); // Iterate through foreach (ReceiverResponsibility rr in interactionModel.ReceiverResponsibilities) { if (rr.InvokeInteraction == null) { System.Diagnostics.Trace.WriteLine("Invoking interaction on receiver responsibility is missing", "warn"); continue; } // Does the receiver responsibility exist in the class repository if (!ClassRepository.ContainsKey(rr.InvokeInteraction.ToString(MifCompiler.NAME_FORMAT))) { InteractionCompiler icc = new InteractionCompiler(); icc.PackageRepository = repository; icc.Package = repository.Find(o => o.PackageLocation.ToString(MifCompiler.NAME_FORMAT) == rr.InvokeInteraction.ToString(MifCompiler.NAME_FORMAT)); icc.ClassRepository = ClassRepository; icc.Compile(); } MohawkCollege.EHR.gpmr.COR.Feature foundFeature = null; if (ClassRepository.TryGetValue(rr.InvokeInteraction.ToString(MifCompiler.NAME_FORMAT), out foundFeature)) { // Reason element for documentation if (rr.Reason != null && (rr.Reason.Language == MifCompiler.Language || rr.Reason.Language == null) && (rr.Reason.MarkupElements != null || rr.Reason.MarkupText != null)) { MohawkCollege.EHR.gpmr.COR.Documentation.TitledDocumentation td= new MohawkCollege.EHR.gpmr.COR.Documentation.TitledDocumentation() { Title = "Reason", Name = "Reason", Text = new List<string>() }; if (rr.Reason.MarkupText != null) td.Text.Add(rr.Reason.MarkupText); if(rr.Reason.MarkupElements != null) foreach(XmlElement xe in rr.Reason.MarkupElements) td.Text.Add(xe.OuterXml.Replace(" xmlns:html=\"http://www.w3.org/1999/xhtml\"", "").Replace("html:", "")); // Append the documentation if (interaction.Documentation == null) interaction.Documentation = new MohawkCollege.EHR.gpmr.COR.Documentation(); if (interaction.Documentation.Other == null) interaction.Documentation.Other = new List<MohawkCollege.EHR.gpmr.COR.Documentation.TitledDocumentation>(); interaction.Documentation.Other.Add(td); } interaction.Responses.Add(foundFeature as MohawkCollege.EHR.gpmr.COR.Interaction); } else System.Diagnostics.Trace.WriteLine(String.Format("Can't find response interaction '{0}'...", rr.InvokeInteraction.ToString(MifCompiler.NAME_FORMAT)), "warn"); } } #endregion // Fire the complete method interaction.FireParsed(); }
/// <summary> /// Generate the condition string for this property /// </summary> /// <param name="root">If null defaults to the RIM name of the p parameter</param> private string GenerateConditionString(Property p, TypeReference tr, string root, List<TypeReference> genericSupplier) { Property rimName = p; // Type reference if (tr == null) { tr = p.Type; if (ResolveTypeReference(tr.Name, genericSupplier) != null) tr = ResolveTypeReference(p.Type.Name, genericSupplier); } // Determine the RIM Name if (p.Container is Choice && (p.Container as Choice).Realization != null && (p.Container as Choice).Realization.Count > 0) rimName = (p.Container as Choice).Realization[0] as Property; else if (p.Realization == null || p.Realization.Count == 0) { //rimName = p; return ""; } else rimName = p.Realization[0] as Property; if (root == null && p.PropertyType != Property.PropertyTypes.Structural) // default to p root = String.Format("./hl7:{0}", rimName.Name, NS_SRC); else if(root == null) root = string.Format("./@{0}", rimName.Name); // Class of the type refernece is null, no point in generating a condition for it if (tr.Class == null && root != ".") return string.Format(" and count({0}) >= {1}", root, p.MinOccurs); else if (tr.Class == null) return ""; // Get all fixed elements List<Property> fixedElements = FlattenPropertyHierarchy(tr.Class.GetFullContent()).FindAll(o => o.FixedValue != null && o.PropertyType == Property.PropertyTypes.Structural); string retVal = ""; if (fixedElements.Count > 0) foreach (Property fixedProperty in fixedElements) retVal += String.Format(" and {0}/@{1} = '{2}'", root, fixedProperty.Name == "semText" ? "*[local-name() = 'semText']" : fixedProperty.Name, fixedProperty.FixedValue); return retVal; }
/// <summary> /// Returns true if the specified <paramref name="tr"/> is /// a collection /// </summary> public static bool IsCollectionType(TypeReference tr) { string trCoreName = tr.CoreDatatypeName; if (trCoreName == null) return false; return collectionTypes.Exists(o => trCoreName.StartsWith(o)); }
/// <summary> /// Write the inline element mapping /// </summary> private void WriteInlineElementMapExpand(XmlWriter xw, Property p, TypeReference tr, List<TypeReference> genericSupplier, string interactionName) { // Write the real name for the property // Write the apply template if (p.AlternateTraversalNames == null || p.AlternateTraversalNames.Count == 0) xw.WriteStartElement(p.Name, NS_SRC); // p.name else { Property.AlternateTraversalData traversal = p.AlternateTraversalNames.Find(o => o.CaseWhen.Name == tr.Name && interactionName == o.InteractionOwner.Name); if (traversal.TraversalName != null) // found an alt traversal xw.WriteStartElement(traversal.TraversalName, NS_SRC); else { traversal = p.AlternateTraversalNames.Find(o => o.CaseWhen.Name == tr.Name && o.InteractionOwner == null); if (traversal.TraversalName != null) xw.WriteStartElement(traversal.TraversalName, NS_SRC); else xw.WriteStartElement(p.Name, NS_SRC); // fall back to the property name } } // Write fixed properties List<Property> elements = tr.Class == null ? new List<Property>() : FlattenPropertyHierarchy(tr.Class.GetFullContent()), fixedElements = elements.FindAll(o => o.FixedValue != null && o.PropertyType == Property.PropertyTypes.Structural); // Generate the fixed type foreach (Property fixedElement in fixedElements) WriteInlineAttributeMapExpand(xw, fixedElement); WriteInlineTypeMapExpand(xw, tr, genericSupplier, interactionName); xw.WriteEndElement(); // p.Name }
/// <summary> /// Generate an inline foreach query pattern /// </summary> private void WriteInlineForeachCollapse(XmlWriter xw, TypeReference tr, List<TypeReference> genericSupplier, string interactionName) { // Clone the class Class clsTr = tr.Class.Clone() as Class; clsTr.MemberOf = tr.Class.MemberOf; // Correct the inheritence if (clsTr.BaseClass == null && clsTr.Name != "InfrastructureRoot") clsTr.BaseClass = (clsTr.MemberOf["RIM.InfrastructureRoot"] as Class).CreateTypeReference(); List<Property> elements = FlattenPropertyHierarchy(clsTr.GetFullContent()); // Write any attributes xw.WriteStartElement("for-each", NS_XSLT); xw.WriteAttributeString("select", String.Format("@* | child::node()[namespace-uri() = '{0}']", NS_SRC)); xw.WriteStartElement("choose", NS_XSLT); // Write the element data foreach(Property p in elements) WriteInlineWhenConditionCollapse(xw, p, genericSupplier, interactionName); xw.WriteEndElement(); // choose xw.WriteEndElement(); // foreach }
/// <summary> /// Generate an inline foreach query pattern /// </summary> private void WriteInlineForeachCollapse(XmlWriter xw, TypeReference tr, List<TypeReference> genericSupplier, string interactionName) { // Clone the class Class clsTr = tr.Class.Clone() as Class; clsTr.MemberOf = tr.Class.MemberOf; // Correct the inheritence if (clsTr.BaseClass == null && clsTr.Name != "InfrastructureRoot") clsTr.BaseClass = (clsTr.MemberOf["RIM.InfrastructureRoot"] as Class).CreateTypeReference(); List<Property> elements = FlattenPropertyHierarchy(clsTr.GetFullContent()); // Write the fixed attributes List<Property> fixedElements = elements.FindAll(o => o.FixedValue != null && o.PropertyType == Property.PropertyTypes.Structural); foreach (var element in fixedElements) WriteInlineAttributeMapCollapse(xw, element); // Is there even any data in the foreach? if (elements.Find(o => o.PropertyType != Property.PropertyTypes.Structural || o.PropertyType == Property.PropertyTypes.Structural && o.FixedValue == null) == null) return; // Write any attributes xw.WriteStartElement("for-each", NS_XSLT); xw.WriteAttributeString("select", String.Format("@* | child::node()[namespace-uri() = '{0}']", NS_SRC)); xw.WriteStartElement("choose", NS_XSLT); // Write the element data foreach (Property p in elements) WriteInlineWhenConditionCollapse(xw, p, genericSupplier, interactionName); xw.WriteEndElement(); // choose xw.WriteEndElement(); // foreach }
/// <summary> /// Write inline element map collapse /// </summary> private void WriteInlineElementMapCollapse(XmlWriter xw, Property p, TypeReference tr, List<TypeReference> genericSupplier, string interactionName) { if (ResolveTypeReference(tr.Name, genericSupplier) != null) tr = ResolveTypeReference(p.Type.Name, genericSupplier); if (p.AlternateTraversalNames == null || p.AlternateTraversalNames.Count == 0) xw.WriteStartElement(p.Name, TargetNamespace); // p.name else { Property.AlternateTraversalData traversal = p.AlternateTraversalNames.Find(o => o.CaseWhen.Name == tr.Name); if (traversal.TraversalName != null) // found an alt traversal xw.WriteStartElement(traversal.TraversalName, TargetNamespace); else xw.WriteStartElement(p.Name, TargetNamespace); // fall back to the property name } // Determine if this should be a genericized parameter WriteInlineTypeMap(xw, tr, genericSupplier, interactionName); xw.WriteEndElement(); // p.name }
/// <summary> /// Write an inline abstract when condition /// </summary> private void WriteInlineAbstractWhenCondition(XmlWriter xw, TypeReference tr, Property p, List<TypeReference> genericSupplier, string interactionName) { foreach (TypeReference child in tr.Class.SpecializedBy) { if (child.Class.IsAbstract) WriteInlineAbstractWhenCondition(xw, child, p, genericSupplier, interactionName); else { xw.WriteStartElement("when", NS_XSLT); // Find the altTraversal Property.AlternateTraversalData altTraversal = p.AlternateTraversalNames.Find(o => o.CaseWhen.Name == child.Name && o.InteractionOwner.Name == interactionName); // Alternate traversal if (altTraversal.TraversalName == null) altTraversal = p.AlternateTraversalNames.Find(o => o.CaseWhen.Name == child.Name); // Traversal was found if (altTraversal.TraversalName != null) xw.WriteAttributeString("test", string.Format("local-name() = '{0}'", altTraversal.TraversalName)); else throw new InvalidOperationException(String.Format("Can't find traversal for alternative data for '{0}' when type is '{1}'...", p.Name, child.Name)); // Perform the inline element map Property rimName = null; // Is this representative of some sort of RIM structure? if ((p.Container is Class) && (p.Container as Class).ContainerName == "RIM") // This is a rim property rimName = p; else if (p.Realization == null || p.Realization.Count == 0) { // xw.WriteElementString("comment", NS_XSLT, String.Format("TODO: Can't realize property '{0}' in the RIM as no realization data was found", p.Name)); rimName = p; //return; } else rimName = p.Realization[0] as Property; // Write the apply template if (rimName.AlternateTraversalNames == null || rimName.AlternateTraversalNames.Count == 0) xw.WriteStartElement(rimName.Name, NS_SRC); // p.name else { Property.AlternateTraversalData traversal = rimName.AlternateTraversalNames.Find(o => o.CaseWhen.Name == child.Name); if (traversal.TraversalName != null) // found an alt traversal xw.WriteStartElement(traversal.TraversalName, NS_XSLT); else xw.WriteStartElement(rimName.Name, NS_XSLT); // fall back to the property name } // Perform the inline element map WriteInlineApplyTemplate(xw, p, child, genericSupplier); xw.WriteEndElement(); // p.name xw.WriteEndElement(); // when } } }
/// <summary> /// Write an inline type mapping for the TypeReference specified /// </summary> private void WriteInlineTypeMap(XmlWriter xw, TypeReference tr, List<TypeReference> genericSupplier, string interactionName) { List<String> collectionTypes = new List<string>(){ "SET","LIST","QSET","DSET","HIST","BAG" }; if (collectionTypes.Contains(tr.CoreDatatypeName ?? "") && tr.GenericSupplier.Count == 1) // Collection tr = tr.GenericSupplier[0]; else if (collectionTypes.Contains(tr.CoreDatatypeName ?? "")) { System.Diagnostics.Trace.WriteLine(String.Format("Can't handle a collection ({0}) with more than one generic parameter", tr.ToString()), "warn"); return; } string schemaFriendlyName = MakeSchemaFriendlyCoreType(tr); // Map the type if (dataTypeMaps.ContainsKey(schemaFriendlyName ?? "")) // simple map { if (dataTypeMaps[schemaFriendlyName ?? ""].Name == "copy") xw.WriteElementString(dataTypeMaps[schemaFriendlyName ?? ""].Name, NS_XSLT, dataTypeMaps[schemaFriendlyName ?? ""].InnerText); else dataTypeMaps[schemaFriendlyName ?? ""].WriteTo(xw); } else if (IsRecursiveReference(tr, tr, new List<string>())) // complex map WriteInlineApplyTemplate(xw, tr.Container as Property, tr, genericSupplier); else if (tr.Class != null) WriteInlineForeachCollapse(xw, tr, genericSupplier, interactionName); //else //System.Diagnostics.Debugger.Break(); }
private void AppendTraversalName(TypeReference ClassRef, string ParameterName, string TraversalName, TypeReference CaseWhen, MohawkCollege.EHR.gpmr.COR.Interaction InteractionOwner, Stack<String> processStack) { if (processStack.Contains(ClassRef.ToString())) return; processStack.Push(ClassRef.ToString()); // Iterate through each of the class contents foreach(ClassContent cc in ClassRef.Class.Content) if (cc is Property) { // Assign Alternative traversal name if the type of property matches the paramter name // and the new traversal name is not the same as the old if ((cc as Property).Type.Name == ParameterName && TraversalName != cc.Name ) (cc as Property).AddTraversalName(TraversalName, CaseWhen, InteractionOwner); else if ((cc as Property).Type.Class != null) AppendTraversalName((cc as Property).Type, ParameterName, TraversalName, CaseWhen, InteractionOwner, processStack); } if (processStack.Pop() != ClassRef.ToString()) throw new PipelineExecutionException(MifCompiler.hostContext, Pipeline.PipelineStates.Error, MifCompiler.hostContext.Data, new Exception("Error occurred traversing traversal name to populate parameter")); }
/// <summary> /// Is recursive reference /// </summary> private bool IsRecursiveReference(TypeReference needle, TypeReference haystack, List<String> alreadyChecked) { // Already checked? if (alreadyChecked.Contains(haystack.Name)) return false; else alreadyChecked.Add(haystack.Name); if (haystack.Class == null) return false; bool isRecursive = false; foreach (Property cc in FlattenPropertyHierarchy(haystack.Class.GetFullContent())) { if (!alreadyChecked.Contains(cc.Type.Name)) isRecursive |= IsRecursiveReference(needle, cc.Type, alreadyChecked); else if (cc.Type.Name == needle.Name) isRecursive |= true; if (isRecursive) break; // no need to check anymore } return isRecursive || (needle.Name == haystack.Name && needle.Container != haystack.Container); }
private void ProcessTypeParameters(List<ParameterModel> parms, TypeReference baseRef, MohawkCollege.EHR.gpmr.COR.Interaction ownerInteraction) { if (parms != null && baseRef.Class != null && baseRef.Class.TypeParameters != null && parms.Count != baseRef.Class.TypeParameters.Count) Trace.WriteLine( string.Format("The argument message '{0}.{1}' requires {2} parameter messages however interaction '{3}' only specifies {4}", baseRef.Class.ContainerName, baseRef.Class.Name, baseRef.Class.TypeParameters.Count, ownerInteraction.Name, parms.Count) , "warn"); else if (parms == null || parms.Count == 0) return; // Check for null // Setup the parameters foreach (ParameterModel p in parms) { // Check if the parameter model exists if (!ClassRepository.ContainsKey(p.ToString(MifCompiler.NAME_FORMAT))) PackageParser.Parse(p.ToString(MifCompiler.NAME_FORMAT), repository, ClassRepository); // Process the package if it doesn't // Check again, if this fails all hell breaks loose var model = (ClassRepository[p.ToString(MifCompiler.NAME_FORMAT)] as MohawkCollege.EHR.gpmr.COR.SubSystem); if (model == null) { System.Diagnostics.Trace.WriteLine(string.Format("Could not find the parameter model '{0}'", p.ToString(MifCompiler.NAME_FORMAT)), "error"); return; } else if (model.EntryPoint.Count == 0) { System.Diagnostics.Trace.WriteLine(string.Format("Parameter model '{0}' must have an entry point", p.ToString(MifCompiler.NAME_FORMAT)), "error"); return; } else if (model.EntryPoint.Count != 1) { System.Diagnostics.Trace.WriteLine(string.Format("Ambiguous entry point for parameter model '{0}'", p.ToString(MifCompiler.NAME_FORMAT)), "error"); return; } // Entry class for p TypeReference parmRef = model.EntryPoint[0].CreateTypeReference(); // Find any reference and set an alternate traversal name for that property if (p.Specialization.Count == 0) AppendTraversalName(baseRef, p.ParameterName, p.TraversalName, parmRef, ownerInteraction, new Stack<string>()); else ProcessSpecializations(p, p.Specialization, baseRef, ownerInteraction, null); // Process Children ProcessTypeParameters(p.ParameterModel, parmRef, ownerInteraction); // Assign for tr as a parameter reference try { baseRef.AddGenericSupplier(p.ParameterName, parmRef); } catch (ArgumentException e) // This is thrown when there are more than one supplier binding { // Was more than one specified if (baseRef.GenericSupplier.Exists(o => (o as TypeParameter).ParameterName == p.ParameterName)) { //baseRef.GenericSupplier.RemoveAll(o => (o as TypeParameter).ParameterName == p.ParameterName); // remove the existing type reference // Add the generic supplier manually for the new type baseRef.AddGenericSupplier(p.ParameterName, parmRef, false); Trace.WriteLine(String.Format("Generic supplier {0} has been specified more than once, will use base object in it's place", p.ParameterName), "warn"); } } catch (Exception e) { // JF - Some UV models attempt to bind to classes that don't support binding if (baseRef.Class.TypeParameters == null) { System.Diagnostics.Trace.WriteLine(String.Format("{0} can't force bind because the target class has not template parameters", e.Message), "error"); if (MifCompiler.hostContext.Mode == Pipeline.OperationModeType.Quirks) System.Diagnostics.Trace.WriteLine(String.Format("{0} will ignore this binding in order to continue. This interaction will effectively be useless", ownerInteraction.Name)); else throw new InvalidOperationException(String.Format("Cannot bind parameter '{0}' to class '{1}' because '{1}' does not support templates", parmRef.Name, baseRef.Name)); } else { System.Diagnostics.Trace.WriteLine(String.Format("{0} will try force binding", e.Message), "error"); foreach (var t in baseRef.Class.TypeParameters) if (baseRef.GenericSupplier.Find(o => o.Name.Equals(t.ParameterName)) == null) { baseRef.AddGenericSupplier(t.ParameterName, parmRef); System.Diagnostics.Trace.WriteLine(String.Format("Bound {0} to {1} in {2}", parmRef, t.ParameterName, baseRef), "warn"); break; } } } } }
public void AddGenericSupplier(string ParameterName, TypeReference typeReference) { AddGenericSupplier(ParameterName, typeReference, true); }
/// TODO: Explanation of parameters missing: tr /// Description of the value returned missing /// <summary> /// Gather all of the using statements /// </summary> private List<string> GatherUsings(TypeReference tr) { List<String> retVal = new List<string>(); retVal.Add(tr.Class.ContainerName); foreach (TypeReference tp in tr.GenericSupplier ?? new List<TypeReference>()) retVal.AddRange(GatherUsings(tp)); return retVal; }