[mapguide-commits] r5251 - in trunk/Tools/Maestro: Maestro/ResourceValidators Maestro/ResourceValidators/Strings MaestroAPI

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Wed Oct 6 23:06:34 EDT 2010


Author: jng
Date: 2010-10-07 03:06:34 +0000 (Thu, 07 Oct 2010)
New Revision: 5251

Modified:
   trunk/Tools/Maestro/Maestro/ResourceValidators/FeatureSourceValidator.cs
   trunk/Tools/Maestro/Maestro/ResourceValidators/Strings/WebLayoutValidator.Designer.cs
   trunk/Tools/Maestro/Maestro/ResourceValidators/Strings/WebLayoutValidator.resx
   trunk/Tools/Maestro/Maestro/ResourceValidators/WebLayoutValidator.cs
   trunk/Tools/Maestro/MaestroAPI/FeatureSetReader.cs
   trunk/Tools/Maestro/MaestroAPI/FeatureSourceDescription.cs
Log:
This submission includes the following changes:
 - Add an IsIdentity property to FeatureSetColumn, which is set internally as part of the feature schema xml deserialization process
 - Improve the performance of the Feature Source validation algorithm by querying the IsIdentity property of the classes in the deserialized feature source description instead of issuing a raw GETIDENITYPROPERTIES request for each class in the feature source.
 - Add extra validation checks in the web layout validator:
   - Check for duplicate command names in the web layout's command set
   - Check for duplicate property references in search commands

Modified: trunk/Tools/Maestro/Maestro/ResourceValidators/FeatureSourceValidator.cs
===================================================================
--- trunk/Tools/Maestro/Maestro/ResourceValidators/FeatureSourceValidator.cs	2010-10-06 17:32:10 UTC (rev 5250)
+++ trunk/Tools/Maestro/Maestro/ResourceValidators/FeatureSourceValidator.cs	2010-10-07 03:06:34 UTC (rev 5251)
@@ -62,14 +62,12 @@
             }
 
             List<string> classes = new List<string>();
+            MaestroAPI.FeatureSourceDescription fsd = null;
             try
             {
-                MaestroAPI.FeatureSourceDescription fsd = feature.DescribeSource();
+                fsd = feature.DescribeSource();
                 if (fsd == null || fsd.Schemas == null || fsd.Schemas.Length == 0)
                     issues.Add(new ValidationIssue(feature, ValidationStatus.Warning, Strings.FeatureSourceValidator.ShemasMissingWarning));
-                else
-                    foreach (MaestroAPI.FeatureSourceDescription.FeatureSourceSchema scm in fsd.Schemas)
-                        classes.Add(scm.FullnameDecoded);
             }
             catch (Exception ex)
             {
@@ -77,31 +75,16 @@
                 issues.Add(new ValidationIssue(feature, ValidationStatus.Error, string.Format(Strings.FeatureSourceValidator.SchemaReadError, msg)));
             }
 
-
-            foreach (string cl in classes)
+            foreach (var cls in fsd.Schemas)
             {
-                try
-                {
-                    string[] ids = feature.GetIdentityProperties(cl);
-                    //According to my tests, this code path never gets reached because the 
-                    //MG server will incorrectly throw MgClassNotFoundException when querying
-                    //a class with no identity properties. Nevertheless we'll leave this in, if/when
-                    //this logic is fixed server-side.
-                    if (ids == null || ids.Length == 0)
-                        issues.Add(new ValidationIssue(feature, ValidationStatus.Information, string.Format(Strings.FeatureSourceValidator.PrimaryKeyMissingInformation, cl)));
-                }
-                catch (Exception ex)
-                {
-                    string msg = NestedExceptionMessageProcessor.GetFullMessage(ex);
-                    if (msg.IndexOf("MgClassNotFoundException") >= 0)
-                    {
-                        issues.Add(new ValidationIssue(feature, ValidationStatus.Warning, string.Format(Strings.FeatureSourceValidator.NoPrimaryKeyOrView, cl)));
-                    }
-                    else
-                    {
-                        issues.Add(new ValidationIssue(feature, ValidationStatus.Error, string.Format(Strings.FeatureSourceValidator.PrimaryKeyReadError, msg)));
-                    }
-                }
+                var ids = cls.GetIdentityProperties();
+                //string[] ids = feature.GetIdentityProperties(cl);
+                //According to my tests, this code path never gets reached because the 
+                //MG server will incorrectly throw MgClassNotFoundException when querying
+                //a class with no identity properties. Nevertheless we'll leave this in, if/when
+                //this logic is fixed server-side.
+                if (ids == null || ids.Length == 0)
+                    issues.Add(new ValidationIssue(feature, ValidationStatus.Information, string.Format(Strings.FeatureSourceValidator.PrimaryKeyMissingInformation, cls.FullnameDecoded)));
             }
 
             return issues.ToArray();

Modified: trunk/Tools/Maestro/Maestro/ResourceValidators/Strings/WebLayoutValidator.Designer.cs
===================================================================
--- trunk/Tools/Maestro/Maestro/ResourceValidators/Strings/WebLayoutValidator.Designer.cs	2010-10-06 17:32:10 UTC (rev 5250)
+++ trunk/Tools/Maestro/Maestro/ResourceValidators/Strings/WebLayoutValidator.Designer.cs	2010-10-07 03:06:34 UTC (rev 5251)
@@ -1,7 +1,7 @@
 //------------------------------------------------------------------------------
 // <auto-generated>
 //     This code was generated by a tool.
-//     Runtime Version:2.0.50727.4927
+//     Runtime Version:2.0.50727.4952
 //
 //     Changes to this file may cause incorrect behavior and will be lost if
 //     the code is regenerated.
@@ -61,6 +61,24 @@
         }
         
         /// <summary>
+        ///   Looks up a localized string similar to There is more than one viewer command named: {0}.
+        /// </summary>
+        internal static string DuplicateCommandName {
+            get {
+                return ResourceManager.GetString("DuplicateCommandName", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Search command {0} has a duplicate result property {1}.
+        /// </summary>
+        internal static string DuplicateSearchResultColumn {
+            get {
+                return ResourceManager.GetString("DuplicateSearchResultColumn", resourceCulture);
+            }
+        }
+        
+        /// <summary>
         ///   Looks up a localized string similar to Error validating MapDefinition {0}, message: {1}.
         /// </summary>
         internal static string MapValidationError {

Modified: trunk/Tools/Maestro/Maestro/ResourceValidators/Strings/WebLayoutValidator.resx
===================================================================
--- trunk/Tools/Maestro/Maestro/ResourceValidators/Strings/WebLayoutValidator.resx	2010-10-06 17:32:10 UTC (rev 5250)
+++ trunk/Tools/Maestro/Maestro/ResourceValidators/Strings/WebLayoutValidator.resx	2010-10-07 03:06:34 UTC (rev 5251)
@@ -117,6 +117,12 @@
   <resheader name="writer">
     <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </resheader>
+  <data name="DuplicateCommandName" xml:space="preserve">
+    <value>There is more than one viewer command named: {0}</value>
+  </data>
+  <data name="DuplicateSearchResultColumn" xml:space="preserve">
+    <value>Search command {0} has a duplicate result property {1}</value>
+  </data>
   <data name="MapValidationError" xml:space="preserve">
     <value>Error validating MapDefinition {0}, message: {1}</value>
     <comment>An error message that is displayed if the map validation fails</comment>

Modified: trunk/Tools/Maestro/Maestro/ResourceValidators/WebLayoutValidator.cs
===================================================================
--- trunk/Tools/Maestro/Maestro/ResourceValidators/WebLayoutValidator.cs	2010-10-06 17:32:10 UTC (rev 5250)
+++ trunk/Tools/Maestro/Maestro/ResourceValidators/WebLayoutValidator.cs	2010-10-07 03:06:34 UTC (rev 5251)
@@ -37,9 +37,39 @@
 
             WebLayout layout = resource as WebLayout;
             if (layout.Map == null || layout.Map.ResourceId == null)
+            {
                 issues.Add(new ValidationIssue(layout, ValidationStatus.Error, string.Format(Strings.WebLayoutValidator.MissingMapError)));
+            }
             else
             {
+                //Check for duplicate command names
+                var cmdSet = layout.CommandSet;
+                Dictionary<string, CommandType> cmds = new Dictionary<string, CommandType>();
+                foreach (CommandType cmd in cmdSet)
+                {
+                    if (cmds.ContainsKey(cmd.Name))
+                        issues.Add(new ValidationIssue(layout, ValidationStatus.Error, string.Format(Strings.WebLayoutValidator.DuplicateCommandName, cmd.Name)));
+                    else
+                        cmds[cmd.Name] = cmd;
+                }
+
+                //Check for duplicate property references in search commands
+                foreach (CommandType cmd in cmdSet)
+                {
+                    if (cmd is SearchCommandType)
+                    {
+                        SearchCommandType search = (SearchCommandType)cmd;
+                        Dictionary<string, string> resColProps = new Dictionary<string, string>();
+                        foreach (ResultColumnType resCol in search.ResultColumns)
+                        {
+                            if (resColProps.ContainsKey(resCol.Property))
+                                issues.Add(new ValidationIssue(layout, ValidationStatus.Error, string.Format(Strings.WebLayoutValidator.DuplicateSearchResultColumn, search.Name, resCol.Property)));
+                            else
+                                resColProps.Add(resCol.Property, resCol.Property);
+                        }
+                    }
+                }
+
                 if (recurse)
                 {
                     try

Modified: trunk/Tools/Maestro/MaestroAPI/FeatureSetReader.cs
===================================================================
--- trunk/Tools/Maestro/MaestroAPI/FeatureSetReader.cs	2010-10-06 17:32:10 UTC (rev 5250)
+++ trunk/Tools/Maestro/MaestroAPI/FeatureSetReader.cs	2010-10-07 03:06:34 UTC (rev 5251)
@@ -279,6 +279,7 @@
 
 		public string Name { get { return m_name; } }
 		public Type Type { get { return m_type; } }
+        public bool IsIdentity { get; internal set; }
 
         public System.Collections.ICollection MetadataKeys { get { return m_metadata.Keys; } }
 

Modified: trunk/Tools/Maestro/MaestroAPI/FeatureSourceDescription.cs
===================================================================
--- trunk/Tools/Maestro/MaestroAPI/FeatureSourceDescription.cs	2010-10-06 17:32:10 UTC (rev 5250)
+++ trunk/Tools/Maestro/MaestroAPI/FeatureSourceDescription.cs	2010-10-07 03:06:34 UTC (rev 5251)
@@ -19,6 +19,7 @@
 #endregion
 using System;
 using System.Xml;
+using System.Collections.Generic;
 
 namespace OSGeo.MapGuide.MaestroAPI
 {
@@ -57,10 +58,41 @@
 			mgr.AddNamespace("gml", "http://www.opengis.net/gml");
 			mgr.AddNamespace("fdo", "http://fdo.osgeo.org/schemas");
 
+            var keys = new Dictionary<string, string[]>();
+            var classMap = new Dictionary<string, FeatureSourceSchema>();
 			XmlNodeList lst = root.SelectNodes("xs:schema/xs:complexType[@abstract='false']", mgr);
 			m_schemas = new FeatureSourceSchema[lst.Count];
             for (int i = 0; i < m_schemas.Length; i++)
-				m_schemas[i] = new FeatureSourceSchema(lst[i], mgr);
+            {
+                m_schemas[i] = new FeatureSourceSchema(lst[i], mgr);
+                classMap.Add(m_schemas[i].FullnameDecoded, m_schemas[i]);
+            }
+            XmlNodeList keyNodes = root.SelectNodes("xs:schema/xs:element[@abstract='false']", mgr);
+            foreach (XmlNode keyNode in keyNodes)
+            {
+                var typeAttr = keyNode.Attributes["type"];
+                if (typeAttr != null)
+                {
+                    string clsName = typeAttr.Value.Substring(0, typeAttr.Value.Length - 4); //class name is suffixed with type
+                    if (classMap.ContainsKey(clsName))
+                    {
+                        List<string> keyFieldNames = new List<string>();
+
+                        var cls = classMap[clsName];
+                        XmlNodeList keyFields = keyNode.SelectNodes("xs:key/xs:field", mgr);
+                        foreach (XmlNode keyField in keyFields)
+                        {
+                            var xpathAttr = keyField.Attributes["xpath"];
+                            if (xpathAttr != null)
+                            {
+                                keyFieldNames.Add(xpathAttr.Value);
+                            }
+                        }
+
+                        cls.MarkIdentityProperties(keyFieldNames);
+                    }
+                }
+            }
 		}
 
 		public FeatureSourceSchema[] Schemas { get { return m_schemas; } }
@@ -135,7 +167,32 @@
 			public string Fullname { get { return m_schema == null ? m_name : m_schema + ":" + m_name; } }
             public string FullnameDecoded { get { return Utility.DecodeFDOName(this.Fullname); } }
 			public FeatureSetColumn[] Columns { get { return m_columns; } }
-		}
+
+            internal void MarkIdentityProperties(IEnumerable<string> keyFieldNames)
+            {
+                foreach (var name in keyFieldNames)
+                {
+                    foreach (var col in m_columns)
+                    {
+                        if (col.Name.Equals(name))
+                        {
+                            col.IsIdentity = true;
+                        }
+                    }
+                }
+            }
+
+            public string[] GetIdentityProperties()
+            {
+                List<string> keys = new List<string>();
+                foreach (var col in m_columns)
+                {
+                    if (col.IsIdentity)
+                        keys.Add(col.Name);
+                }
+                return keys.ToArray();
+            }
+        }
 	}
 
     internal class ClassPropertyColumn : XmlFeatureSetColumn



More information about the mapguide-commits mailing list