/// <summary> /// Look for a "kind" attribute on the specified node and return an /// equivalent c# type name. Returns blank on error. /// </summary> private static string GetDotNetType(XmlNode Node) { if (Node != null) { string CMPTypeName = XmlHelper.Attribute(Node, "kind"); switch (CMPTypeName) { case "boolean": CMPTypeName = "Boolean"; break; case "single": CMPTypeName = "Single"; break; case "double": CMPTypeName = "Double"; break; case "integer4": CMPTypeName = "Int32"; break; case "string": CMPTypeName = "String"; break; default: return(StringManip.CamelCase(CMPTypeName + "Type")); } if (XmlHelper.Attribute(Node, "array").ToLower() == "t") { CMPTypeName += "[]"; } return(CMPTypeName); } return(""); }
public static void InsertClassCodeIntoDotNetProxyFile(string ClassName, string ClassSourceCode) { if (ClassSourceCode != "") { ClassName = StringManip.CamelCase(ClassName); // Go open the proxy source file and read it's contents. string Contents = ""; if (File.Exists(WriteableBaseProxyFileName)) { StreamReader In = new StreamReader(WriteableBaseProxyFileName); Contents = In.ReadToEnd(); In.Close(); } if (Contents == "") { Contents = "using System;\r\n" + "using System.Collections.Generic;\r\n" + "using System.Text;\r\n" + "using System.Runtime.InteropServices;\r\n" + "#pragma warning disable 67 // Suppress warning messages about unused events\r\n" + "namespace ModelFramework {\r\n" + "}\r\n"; } // See if we can find an existing class in the source code. int PosStartClass = Contents.IndexOf("public class " + ClassName + " "); if (PosStartClass != -1) { int PosStartAttribute = Contents.LastIndexOf("[ComponentType", PosStartClass); int PosOpenBracket = Contents.IndexOf("{", PosStartClass); int PosEndClass = StringManip.FindMatchingClosingBracket(Contents, PosStartClass, '{', '}'); if (PosEndClass != -1) { if (PosStartAttribute != -1) { PosStartClass = PosStartAttribute; } Contents = Contents.Remove(PosStartClass, PosEndClass - PosStartClass + 5); // also removes 2 x \r\n } } // Remove the last curly bracket - namespace bracket. We'll add it in later. int PosLastBracket = Contents.LastIndexOf('}'); if (PosLastBracket == -1) { throw new Exception("Cannot find namespace in DotNetProxies.cs"); } Contents = Contents.Remove(PosLastBracket); // Now add in our class and closing bracket for namespace. Contents = Contents + ClassSourceCode + "\r\n}"; // Write contents back to proxy file StreamWriter Out = new StreamWriter(WriteableBaseProxyFileName); Out.Write(Contents); Out.Close(); } }
public string ProxyClassName(string TypeName, string DLLFileName) { if (Dlls(TypeName).Count > 1) { return(StringManip.CamelCase(Path.GetFileNameWithoutExtension(DLLFileName))); } else { // Try to return the name with the same case lettering as we store internally foreach (string aName in XmlHelper.ChildNames(TypesDoc.DocumentElement, "type")) { if (aName.ToLower() == TypeName.ToLower()) { return(StringManip.CamelCase(aName)); } } } return(StringManip.CamelCase(TypeName)); }
//========================================================================= /// <summary> /// Create and return a C# proxy class based on the specified DescriptionXML. /// </summary> public static string CreateProxyClassForDLL(string TypeName, string ClassName, string DLLFileName) { string DescriptionXML = ""; try { DescriptionXML = ProbeDLLForDescriptionXML(TypeName, DLLFileName); } catch (Exception e) { Console.WriteLine(e.Message); } if (DescriptionXML != "") { string ClassCode = ""; XmlDocument Doc = new XmlDocument(); Doc.LoadXml(DescriptionXML); String compClass = ""; XmlNode classNode = XmlHelper.Find(Doc.DocumentElement, "class"); if (classNode != null) { String typeName = classNode.InnerText; int firstPeriod = typeName.IndexOf('.'); compClass = firstPeriod == -1 ? typeName : typeName.Substring(0, firstPeriod); } if (compClass == "") { compClass = Path.GetFileNameWithoutExtension(DLLFileName); } if (compClass.Length > 0) { ClassCode = "[ComponentType(\"" + compClass + "\")]\r\n"; } ClassCode += "public class $CLASSNAME$ : ModelFramework.Component\r\n" + " {\r\n" + " public $CLASSNAME$(string _FullName, object _Comp) : base (_FullName, _Comp) {}\r\n"; // Write all properties foreach (XmlNode Node in XmlHelper.ChildNodes(Doc.DocumentElement, "property")) { if (XmlHelper.Name(Node).IndexOfAny("{}/\\ ".ToCharArray()) == -1) { string PropertyCode; if (XmlHelper.Attribute(Node, "access") == "none") { continue; } if (XmlHelper.Attribute(Node, "access") == "read") { PropertyCode = "$DESCRIPTION$ $UNITS$ public $TYPE$ $NAME$ {$GETTER$}\r\n"; } else { PropertyCode = " public $TYPE$ $NAME$ \r\n" + " {\r\n" + "$GETTER$\r\n" + "$SETTER$\r\n" + " }\r\n"; } string GetterCode = " get {return Variable(\"$NAME$\").To$DOTNETTYPE$();}"; string SetterCode = " set {Variable(\"$NAME$\").Set(value);}"; XmlNode TypeNode = XmlHelper.Find(Node, "type"); if (TypeNode != null && XmlHelper.Attribute(TypeNode, "kind") != "" && XmlHelper.Attribute(TypeNode, "kind") != "defined" && XmlHelper.ChildNodes(TypeNode, "field").Count == 0) { string PropertyTypeName = GetDotNetType(TypeNode); string Description = XmlHelper.Attribute(TypeNode, "description"); if (Description == "") { Description = XmlHelper.Attribute(Node, "descr"); if (Description == "") { XmlNode descriptionNode = XmlHelper.Find(Node, "Description"); if (descriptionNode != null) { Description = descriptionNode.InnerText; } } } if (Description != "") { Description = " [Description(\"" + Description + "\")]"; } string Units = XmlHelper.Attribute(TypeNode, "unit"); if (Units != "") { Units = " [Units(\"" + Units + "\")]"; } if (XmlHelper.Attribute(Node, "access") == "read" || XmlHelper.Attribute(Node, "access") == "both") { PropertyCode = PropertyCode.Replace("$GETTER$", GetterCode); } else { PropertyCode = PropertyCode.Replace("$GETTER$\r\n", ""); } if (XmlHelper.Attribute(Node, "access") == "write" || XmlHelper.Attribute(Node, "access") == "both") { PropertyCode = PropertyCode.Replace("$SETTER$", SetterCode); } else { PropertyCode = PropertyCode.Replace("$SETTER$\r\n", ""); } string PropertyName = XmlHelper.Name(Node); string DotNetType = GetDotNetTypeName(TypeNode); if (PropertyName == "today") { PropertyName = "Today"; PropertyTypeName = "DateTime"; DotNetType = "DateTime"; } PropertyCode = PropertyCode.Replace("$TYPE$", PropertyTypeName); PropertyCode = PropertyCode.Replace("$DOTNETTYPE$", DotNetType); PropertyCode = PropertyCode.Replace("$NAME$", PropertyName); PropertyCode = PropertyCode.Replace("$DESCRIPTION$", Description); PropertyCode = PropertyCode.Replace("$UNITS$", Units); ClassCode += PropertyCode; } } } // Write all events foreach (XmlNode Node in XmlHelper.ChildNodes(Doc.DocumentElement, "event")) { string EventName = XmlHelper.Name(Node); string EventCode = ""; bool NullType = (XmlHelper.ChildNodes(Node, "field").Count == 0); if (XmlHelper.Attribute(Node, "kind") == "subscribed") { if (XmlHelper.Find(Node, "param1_name") == null) // make sure its not an Apsim Variant. { if (!NullType) { // Create a method that takes a structure for an argument. string CamelName = StringManip.CamelCase(EventName + "Type"); if (XmlHelper.Attribute(Node, "typename") != "") { CamelName = StringManip.CamelCase(XmlHelper.Attribute(Node, "typename") + "Type"); } // Ugly hack to prevent ambiguity between stock "buy" and supplement "buy" else if (EventName.Equals("Buy", StringComparison.OrdinalIgnoreCase) && compClass.Equals("Supplement", StringComparison.OrdinalIgnoreCase)) { CamelName = "SupplementBuyType"; } else { XmlNode TypeNode = XmlHelper.Find(Node, "type"); if (TypeNode != null && XmlHelper.Attribute(TypeNode, "typename") != "") { CamelName = StringManip.CamelCase(XmlHelper.Attribute(TypeNode, "typename") + "Type"); } } EventCode += " public void $CAMELEVENTNAME$(" + CamelName + " Data)\r\n"; EventCode += " {\r\n"; EventCode += " Publish(\"$EVENTNAME$\", Data);\r\n"; EventCode += " }\r\n"; } if (!IsComplexType(Node)) { // SIMPLE EVENTS // Simple structure - no nesting of types. EventCode += " public void $CAMELEVENTNAME$("; bool First = true; foreach (XmlNode Field in XmlHelper.ChildNodes(Node, "field")) { if (!First) { EventCode += ", "; } string FieldTypeName = GetDotNetType(Field); EventCode += FieldTypeName + " " + XmlHelper.Name(Field); First = false; } EventCode += ")\r\n"; EventCode += " {\r\n"; EventCode += " GenericType Data = new GenericType();\r\n"; foreach (XmlNode Field in XmlHelper.ChildNodes(Node, "field")) { EventCode += " Data.Add(new $TYPENAME$Type ($NAME$));\r\n"; EventCode = EventCode.Replace("$NAME$", XmlHelper.Name(Field)); EventCode = EventCode.Replace("$TYPE$", GetDotNetType(Field)); EventCode = EventCode.Replace("$TYPENAME$", GetDotNetTypeName(Field)); } string DDML = MakeDDML(Node); DDML = DDML.Replace("\"", "\\\""); EventCode += " Data.SetDDML(\"" + DDML + "\");\r\n"; EventCode += " Publish(\"$EVENTNAME$\", Data);\r\n"; EventCode += " }\r\n"; } } EventCode = EventCode.Replace("$CAMELEVENTNAME$", StringManip.CamelCase(EventName)); string EventTypeName = XmlHelper.Attribute(Node, "typename"); if (EventTypeName == "") { EventTypeName = StringManip.CamelCase(EventName); } EventTypeName += "Type"; EventCode = EventCode.Replace("$EVENTTYPE$", EventTypeName); } else { // published event. if (NullType || EventName.ToLower() == "error") { EventCode += " [Event] public event NullTypeDelegate $EVENTNAME$;\r\n"; } else { // Create a method that takes a structure for an argument. string CamelName = StringManip.CamelCase(EventName) + "Delegate";; if (XmlHelper.Attribute(Node, "typename") != "") { CamelName = StringManip.CamelCase(XmlHelper.Attribute(Node, "typename") + "Delegate"); } else { XmlNode TypeNode = XmlHelper.Find(Node, "type"); if (TypeNode != null && XmlHelper.Attribute(TypeNode, "typename") != "") { CamelName = StringManip.CamelCase(XmlHelper.Attribute(TypeNode, "typename") + "Delegate"); } } EventCode += " [Event] public event $CAMELDELEGATENAME$ $EVENTNAME$;\r\n"; EventCode = EventCode.Replace("$CAMELDELEGATENAME$", CamelName); } } EventCode = EventCode.Replace("$EVENTNAME$", EventName); ClassCode += EventCode; } ClassCode += " }\r\n"; ClassCode = ClassCode.Replace("$CLASSNAME$", StringManip.CamelCase(ClassName)); return(ClassCode); } else { return(""); } }