[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