public string CreateFile(Feature f, string FilePath) { try { Directory.CreateDirectory(Path.Combine(FilePath, f.Name)); return Path.Combine(FilePath, f.Name); } catch (Exception e) { System.Diagnostics.Trace.WriteLine(String.Format("Can't create directory '{0}', {1}", Path.Combine(FilePath, f.Name), e.Message), "error"); throw new DirectoryNotFoundException(e.Message, e); } }
/// <summary> /// Create a file name /// </summary> /// <param name="f">The feature to create a file for</param> /// <param name="FilePath">The path of the file</param> /// <returns>The full name of the file to create</returns> public string CreateFile(MohawkCollege.EHR.gpmr.COR.Feature f, string FilePath) { string fileName = Util.Util.MakeFriendly(f.Name); // Render as if (f.Annotations != null && f.Annotations.Exists(o => o is RenderAsAnnotation)) { fileName = Util.Util.MakeFriendly((f.Annotations.Find(o => o is RenderAsAnnotation) as RenderAsAnnotation).RenderName); } fileName = Path.ChangeExtension(Path.Combine(Path.Combine(FilePath, "Vocabulary"), fileName), ".cs"); var enu = f as Enumeration; if (!String.IsNullOrEmpty(Datatypes.GetBuiltinVocabulary(enu.Name))) { throw new InvalidOperationException("Enumeration is builtin to core library. Will not render"); } // Is this code system even used? if (!m_markedForUse.Exists(o => o.GetType().Equals(f.GetType()) && o.Name == f.Name)) { if (enu.GetEnumeratedLiterals().Count > RimbaCsRenderer.MaxLiterals) { throw new InvalidOperationException(String.Format("Enumeration '{2}' too large, enumeration has {0} literals, maximum allowed is {1}", enu.GetEnumeratedLiterals().Count, RimbaCsRenderer.MaxLiterals, enu.Name)); } else { throw new InvalidOperationException("Enumeration is not used, or is an unbound concept domain!"); } } // First, if the feature is a value set we will always render it if (File.Exists(fileName) && !(f as Enumeration).OwnerRealm.EndsWith(RimbaCsRenderer.prefRealm)) { throw new InvalidOperationException("Enumeration has already been rendered from the preferred realm. Will not render this feature"); } return(fileName); }
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> /// Create a length value change /// </summary> // TODO: Find a delta-set example that uses this so we can test. // TODO: Can't determine if this changes maximum or minimum length, should bring this // up with CHI to see if there is a definition for what this attribute changes private void CreateLengthValueChange(Feature feature, Constraint constraint) { #region Length Value // Validate the constraint var lnConstraint = constraint.Value as ConstraintValue<Int32>; Property ccFeature = feature as Property; if (ccFeature == null) { Trace.WriteLine(String.Format("Delta: Cannot apply the length value constraint against a a feature of type '{0}', skipping...", feature.GetType().Name), "error"); return; } // Validate the current default value if (!lnConstraint.Original.Equals(ccFeature.MaxLength)) Trace.WriteLine(String.Format("Delta: Current length of '{0}' does not match original listed in the delta of '{1}', will continue processing anyways...", ccFeature.DefaultValue, lnConstraint.Original), "warn"); // Validate the annotation doesn't already exist if (ccFeature.Annotations.Exists(o => o is LengthConstraintAnnotation && (o as LengthConstraintAnnotation).RealmCode == this.m_deltaSet.Realm.Code)) { Trace.WriteLine(String.Format("Delta: Length constraint has already been applied to '{0}'", feature.Name), "error"); return; } // Add the annotation to the feature ccFeature.Annotations.Add(new LengthConstraintAnnotation() { ChangeType = ChangeType.Edit, RealmCode = this.m_deltaSet.Realm.Code, NewValue = lnConstraint.New, RealmName = this.m_deltaSet.MetaData.Description }); #endregion }
/// <summary> /// Create a data type change /// </summary> private void CreateDatatypeChange(Feature feature, Constraint constraint) { #region Data Type Change // 1. Validate constraint & target var stConstriant = constraint.Value as ConstraintValue<String>; Property ccFeature = feature as Property; if (ccFeature == null) { Trace.WriteLine(String.Format("Delta: Cannot apply data type change constraint against a feature of type '{0}', skipping...", feature.GetType().Name), "error"); return; } TypeReference trNew = this.ParseTypeReference(stConstriant.New), trOld = this.ParseTypeReference(stConstriant.Original); // 2. Validate current data type if (trNew == null || trOld == null) { Trace.WriteLine(String.Format("Delta: Could not process '{0}' or '{1}', skipping...", stConstriant.Original, stConstriant.New), "error"); return; } if (!TypeReferenceEqual(ccFeature.Type, trOld)) Trace.WriteLine(String.Format("Delta: Current type of '{0}' is not '{1}' as specified in delta, rather it is '{2}', will continue processing anyways...", feature.Name, trOld, ccFeature.Type), "warn"); // 3. Validate that the cardinality doesn't already exist if (ccFeature.Annotations.Exists(o => o is DatatypeChangeConstraintAnnotation && (o as DatatypeChangeConstraintAnnotation).RealmCode == this.m_deltaSet.Realm.Code)) { Trace.WriteLine(String.Format("Delta: Datatype constraint has already been applied to '{0}'", feature.Name), "error"); return; } // 4. Append the annotation ccFeature.Annotations.Add(new DatatypeChangeConstraintAnnotation() { ChangeType = ChangeType.Edit, RealmCode = this.m_deltaSet.Realm.Code, NewValue = trNew, RealmName = this.m_deltaSet.MetaData.Description }); #endregion }
/// <summary> /// Create a change that modifies the fixed value /// </summary> private void CreateFixedValueChange(Feature feature, Constraint constraint) { #region Fixed Value // 1. Validate constraint & target var stConstriant = constraint.Value as ConstraintValue<String>; Property ccFeature = feature as Property; if (ccFeature == null) { Trace.WriteLine(String.Format("Delta: Cannot apply fixed value change constraint against a feature of type '{0}', skipping...", feature.GetType().Name), "error"); return; } // 2. Validate current data type if (stConstriant.Original != null && !stConstriant.Original.Equals(ccFeature.FixedValue)) Trace.WriteLine(String.Format("Delta: Current fixed value of '{0}' does not match original listed in delta of '{1}', will continue processing anyways...", ccFeature.FixedValue, stConstriant.Original), "warn"); // 3. Validate that the annotation doesn't already exist if (ccFeature.Annotations.Exists(o => o is FixedValueConstraintAnnotation && (o as FixedValueConstraintAnnotation).RealmCode == this.m_deltaSet.Realm.Code)) { Trace.WriteLine(String.Format("Delta: Fixed value constraint has already been applied to '{0}'", feature.Name), "error"); return; } // 4. Append the annotation ccFeature.Annotations.Add(new FixedValueConstraintAnnotation() { ChangeType = ChangeType.Edit, RealmCode = this.m_deltaSet.Realm.Code, NewValue = stConstriant.New, RealmName = this.m_deltaSet.MetaData.Description }); #endregion }
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); }
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> /// Apply constraints for the specified feature /// </summary> private void ApplyConstraint(Feature feature, Constraint constraint) { // Determine the type of constraint switch (constraint.Type) { case ConstraintDeltaType.Conformance: CreateConformanceChange(feature, constraint); break; case ConstraintDeltaType.Annotation: CreateAnnotationChange(feature, constraint); break; case ConstraintDeltaType.Remove: CreateRemoveChange(feature, constraint); break; case ConstraintDeltaType.BusinessName: CreateBusinessNameChange(feature, constraint); break; case ConstraintDeltaType.Cardinality: CreateCardinalityChange(feature, constraint); break; case ConstraintDeltaType.SubstituteCmet: case ConstraintDeltaType.Datatype: CreateDatatypeChange(feature, constraint); break; case ConstraintDeltaType.Fixed: CreateFixedValueChange(feature, constraint); break; case ConstraintDeltaType.DefaultValue: CreateDefaultValueChange(feature, constraint); break; case ConstraintDeltaType.Length: CreateLengthValueChange(feature, constraint); break; case ConstraintDeltaType.VocabularyStrength: CreateVocabularyStrengthChange(feature, constraint); break; case ConstraintDeltaType.VocabularyBinding: CreateVocabularyDomainChange(feature, constraint); break; case ConstraintDeltaType.UpdateModeDefault: case ConstraintDeltaType.UpdateModeValue: { Trace.WriteLine(String.Format("Delta: Update mode deltas are not supported by this delta engine")); break; } default: { Trace.WriteLine(String.Format("Delta: Don't understand constraint of type '{0}'", constraint.Type), "warn"); break; } } }
/// <summary> /// Render the enumeration /// </summary> public void Render(string ownerPackage, string apiNs, Feature f, System.IO.TextWriter tw) { // Validate arguments if (String.IsNullOrEmpty(ownerPackage)) throw new ArgumentNullException("ownerPackage"); if (String.IsNullOrEmpty(apiNs)) throw new ArgumentNullException("apiNs"); if (f == null || !(f is Enumeration)) throw new ArgumentException("Parameter must be of type Enumeration", "f"); Enumeration cls = f as Enumeration; // enumeration is a concept domain? do the binding if (cls is ConceptDomain && (cls as ConceptDomain).ContextBinding != null) cls = (cls as ConceptDomain).ContextBinding[0]; else if (cls is ConceptDomain) throw new InvalidOperationException("Won't render unbound concept domains"); tw.WriteLine("package {0}.vocabulary;", ownerPackage); #region Render the imports string[] apiImports = { "annotations.*", "datatypes.*", "datatypes.generic.*" }, jImports = { "java.lang.*", "java.util.*" }; foreach (var import in apiImports) tw.WriteLine("import {0}.{1};", apiNs, import); foreach (var import in jImports) tw.WriteLine("import {0};", import); #endregion #region Render Class Signature // Documentation if (DocumentationRenderer.Render(cls.Documentation, 0).Length == 0) tw.WriteLine("/** No Summary Documentation Found */"); else tw.Write(DocumentationRenderer.Render(cls.Documentation, 0)); // Create structure annotation tw.WriteLine(CreateStructureAnnotation(cls)); string renderName = cls.Name; if (cls.Annotations != null && cls.Annotations.Exists(o => o is RenderAsAnnotation)) renderName = (cls.Annotations.Find(o => o is RenderAsAnnotation) as RenderAsAnnotation).RenderName; // Create class signature //tw.WriteLine("@Structure(name = \"{0}\", structureType = StructureType.{1})", cls.Name, cls.GetType().Name.ToUpper()); tw.Write("public class {0} implements {1}.interfaces.IEnumeratedVocabulary", Util.Util.MakeFriendly(renderName), apiNs); tw.WriteLine("{"); #endregion #region Render Properties StringWriter sw = new StringWriter(); RenderLiterals(sw, cls, new List<string>(), new List<string>(), cls.Literals, renderName); String tStr = sw.ToString(); tw.WriteLine(tStr); #endregion #region Render IEnumeratedVocabulary Methods tw.WriteLine("\tpublic {0}(String code, String codeSystem) {{ this.m_code = code; this.m_codeSystem = codeSystem; }}", Util.Util.MakeFriendly(renderName)); tw.WriteLine("\tprivate final String m_code;"); tw.WriteLine("\tprivate final String m_codeSystem;"); tw.WriteLine("\tpublic String getCodeSystem() { return this.m_codeSystem; }"); tw.WriteLine("\tpublic String getCode() { return this.m_code; }"); tw.WriteLine("\t@Override"); tw.WriteLine("\tpublic String toString() { return this.m_code; }"); tw.WriteLine("\t@Override"); tw.WriteLine("\tpublic boolean equals(Object obj) {"); tw.WriteLine("\t\tif (this == obj)"); tw.WriteLine("\t\t\treturn true;"); tw.WriteLine("\t\tif (!super.equals(obj))"); tw.WriteLine("\t\t\treturn false;"); tw.WriteLine("\t\tif (getClass() != obj.getClass())"); tw.WriteLine("\t\t\treturn false;"); tw.WriteLine("\t\t\tif(obj instanceof String && this.m_code.equals(obj))"); tw.WriteLine("\t\t\treturn true;"); tw.WriteLine("\t\t\tif(obj instanceof org.marc.everest.interfaces.IEnumeratedVocabulary && this.m_code.equals(((org.marc.everest.interfaces.IEnumeratedVocabulary)obj).getCode()))"); tw.WriteLine("\t\t\treturn true;"); tw.WriteLine("\t\treturn false;"); tw.WriteLine("\t}"); #endregion // End enumeration tw.WriteLine("}"); }
/// <summary> /// Add supported annotation /// </summary> private void AddSupportedAnnotation(Feature featureData) { if(!featureData.Annotations.Exists(o=>o is SupportedConstraintAnnotation && (o as SupportedConstraintAnnotation).RealmCode == this.m_deltaSet.Realm.Code)) featureData.Annotations.Add(new SupportedConstraintAnnotation() { RealmCode = this.m_deltaSet.Realm.Code }); if (featureData is Class) foreach (var dat in (featureData as Class).Content) AddSupportedAnnotation(dat); else if (featureData is Choice) foreach (var dat in (featureData as Choice).Content) AddSupportedAnnotation(dat); }
/// <summary> /// Set the member of /// </summary> private void SetMemberOf(Feature feature, ClassRepository newOwner) { feature.MemberOf = newOwner; if (feature is Class) foreach (var p in (feature as Class).Content) SetMemberOf(p, newOwner); if (feature is Enumeration) foreach (var p in (feature as Enumeration).Literals) SetMemberOf(p, newOwner); if (feature is Choice) foreach (var p in (feature as Choice).Content) SetMemberOf(p, newOwner); }
/// <summary> /// Determine if a factory is needed /// </summary> public string CreateFile(Feature f, string FilePath) { Class cls = f as Class; if(cls.IsAbstract && cls.SpecializedBy != null && cls.SpecializedBy.Count > 0) return Path.ChangeExtension(Path.Combine(Path.Combine(FilePath, cls.ContainerName.ToLower()), String.Format("{0}Factory", Util.Util.PascalCase(f.Name))), "java"); throw new NotSupportedException(); }
/// <summary> /// Render the factory /// </summary> public void Render(string ownerPackage, string apiNs, Feature f, System.IO.TextWriter tw) { ClassRenderer.s_imports.Clear(); // Validate arguments if (String.IsNullOrEmpty(ownerPackage)) throw new ArgumentNullException("ownerPackage"); if (String.IsNullOrEmpty(apiNs)) throw new ArgumentNullException("apiNs"); if (f == null || !(f is Class)) throw new ArgumentException("Parameter must be of type Class", "f"); // Create a local copy of the class Class cls = f as Class; StringWriter sw = new StringWriter(); tw.WriteLine("package {0}.{1};", ownerPackage, cls.ContainerName.ToLower()); #region Render Class Signature // Documentation if (DocumentationRenderer.Render(cls.Documentation, 0).Length == 0) sw.WriteLine("\t/** No Summary Documentation Found */"); else sw.Write(DocumentationRenderer.Render(cls.Documentation, 0)); // Create class signature sw.Write("public final class {0}Factory", Util.Util.PascalCase(cls.Name)); // If class is generic class string genericString = String.Empty; foreach (TypeParameter tp in cls.TypeParameters ?? new List<TypeParameter>()) genericString += tp + ","; if (!String.IsNullOrEmpty(genericString)) genericString = String.Format("<{0}>", genericString.Substring(0, genericString.Length - 1)); // get rid of trailing , sw.WriteLine("{"); #endregion sw.WriteLine("\tprivate {0}Factory() {{ super(); }}\r\n", Util.Util.PascalCase(cls.Name)); // Create newInstanceMethod sw.WriteLine("\tpublic static final {0} {1}Factory newInstance() {{", cls.TypeParameters != null && cls.TypeParameters.Count > 0 ? string.Format("<{0}>", genericString) : "", Util.Util.PascalCase(cls.Name)); sw.WriteLine("\t\treturn new {0}Factory{1}();", Util.Util.PascalCase(cls.Name), genericString); sw.WriteLine("\t}"); // Move to a factory // Is this an emtpy class that facilitates a choice? if (cls.SpecializedBy != null && cls.SpecializedBy.Count > 0 && cls.IsAbstract) { //// NB: In Java apparently super classes' static methods are acceessable //// in child classes which is different than .NET, so we're not going to cascade specializers foreach (TypeReference tr in cls.SpecializedBy) { if (tr.Class == null || tr.Class.ContainerName == "RIM" && !RimbaJavaRenderer.GenerateRim || tr.Class.IsAbstract) continue; Class child = tr.Class; // Create factory for the child Dictionary<String, String[]> ctors = ClassRenderer.CreateFactoryMethod(tr, "retVal", ownerPackage); // Write factory foreach (var kv in ctors) { string methodSignature = String.Format("{1}.{0}.{2}.create{3}", cls.ContainerName, ownerPackage, Util.Util.PascalCase(cls.Name), Util.Util.PascalCase(child.Name)), publicName = methodSignature; // Regex for extracting the parameter type rather than the type/name Regex parmRegex = new Regex(@"(([\w<>,.]*)\s(\w*)),?\s?"); MatchCollection parmMatches = parmRegex.Matches(kv.Value[0]); foreach (Match match in parmMatches) methodSignature += match.Groups[1].Value.Substring(0, match.Groups[1].Value.IndexOf(" ")); // JF: Added to protected against rendering the same factory method if (s_methodDeclarations.Contains(methodSignature)) continue; s_methodDeclarations.Add(methodSignature); // Render if there is even any content if (kv.Value[0].Length > 0) { string clsDoc = DocumentationRenderer.Render(child.Documentation, 1); string ctorClassName = String.Format("{0}.{2}.{1}", ownerPackage, tr.Class.Name, tr.Class.ContainerName.ToLower()); //// import already exists? //if(!s_imports.Exists(o=>o.EndsWith(Util.Util.PascalCase(tr.Class.Name)))) //{ // s_imports.Add(ctorClassName); // ctorClassName = ctorClassName.Substring(ctorClassName.LastIndexOf(".") + 1); //} //if (s_imports.Contains(ctorClassName)) // ctorClassName = ctorClassName.Substring(ctorClassName.LastIndexOf(".") + 1); if (clsDoc.Contains("*/")) sw.Write(clsDoc.Substring(0, clsDoc.LastIndexOf("*/"))); sw.WriteLine("* This function creates a new instance of {5}.{1}\r\n\t {4}\r\n\t*/\t\n\tpublic final {0} create{2}({3}) {{ ", ctorClassName, tr.Class.Name, Util.Util.PascalCase(child.Name), kv.Value[0].Substring(0, kv.Value[0].Length - 1), kv.Value[2], tr.Class.ContainerName.ToLower(), Util.Util.PascalCase(cls.Name) ); sw.WriteLine("\t\t{0} retVal = new {0}();", ctorClassName); sw.WriteLine("{0}", kv.Value[1]); sw.WriteLine("\t\treturn retVal;"); sw.WriteLine("\t}"); if (!factoryMethods.ContainsKey(tr.Name)) factoryMethods.Add(tr.Name, new List<MohawkCollege.EHR.gpmr.Pipeline.Renderer.Java.Renderer.ClassRenderer.FactoryMethodInfo>()); MohawkCollege.EHR.gpmr.Pipeline.Renderer.Java.Renderer.ClassRenderer.FactoryMethodInfo myInfo = new MohawkCollege.EHR.gpmr.Pipeline.Renderer.Java.Renderer.ClassRenderer.FactoryMethodInfo(publicName, kv.Value[2], methodSignature); //Match the regular expression below and capture its match into backreference number 1 «(([\w<>,]*?)\s(\w*),?\s?)» //Match the regular expression below and capture its match into backreference number 2 «([\w<>,]*?)» //Match a single character present in the list below «[\w<>,]*?» //Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?» //A word character (letters, digits, etc.) «\w» //One of the characters “<>,” «<>,» //Match a single character that is a “whitespace character” (spaces, tabs, line breaks, etc.) «\s» //Match the regular expression below and capture its match into backreference number 3 «(\w*)» //Match a single character that is a “word character” (letters, digits, etc.) «\w*» //Between zero and unlimited times, as many times as possible, giving back as needed (greedy) «*» //Match the character “,” literally «,?» //Between zero and one times, as many times as possible, giving back as needed (greedy) «?» //Match a single character that is a “whitespace character” (spaces, tabs, line breaks, etc.) «\s?» //Between zero and one times, as many times as possible, giving back as needed (greedy) «?» foreach (Match match in parmMatches) myInfo.parameters.Add(match.Groups[1].Value); // ADd the factory signature to the dictionary factoryMethods[tr.Name].Add(myInfo); } } } //#endregion } // End class sw.WriteLine("}"); #region Render the imports string[] apiImports = { "annotations.*", "datatypes.*", "datatypes.generic.*" }, jImports = { "java.lang.*", "java.util.*" }; foreach (var import in apiImports) tw.WriteLine("import {0}.{1};", apiNs, import); foreach (var import in jImports) tw.WriteLine("import {0};", import); foreach (var import in ClassRenderer.s_imports) { if (!import.EndsWith(String.Format(".{0}", Util.Util.PascalCase(f.Name)))) tw.WriteLine("import {0};", import); } tw.WriteLine(sw.ToString()); #endregion if (cls.ContainerName == "RIM" && String.Format("{0}.rim.{1}", ownerPackage, Util.Util.PascalCase(cls.Name)) != RimbaJavaRenderer.RootClass && !RimbaJavaRenderer.GenerateRim) throw new NotSupportedException("RIM Elements will not be rendered"); }
internal static MohawkCollege.EHR.gpmr.COR.Class Parse(ClassParameterInfo classInfo) { // Has this been processed? if (classInfo.CompilerRepository.ContainsKey(string.Format("{0}.{1}", classInfo.ScopedPackageName, classInfo.Class.Name))) { return(null); } // Get the vocabulary realm that this package is bound to string vocabularyRealm = classInfo.MifContainer is StaticModel && (classInfo.MifContainer as StaticModel).ImportedVocabularyModelPackage != null ? (classInfo.MifContainer as StaticModel).ImportedVocabularyModelPackage.Realm : null; // Parse the common (class base) portion of the classes MohawkCollege.EHR.gpmr.COR.Class retVal = Parse(classInfo.Class as ClassBase, vocabularyRealm, classInfo.CompilerRepository, classInfo.DerivationSuppliers); // Base class retVal.BaseClass = classInfo.EnforcedBaseClass; // Containing subsystem retVal.ContainerPackage = classInfo.CompilerRepository[classInfo.ScopedPackageName] as MohawkCollege.EHR.gpmr.COR.SubSystem; // Fire parsed event retVal.FireParsed(); #region Specializations retVal.SpecializedBy = new List <TypeReference>(); // Iterate through each child class and process where neccessary foreach (ClassGeneralization cg in (classInfo.Class as MohawkCollege.EHR.HL7v3.MIF.MIF20.StaticModel.Flat.Class).SpecializationChild) { TypeReference tr = new TypeReference(); tr.Name = string.Format("{0}.{1}", classInfo.ScopedPackageName, cg.ChildClassName); // Make a ref to the child class tr.MemberOf = classInfo.CompilerRepository; bool isCMET = false; // Get the child class if (classInfo.MifContainer is GlobalStaticModel) { // Get the CMET reference from the MIF class hierarchy ClassElement ce = (classInfo.MifContainer as GlobalStaticModel).OwnedClass.Find(delegate(ClassElement c) { if (c != null && c.Choice != null && c.Choice is CommonModelElementRef) { return((c.Choice as CommonModelElementRef).Name == cg.ChildClassName); } else { return(false); } }); string cmetName = ce != null ? (ce.Choice as CommonModelElementRef).CmetName ?? (ce.Choice as CommonModelElementRef).Name : ""; // Determine if the reference is a cmet and gathe t isCMET = cmetName != null && ce != null && classInfo.CompilerRepository.ContainsKey(cmetName) && classInfo.CompilerRepository[cmetName] is CommonTypeReference; if (isCMET) // A CMET was successfully resolved { tr = (classInfo.CompilerRepository[cmetName] as CommonTypeReference).Class; } else if (ce != null && MifCompiler.cmetBindings.ContainsKey(cmetName)) // A CMET was not resolved, but a binding exists! { string boundModel = MifCompiler.cmetBindings[cmetName]; MohawkCollege.EHR.gpmr.COR.Feature boundSubSystem = null; if (classInfo.CompilerRepository.TryGetValue(boundModel, out boundSubSystem)) { tr = (boundSubSystem as MohawkCollege.EHR.gpmr.COR.SubSystem).EntryPoint[0].CreateTypeReference(); } else { PackageParser.Parse(boundModel, classInfo.MifContainer.MemberOfRepository, classInfo.CompilerRepository); } } else if (ce != null) // MIF References a CMET but one was never processed? This is odd! { System.Diagnostics.Trace.WriteLine(string.Format("CMET '{0}' was never processed, therefore CommonModelElementRef can't be processed in file '{1}'", cmetName, classInfo.ScopedPackageName), "warn"); continue; } } // The child class has not been processed yet if (!classInfo.CompilerRepository.ContainsKey(tr.Name)) { if (isCMET) // Explicit, have to process another model { PackageParser.ParseClassFromPackage(tr.Name, classInfo.MifContainer.MemberOfRepository, classInfo.CompilerRepository); // Assign the base class //if ((classInfo.CompilerRepository[tr.Name] as MohawkCollege.EHR.gpmr.COR.Class).BaseClass != null) // System.Diagnostics.Debugger.Break(); } else { ClassParameterInfo parm2 = new ClassParameterInfo(); parm2.Class = (classInfo.MifContainer as StaticModel).OwnedClass.Find(o => (o.Choice is MohawkCollege.EHR.HL7v3.MIF.MIF20.StaticModel.Flat.Class && string.Format("{0}.{1}", classInfo.ScopedPackageName, (o.Choice as MohawkCollege.EHR.HL7v3.MIF.MIF20.StaticModel.Flat.Class).Name) == tr.Name)).Choice as ClassBase; parm2.CompilerRepository = classInfo.CompilerRepository; parm2.DerivationSuppliers = classInfo.DerivationSuppliers; parm2.MifContainer = classInfo.MifContainer; parm2.ScopedPackageName = classInfo.ScopedPackageName; parm2.EnforcedBaseClass = retVal.CreateTypeReference(); ClassParser.Parse(parm2); } } // Add to specialization list MohawkCollege.EHR.gpmr.COR.Feature f = null; if (classInfo.CompilerRepository.TryGetValue(tr.Name, out f)) { retVal.SpecializedBy.Add((f as MohawkCollege.EHR.gpmr.COR.Class).CreateTypeReference()); (f as MohawkCollege.EHR.gpmr.COR.Class).BaseClass = retVal.CreateTypeReference(); } else { Trace.WriteLine(String.Format("Cannot find base class '{0}' for '{1}'. Base class must exist before it can be specialized", tr.Name, retVal.Name), "error"); } } #endregion // Assign Temporary Membership to the compiler class repository so the // locating of a structural member will succeed retVal.MemberOf = classInfo.CompilerRepository; // Is a classCode enforcement placed on this class? #region Supplier Structural Domain if (classInfo.Class.SupplierStructuralDomain != null && classInfo.Class.SupplierStructuralDomain.Code != null) { MohawkCollege.EHR.gpmr.COR.Property clsa = retVal.FindMember("classCode", false, MohawkCollege.EHR.gpmr.COR.Property.PropertyTypes.Structural); if (clsa == null)// Class code is derived... we need to override it { clsa = retVal.FindMember("classCode", true, MohawkCollege.EHR.gpmr.COR.Property.PropertyTypes.Structural); // Any class code defined? if (clsa != null) { clsa = PropertyParser.Parse(clsa.DerivedFrom as ClassAttribute, vocabularyRealm, classInfo.CompilerRepository, classInfo.DerivationSuppliers); retVal.AddContent(clsa); } else // Makes no sense, we have a class code enforcement but no class code? { if (MifCompiler.hostContext.Mode == Pipeline.OperationModeType.Quirks) { Trace.WriteLine(String.Format("Supplier domain is specified on class '{0}' which has class code. Since GPMR is in quirks mode, the classCode attribute will be created", retVal.Name), "quirks"); clsa = new Property(); clsa.Name = "classCode"; clsa.PropertyType = Property.PropertyTypes.Structural; clsa.Conformance = ClassContent.ConformanceKind.Mandatory; retVal.AddContent(clsa); } else { throw new InvalidOperationException("Shouldn't be here. Supplier domain specified on a class with no classCode"); } } } #region Now populate the code domain // Supplier domains if (classInfo.Class.SupplierStructuralDomain != null) { var supplierStruct = classInfo.Class.SupplierStructuralDomain; if (supplierStruct.Code != null && !String.IsNullOrEmpty(supplierStruct.Code.Code)) // Fixed code { clsa.FixedValue = string.Format("{0}", supplierStruct.Code.Code); } // JF: If the code system is identified, then bind if (supplierStruct.Code != null && !String.IsNullOrEmpty(supplierStruct.Code.CodeSystemName)) // Very odd thing that is present in UV mifs { Trace.WriteLine(String.Format("'{0}' is specified as fixed code's code system, however no fixed code is present. Assuming this is a bound code system instead", "assumption")); clsa.SupplierDomain = classInfo.CompilerRepository.Find(o => o is CodeSystem && (o as CodeSystem).Name.Equals(supplierStruct.Code.CodeSystemName)) as Enumeration; if (clsa.SupplierDomain == null) { Trace.WriteLine(String.Format("'{0}' could not be bound to '{1}' as the code system was not found", clsa.Name, supplierStruct.Code.CodeSystemName), "warn"); } } if (supplierStruct.ConceptDomain != null) { clsa.SupplierDomain = classInfo.CompilerRepository.Find(o => o is ConceptDomain && (o as ConceptDomain).Name.Equals(supplierStruct.ConceptDomain.Name)) as Enumeration; if (clsa.SupplierDomain == null) { Trace.WriteLine(String.Format("'{0}' could not be bound to '{1}' as the concept domain was not found", clsa.Name, supplierStruct.ConceptDomain.Name), "warn"); } } if (supplierStruct.ValueSet != null) { clsa.SupplierDomain = classInfo.CompilerRepository.Find(o => o is ValueSet && (o as ValueSet).Name.Equals(supplierStruct.ValueSet.Name)) as Enumeration; if (clsa.SupplierDomain == null) { Trace.WriteLine(String.Format("'{0}' could not be bound to '{1}' as the value set was not found", clsa.Name, supplierStruct.ValueSet.Name), "warn"); } bool shouldFix = false; if (clsa.SupplierDomain != null) { var enumLiteral = clsa.SupplierDomain.Literals.Find(o => o.Name == supplierStruct.ValueSet.RootCode); shouldFix = enumLiteral != null && enumLiteral.RelatedCodes != null && enumLiteral.RelatedCodes.Count == 0; } if (shouldFix) { clsa.FixedValue = String.Format("{0}", supplierStruct.ValueSet.RootCode); } } // Supplier strength(s) if (supplierStruct.ValueSet != null) { clsa.SupplierStrength = supplierStruct.ValueSet.CodingStrength == CodingStrengthKind.CNE ? (Property.CodingStrengthKind?)Property.CodingStrengthKind.CodedNoExtensions: supplierStruct.ValueSet.CodingStrength == CodingStrengthKind.CWE ? (Property.CodingStrengthKind?)Property.CodingStrengthKind.CodedNoExtensions : null; } else { clsa.SupplierStrength = Property.CodingStrengthKind.CodedNoExtensions; System.Diagnostics.Trace.WriteLine(string.Format("No vocabulary value set on property {0}! Defaulting to CNE for supplier strength", retVal.Name), "assumption"); } } //if (classInfo.Class.SupplierStructuralDomain.Code != null) // clsa.FixedValue = string.Format("{0}{1}", classInfo.Class.SupplierStructuralDomain.Code.CodeSystem == null ? "" : classInfo.Class.SupplierStructuralDomain.Code.CodeSystem + ":", classInfo.Class.SupplierStructuralDomain.Code.Code); //if (classInfo.Class.SupplierStructuralDomain.ConceptDomain != null) // clsa.SupplierDomain = classInfo.Class.SupplierStructuralDomain.ConceptDomain.Name; //if (classInfo.Class.SupplierStructuralDomain.ValueSet != null) //{ // clsa.SupplierStrength = classInfo.Class.SupplierStructuralDomain.ValueSet.CodingStrength == CodingStrengthKind.CNE ? (Property.CodingStrengthKind?)Property.CodingStrengthKind.CodedNoExtensions : // classInfo.Class.SupplierStructuralDomain.ValueSet.CodingStrength == CodingStrengthKind.CWE ? (Property.CodingStrengthKind?)Property.CodingStrengthKind.CodedNoExtensions : null; // clsa.SupplierDomainValueSet = classInfo.Class.SupplierStructuralDomain.ValueSet.Id; //} //else //{ // clsa.SupplierStrength = Property.CodingStrengthKind.CodedNoExtensions; // System.Diagnostics.Trace.WriteLine(string.Format("No vocabulary value set on property {0}! Defaulting to CNE for supplier strength", retVal.Name), "assumption"); //} #endregion } #endregion // All specifications #region Specializations //if ((classInfo.Class as MohawkCollege.EHR.HL7v3.MIF.MIF20.StaticModel.Flat.Class).SpecializationChild != null && (classInfo.Class as MohawkCollege.EHR.HL7v3.MIF.MIF20.StaticModel.Flat.Class).SpecializationChild.Count > 0) //{ // retVal.SpecializedBy = new List<MohawkCollege.EHR.gpmr.COR.TypeReference>(); // foreach (ClassGeneralization cg in (classInfo.Class as MohawkCollege.EHR.HL7v3.MIF.MIF20.StaticModel.Flat.Class).SpecializationChild) // { // MohawkCollege.EHR.gpmr.COR.TypeReference specRef = new MohawkCollege.EHR.gpmr.COR.TypeReference(); // specRef.Name = string.Format("{0}.{1}", classInfo.ScopedPackageName, cg.ChildClassName); // MohawkCollege.EHR.gpmr.COR.Property noProp = new MohawkCollege.EHR.gpmr.COR.Property(); // noProp.Container = retVal; // specRef.Container = noProp; // retVal.SpecializedBy.Add(specRef); // } //} #endregion #region Behaviors // State machine on the class if (classInfo.Class.Behavior != null) { // Find the property that this state machine acts on Property stateProperty = retVal.FindMember(classInfo.Class.Behavior.SupplierStateAttributeName, false, Property.PropertyTypes.NonStructural | Property.PropertyTypes.Structural); stateProperty.StateMachine = StateMachineParser.Parse(classInfo.Class.Behavior); } #endregion #region Derivation Supplier if (classInfo.Class.DerivedFrom != null) { // Init retVal projection retVal.Realizations = new List <MohawkCollege.EHR.gpmr.COR.TypeReference>(); // Iterate through each class this class is a projection of (is based on) foreach (ClassDerivation cd in classInfo.Class.DerivedFrom) { try { // See if this class has been parsed Package derivationPackage = null; if (!classInfo.DerivationSuppliers.TryGetValue(cd.StaticModelDerivationId, out derivationPackage) || derivationPackage == null) { continue; } MohawkCollege.EHR.gpmr.COR.Feature ss = null; // Has the package been compiled? if (!classInfo.CompilerRepository.TryGetValue(string.Format("{0}", derivationPackage.PackageLocation.Artifact == ArtifactKind.RIM ? "RIM" : derivationPackage.PackageLocation.ToString(MifCompiler.NAME_FORMAT)), out ss)) { // Attempt to parse PackageParser.Parse(derivationPackage.PackageLocation.ToString(MifCompiler.NAME_FORMAT), derivationPackage.MemberOfRepository, classInfo.CompilerRepository); // Ditch if still can't find if (!classInfo.CompilerRepository.TryGetValue(string.Format("{0}", derivationPackage.PackageLocation.Artifact == ArtifactKind.RIM ? "RIM" : derivationPackage.PackageLocation.ToString(MifCompiler.NAME_FORMAT)), out ss) || ss == null) { System.Diagnostics.Trace.WriteLine(String.Format("Can't find derivation class '{0}' (derivation supplier {1})", cd.ClassName, cd.StaticModelDerivationId), "warn"); } } // Attempt to parse MohawkCollege.EHR.gpmr.COR.SubSystem supplierSubSystem = ss as MohawkCollege.EHR.gpmr.COR.SubSystem; // Find the class MohawkCollege.EHR.gpmr.COR.Class supplierClass = classInfo.CompilerRepository[string.Format("{0}.{1}", supplierSubSystem.Name, cd.ClassName)] as MohawkCollege.EHR.gpmr.COR.Class; // Add a realization retVal.Realizations.Add(supplierClass.CreateTypeReference()); // Now do some processing foreach (ClassContent cc in supplierClass.Content) { ClassContent rcc = null; // Find the class content we are talking about if (cc is Property) { rcc = retVal.FindMember(cc.Name, true, (cc as MohawkCollege.EHR.gpmr.COR.Property).PropertyType); } else { ; //TODO: Clean up choices so they match the realization class. Not sure if this supposed to be done } // Correct Items if (rcc != null) { if (MohawkCollege.EHR.gpmr.COR.Documentation.IsEmpty(rcc.Documentation))// Correct documentation { rcc.Documentation = cc.Documentation; } // Removed: This was supposed to correct missing supplier domains from the RMIMs using the RIM data, however it does // cause some issues. // if (rcc is MohawkCollege.EHR.gpmr.COR.Property && (rcc as MohawkCollege.EHR.gpmr.COR.Property).SupplierDomain == null && // (cc as MohawkCollege.EHR.gpmr.COR.Property).SupplierDomain != null) // { // (rcc as MohawkCollege.EHR.gpmr.COR.Property).SupplierDomain = (cc as MohawkCollege.EHR.gpmr.COR.Property).SupplierDomain; // (rcc as MohawkCollege.EHR.gpmr.COR.Property).SupplierStrength = (cc as MohawkCollege.EHR.gpmr.COR.Property).SupplierStrength; // } } } } catch (Exception e) { System.Diagnostics.Trace.WriteLine(string.Format("Could not find derivation supplier information for {0}", retVal.Name), "warn"); } } } #endregion #region Correct Vocabulary // This is quite a problem, when a property is bound to a value set, and that value set // is merely a pointer to other value sets of data we need to correct the pointer foreach (var property in retVal.Content) { // If the content is a property and it has a supplier domain, try to find the supplier domain if (property is Property && (property as Property).SupplierDomain != null) { // Now to correct the reference if ((property as Property).SupplierDomain.EnumerationReference != null && (property as Property).SupplierDomain.EnumerationReference.Count == 1) { (property as Property).SupplierDomain = (property as Property).SupplierDomain.EnumerationReference[0]; } } } #endregion // Sort the class content retVal.Content.Sort(new ClassContent.Comparator()); // Return return(retVal); }
public void Render(string OwnerNS, string apiNs, MohawkCollege.EHR.gpmr.COR.Feature f, System.IO.TextWriter tw) { StringWriter sw = new StringWriter(); // Make a strong typed reference to enumeration Enumeration enu = f as Enumeration; // enumeration is a concept domain? do the binding if (enu is ConceptDomain && (enu as ConceptDomain).ContextBinding != null) { enu = (enu as ConceptDomain).ContextBinding[0]; } else if (enu is ConceptDomain) { throw new InvalidOperationException("Won't render unbound concept domains"); } #region Usings // Validate Usings string[] usings = new string[] { "Attributes", "Interfaces", "DataTypes" }; foreach (string s in usings) { sw.WriteLine("using {1}.{0};", s, apiNs); } sw.WriteLine("using System.ComponentModel;"); #endregion sw.WriteLine("namespace {0}.Vocabulary {{", OwnerNS); // start ns // Generate the documentation if (DocumentationRenderer.Render(enu.Documentation, 1).Length == 0) { sw.WriteLine("\t/// <summary>{0}</summary>", enu.BusinessName ?? "No Documentation Found"); } else { sw.Write(DocumentationRenderer.Render(enu.Documentation, 1)); } // Generate the structure attribute sw.WriteLine("\t[Structure(Name = \"{0}\", CodeSystem = \"{1}\", StructureType = StructureAttribute.StructureAttributeType.{2}, Publisher = {3})]", enu.Name, enu.ContentOid, enu.GetType().Name, enu.Documentation != null ? "\"" + enu.Documentation.Copyright + "\"" : "null"); sw.WriteLine("#if !WINDOWS_PHONE"); sw.WriteLine("\t[Serializable]"); sw.WriteLine("#endif"); string renderName = enu.Name; if (enu.Annotations != null && enu.Annotations.Exists(o => o is RenderAsAnnotation)) { renderName = (enu.Annotations.Find(o => o is RenderAsAnnotation) as RenderAsAnnotation).RenderName; } // Generate enum sw.WriteLine("\tpublic enum {0} {{ ", Util.Util.MakeFriendly(renderName)); List <String> rendered = new List <string>(), mnemonics = new List <string>(); RenderLiterals(sw, enu, rendered, mnemonics, enu.Literals); String tStr = sw.ToString(); tStr = tStr.Remove(tStr.LastIndexOf(",")); tStr += ("\r\n\t}"); tStr += ("\r\n}"); // end ns // Write to tw tw.Write(tStr); }
/// <summary> /// Create a file for the enumeration /// </summary> public string CreateFile(Feature f, string filePath) { string fileName = Util.Util.MakeFriendly(f.Name); // Render as if (f.Annotations != null && f.Annotations.Exists(o => o is RenderAsAnnotation)) fileName = Util.Util.MakeFriendly((f.Annotations.Find(o => o is RenderAsAnnotation) as RenderAsAnnotation).RenderName); fileName = Path.ChangeExtension(Path.Combine(Path.Combine(filePath, "vocabulary"), Util.Util.MakeFriendly(fileName)), ".java"); var enu = f as Enumeration; if (!String.IsNullOrEmpty(Datatypes.GetBuiltinVocabulary(enu.Name))) throw new InvalidOperationException("Enumeration is builtin to core library. Will not render"); // Is this code system even used? if (!m_markedForUse.Exists(o => o.GetType().Equals(f.GetType()) && o.Name == f.Name)) { if (enu.GetEnumeratedLiterals().Count > RimbaJavaRenderer.MaxLiterals) throw new InvalidOperationException(String.Format("Enumeration '{2}' too large, enumeration has {0} literals, maximum allowed is {1}", enu.GetEnumeratedLiterals().Count, RimbaJavaRenderer.MaxLiterals, enu.Name)); else throw new InvalidOperationException("Enumeration is not used, or is an unbound concept domain!"); } // First, if the feature is a value set we will always render it if (File.Exists(fileName) && !(f as Enumeration).OwnerRealm.EndsWith(RimbaJavaRenderer.prefRealm)) throw new InvalidOperationException("Enumeration has already been rendered from the preferred realm. Will not render this feature"); return fileName; }
/// <summary> /// Create a vocbulary change strength /// </summary> private void CreateVocabularyStrengthChange(Feature feature, Constraint constraint) { #region Default Value // Validate the constraint var strConstraint = constraint.Value as ConstraintValue<String>; Property ccFeature = feature as Property; if (ccFeature == null) { Trace.WriteLine(String.Format("Delta: Cannot apply the vocabulary strength constraint against a a feature of type '{0}', skipping...", feature.GetType().Name), "error"); return; } // Default Property.CodingStrengthKind newStrength = Property.CodingStrengthKind.CodedNoExtensions; // Parse the new value switch (strConstraint.New) { case "CWE": newStrength = Property.CodingStrengthKind.CodedWithExtensions; break; case "CNE": break; default: Trace.WriteLine(String.Format("Delta: Don't understand coding strength '{0}', ignoring...", strConstraint.New), "warn"); return; } // Validate the annotation doesn't already exist if (ccFeature.Annotations.Exists(o => o is SupplierStrengthConstraintAnnotation && (o as SupplierStrengthConstraintAnnotation).RealmCode == this.m_deltaSet.Realm.Code)) { Trace.WriteLine(String.Format("Delta: Supplier constraint has already been applied to '{0}'", feature.Name), "error"); return; } // Add the annotation to the feature ccFeature.Annotations.Add(new SupplierStrengthConstraintAnnotation() { ChangeType = ChangeType.Edit, RealmCode = this.m_deltaSet.Realm.Code, NewValue = newStrength, RealmName = this.m_deltaSet.MetaData.Description }); #endregion }
public void Render(string ownerPackage, string apiNs, Feature f, System.IO.TextWriter tw) { ClassRenderer.s_imports.Clear(); // Validate arguments if (String.IsNullOrEmpty(ownerPackage)) throw new ArgumentNullException("ownerPackage"); if (String.IsNullOrEmpty(apiNs)) throw new ArgumentNullException("apiNs"); if (f == null || !(f is Interaction)) throw new ArgumentException("Parameter must be of type Enumeration", "f"); this.generatedFactoryMethods = new List<string>(); // Get a strongly typed reference to the Interaction interaction = f.Clone() as Interaction; interaction.MemberOf = f.MemberOf; StringWriter sw = new StringWriter(); #endregion // HACK: If there is no description on the interaction then we'll // HACK: add the business name as a description // TODO: Remove this and come up with a better solution if (interaction.Documentation == null || interaction.Documentation.Description == null) interaction.Documentation = new Documentation() { Description = new List<string>() { interaction.BusinessName } }; // Determine if this class is an interaction bool isIInteraction = true; string[] members = { "creationtime", "versioncode", "interactionid", "processingmodecode" }; foreach (var m in members) isIInteraction &= interaction.MessageType.Class.Content.Exists(o => o.Name.ToLower() == m); sw.Write(DocumentationRenderer.Render(interaction.Documentation, 0)); sw.WriteLine("@Structure(name = \"{0}\", structureType = StructureType.INTERACTION)", interaction.Name); sw.WriteLine("@Interaction(name=\"{1}\", triggerEvent = \"{0}\")", interaction.TriggerEvent, interaction.Name); sw.WriteLine("@InteractionResponses( value = {"); List<String> resp = new List<string>(); foreach (Interaction response in interaction.Responses) { if (resp.Contains(response.Name)) continue; sw.WriteLine("\t@Interaction(name = \"{0}\", triggerEvent = \"{1}\"){2}", response.Name, response.TriggerEvent, response == interaction.Responses.Last() ? "" : ","); resp.Add(response.Name); } sw.WriteLine("})"); sw.WriteLine("public class {0} extends {1} {2} {{", interaction.Name, CreateInteractionDatatype(interaction.MessageType, ownerPackage), isIInteraction ? "implements IInteraction" : ""); #region Constants // Get the trigger event sw.WriteLine("\t/** Gets the default trigger event to be used for this interaction */"); sw.WriteLine("\tpublic static CV<String> defaultTriggerEvent() {{ return new CV<String>(\"{0}\", \"{1}\"); }}", interaction.TriggerEvent, triggerEventOid, apiNs); // Get the interaction id sw.WriteLine("\t/** Gets the interaction ID of this interaction */"); sw.WriteLine("\tpublic static II defaultInteractionId() {{ return new II(\"{1}\", \"{0}\"); }}", interaction.Name, interactionIdOid, apiNs); // Get the profile id if (!String.IsNullOrEmpty(profileId)) { sw.WriteLine("\t/** Gets the profile id of this interaction */"); sw.WriteLine("\tpublic static LIST<II> defaultProfileId() {{ LIST<II> retVal = new LIST<II>(); retVal.add(new II (\"{0}\", \"{1}\")); return retVal; }}", profileIdOid, profileId, apiNs); } #endregion #region Constructors sw.WriteLine("\t/** Creates a new, empty instance of {0} */", interaction.Name); sw.WriteLine("\tpublic {0}() {{ super(); }}\r\n", interaction.Name); //string ctor_parameters = ""; //string ctor_body = ""; //foreach (ClassContent cc in interaction.MessageType.Class.Content) //{ // if (cc.Conformance == ClassContent.ConformanceKind.Mandatory) // Mandatory ctor // { // if (cc is Property && ((cc as Property).FixedValue == null || (cc as Property).PropertyType == Property.PropertyTypes.TraversableAssociation)) // { // Property p = cc as Property; // TypeReference tr = Datatypes.MapDatatype(p.Type); // // Documentation // if (p.Documentation != null && p.Documentation.Definition != null && p.Documentation.Definition.Count > 0) // sw.WriteLine("\t\t/// <param name=\"{0}\">{1}</param>", p.Name, p.Documentation.Definition[0]); // // Now the signature // ctor_parameters += string.Format("{0} {1},", ClassRenderer.CreateDatatypeRef(tr, p), p.Name); // ctor_body += string.Format("\t\t\tthis.{0} = {1};\r\n", Util.Util.PascalCase(p.Name), p.Name); // } // else // { // } // } //} //// Write CTOR //if (ctor_parameters.Length > 0) //{ // sw.WriteLine("\t\t/// <summary>\r\n\t\t/// CTOR for all mandatory elements\r\n\t\t/// </summary>"); // sw.WriteLine("\t\tpublic {0}({1}) : base() {{ \r\n\t\t{2}\t\t}}", interaction.Name, ctor_parameters.Substring(0, ctor_parameters.Length - 1), ctor_body); //} Dictionary<String, String[]> ctors = ClassRenderer.CreateFactoryMethod(interaction.MessageType, "this", true, ownerPackage); // Write CTOR List<String> wroteParms = new List<string>(); // Keep track of the parameters used foreach (KeyValuePair<String, String[]> kv in ctors) { if (kv.Value[0].Length > 0 && !wroteParms.Contains(kv.Value[0])) { wroteParms.Add(kv.Value[0]); sw.WriteLine("\t/**\r\n\t * CTOR for all {0} elements\r\n\t", kv.Key); sw.WriteLine(kv.Value[2]); sw.WriteLine("\t*/\r\n\tpublic {0}({1}) {{ \r\n\t\tsuper();\r\n{2}\t}}", interaction.Name, kv.Value[0].Substring(0, kv.Value[0].Length - 1), kv.Value[1]); } } #endregion #region Creator for payload, control act, etc... // Owner namespace if (interaction.MessageType.GenericSupplier != null) foreach (TypeReference tr in interaction.MessageType.GenericSupplier) sw.WriteLine(GenerateFactoryMethod(tr, ownerPackage)); #endregion #region Interaction members if (isIInteraction) { sw.WriteLine("\t\t/** Implementation of generic IInteraction.ControlActEvent Property */"); // Create the control act event if (interaction.MessageType.GenericSupplier != null && interaction.MessageType.GenericSupplier.Count > 0) { Property cactProperty = interaction.MessageType.Class.Content.Find(o => o is Property && (o as Property).Type.Name == interaction.MessageType.Class.TypeParameters[0].ParameterName) as Property; if (cactProperty == null) ; string cactName = Util.Util.PascalCase(cactProperty.Name); sw.WriteLine("\t\tObject getControlAct() {"); sw.WriteLine("\t\t\treturn this.get{0}();", cactName); sw.WriteLine("\t\t}"); } else { sw.WriteLine("\t\tObject getControlAct() {"); sw.WriteLine("\t\t\treturn null;"); sw.WriteLine("\t\t}"); } } #endregion sw.WriteLine("}"); #region Usings // Interactions package tw.WriteLine("package {0}.interaction;", ownerPackage); #region Render the imports string[] apiImports = { "annotations.*", "datatypes.*", "datatypes.generic.*", "interfaces.IGraphable", "interfaces.IInteraction" }, jImports = { "java.lang.*", "java.util.*" }; foreach (var import in apiImports) tw.WriteLine("import {0}.{1};", apiNs, import); foreach (var import in jImports) tw.WriteLine("import {0};", import); foreach (var import in ClassRenderer.s_imports) tw.WriteLine("import {0};", import); #endregion tw.WriteLine(sw.ToString()); }
/// <summary> /// Create a vocabulary domain change /// </summary> private void CreateVocabularyDomainChange(Feature feature, Constraint constraint) { #region Vocabulary Domain Change // 1. Validate the constraint var vocConstraint = constraint.Value as VocabularyConstraintValue; Property ccFeature = feature as Property; if (ccFeature == null) { Trace.WriteLine(String.Format("Delta: Cannot apply the vocabulary binding constraint against a a feature of type '{0}', skipping...", feature.GetType().Name), "error"); return; } // 2. Validate the parameters Type originalType = typeof(Enumeration), newType = typeof(Enumeration); // Type map Dictionary<DomainSourceType, Type> typeMap = new Dictionary<DomainSourceType, Type>() { { DomainSourceType.CodeSystem, typeof(CodeSystem) }, { DomainSourceType.ConceptDomain, typeof(ConceptDomain) }, { DomainSourceType.ValueSet, typeof(ValueSet) } }; // Map if (!typeMap.TryGetValue(vocConstraint.OriginalSourceType, out originalType)) { Trace.WriteLine(String.Format("Delta: Don't understand the source type of the vocabulary constraint '{0}', skipping", vocConstraint.OriginalSourceType), "error"); return; } else if (!typeMap.TryGetValue(vocConstraint.NewSourceType, out newType)) { Trace.WriteLine(String.Format("Delta: Don't understand the destination type of the vocabulary constraint '{0}', skipping", vocConstraint.NewSourceType), "error"); return; } // a. Validate original source parameters if (!ccFeature.SupplierDomain.Equals(vocConstraint.OriginalDomain) || ccFeature.SupplierDomain != null && !ccFeature.SupplierDomain.GetType().Equals(originalType)) Trace.WriteLine(String.Format("Delta: Current supplier domain '{2}:{0}' does not match original listed in the delta of '{3}:{1}', will continue processing anyways...", ccFeature.SupplierDomain, vocConstraint.OriginalDomain, ccFeature.SupplierDomain.GetType().Name, originalType.Name), "warn"); // b. Validate the destination parameters // Try to get the destination vocabulary domain ClassRepository cr = ccFeature.MemberOf ?? ccFeature.Container.MemberOf; Feature targetEnum = null; if (cr != null && !cr.TryGetValue(vocConstraint.NewDomain, out targetEnum)) Trace.WriteLine(String.Format("Delta: Could not find vocabulary '{0}' in repository! Cannot verify parameters", vocConstraint.NewDomain), "warn"); else if (targetEnum != null && !targetEnum.GetType().Equals(newType)) Trace.WriteLine(String.Format("Delta: Could not verify the destination vocabulary type. Actual type is '{0}:{1}', delta set describes '{2}:{3}'", targetEnum.GetType().Name, targetEnum.Name, vocConstraint.NewSourceType, vocConstraint.NewDomain), "warn"); // Identify the new type object newValue = (object)targetEnum ?? (object)vocConstraint.NewDomain; // Validate the annotation doesn't already exist if (ccFeature.Annotations.Exists(o => o is SupplierDomainConstraintAnnotation && (o as SupplierDomainConstraintAnnotation).RealmCode == this.m_deltaSet.Realm.Code)) { Trace.WriteLine(String.Format("Delta: Supplier domain constraint has already been applied to '{0}'", feature.Name), "error"); return; } // Add the annotation to the feature ccFeature.Annotations.Add(new SupplierDomainConstraintAnnotation() { ChangeType = ChangeType.Edit, RealmCode = this.m_deltaSet.Realm.Code, NewValue = newValue, RealmName = this.m_deltaSet.MetaData.Description }); #endregion }
/// TODO: Explanation of parameters missing: f and FilePath /// Description of the value returned missing /// <summary> /// Create interaction /// </summary> public string CreateFile(Feature f, string FilePath) { return Path.ChangeExtension(Path.Combine(Path.Combine(FilePath, "Interaction"), f.Name), "cs"); }
/// <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 }
public void ParseAssociation(Association asc, Dictionary <string, Package> derivationSuppliers) { // There are two scenarios // A: Two traversable connections // B: A traversable and non traversable end // Case A: Two traversable connections, this means that the connection appears in both classes if (asc.Ends[0] is AssociationEnd && asc.Ends[1] is AssociationEnd) { // Make processing a little easier AssociationEnd[] ends = new AssociationEnd[] { asc.Ends[0] as AssociationEnd, asc.Ends[1] as AssociationEnd }; // Loop so we write the code once for (int i = 0; i < 2; i++) { Property p = new Property(); p.Name = ends[i].Name; // Business Name foreach (BusinessName bn in ends[i].BusinessName ?? new List <BusinessName>()) { if (bn.Language == MifCompiler.Language || bn.Language == null) { p.BusinessName = bn.Name; } } // The multiplicity of the opposing end influences the property on this end of the // association p.MinOccurs = ends[1 - i].MinimumMultiplicity; p.MaxOccurs = ends[1 - i].MaximumMultiplicity; p.Conformance = ends[1 - i].IsMandatory ? ClassContent.ConformanceKind.Mandatory : ends[1 - i].Conformance == ConformanceKind.Required ? ClassContent.ConformanceKind.Required : ends[1 - i].MinimumMultiplicity == "1" ? ClassContent.ConformanceKind.Populated : ClassContent.ConformanceKind.Optional; // The type of this end is the type of the association p.Type = CreateTypeReference(ends[i], p); if (p.Type.Name == null) { if (p.Documentation == null) { p.Documentation = new MohawkCollege.EHR.gpmr.COR.Documentation(); } if (p.Documentation.Description == null) { p.Documentation.Description = new List <string>(); } p.Documentation.Description.Add(String.Format("GPMR: Association to type '{0}' was ignored and set as nothing as '{0}' could not be found. You should consider revising this", ends[i].ParticipantClassName)); } // Traversable association p.PropertyType = Property.PropertyTypes.TraversableAssociation; // Annotations if (asc.Annotations != null) { p.Documentation = MohawkCollege.EHR.gpmr.Pipeline.Compiler.Mif20.Parsers.DocumentationParser.Parse(asc.Annotations.Documentation); } // Find the class this end belongs in if (!ClassRepository.ContainsKey(string.Format("{0}.{1}", staticModel.PackageLocation.Artifact == ArtifactKind.RIM ? "RIM" : staticModel.PackageLocation.ToString(MifCompiler.NAME_FORMAT), ends[1 - i].ParticipantClassName))) { throw new Exception(string.Format("Can't bind property '{0}' to class '{1}'... Class does not exist", p.Name, ends[1 - i].ParticipantClassName)); } // Set derivation p.DerivedFrom = asc; p.SortKey = asc.SortKey; try { if (ends[i].DerivedFrom != null) { p.Realization = new List <ClassContent>(); foreach (var dei in ends[i].DerivedFrom) { MohawkCollege.EHR.gpmr.COR.Feature f = null; if (!ClassRepository.TryGetValue(string.Format("{0}.{1}", derivationSuppliers[dei.StaticModelDerivationId].PackageLocation.Artifact == ArtifactKind.RIM ? "RIM" : derivationSuppliers[dei.StaticModelDerivationId].PackageLocation.ToString(MifCompiler.NAME_FORMAT), dei.ClassName), out f)) { System.Diagnostics.Trace.WriteLine(String.Format("Can't find derivation class '{0}' for association '{1}'", dei.ClassName, ends[i].Name), "debug"); } else { ClassContent cc = (f as MohawkCollege.EHR.gpmr.COR.Class).GetFullContent().Find(o => o.Name == dei.AssociationEndName); p.Realization.Add(cc); } } } } catch (Exception ex) { Trace.WriteLine(String.Format("Cannot append derivation information to {0} (reason:{1})", ends[i].Name, ex.ToString()), "error"); } // Add to repository if (ends[1 - i].Conformance != ConformanceKind.NotPermitted) { (ClassRepository[string.Format("{0}.{1}", staticModel.PackageLocation.Artifact == ArtifactKind.RIM ? "RIM" : staticModel.PackageLocation.ToString(MifCompiler.NAME_FORMAT), ends[1 - i].ParticipantClassName)] as MohawkCollege.EHR.gpmr.COR.Class).AddContent(p); } } } else // Case 2: A traversable and non-traversable connection, { AssociationEnd ae = (asc.Ends[0] as AssociationEnd) ?? (asc.Ends[1] as AssociationEnd); NonTraversableAssociationEnd ntae = (asc.Ends[0] as NonTraversableAssociationEnd) ?? (asc.Ends[1] as NonTraversableAssociationEnd); // Start to process the property. ClassContent cc; if (ae.ChoiceItem != null && ae.ChoiceItem.Count > 0) { cc = new Choice(); } else { cc = new Property(); } cc.Name = ae.Name; // Business Name foreach (BusinessName bn in ae.BusinessName ?? new List <BusinessName>()) { if (bn.Language == MifCompiler.Language || bn.Language == null) { cc.BusinessName = bn.Name; } } // The multiplicity of the opposing end influences the property on this end of the // association cc.MinOccurs = ae.MinimumMultiplicity; cc.MaxOccurs = ae.MaximumMultiplicity; cc.Conformance = ae.IsMandatory ? ClassContent.ConformanceKind.Mandatory : ae.Conformance == ConformanceKind.Required && ae.MinimumMultiplicity == "1" ? ClassContent.ConformanceKind.Populated : ae.Conformance == ConformanceKind.Required ? ClassContent.ConformanceKind.Required : ClassContent.ConformanceKind.Optional; #region Bind To Class // Find the class on the traversable end, we'll need to append the property to it if (!ClassRepository.ContainsKey(string.Format("{0}.{1}", staticModel.PackageLocation.Artifact == ArtifactKind.RIM ? "RIM" : staticModel.PackageLocation.ToString(MifCompiler.NAME_FORMAT), ntae.ParticipantClassName))) { System.Diagnostics.Trace.WriteLine(string.Format("Can't bind property '{0}' to class '{1}'... Class does not exist", cc.Name, ntae.ParticipantClassName), "error"); } //throw new Exception(string.Format("Can't bind property '{0}' to class '{1}'... Class does not exist", p.Name, ae.ParticipantClassName)); else if (ae.Conformance != ConformanceKind.NotPermitted) // Append the property to the class { MohawkCollege.EHR.gpmr.COR.Class cls = ClassRepository[string.Format("{0}.{1}", staticModel.PackageLocation.Artifact == ArtifactKind.RIM ? "RIM" : staticModel.PackageLocation.ToString(MifCompiler.NAME_FORMAT), ntae.ParticipantClassName)] as MohawkCollege.EHR.gpmr.COR.Class; cls.AddContent(cc); // Add template parameter if (templateParameters.ContainsKey(ae.ParticipantClassName)) { cls.AddTypeParameter(templateParameters[ae.ParticipantClassName]); } } else { return; } #endregion // Choice or property? if (cc is Property) { Property p = cc as Property; p.Type = CreateTypeReference(ae, p); if (p.Type.Name == null) { if (p.Documentation == null) { p.Documentation = new MohawkCollege.EHR.gpmr.COR.Documentation(); } if (p.Documentation.Description == null) { p.Documentation.Description = new List <string>(); } p.Documentation.Description.Add(String.Format("GPMR: Association to type '{0}' was ignored and set as nothing as '{0}' could not be found. You should consider revising this", ae.ParticipantClassName)); } // Traversable association p.PropertyType = Property.PropertyTypes.TraversableAssociation; } else // Choice { Choice chc = cc as Choice; chc.MemberOf = ClassRepository; chc.Content = new List <ClassContent>(); // Get a type reference to the CMET or main type to be used TypeReference trf = CreateTypeReference(ae, cc); // Cannot find association if (trf.Name == null) { if (chc.Documentation == null) { chc.Documentation = new MohawkCollege.EHR.gpmr.COR.Documentation(); } if (chc.Documentation.Description == null) { chc.Documentation.Description = new List <string>(); } chc.Documentation.Description.Add(String.Format("GPMR: Association to type '{0}' was ignored and set as nothing as '{0}' could not be found. You should consider revising this", ae.ParticipantClassName)); } // Warn if (trf.Class == null) { throw new InvalidOperationException(String.Format("Cannot make association to class '{0}' as it was not defined!", ae.ParticipantClassName)); } if (ae.ChoiceItem.Count != trf.Class.SpecializedBy.Count) { System.Diagnostics.Trace.WriteLine(string.Format("Number of choices on property does not match the number of child classes for its data type for association '{0}'", cc.Name), "warn"); } chc.Content.AddRange(ProcessAssociations(ae, ae.ChoiceItem, trf, chc)); /* * // Specializations * List<TypeReference> specializations = new List<TypeReference>(trf.Class.SpecializedBy); * * // Flatten choice members * for (int i = 0; i < ae.ChoiceItem.Count ; i++) * if (ae.ChoiceItem[i].Specialization != null && ae.ChoiceItem[i].Specialization.Count > 0) * { * AssociationEndSpecialization aes = ae.ChoiceItem[i]; // Get local reference * // Remove redundant data * ae.ChoiceItem.RemoveAt(i); // Remove the redundant choice item * i--; // redo this item * // is this a cmet? * if (ClassRepository.ContainsKey(aes.ClassName) && ClassRepository[aes.ClassName] is CommonTypeReference) * { * specializations.RemoveAll(o => o.Name == (ClassRepository[aes.ClassName] as CommonTypeReference).Class.Name); * specializations.AddRange((ClassRepository[aes.ClassName] as CommonTypeReference).Class.Class.SpecializedBy); * } * * ae.ChoiceItem.AddRange(aes.Specialization); // Now add the choices * } * * int ip = 0; * * // Add choice members * foreach (AssociationEndSpecialization aes in ae.ChoiceItem) * { * Property p = new Property(); * * // Now, construct the properties from the CMET entries * // Try ... * * var rClassName = specializations.Find(o => o.Class != null && o.Class.Name.Equals(aes.ClassName)); * * // Determine if this is a CMET * if (ClassRepository.ContainsKey(aes.ClassName) && ClassRepository[aes.ClassName] is CommonTypeReference) * p.Type = (ClassRepository[aes.ClassName] as CommonTypeReference).Class; * else if (rClassName != null) // Try using the inheritence method * p.Type = rClassName; * else if (ClassRepository.ContainsKey(String.Format("{0}.{1}", staticModel.PackageLocation.ToString(MifCompiler.NAME_FORMAT), aes.ClassName))) * p.Type = ((ClassRepository[String.Format("{0}.{1}", staticModel.PackageLocation.ToString(MifCompiler.NAME_FORMAT), aes.ClassName)] as MohawkCollege.EHR.gpmr.COR.Class).CreateTypeReference()); * else * { * System.Diagnostics.Trace.WriteLine(string.Format("Class '{2}' of CMET '{1}' could not be found or was not processed. The processing of the property '{0}' in '{3}.{4}' will NOT continue", cc.Name, aes.ClassName, ae.ParticipantClassName, staticModel.PackageLocation.ToString(MifCompiler.NAME_FORMAT), ntae.ParticipantClassName), "error"); * break; * } * * p.PropertyType = Property.PropertyTypes.TraversableAssociation; * * // Fix bug with optional choice * p.MinOccurs = chc.MinOccurs; * p.MaxOccurs = chc.MaxOccurs; * p.Conformance = chc.Conformance; * * p.DerivedFrom = aes; * p.Documentation = p.Type.ClassDocumentation; * * p.MemberOf = ClassRepository; * p.Container = chc; * * // Traversal names * p.Name = aes.TraversalName; * * chc.Content.Add(p); * * ip++; * } */ } // Annotations if (asc.Annotations != null) { cc.Documentation = MohawkCollege.EHR.gpmr.Pipeline.Compiler.Mif20.Parsers.DocumentationParser.Parse(asc.Annotations.Documentation); } // Set derivation cc.DerivedFrom = asc; cc.SortKey = ae.SortKey; try { if (ae.DerivedFrom != null) { cc.Realization = new List <ClassContent>(); foreach (var dei in ae.DerivedFrom) { MohawkCollege.EHR.gpmr.COR.Feature ss = null; Package derivationPkg = null; if (!derivationSuppliers.TryGetValue(dei.StaticModelDerivationId, out derivationPkg) || derivationPkg == null) { continue; } // Has the package been compiled? if (!ClassRepository.TryGetValue(string.Format("{0}", derivationPkg.PackageLocation.Artifact == ArtifactKind.RIM ? "RIM" : derivationPkg.PackageLocation.ToString(MifCompiler.NAME_FORMAT)), out ss)) { // Attempt to parse PackageParser.Parse(derivationPkg.PackageLocation.ToString(MifCompiler.NAME_FORMAT), derivationPkg.MemberOfRepository, ClassRepository); // Ditch if still can't find if (!ClassRepository.TryGetValue(string.Format("{0}", derivationPkg.PackageLocation.Artifact == ArtifactKind.RIM ? "RIM" : derivationPkg.PackageLocation.ToString(MifCompiler.NAME_FORMAT)), out ss)) { System.Diagnostics.Trace.WriteLine(String.Format("Can't find derivation class '{0}' for association '{1}' (derivation supplier {2})", dei.ClassName, dei.AssociationEndName, dei.StaticModelDerivationId), "warn"); } } // Feature was found var f = (ss as MohawkCollege.EHR.gpmr.COR.SubSystem).FindClass(dei.ClassName); if (f != null) { // Realized Class content ClassContent rcc = f.GetFullContent().Find(o => o.Name == dei.AssociationEndName); cc.Realization.Add(rcc); } else { System.Diagnostics.Trace.WriteLine(String.Format("Can't find derivation class '{0}' for association '{1}' (derivation supplier {2})", dei.ClassName, dei.AssociationEndName, dei.StaticModelDerivationId), "warn"); } } } } catch (Exception ex) { Trace.WriteLine(String.Format("Cannot append derivation information to {0} (reason:{1})", ae.Name, ex.ToString()), "error"); } (cc.Container as MohawkCollege.EHR.gpmr.COR.Class).Content.Sort(new ClassContent.Comparator()); } }
/// <summary> /// Generate feature /// </summary> private bool GenerateFeature(KeyValuePair<FeatureRendererAttribute, IFeatureRenderer> fr, Feature f, string[][] templateFields, string projectName, TextWriter jFileList, Dictionary<String, StringCollection> parameters, string sourcePath) { string file = String.Empty; try // To write the file { // Start the rendering file = fr.Value.CreateFile(f, Path.Combine(sourcePath, JabaUtils.PackageNameToDirectory(projectName))); // Is the renderer for a file if (fr.Key.IsFile) { TextWriter tw = File.CreateText(file); try // Render the file { string Header = Template.Default; // Set the header to the default // Populate template fields foreach (String[] st in templateFields) Header = Header.Replace(st[0], st[1]); // Write header tw.Write(Header); // Render the template out fr.Value.Render(parameters["rimbapi-target-ns"][0], parameters["rimbapi-api-ns"][0], f, tw); jFileList.WriteLine(file); } finally { tw.Close(); } return true; } return true; } catch (NotSupportedException) { if (!String.IsNullOrEmpty(file)) File.Delete(file); return false; } catch (Exception e) { if (!String.IsNullOrEmpty(file)) File.Delete(file); System.Diagnostics.Trace.WriteLine(String.Format("Could not write file '{0}', {1}", file, e.Message), "error"); return false; } }
/// <summary> /// Create an annotation change delta /// </summary> private void CreateAnnotationChange(Feature feature, Constraint constraint) { #region Annotation Change AnnotationConstraintValue acv = constraint.Value as AnnotationConstraintValue; if (acv.ChangeType == ChangeType.Remove) { // Determine modification type var modType = AnnotationConstraintAnnotation.ModificationTargetType.Other; switch (acv.Type) { case AnnotationType.Description: modType = AnnotationConstraintAnnotation.ModificationTargetType.Description; break; case AnnotationType.UseageNotes: modType = AnnotationConstraintAnnotation.ModificationTargetType.Usage; break; case AnnotationType.Rationale: modType = AnnotationConstraintAnnotation.ModificationTargetType.Rationale; break; } feature.Annotations.Add(new AnnotationConstraintAnnotation() { AnnotationType = modType, ChangeType = ChangeType.Remove, RealmCode = this.m_deltaSet.Realm.Code }); } else switch (acv.Type) { case AnnotationType.UseageNotes: case AnnotationType.Description: case AnnotationType.Rationale: // 1. Validate the current value is equal if (feature.Documentation == null || acv.Type == AnnotationType.Description && (feature.Documentation.Description == null || feature.Documentation.Description.Count == 0 || !feature.Documentation.Description[0].Equals(acv.Original)) || acv.Type == AnnotationType.UseageNotes && (feature.Documentation.Usage == null || feature.Documentation.Usage.Count == 0 || !feature.Documentation.Usage[0].Equals(acv.Original)) || acv.Type == AnnotationType.Rationale && (feature.Documentation.Rationale == null || feature.Documentation.Rationale.Count == 0 || !feature.Documentation.Rationale[0].Equals(acv.Original))) Trace.WriteLine(String.Format("Delta: Annotation constraint for '{0}' of type '{1}' does not have the same origial content, this may be an error!", feature.Name, acv.Type), "warn"); // 2. Add the annotation feature.Annotations.Add(new AnnotationConstraintAnnotation() { AnnotationType = acv.Type == AnnotationType.Description ? AnnotationConstraintAnnotation.ModificationTargetType.Description : acv.Type == AnnotationType.Rationale ? AnnotationConstraintAnnotation.ModificationTargetType.Rationale : AnnotationConstraintAnnotation.ModificationTargetType.Usage, ChangeType = acv.ChangeType, NewValue = acv.New, RealmCode = this.m_deltaSet.Realm.Code, RealmName = this.m_deltaSet.MetaData.Description }); break; case AnnotationType.Constraint: // 1. Create a new titled documentation feature.Annotations.Add(new AnnotationConstraintAnnotation() { AnnotationType = AnnotationConstraintAnnotation.ModificationTargetType.Constraint, ChangeType = acv.ChangeType, NewValue = acv.New, RealmCode = this.m_deltaSet.Realm.Code, RealmName = this.m_deltaSet.MetaData.Description }); break; case AnnotationType.DesignComments: case AnnotationType.Mapping: case AnnotationType.OpenIssue: case AnnotationType.OtherNotes: // 1. Create a new titled documentation feature.Annotations.Add(new AnnotationConstraintAnnotation() { AnnotationType = AnnotationConstraintAnnotation.ModificationTargetType.Other, ChangeType = acv.ChangeType, NewValue = acv.New, RealmCode = this.m_deltaSet.Realm.Code, RealmName = this.m_deltaSet.MetaData.Description }); break; } #endregion }
public void Render(string OwnerNS, string apiNs, Feature f, System.IO.TextWriter tw) { this.generatedFactoryMethods = new List<string>(); // Get a strongly typed reference to the Interaction interaction = f.Clone() as Interaction; interaction.MemberOf = f.MemberOf; StringWriter sw = new StringWriter(); #region Usings // Validate Usings string[] usings = new string[] { "Attributes", "Interfaces", "DataTypes", "DataTypes.Primitives" }; // API usings foreach (string s in usings) sw.WriteLine("using {1}.{0};", s, apiNs); // Owner Usings foreach (String s in GatherUsings(interaction.MessageType)) sw.WriteLine("using {0}.{1};", OwnerNS, s); if(f.MemberOf.Find(o=>o is Enumeration) != null) sw.WriteLine("using {0}.Vocabulary;", OwnerNS); #endregion // HACK: If there is no description on the interaction then we'll // HACK: add the business name as a description // TODO: Remove this and come up with a better solution if (interaction.Documentation == null || interaction.Documentation.Description == null) interaction.Documentation = new Documentation() { Description = new List<string>() { interaction.BusinessName } }; // Determine if the interaction is an IInteraction bool isIInteraction = true; string[] members = { "creationtime", "versioncode", "interactionid", "processingmodecode" }; foreach (var m in members) isIInteraction &= interaction.MessageType.Class.Content.Exists(o => o.Name.ToLower() == m); sw.WriteLine("namespace {0}.Interactions {{\r\n", OwnerNS); var vLength = sw.ToString().Length; sw.Write(DocumentationRenderer.Render(interaction.Documentation, 1)); if (sw.ToString().Length == vLength) sw.WriteLine("\t/// <summary>{0}</summary>", interaction.BusinessName != null ? interaction.BusinessName.Replace("\n", "").Replace("\r", "") : interaction.Name); sw.WriteLine("\t[Structure(Name = \"{0}\", StructureType = StructureAttribute.StructureAttributeType.Interaction)]", interaction.Name); sw.WriteLine("\t[Interaction(TriggerEvent = \"{0}\")]", interaction.TriggerEvent); sw.WriteLine("\t#if !WINDOWS_PHONE"); sw.WriteLine("\t[Serializable]"); sw.WriteLine("\t#endif"); sw.WriteLine("\t[System.CodeDom.Compiler.GeneratedCode(\"gpmr\",\"{0}\")]", Assembly.GetEntryAssembly().GetName().Version.ToString()); foreach (Interaction response in interaction.Responses) sw.WriteLine("\t[InteractionResponse(Name = \"{0}\", TriggerEvent = \"{1}\")]", response.Name, response.TriggerEvent); sw.WriteLine("\t[System.ComponentModel.Description(\"{0}\")]", interaction.BusinessName != null ? interaction.BusinessName.Replace("\n", "").Replace("\r", "") : interaction.Name); sw.WriteLine("\tpublic class {0} : {1}{2} {{", interaction.Name, CreateInteractionDatatype(interaction.MessageType), isIInteraction ? ", MARC.Everest.Interfaces.IInteraction" : ""); #region Constants // Get the trigger event sw.WriteLine("\t\t/// <summary> Gets the default trigger event to be used for this interaction </summary>"); sw.WriteLine("\t\tpublic static CV<String> GetTriggerEvent() {{ return new CV<String>(\"{0}\", \"{1}\"); }}", interaction.TriggerEvent, triggerEventOid); // Get the interaction id sw.WriteLine("\t\t/// <summary> Gets the interaction ID of this interaction </summary>"); sw.WriteLine("\t\tpublic static II GetInteractionId() {{ return new II(new OID(\"{1}\"), \"{0}\"); }}", interaction.Name, interactionIdOid); // Get the profile id if (!String.IsNullOrEmpty(profileId)) { sw.WriteLine("\t\t/// <summary> Gets the profile id of this interaction </summary>"); sw.WriteLine("\t\tpublic static LIST<II> GetProfileId() {{ return new LIST<II>() {{ new II (new OID(\"{0}\"), \"{1}\") }}; }}", profileIdOid, profileId); } #endregion #region Constructors sw.WriteLine("\t\t/// <summary> Creates a new, empty instance of {0} </summary>", interaction.Name); sw.WriteLine("\t\tpublic {0}() : base() {{ }}\r\n", interaction.Name); //string ctor_parameters = ""; //string ctor_body = ""; //foreach (ClassContent cc in interaction.MessageType.Class.Content) //{ // if (cc.Conformance == ClassContent.ConformanceKind.Mandatory) // Mandatory ctor // { // if (cc is Property && ((cc as Property).FixedValue == null || (cc as Property).PropertyType == Property.PropertyTypes.TraversableAssociation)) // { // Property p = cc as Property; // TypeReference tr = Datatypes.MapDatatype(p.Type); // // Documentation // if (p.Documentation != null && p.Documentation.Definition != null && p.Documentation.Definition.Count > 0) // sw.WriteLine("\t\t/// <param name=\"{0}\">{1}</param>", p.Name, p.Documentation.Definition[0]); // // Now the signature // ctor_parameters += string.Format("{0} {1},", ClassRenderer.CreateDatatypeRef(tr, p), p.Name); // ctor_body += string.Format("\t\t\tthis.{0} = {1};\r\n", Util.Util.PascalCase(p.Name), p.Name); // } // else // { // } // } //} //// Write CTOR //if (ctor_parameters.Length > 0) //{ // sw.WriteLine("\t\t/// <summary>\r\n\t\t/// CTOR for all mandatory elements\r\n\t\t/// </summary>"); // sw.WriteLine("\t\tpublic {0}({1}) : base() {{ \r\n\t\t{2}\t\t}}", interaction.Name, ctor_parameters.Substring(0, ctor_parameters.Length - 1), ctor_body); //} Dictionary<String, String[]> ctors = ClassRenderer.CreateFactoryMethod(interaction.MessageType, "this", true); // Write CTOR List<String> wroteParms = new List<string>(); // Keep track of the parameters used foreach (KeyValuePair<String, String[]> kv in ctors) { if (kv.Value[0].Length > 0 && !wroteParms.Contains(kv.Value[0])) { wroteParms.Add(kv.Value[0]); sw.WriteLine("\t\t/// <summary>\r\n\t\t/// CTOR for all {0} elements\r\n\t\t/// </summary>", kv.Key); sw.WriteLine(kv.Value[2]); sw.WriteLine("\t\tpublic {0}({1}) : base() {{ \r\n\t\t{2}\t\t}}", interaction.Name, kv.Value[0].Substring(0, kv.Value[0].Length - 1), kv.Value[1]); } } #endregion #region Creator for payload, control act, etc... // Owner namespace if(interaction.MessageType.GenericSupplier != null) foreach (TypeReference tr in interaction.MessageType.GenericSupplier) sw.WriteLine(GenerateFactoryMethod(tr, OwnerNS)); if (isIInteraction) { // Version code sw.WriteLine("\t\t/// <summary>Implementation of version code</summary>"); sw.WriteLine("\t\tMARC.Everest.DataTypes.Interfaces.ICodedSimple MARC.Everest.Interfaces.IInteraction.VersionCode { get { return this.VersionCode; } }"); // Version code sw.WriteLine("\t\t/// <summary>Implementation of processing mode code</summary>"); sw.WriteLine("\t\tMARC.Everest.DataTypes.Interfaces.ICodedSimple MARC.Everest.Interfaces.IInteraction.ProcessingModeCode { get { return this.ProcessingModeCode; } }"); sw.WriteLine("\t\t/// <summary>Implementation of generic IInteraction.ControlActEvent Property</summary>"); // Create the control act event if (interaction.MessageType.GenericSupplier != null && interaction.MessageType.GenericSupplier.Count > 0) { Property cactProperty = interaction.MessageType.Class.Content.Find(o => o is Property && (o as Property).Type.Name == interaction.MessageType.Class.TypeParameters[0].ParameterName) as Property; if (cactProperty == null) ; string cactName = cactProperty.Type.Name == interaction.MessageType.Class.TypeParameters[0].ParameterName ? Util.Util.MakeFriendly(cactProperty.Name) : Util.Util.PascalCase(cactProperty.Name); sw.WriteLine("\t\tSystem.Object MARC.Everest.Interfaces.IInteraction.ControlAct {"); sw.WriteLine("\t\t\tget {{ return this.{0}; }}", cactName); sw.WriteLine("\t\t\tset {{ this.{1} = value as {0}; }}", CreateInteractionDatatype(interaction.MessageType.GenericSupplier[0]), cactName); sw.WriteLine("\t\t}"); } else { sw.WriteLine("\t\tSystem.Object MARC.Everest.Interfaces.IInteraction.ControlAct {"); sw.WriteLine("\t\t\tget { return null; }"); sw.WriteLine("\t\t\tset { ; }"); sw.WriteLine("\t\t}"); } } #endregion sw.WriteLine("\t}"); sw.WriteLine("}"); tw.WriteLine(sw); }
/// <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 }
/// <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); }
/// <summary> /// Create a change that modifies the business name /// </summary> private void CreateBusinessNameChange(Feature feature, Constraint constraint) { #region Business Name Change // 1. Validate constraint if possible BusinessNameConstraintAnnotation bnc = new BusinessNameConstraintAnnotation(); var stConstraint = constraint.Value as ConstraintValue<String>; if (stConstraint.Original != null && !stConstraint.Original.Equals(feature.BusinessName)) Trace.WriteLine(String.Format("Delta: Business name constraint original text does not match actual business name on feature '{0}'", feature.Name), "warn"); // 2. Check for duplicates if (feature.Annotations.Exists(o => o is BusinessNameConstraintAnnotation && (o as BusinessNameConstraintAnnotation).RealmCode == this.m_deltaSet.Realm.Code)) { Trace.WriteLine(String.Format("Delta: Business name constraint has already been applied to '{0}'", feature.Name), "error"); return; } // 3. Append constraint feature.Annotations.Add(new BusinessNameConstraintAnnotation() { RealmCode = this.m_deltaSet.Realm.Code, NewValue = stConstraint.New, ChangeType = ChangeType.Edit, RealmName = this.m_deltaSet.MetaData.Description }); #endregion }
/// TODO: Explanation of parameters missing: OwnerNS, apiNs, f and tw /// Summary explanation needed public void Render(String OwnerNS, String apiNs, MohawkCollege.EHR.gpmr.COR.Feature f, System.IO.TextWriter tw) { return; // no file is created }
/// <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 }