/// <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();
        }
    }
Beispiel #3
0
 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("");
        }
    }