[mapguide-commits] r6682 - in branches/maestro-4.0.x: Maestro Maestro.Editors/FeatureSource Maestro.Editors/FeatureSource/Extensions Maestro.Editors/FeatureSource/Preview Maestro.Editors/LayerDefinition Maestro.Editors/LayerDefinition/Raster Maestro.Editors/LayerDefinition/Vector OSGeo.MapGuide.MaestroAPI/Commands OSGeo.MapGuide.MaestroAPI/ObjectModels OSGeo.MapGuide.MaestroAPI/Resource/Validation OSGeo.MapGuide.MaestroAPI/Services OSGeo.MapGuide.MaestroAPI.Http

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Tue May 22 12:02:08 EDT 2012


Author: jng
Date: 2012-05-22 09:02:07 -0700 (Tue, 22 May 2012)
New Revision: 6682

Modified:
   branches/maestro-4.0.x/Maestro.Editors/FeatureSource/Extensions/JoinSettings.cs
   branches/maestro-4.0.x/Maestro.Editors/FeatureSource/ExtensionsCtrl.cs
   branches/maestro-4.0.x/Maestro.Editors/FeatureSource/Preview/LocalFeatureSourcePreviewCtrl.cs
   branches/maestro-4.0.x/Maestro.Editors/LayerDefinition/LayerPropertiesSectionCtrl.cs
   branches/maestro-4.0.x/Maestro.Editors/LayerDefinition/Raster/RasterLayerSettingsSectionCtrl.cs
   branches/maestro-4.0.x/Maestro.Editors/LayerDefinition/Vector/VectorLayerSettingsSectionCtrl.cs
   branches/maestro-4.0.x/Maestro/Maestro_All.sln
   branches/maestro-4.0.x/Maestro/changelog.txt
   branches/maestro-4.0.x/OSGeo.MapGuide.MaestroAPI.Http/HttpServerConnection.cs
   branches/maestro-4.0.x/OSGeo.MapGuide.MaestroAPI.Http/RequestBuilder.cs
   branches/maestro-4.0.x/OSGeo.MapGuide.MaestroAPI/Commands/ExecuteLoadProcedure.cs
   branches/maestro-4.0.x/OSGeo.MapGuide.MaestroAPI/ObjectModels/FeatureSourceInterfaces.cs
   branches/maestro-4.0.x/OSGeo.MapGuide.MaestroAPI/Resource/Validation/BaseLayerDefinitionValidator.cs
   branches/maestro-4.0.x/OSGeo.MapGuide.MaestroAPI/Resource/Validation/FeatureSourceValidator.cs
   branches/maestro-4.0.x/OSGeo.MapGuide.MaestroAPI/Services/IFeatureService.cs
Log:
Backport r6678, r6679, r6680 and r6681 to 4.0.x

Modified: branches/maestro-4.0.x/Maestro/Maestro_All.sln
===================================================================
--- branches/maestro-4.0.x/Maestro/Maestro_All.sln	2012-05-22 15:50:40 UTC (rev 6681)
+++ branches/maestro-4.0.x/Maestro/Maestro_All.sln	2012-05-22 16:02:07 UTC (rev 6682)
@@ -1,6 +1,7 @@
 
 Microsoft Visual Studio Solution File, Format Version 10.00
 # Visual Studio 2008
+# SharpDevelop 4.2.0.8783
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Maestro", "Maestro.csproj", "{E0C36475-2B70-4F6D-ACE0-8943167806DC}"
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.Core", "..\Thirdparty\SharpDevelop\ICSharpCode.Core\ICSharpCode.Core.csproj", "{35CEF10F-2D4C-45F2-9DD1-161E0FEC583C}"

Modified: branches/maestro-4.0.x/Maestro/changelog.txt
===================================================================
--- branches/maestro-4.0.x/Maestro/changelog.txt	2012-05-22 15:50:40 UTC (rev 6681)
+++ branches/maestro-4.0.x/Maestro/changelog.txt	2012-05-22 16:02:07 UTC (rev 6682)
@@ -1,5 +1,8 @@
 4.0.2
 -----
+ - Fix: HttpServerConnection no longer re-creates MapGuide session on any exception thrown, only ones relating to session expiry.
+ - Fix: Avoid using full schema walks wherever possible. Will improve performance on large data stores.
+ - Fix: Broken Server Status Monitor
  - Fix: Some MgCooker command line arguments were being ignored
  - Fix: Raise signficantly the maximum allowed "Meters per unit" value in MgCooker.
  - Fix: Dragging and dropping onto a layer in the Map Definition editor will add the layer to that layer's parent group instead of the root

Modified: branches/maestro-4.0.x/Maestro.Editors/FeatureSource/Extensions/JoinSettings.cs
===================================================================
--- branches/maestro-4.0.x/Maestro.Editors/FeatureSource/Extensions/JoinSettings.cs	2012-05-22 15:50:40 UTC (rev 6681)
+++ branches/maestro-4.0.x/Maestro.Editors/FeatureSource/Extensions/JoinSettings.cs	2012-05-22 16:02:07 UTC (rev 6682)
@@ -47,17 +47,20 @@
 
         private IAttributeRelation _rel;
 
-        private ClassDefinition _primaryClass;
-        private ClassDefinition[] _secondaryClasses;
-        private ClassDefinition _secondaryClass;
+        private string _primaryFeatureSource;
+        private string _primaryClass;
+        private string[] _secondaryClasses;
+        private string _secondaryClass;
 
         private BindingList<IRelateProperty> _propertyJoins;
 
-        public JoinSettings(ClassDefinition primaryClass, IAttributeRelation rel)
+        public JoinSettings(string primaryFeatureSource, string primaryClass, IAttributeRelation rel)
             : this()
         {
             Check.NotNull(rel, "rel");
             Check.NotNull(primaryClass, "primaryClass");
+            Check.NotNull(primaryFeatureSource, "primaryFeatureSource");
+            _primaryFeatureSource = primaryFeatureSource;
             _primaryClass = primaryClass;
 
             _init = true;
@@ -89,9 +92,7 @@
             if (!string.IsNullOrEmpty(resId))
             {
                 txtFeatureSource.Text = resId;
-
-                var schema = _edSvc.FeatureService.DescribeFeatureSource(txtFeatureSource.Text);
-                _secondaryClasses = new List<ClassDefinition>(schema.AllClasses).ToArray();
+                _secondaryClasses = _edSvc.FeatureService.GetClassNames(txtFeatureSource.Text, null);
                 //Invalidate existing secondary class
                 txtSecondaryClass.Text = string.Empty;
                 _secondaryClass = null;
@@ -113,7 +114,7 @@
             if (selClass != null)
             {
                 _secondaryClass = selClass;
-                txtSecondaryClass.Text = _secondaryClass.QualifiedName;
+                txtSecondaryClass.Text = _secondaryClass;
                 CheckAddStatus();
             }
         }
@@ -137,14 +138,13 @@
             //Init selected classes
             if (!string.IsNullOrEmpty(_rel.ResourceId))
             {
-                var schema = _edSvc.FeatureService.DescribeFeatureSource(_rel.ResourceId);
-                _secondaryClasses = new List<ClassDefinition>(schema.AllClasses).ToArray();
+                _secondaryClasses = _edSvc.FeatureService.GetClassNames(_rel.ResourceId, null);
 
                 if (!string.IsNullOrEmpty(_rel.AttributeClass))
                 {
                     foreach (var cls in _secondaryClasses)
                     {
-                        if (cls.QualifiedName.Equals(_rel.AttributeClass))
+                        if (cls.Equals(_rel.AttributeClass))
                         {
                             _secondaryClass = cls;
                             break;
@@ -235,7 +235,10 @@
         {
             if (_primaryClass != null && _secondaryClass != null)
             {
-                var dlg = new SelectJoinKeyDialog(_primaryClass, _secondaryClass);
+                var pc = _edSvc.FeatureService.GetClassDefinition(_primaryFeatureSource, _primaryClass);
+                var sc = _edSvc.FeatureService.GetClassDefinition(_rel.ResourceId, _secondaryClass);
+                
+                var dlg = new SelectJoinKeyDialog(pc, sc);
                 if (dlg.ShowDialog() == DialogResult.OK)
                 {
                     var rel = _rel.CreatePropertyJoin(dlg.PrimaryProperty, dlg.SecondaryProperty);

Modified: branches/maestro-4.0.x/Maestro.Editors/FeatureSource/ExtensionsCtrl.cs
===================================================================
--- branches/maestro-4.0.x/Maestro.Editors/FeatureSource/ExtensionsCtrl.cs	2012-05-22 15:50:40 UTC (rev 6681)
+++ branches/maestro-4.0.x/Maestro.Editors/FeatureSource/ExtensionsCtrl.cs	2012-05-22 16:02:07 UTC (rev 6682)
@@ -346,11 +346,12 @@
                 ext = e.Node.Parent.Tag as IFeatureSourceExtension;
                 if (ext != null)
                 {
-                    ClassDefinition cls = CachedSchema().GetClass(ext.FeatureClass);
-                    
-                    if (cls != null)
+                    if (ext.FeatureClass != null)
                     {
-                        var ctl = new JoinSettings(cls, join);
+                        //NOTE: The feature source id here may be session based, but this is still okay
+                        //as we're only giving context (the primary class to join on) for the secondary join UI. 
+                        //This feature source id is never written into the actual document
+                        var ctl = new JoinSettings(_fs.ResourceID, ext.FeatureClass, join);
                         ctl.Bind(_edSvc);
                         ctl.Dock = DockStyle.Fill;
                         splitContainer1.Panel2.Controls.Clear();

Modified: branches/maestro-4.0.x/Maestro.Editors/FeatureSource/Preview/LocalFeatureSourcePreviewCtrl.cs
===================================================================
--- branches/maestro-4.0.x/Maestro.Editors/FeatureSource/Preview/LocalFeatureSourcePreviewCtrl.cs	2012-05-22 15:50:40 UTC (rev 6681)
+++ branches/maestro-4.0.x/Maestro.Editors/FeatureSource/Preview/LocalFeatureSourcePreviewCtrl.cs	2012-05-22 16:02:07 UTC (rev 6682)
@@ -88,6 +88,8 @@
             _caps = caps;
             ClearPreviewPanes();
             trvSchema.Nodes.Clear();
+            
+            //FIXME: Do this lazily ala. FDO Toolbox
             var schema = _fsvc.DescribeFeatureSource(currentFsId);
 
             Dictionary<string, List<ClassDefinition>> classes = new Dictionary<string, List<ClassDefinition>>();

Modified: branches/maestro-4.0.x/Maestro.Editors/LayerDefinition/LayerPropertiesSectionCtrl.cs
===================================================================
--- branches/maestro-4.0.x/Maestro.Editors/LayerDefinition/LayerPropertiesSectionCtrl.cs	2012-05-22 15:50:40 UTC (rev 6681)
+++ branches/maestro-4.0.x/Maestro.Editors/LayerDefinition/LayerPropertiesSectionCtrl.cs	2012-05-22 16:02:07 UTC (rev 6682)
@@ -81,9 +81,7 @@
 
             if (_edsvc.ResourceService.ResourceExists(_vl.ResourceId))
             {
-                //TODO: Should just fetch the class definition
-                var desc = _edsvc.FeatureService.DescribeFeatureSource(_vl.ResourceId);
-                var cls = desc.GetClass(_vl.FeatureName);
+                var cls = _edsvc.FeatureService.GetClassDefinition(_vl.ResourceId, _vl.FeatureName);
                 if (cls != null)
                 {
                     grdProperties.Rows.Clear();

Modified: branches/maestro-4.0.x/Maestro.Editors/LayerDefinition/Raster/RasterLayerSettingsSectionCtrl.cs
===================================================================
--- branches/maestro-4.0.x/Maestro.Editors/LayerDefinition/Raster/RasterLayerSettingsSectionCtrl.cs	2012-05-22 15:50:40 UTC (rev 6681)
+++ branches/maestro-4.0.x/Maestro.Editors/LayerDefinition/Raster/RasterLayerSettingsSectionCtrl.cs	2012-05-22 16:02:07 UTC (rev 6682)
@@ -35,6 +35,10 @@
 
 namespace Maestro.Editors.LayerDefinition.Raster
 {
+    //NOTE: Unlike the Vector Layer editor, we have to do a full schema walk here because
+    //we need to filter out non-raster feature classes, something that the existing GetSchemas()
+    //and GetClassNames() cannot do for us.
+    
     [ToolboxItem(false)]
     internal partial class RasterLayerSettingsSectionCtrl : EditorBindableCollapsiblePanel
     {

Modified: branches/maestro-4.0.x/Maestro.Editors/LayerDefinition/Vector/VectorLayerSettingsSectionCtrl.cs
===================================================================
--- branches/maestro-4.0.x/Maestro.Editors/LayerDefinition/Vector/VectorLayerSettingsSectionCtrl.cs	2012-05-22 15:50:40 UTC (rev 6681)
+++ branches/maestro-4.0.x/Maestro.Editors/LayerDefinition/Vector/VectorLayerSettingsSectionCtrl.cs	2012-05-22 16:02:07 UTC (rev 6682)
@@ -76,13 +76,10 @@
             if (this.DesignMode)
                 return;
 
-            if (_cachedDesc == null)
-                _cachedDesc = _edsvc.FeatureService.DescribeFeatureSource(txtFeatureSource.Text);
-
             //Init cached schemas and selected class
             if (!string.IsNullOrEmpty(txtFeatureClass.Text))
             {                
-                var cls = _cachedDesc.GetClass(txtFeatureClass.Text);
+                var cls = _edsvc.FeatureService.GetClassDefinition(txtFeatureSource.Text, txtFeatureClass.Text);
                 if (cls != null)
                 {
                     _selectedClass = cls;
@@ -105,39 +102,15 @@
             base.UnsubscribeEventHandlers();
         }
 
-        private FeatureSourceDescription _cachedDesc;
-
         private void txtFeatureSource_TextChanged(object sender, EventArgs e)
         {
             if (string.IsNullOrEmpty(txtFeatureSource.Text))
                 return;
 
-            _cachedDesc = _edsvc.FeatureService.DescribeFeatureSource(txtFeatureSource.Text);
-
-            if (string.IsNullOrEmpty(txtFeatureClass.Text))
+            if (!string.IsNullOrEmpty(txtFeatureClass.Text))
             {
                 //This feature source must have at least one class definition with a geometry property
-                ClassDefinition clsDef = null;
-                foreach (FeatureSchema fs in _cachedDesc.Schemas)
-                {
-                    if (clsDef != null)
-                        break;
-
-                    foreach (ClassDefinition cls in fs.Classes)
-                    {
-                        if (clsDef != null)
-                            break;
-
-                        foreach (PropertyDefinition prop in cls.Properties)
-                        {
-                            if (prop.Type == PropertyDefinitionType.Geometry)
-                            {
-                                clsDef = cls;
-                                break;
-                            }
-                        }
-                    }
-                }
+                ClassDefinition clsDef = _edsvc.FeatureService.GetClassDefinition(txtFeatureSource.Text, txtFeatureClass.Text);
                 if (clsDef == null)
                 {
                     MessageBox.Show(string.Format(Properties.Resources.InvalidFeatureSourceNoClasses, txtFeatureSource.Text));
@@ -238,11 +211,12 @@
 
         private void btnBrowseSchema_Click(object sender, EventArgs e)
         {
-            var list = new List<ClassDefinition>(_cachedDesc.AllClasses).ToArray();
-            var item = GenericItemSelectionDialog.SelectItem(null, null, list, "QualifiedName", "QualifiedName");
+            var list = _edsvc.FeatureService.GetClassNames(txtFeatureSource.Text, null);
+            var item = GenericItemSelectionDialog.SelectItem(null, null, list);
             if (item != null)
             {
-                SetFeatureClass(item);
+                var cls = _edsvc.FeatureService.GetClassDefinition(txtFeatureSource.Text, item);
+                SetFeatureClass(cls);
             }
         }
 

Modified: branches/maestro-4.0.x/OSGeo.MapGuide.MaestroAPI/Commands/ExecuteLoadProcedure.cs
===================================================================
--- branches/maestro-4.0.x/OSGeo.MapGuide.MaestroAPI/Commands/ExecuteLoadProcedure.cs	2012-05-22 15:50:40 UTC (rev 6681)
+++ branches/maestro-4.0.x/OSGeo.MapGuide.MaestroAPI/Commands/ExecuteLoadProcedure.cs	2012-05-22 16:02:07 UTC (rev 6682)
@@ -420,6 +420,10 @@
                             // 4. Infer the supported geometry types for this feature class. Toggle supported styles accordingly.
 
                             //Step 1: Describe the schema
+                            //
+                            //NOTE: I think we can get away with the full schema walk here. It's very unlikely we will be uploading a flat
+                            //file with hundreds of classes. Even then, flat-file schema walk performance blows RDBMS walking performance
+                            //out of the water anyway.
                             FeatureSourceDescription desc = this.Parent.FeatureService.DescribeFeatureSource(fsId);
 
                             //Step 2: Find the first feature class with a geometry property
@@ -735,6 +739,10 @@
                                 // 4. Infer the supported geometry types for this feature class. Toggle supported styles accordingly.
 
                                 //Step 1: Describe the schema
+                                //
+                                //NOTE: I think we can get away with the full schema walk here. It's very unlikely we will be uploading a flat
+                                //file with hundreds of classes. Even then, flat-file schema walk performance blows RDBMS walking performance
+                                //out of the water anyway.
                                 FeatureSourceDescription desc = this.Parent.FeatureService.DescribeFeatureSource(fsId);
 
                                 if (desc.HasClasses())

Modified: branches/maestro-4.0.x/OSGeo.MapGuide.MaestroAPI/ObjectModels/FeatureSourceInterfaces.cs
===================================================================
--- branches/maestro-4.0.x/OSGeo.MapGuide.MaestroAPI/ObjectModels/FeatureSourceInterfaces.cs	2012-05-22 15:50:40 UTC (rev 6681)
+++ branches/maestro-4.0.x/OSGeo.MapGuide.MaestroAPI/ObjectModels/FeatureSourceInterfaces.cs	2012-05-22 16:02:07 UTC (rev 6682)
@@ -474,6 +474,11 @@
         /// <summary>
         /// Convenience method to return the description of this feature source
         /// </summary>
+        /// <remarks>
+        /// If you only need to list schemas and class names, use the respective <see cref="M:OSGeo.MapGuide.MaestroAPI.Services.IFeatureService.GetSchemas" /> and
+        /// <see cref="M:OSGeo.MapGuide.MaestroAPI.Services.IFeatureService.GetClassNames" /> methods. Using this API will have a noticeable performance impact on 
+        /// really large datastores (whose size is in the 100s of classes).
+        /// </remarks>
         /// <returns></returns>
         public static FeatureSourceDescription Describe(this IFeatureSource fs)
         {

Modified: branches/maestro-4.0.x/OSGeo.MapGuide.MaestroAPI/Resource/Validation/BaseLayerDefinitionValidator.cs
===================================================================
--- branches/maestro-4.0.x/OSGeo.MapGuide.MaestroAPI/Resource/Validation/BaseLayerDefinitionValidator.cs	2012-05-22 15:50:40 UTC (rev 6681)
+++ branches/maestro-4.0.x/OSGeo.MapGuide.MaestroAPI/Resource/Validation/BaseLayerDefinitionValidator.cs	2012-05-22 16:02:07 UTC (rev 6682)
@@ -75,7 +75,83 @@
 
             if (ldef.SubLayer == null)
                 issues.Add(new ValidationIssue(resource, ValidationStatus.Error, ValidationStatusCode.Error_LayerDefinition_LayerNull, Properties.Resources.LDF_LayerNullError));
-            
+
+            ClassDefinition cls = null;
+            if (vldef != null || gldef != null)
+            {
+                //Load referenced feature source
+                IFeatureSource fs = null;
+
+                try
+                {
+                    fs = (IFeatureSource)context.GetResource(ldef.SubLayer.ResourceId);
+                    issues.AddRange(ResourceValidatorSet.Validate(context, fs, recurse));
+                }
+                catch (Exception)
+                {
+                    issues.Add(new ValidationIssue(resource, ValidationStatus.Error, ValidationStatusCode.Error_LayerDefinition_FeatureSourceLoadError, string.Format(Properties.Resources.LDF_FeatureSourceLoadError)));
+                }
+
+                if (fs != null)
+                {
+                    //Verify specified feature class and geometry check out
+                    try
+                    {
+                        string qualClassName = vldef == null ? gldef.FeatureName : vldef.FeatureName;
+                        string geometry = vldef == null ? gldef.Geometry : vldef.Geometry;
+
+                        bool foundSchema = false;
+                        bool foundGeometry = false;
+
+                        cls = fs.GetClass(qualClassName);
+                        if (cls != null)
+                        {
+                            foundSchema = true;
+                            foreach (PropertyDefinition col in cls.Properties)
+                            {
+                                if (col.Name == geometry)
+                                {
+                                    foundGeometry = true;
+                                    break;
+                                }
+                            }
+
+                            if (vldef != null && vldef.PropertyMapping != null)
+                            {
+                                foreach (INameStringPair s in vldef.PropertyMapping)
+                                {
+                                    bool found = false;
+                                    foreach (PropertyDefinition col in cls.Properties)
+                                    {
+                                        if (col.Name == s.Name)
+                                        {
+                                            found = true;
+                                            break;
+                                        }
+                                    }
+                                    if (!found)
+                                        issues.Add(new ValidationIssue(resource, ValidationStatus.Error, ValidationStatusCode.Error_LayerDefinition_ClassNotFound, string.Format(Properties.Resources.LDF_SchemaMissingError, qualClassName, fs.ResourceID)));
+                                }
+                            }
+                        }
+
+                        if (!foundSchema)
+                            issues.Add(new ValidationIssue(resource, ValidationStatus.Error, ValidationStatusCode.Error_LayerDefinition_ClassNotFound, string.Format(Properties.Resources.LDF_SchemaMissingError, qualClassName, fs.ResourceID)));
+                        else if (!foundGeometry)
+                            issues.Add(new ValidationIssue(resource, ValidationStatus.Error, ValidationStatusCode.Error_LayerDefinition_GeometryNotFound, string.Format(Properties.Resources.LDF_GeometryMissingError, geometry, qualClassName, fs.ResourceID)));
+                    }
+                    catch (Exception)
+                    {
+                        issues.Add(new ValidationIssue(fs, ValidationStatus.Error, ValidationStatusCode.Error_LayerDefinition_Generic, string.Format(Properties.Resources.LDF_SchemaAndColumnReadFailedError)));
+                    }
+
+                    if (recurse)
+                    {
+                        issues.AddRange(ResourceValidatorSet.Validate(context, fs, recurse));
+                    }
+                }
+            }
+
             if (vldef != null)
             {
                 if (string.IsNullOrEmpty(vldef.FeatureName))

Modified: branches/maestro-4.0.x/OSGeo.MapGuide.MaestroAPI/Resource/Validation/FeatureSourceValidator.cs
===================================================================
--- branches/maestro-4.0.x/OSGeo.MapGuide.MaestroAPI/Resource/Validation/FeatureSourceValidator.cs	2012-05-22 15:50:40 UTC (rev 6681)
+++ branches/maestro-4.0.x/OSGeo.MapGuide.MaestroAPI/Resource/Validation/FeatureSourceValidator.cs	2012-05-22 16:02:07 UTC (rev 6682)
@@ -20,12 +20,14 @@
 using System;
 using System.Collections.Generic;
 using System.Text;
+
+using OSGeo.MapGuide.MaestroAPI;
+using OSGeo.MapGuide.MaestroAPI.Exceptions;
 using OSGeo.MapGuide.MaestroAPI.Resource;
-using OSGeo.MapGuide.MaestroAPI.Exceptions;
-using OSGeo.MapGuide.MaestroAPI;
+using OSGeo.MapGuide.MaestroAPI.Schema;
+using OSGeo.MapGuide.MaestroAPI.Services;
+using OSGeo.MapGuide.ObjectModels.Common;
 using OSGeo.MapGuide.ObjectModels.FeatureSource;
-using OSGeo.MapGuide.ObjectModels.Common;
-using OSGeo.MapGuide.MaestroAPI.Schema;
 
 namespace OSGeo.MapGuide.MaestroAPI.Resource.Validation
 {
@@ -55,8 +57,9 @@
             List<ValidationIssue> issues = new List<ValidationIssue>();
 
             IFeatureSource feature = (IFeatureSource)resource;
+            IFeatureService featSvc = feature.CurrentConnection.FeatureService;
             //Note: Must be saved!
-            string s = feature.CurrentConnection.FeatureService.TestConnection(feature.ResourceID);
+            string s = featSvc.TestConnection(feature.ResourceID);
             if (s.Trim().ToUpper() != true.ToString().ToUpper())
                 return new ValidationIssue[] { new ValidationIssue(feature, ValidationStatus.Error, ValidationStatusCode.Error_FeatureSource_ConnectionTestFailed, string.Format(Properties.Resources.FS_ConnectionTestFailed, s)) };
 
@@ -80,11 +83,10 @@
             }
 
             List<string> classes = new List<string>();
-            FeatureSourceDescription fsd = null;
             try
             {
-                fsd = context.DescribeFeatureSource(feature.ResourceID);
-                if (fsd == null || fsd.Schemas.Length == 0)
+                var schemaNames = featSvc.GetSchemas(feature.ResourceID);
+                if (schemaNames.Length == 0)
                     issues.Add(new ValidationIssue(feature, ValidationStatus.Warning, ValidationStatusCode.Warning_FeatureSource_NoSchemasFound, Properties.Resources.FS_SchemasMissingWarning));
             }
             catch (Exception ex)
@@ -93,12 +95,23 @@
                 issues.Add(new ValidationIssue(feature, ValidationStatus.Error, ValidationStatusCode.Error_FeatureSource_SchemaReadError, string.Format(Properties.Resources.FS_SchemaReadError, msg)));
             }
 
-
-            foreach (var cl in fsd.AllClasses)
+            var classNames = featSvc.GetClassNames(feature.ResourceID, null);
+            foreach (var className in classNames)
             {
-                var ids = cl.IdentityProperties;
-                if (ids.Count == 0)
-                    issues.Add(new ValidationIssue(feature, ValidationStatus.Information, ValidationStatusCode.Info_FeatureSource_NoPrimaryKey, string.Format(Properties.Resources.FS_PrimaryKeyMissingInformation, cl.QualifiedName)));
+                try 
+                {
+                    string[] idProps = featSvc.GetIdentityProperties(feature.ResourceID, className);
+                    if (idProps.Length == 0)
+                        issues.Add(new ValidationIssue(feature, ValidationStatus.Information, ValidationStatusCode.Info_FeatureSource_NoPrimaryKey, string.Format(Properties.Resources.FS_PrimaryKeyMissingInformation, className)));
+                }
+                catch (Exception ex)
+                {
+                    string msg = NestedExceptionMessageProcessor.GetFullMessage(ex);
+                    if (msg.Contains("MgClassNotFound")) //#1403 workaround
+                        issues.Add(new ValidationIssue(feature, ValidationStatus.Information, ValidationStatusCode.Info_FeatureSource_NoPrimaryKey, string.Format(Properties.Resources.FS_PrimaryKeyMissingInformation, className)));
+                    else
+                        issues.Add(new ValidationIssue(feature, ValidationStatus.Error, ValidationStatusCode.Error_FeatureSource_SchemaReadError, string.Format(Properties.Resources.FS_SchemaReadError, msg)));
+                }
             }
 
             context.MarkValidated(resource.ResourceID);

Modified: branches/maestro-4.0.x/OSGeo.MapGuide.MaestroAPI/Services/IFeatureService.cs
===================================================================
--- branches/maestro-4.0.x/OSGeo.MapGuide.MaestroAPI/Services/IFeatureService.cs	2012-05-22 15:50:40 UTC (rev 6681)
+++ branches/maestro-4.0.x/OSGeo.MapGuide.MaestroAPI/Services/IFeatureService.cs	2012-05-22 16:02:07 UTC (rev 6682)
@@ -195,6 +195,11 @@
         /// Describes the specified feature source
         /// </summary>
         /// <param name="resourceID"></param>
+        /// <remarks>
+        /// If you only need to list schemas and class names, use the respective <see cref="M:OSGeo.MapGuide.MaestroAPI.Services.IFeatureService.GetSchemas" /> and
+        /// <see cref="M:OSGeo.MapGuide.MaestroAPI.Services.IFeatureService.GetClassNames" /> methods. Using this API will have a noticeable performance impact on 
+        /// really large datastores (whose size is in the 100s of classes).
+        /// </remarks>
         /// <returns></returns>
         FeatureSourceDescription DescribeFeatureSource(string resourceID);
 
@@ -203,6 +208,11 @@
         /// </summary>
         /// <param name="resourceID"></param>
         /// <param name="schema"></param>
+        /// <remarks>
+        /// If you only need to list schemas and class names, use the respective <see cref="M:OSGeo.MapGuide.MaestroAPI.Services.IFeatureService.GetSchemas" /> and
+        /// <see cref="M:OSGeo.MapGuide.MaestroAPI.Services.IFeatureService.GetClassNames" /> methods. Using this API will have a noticeable performance impact on 
+        /// really large datastores (whose size is in the 100s of classes).
+        /// </remarks>
         /// <returns></returns>
         FeatureSchema DescribeFeatureSource(string resourceID, string schema);
 
@@ -246,10 +256,13 @@
         string[] GetSchemas(string resourceId);
 
         /// <summary>
-        /// Gets an array of feature class names from the specified feature source
+        /// Gets an array of qualified feature class names from the specified feature source
         /// </summary>
-        /// <param name="resourceId"></param>
-        /// <param name="schemaName"></param>
+        /// <param name="resourceId">The feature source id</param>
+        /// <param name="schemaName">
+        /// The name of the schema whose class names are to be returned. If null, class names from all schemas in the feature source
+        /// are returned
+        /// </param>
         /// <returns></returns>
         string[] GetClassNames(string resourceId, string schemaName);
     }

Modified: branches/maestro-4.0.x/OSGeo.MapGuide.MaestroAPI.Http/HttpServerConnection.cs
===================================================================
--- branches/maestro-4.0.x/OSGeo.MapGuide.MaestroAPI.Http/HttpServerConnection.cs	2012-05-22 15:50:40 UTC (rev 6681)
+++ branches/maestro-4.0.x/OSGeo.MapGuide.MaestroAPI.Http/HttpServerConnection.cs	2012-05-22 16:02:07 UTC (rev 6682)
@@ -1225,7 +1225,9 @@
                 if (typeof(WebException).IsAssignableFrom(ex.GetType()))
                     LogFailedRequest((WebException)ex);
 
-                var sessionRecreated = this.RestartSession(false);
+                var sessionRecreated = false;
+                if (this.IsSessionExpiredException(ex))
+                    sessionRecreated = this.RestartSession(false);
                 if (!this.m_autoRestartSession || !this.IsSessionExpiredException(ex) || !sessionRecreated)
                 {
                     Exception ex2 = Utility.ThrowAsWebException(ex);

Modified: branches/maestro-4.0.x/OSGeo.MapGuide.MaestroAPI.Http/RequestBuilder.cs
===================================================================
--- branches/maestro-4.0.x/OSGeo.MapGuide.MaestroAPI.Http/RequestBuilder.cs	2012-05-22 15:50:40 UTC (rev 6681)
+++ branches/maestro-4.0.x/OSGeo.MapGuide.MaestroAPI.Http/RequestBuilder.cs	2012-05-22 16:02:07 UTC (rev 6682)
@@ -1510,7 +1510,8 @@
                 param.Add("LOCALE", m_locale);
 
             param.Add("RESOURCEID", resourceId);
-            param.Add("SCHEMA", schemaName);
+            if (!string.IsNullOrEmpty(schemaName))
+                param.Add("SCHEMA", schemaName);
 
             return m_hosturi + "?" + EncodeParameters(param);
         }



More information about the mapguide-commits mailing list