/// <summary> /// Render literals /// </summary> private void RenderLiterals(StringWriter sw, Enumeration enu, List <string> rendered, List <String> mnemonics, List <Enumeration.EnumerationValue> literals, string ctorName) { // Literals foreach (Enumeration.EnumerationValue ev in literals) { string bn = Util.Util.PascalCase(ev.BusinessName); string rendName = Util.Util.PascalCase(bn ?? ev.Name) ?? "__Unknown"; // Already rendered, so warn and skip if (rendered.Contains(rendName) || mnemonics.Contains(ev.Name)) { System.Diagnostics.Trace.WriteLine(String.Format("Enumeration value {0} already rendered, skipping", ev.BusinessName), "warn"); } else if (!ev.Annotations.Exists(o => o is SuppressBrowseAnnotation)) { sw.Write(DocumentationRenderer.Render(ev.Documentation, 1)); if (DocumentationRenderer.Render(ev.Documentation, 1).Length == 0) // Documentation correction { sw.WriteLine("\t/** {0} */", (ev.BusinessName ?? ev.Name).Replace("&", "&").Replace("<", "<").Replace(">", ">").Replace("\r", "").Replace("\n", "")); } // Annotations? if (ev.Annotations != null && ev.Annotations.Find(o => o is SuppressBrowseAnnotation) != null) { // Can't suppress browse in Jaba System.Diagnostics.Trace.WriteLine(String.Format("Enumation literal '{0}' won't be rendered as it has SuppressBrowse enabled", ev.Name)); //sw.WriteLine("\t\t[EditorBrowsable(EditorBrowsableState.Never)]\r\n\t\t[Browsable(false)]"); } // Render ? if (rendered.Find(o => o.Equals(rendName)) != null) // .NET enumeration field will be the same, so render something different { sw.Write("\tpublic static final {3} {0} = new {3}(\"{1}\",\"{2}\")", Util.Util.MakeFriendly(rendName + "_" + ev.Name) ?? "__Unknown", ev.Name, ev.CodeSystem ?? enu.ContentOid, Util.Util.MakeFriendly(ctorName)); } else { sw.Write("\tpublic static final {3} {0} = new {3}(\"{1}\",\"{2}\")", rendName, ev.Name, ev.CodeSystem ?? enu.ContentOid, Util.Util.MakeFriendly(ctorName)); } sw.WriteLine(";"); // Another literal follows sw.Write("\r\n"); // Newline rendered.Add(rendName); // Add to rendered list to keep track mnemonics.Add(ev.Name); } if (ev.RelatedCodes != null) { RenderLiterals(sw, enu, rendered, mnemonics, ev.RelatedCodes, ctorName); } } }
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> /// 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"); } }
/// <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("}"); }