[mapguide-commits] r5269 - in sandbox/maestro-3.0: Generated Maestro.AddIn.LayerDefinition-1.1.0/Commands Maestro.AddIn.LayerDefinition-1.2.0/Commands Maestro.AddIn.LayerDefinition-1.3.0/Commands Maestro.Base/Editor Maestro.Base/Templates Maestro.Base/UI Maestro.Editors/Common Maestro.Editors/FeatureSource Maestro.Editors/FeatureSource/Extensions Maestro.Editors/FeatureSource/Providers Maestro.Editors/FeatureSource/Providers/Rdbms Maestro.Editors/FeatureSource/Providers/Sdf Maestro.Editors/FeatureSource/Providers/Shp Maestro.Editors/LayerDefinition Maestro.Editors/LayerDefinition/Vector Maestro.Editors/LayerDefinition/Vector/StyleEditors Maestro.Editors/WebLayout/Commands Maestro.ResourceValidation OSGeo.MapGuide.MaestroAPI OSGeo.MapGuide.MaestroAPI/Commands OSGeo.MapGuide.MaestroAPI/ObjectModels OSGeo.MapGuide.MaestroAPI/Resource

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Mon Oct 11 11:31:19 EDT 2010


Author: jng
Date: 2010-10-11 08:31:19 -0700 (Mon, 11 Oct 2010)
New Revision: 5269

Added:
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ObjectModels/FeatureSourceInterfaces.cs
Modified:
   sandbox/maestro-3.0/Generated/FeatureSource-1.0.0.designer.cs
   sandbox/maestro-3.0/Maestro.AddIn.LayerDefinition-1.1.0/Commands/StartupCommand.cs
   sandbox/maestro-3.0/Maestro.AddIn.LayerDefinition-1.2.0/Commands/StartupCommand.cs
   sandbox/maestro-3.0/Maestro.AddIn.LayerDefinition-1.3.0/Commands/StartupCommand.cs
   sandbox/maestro-3.0/Maestro.Base/Editor/EditorContentBase.cs
   sandbox/maestro-3.0/Maestro.Base/Editor/ResourceEditorService.cs
   sandbox/maestro-3.0/Maestro.Base/Editor/ResourcePreviewEngine.cs
   sandbox/maestro-3.0/Maestro.Base/Editor/XmlEditor.cs
   sandbox/maestro-3.0/Maestro.Base/Templates/FeatureSourceItemTemplate.cs
   sandbox/maestro-3.0/Maestro.Base/UI/ResourcePropertiesDialog.cs
   sandbox/maestro-3.0/Maestro.Editors/Common/ResourceDataCtrl.cs
   sandbox/maestro-3.0/Maestro.Editors/FeatureSource/CoordSysOverrideCtrl.cs
   sandbox/maestro-3.0/Maestro.Editors/FeatureSource/Extensions/CalculationSettings.cs
   sandbox/maestro-3.0/Maestro.Editors/FeatureSource/Extensions/ExtendedClassSettings.cs
   sandbox/maestro-3.0/Maestro.Editors/FeatureSource/Extensions/JoinSettings.cs
   sandbox/maestro-3.0/Maestro.Editors/FeatureSource/ExtensionsCtrl.cs
   sandbox/maestro-3.0/Maestro.Editors/FeatureSource/FeatureSourceEditorCtrl.cs
   sandbox/maestro-3.0/Maestro.Editors/FeatureSource/Providers/FileBasedCtrl.cs
   sandbox/maestro-3.0/Maestro.Editors/FeatureSource/Providers/GenericCtrl.cs
   sandbox/maestro-3.0/Maestro.Editors/FeatureSource/Providers/Rdbms/RdbmsBaseCtrl.cs
   sandbox/maestro-3.0/Maestro.Editors/FeatureSource/Providers/Sdf/SdfFileCtrl.cs
   sandbox/maestro-3.0/Maestro.Editors/FeatureSource/Providers/Shp/ShpFileCtrl.cs
   sandbox/maestro-3.0/Maestro.Editors/LayerDefinition/Vector/StyleEditors/AreaFeatureStyleEditor.cs
   sandbox/maestro-3.0/Maestro.Editors/LayerDefinition/Vector/StyleEditors/FontStyleEditor.cs
   sandbox/maestro-3.0/Maestro.Editors/LayerDefinition/Vector/StyleEditors/LineFeatureStyleEditor.cs
   sandbox/maestro-3.0/Maestro.Editors/LayerDefinition/Vector/StyleEditors/PointFeatureStyleEditor.cs
   sandbox/maestro-3.0/Maestro.Editors/LayerDefinition/Vector/VectorLayerSettingsSectionCtrl.cs
   sandbox/maestro-3.0/Maestro.Editors/LayerDefinition/VectorLayerEditorCtrl.cs
   sandbox/maestro-3.0/Maestro.Editors/WebLayout/Commands/SearchCmdCtrl.cs
   sandbox/maestro-3.0/Maestro.ResourceValidation/FeatureSourceValidator.cs
   sandbox/maestro-3.0/Maestro.ResourceValidation/MapDefinitionValidator.cs
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Commands/ExecuteLoadProcedure.cs
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/OSGeo.MapGuide.MaestroAPI.csproj
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ObjectModels/FeatureSource.cs
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ObjectModels/LayerFactory.cs
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ObjectModels/ObjectFactory.cs
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/BaseLayerDefinitionValidator.cs
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/IResource.cs
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/ValidationResultSet.cs
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ResourceTypeRegistry.cs
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ServerConnectionBase.cs
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Utility.cs
Log:
3.0 sandbox changes:
 - Introduce a set of abstract Feature Source interfaces
 - Refactor Feature Source Editors to work off of these interfaces
 - Fix some problems with resource saving (attached resource data was not being copied to the final destination)
 - Fix resource preview problems (again resource data was not being copied to the resource id being previewed)

Modified: sandbox/maestro-3.0/Generated/FeatureSource-1.0.0.designer.cs
===================================================================
--- sandbox/maestro-3.0/Generated/FeatureSource-1.0.0.designer.cs	2010-10-11 07:19:07 UTC (rev 5268)
+++ sandbox/maestro-3.0/Generated/FeatureSource-1.0.0.designer.cs	2010-10-11 15:31:19 UTC (rev 5269)
@@ -1431,23 +1431,6 @@
     
     [System.CodeDom.Compiler.GeneratedCodeAttribute("Xsd2Code", "3.3.0.33572")]
     [System.SerializableAttribute()]
-    public enum RelateTypeEnum {
-        
-        /// <remarks/>
-        LeftOuter,
-        
-        /// <remarks/>
-        RightOuter,
-        
-        /// <remarks/>
-        Inner,
-        
-        /// <remarks/>
-        Association,
-    }
-    
-    [System.CodeDom.Compiler.GeneratedCodeAttribute("Xsd2Code", "3.3.0.33572")]
-    [System.SerializableAttribute()]
     [System.Diagnostics.DebuggerStepThroughAttribute()]
     [System.ComponentModel.DesignerCategoryAttribute("code")]
     [System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=true)]

Modified: sandbox/maestro-3.0/Maestro.AddIn.LayerDefinition-1.1.0/Commands/StartupCommand.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.AddIn.LayerDefinition-1.1.0/Commands/StartupCommand.cs	2010-10-11 07:19:07 UTC (rev 5268)
+++ sandbox/maestro-3.0/Maestro.AddIn.LayerDefinition-1.1.0/Commands/StartupCommand.cs	2010-10-11 15:31:19 UTC (rev 5269)
@@ -25,6 +25,7 @@
 using OSGeo.MapGuide.MaestroAPI.Resource;
 using OSGeo.MapGuide.ObjectModels.LayerDefinition_1_1_0;
 using OSGeo.MapGuide.MaestroAPI;
+using OSGeo.MapGuide.MaestroAPI.ObjectModels;
 
 namespace Maestro.AddIn.LayerDefinition_1_1_0.Commands
 {
@@ -35,11 +36,9 @@
             ResourceValidatorSet.RegisterValidator(new LayerDefinitionValidator());
             ResourceTypeRegistry.RegisterResource(
                 new ResourceTypeDescriptor(ResourceTypes.LayerDefinition, "1.1.0"),
-                new ResourceSerializer()
-                {
-                    Serialize = (res) => { return res.SerializeToStream(); },
-                    Deserialize = (xml) => { return LayerDefinition.Deserialize(xml); }
-                });
+                new ResourceSerializationCallback(LdfEntryPoint.Serialize),
+                new ResourceDeserializationCallback(LdfEntryPoint.Deserialize));
+            ObjectFactory.RegisterLayerFactoryMethod(new Version(1, 1, 0), new LayerCreatorFunc(LdfEntryPoint.CreateDefault));
         }
     }
 }

Modified: sandbox/maestro-3.0/Maestro.AddIn.LayerDefinition-1.2.0/Commands/StartupCommand.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.AddIn.LayerDefinition-1.2.0/Commands/StartupCommand.cs	2010-10-11 07:19:07 UTC (rev 5268)
+++ sandbox/maestro-3.0/Maestro.AddIn.LayerDefinition-1.2.0/Commands/StartupCommand.cs	2010-10-11 15:31:19 UTC (rev 5269)
@@ -35,11 +35,8 @@
             ResourceValidatorSet.RegisterValidator(new LayerDefinitionValidator());
             ResourceTypeRegistry.RegisterResource(
                 new ResourceTypeDescriptor(ResourceTypes.LayerDefinition, "1.2.0"),
-                new ResourceSerializer()
-                {
-                    Serialize = (res) => { return res.SerializeToStream(); },
-                    Deserialize = (xml) => { return LayerDefinition.Deserialize(xml); }
-                });
+                new ResourceSerializationCallback(LdfEntryPoint.Serialize),
+                new ResourceDeserializationCallback(LdfEntryPoint.Deserialize));
         }
     }
 }

Modified: sandbox/maestro-3.0/Maestro.AddIn.LayerDefinition-1.3.0/Commands/StartupCommand.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.AddIn.LayerDefinition-1.3.0/Commands/StartupCommand.cs	2010-10-11 07:19:07 UTC (rev 5268)
+++ sandbox/maestro-3.0/Maestro.AddIn.LayerDefinition-1.3.0/Commands/StartupCommand.cs	2010-10-11 15:31:19 UTC (rev 5269)
@@ -35,11 +35,8 @@
             ResourceValidatorSet.RegisterValidator(new LayerDefinitionValidator());
             ResourceTypeRegistry.RegisterResource(
                 new ResourceTypeDescriptor(ResourceTypes.LayerDefinition, "1.3.0"),
-                new ResourceSerializer()
-                {
-                    Serialize = (res) => { return res.SerializeToStream(); },
-                    Deserialize = (xml) => { return LayerDefinition.Deserialize(xml); }
-                });
+                new ResourceSerializationCallback(LdfEntryPoint.Serialize),
+                new ResourceDeserializationCallback(LdfEntryPoint.Deserialize));
         }
     }
 }

Modified: sandbox/maestro-3.0/Maestro.Base/Editor/EditorContentBase.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Editor/EditorContentBase.cs	2010-10-11 07:19:07 UTC (rev 5268)
+++ sandbox/maestro-3.0/Maestro.Base/Editor/EditorContentBase.cs	2010-10-11 15:31:19 UTC (rev 5269)
@@ -100,6 +100,7 @@
             //We've been editing an in-memory model of the session copy
             //so we need to save this model back to the session copy before Save()
             //commits the changes back to the original resource
+            _svc.UpdateResourceContent(GetXmlContent());
             try
             {
                 var errors = new List<ValidationIssue>(ValidateEditedResource()).ToArray();
@@ -112,7 +113,6 @@
                 }
                 else
                 {
-                    _svc.UpdateResourceContent(GetXmlContent());
                     e.Cancel = false;
                 }
             }
@@ -235,7 +235,16 @@
 
         public virtual string SetupPreviewUrl(string mapguideRootUrl)
         {
-            return new ResourcePreviewEngine(mapguideRootUrl, this.EditorService).GeneratePreviewUrl(this.Resource);
+            //Save the current resource to another session copy
+            string resId = "Session:" + this.EditorService.SessionID + "//" + Guid.NewGuid() + "." + this.Resource.ResourceType.ToString();
+            this.EditorService.ResourceService.SetResourceXmlData(resId, this.Resource.SerializeToStream());
+
+            //Copy any resource data
+            var previewCopy = this.EditorService.ResourceService.GetResource(resId);
+            this.Resource.CopyResourceDataTo(previewCopy);
+
+            //Now feed it to the preview engine
+            return new ResourcePreviewEngine(mapguideRootUrl, this.EditorService).GeneratePreviewUrl(previewCopy);
         }
     }
 }

Modified: sandbox/maestro-3.0/Maestro.Base/Editor/ResourceEditorService.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Editor/ResourceEditorService.cs	2010-10-11 07:19:07 UTC (rev 5268)
+++ sandbox/maestro-3.0/Maestro.Base/Editor/ResourceEditorService.cs	2010-10-11 15:31:19 UTC (rev 5269)
@@ -172,6 +172,8 @@
             if (!OnBeforeSave())
             {
                 _conn.ResourceService.SaveResourceAs(_editCopy, resourceID);
+                //Don't forget to copy attached resource data!
+                _editCopy.CopyResourceDataTo(resourceID);
                 this.ResourceID = resourceID;
                 this.IsNew = false;
                 this.IsDirty = false;

Modified: sandbox/maestro-3.0/Maestro.Base/Editor/ResourcePreviewEngine.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Editor/ResourcePreviewEngine.cs	2010-10-11 07:19:07 UTC (rev 5268)
+++ sandbox/maestro-3.0/Maestro.Base/Editor/ResourcePreviewEngine.cs	2010-10-11 15:31:19 UTC (rev 5269)
@@ -166,7 +166,7 @@
             var resId = "Session:" + sessionId + "//" + Guid.NewGuid() + ".ApplicationDefinition";
             
             conn.ResourceService.SaveResourceAs(appDef, resId);
-            url += "fusion/templates/mapguide/preview/index.html?Session=" + sessionId + "&ApplicationDefinition=" + resId;
+            url += appDef.TemplateUrl + "?Session=" + sessionId + "&ApplicationDefinition=" + resId;
             return url;
         }
 

Modified: sandbox/maestro-3.0/Maestro.Base/Editor/XmlEditor.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Editor/XmlEditor.cs	2010-10-11 07:19:07 UTC (rev 5268)
+++ sandbox/maestro-3.0/Maestro.Base/Editor/XmlEditor.cs	2010-10-11 15:31:19 UTC (rev 5269)
@@ -136,22 +136,5 @@
                 return false; //We're already in the XML editor!
             }
         }
-
-        public override string SetupPreviewUrl(string mapguideRootUrl)
-        {
-            //This one's a bit different, the current state of the edited resource 
-            //is in the XML text area. We need to save this to another temp session 
-            //copy before attempting to generate a preview url
-
-            string resId = "Session:" + _edSvc.SessionID + "//" + Guid.NewGuid() + "." + this.Resource.ResourceType.ToString();
-            _edSvc.ResourceService.SetResourceXmlData(resId, this.Resource.SerializeToStream());
-
-            //Copy any resource data
-            var previewCopy = _edSvc.ResourceService.GetResource(resId);
-            this.Resource.CopyResourceDataTo(previewCopy);
-
-            //Now feed it to the preview engine
-            return new ResourcePreviewEngine(mapguideRootUrl, _edSvc).GeneratePreviewUrl(previewCopy);
-        }
     }
 }

Modified: sandbox/maestro-3.0/Maestro.Base/Templates/FeatureSourceItemTemplate.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Templates/FeatureSourceItemTemplate.cs	2010-10-11 07:19:07 UTC (rev 5268)
+++ sandbox/maestro-3.0/Maestro.Base/Templates/FeatureSourceItemTemplate.cs	2010-10-11 15:31:19 UTC (rev 5269)
@@ -51,7 +51,7 @@
 
             if (provider != null)
             {
-                return ObjectFactory.CreateFeatureSource(conn, provider.Name);
+                return ObjectFactory.CreateFeatureSource(conn, Utility.StripVersionFromProviderName(provider.Name));
             }
             return null;
         }

Modified: sandbox/maestro-3.0/Maestro.Base/UI/ResourcePropertiesDialog.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/UI/ResourcePropertiesDialog.cs	2010-10-11 07:19:07 UTC (rev 5268)
+++ sandbox/maestro-3.0/Maestro.Base/UI/ResourcePropertiesDialog.cs	2010-10-11 15:31:19 UTC (rev 5269)
@@ -862,7 +862,7 @@
             try
             {
                 System.Globalization.CultureInfo ic = System.Globalization.CultureInfo.InvariantCulture;
-                FeatureSourceType fs = (FeatureSourceType)m_connection.ResourceService.GetResource(m_resourceId);
+                IFeatureSource fs = (IFeatureSource)m_connection.ResourceService.GetResource(m_resourceId);
                 bool failures = false;
 
                 Envelope env = null;

Modified: sandbox/maestro-3.0/Maestro.Editors/Common/ResourceDataCtrl.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Editors/Common/ResourceDataCtrl.cs	2010-10-11 07:19:07 UTC (rev 5268)
+++ sandbox/maestro-3.0/Maestro.Editors/Common/ResourceDataCtrl.cs	2010-10-11 15:31:19 UTC (rev 5269)
@@ -238,6 +238,8 @@
                 //Bold the selected item
                 var f = item.Font;
                 item.Font = new Font(f, f.Style | FontStyle.Bold);
+
+                OnResourceDataMarked(item.Name);
             }
         }
 

Modified: sandbox/maestro-3.0/Maestro.Editors/FeatureSource/CoordSysOverrideCtrl.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Editors/FeatureSource/CoordSysOverrideCtrl.cs	2010-10-11 07:19:07 UTC (rev 5268)
+++ sandbox/maestro-3.0/Maestro.Editors/FeatureSource/CoordSysOverrideCtrl.cs	2010-10-11 15:31:19 UTC (rev 5269)
@@ -41,13 +41,13 @@
         }
 
         private IEditorService _ed;
-        private FeatureSourceType _fs;
+        private IFeatureSource _fs;
 
         public override void Bind(IEditorService service)
         {
             _ed = service;
             _ed.RegisterCustomNotifier(this);
-            _fs = (FeatureSourceType)_ed.GetEditedResource();
+            _fs = (IFeatureSource)_ed.GetEditedResource();
 
             grdOverrides.AutoGenerateColumns = false;
             grdOverrides.DataSource = _fs.SupplementalSpatialContextInfo;
@@ -58,11 +58,7 @@
             var dlg = new CoordSysOverrideDialog(_ed);
             if (dlg.ShowDialog() == DialogResult.OK)
             {
-                _fs.SupplementalSpatialContextInfo.Add(new SpatialContextType()
-                {
-                    Name = dlg.CsName,
-                    CoordinateSystem = dlg.CoordinateSystemWkt
-                });
+                _fs.AddSpatialContextOverride(dlg.CsName, dlg.CoordinateSystemWkt);
                 OnResourceChanged();
             }
         }
@@ -85,8 +81,8 @@
             if (grdOverrides.SelectedRows.Count != 1)
                 return;
 
-            var sc = (SpatialContextType)grdOverrides.SelectedRows[0].DataBoundItem;
-            _fs.SupplementalSpatialContextInfo.Remove(sc);
+            var sc = (ISpatialContextInfo)grdOverrides.SelectedRows[0].DataBoundItem;
+            _fs.RemoveSpatialContextOverride(sc);
             OnResourceChanged();
         }
 
@@ -95,7 +91,7 @@
             if (grdOverrides.SelectedRows.Count != 1)
                 return;
 
-            var sc = (SpatialContextType)grdOverrides.SelectedRows[0].DataBoundItem;
+            var sc = (ISpatialContextInfo)grdOverrides.SelectedRows[0].DataBoundItem;
             var dlg = new CoordSysOverrideDialog(_ed);
             dlg.CsName = sc.Name;
             dlg.CoordinateSystemWkt = sc.CoordinateSystem;

Modified: sandbox/maestro-3.0/Maestro.Editors/FeatureSource/Extensions/CalculationSettings.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Editors/FeatureSource/Extensions/CalculationSettings.cs	2010-10-11 07:19:07 UTC (rev 5268)
+++ sandbox/maestro-3.0/Maestro.Editors/FeatureSource/Extensions/CalculationSettings.cs	2010-10-11 15:31:19 UTC (rev 5269)
@@ -39,9 +39,9 @@
 
         private IEditorService _edSvc;
         private FeatureSourceDescription.FeatureSourceSchema _cls;
-        private FeatureSourceType _parent;
+        private IFeatureSource _parent;
 
-        public CalculationSettings(IEditorService edSvc, FeatureSourceDescription.FeatureSourceSchema cls, FeatureSourceType parent, CalculatedPropertyType calc)
+        public CalculationSettings(IEditorService edSvc, FeatureSourceDescription.FeatureSourceSchema cls, IFeatureSource parent, ICalculatedProperty calc)
             : this()
         {
             _edSvc = edSvc;

Modified: sandbox/maestro-3.0/Maestro.Editors/FeatureSource/Extensions/ExtendedClassSettings.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Editors/FeatureSource/Extensions/ExtendedClassSettings.cs	2010-10-11 07:19:07 UTC (rev 5268)
+++ sandbox/maestro-3.0/Maestro.Editors/FeatureSource/Extensions/ExtendedClassSettings.cs	2010-10-11 15:31:19 UTC (rev 5269)
@@ -37,7 +37,7 @@
             InitializeComponent();
         }
 
-        public ExtendedClassSettings(FeatureSourceDescription.FeatureSourceSchema[] classes, FeatureSourceTypeExtension ext)
+        public ExtendedClassSettings(FeatureSourceDescription.FeatureSourceSchema[] classes, IFeatureSourceExtension ext)
             : this()
         {
             cmbBaseClass.DisplayMember = "Fullname";

Modified: sandbox/maestro-3.0/Maestro.Editors/FeatureSource/Extensions/JoinSettings.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Editors/FeatureSource/Extensions/JoinSettings.cs	2010-10-11 07:19:07 UTC (rev 5268)
+++ sandbox/maestro-3.0/Maestro.Editors/FeatureSource/Extensions/JoinSettings.cs	2010-10-11 15:31:19 UTC (rev 5269)
@@ -40,9 +40,9 @@
 
         private bool _init = false;
 
-        private AttributeRelateType _rel;
+        private IAttributeRelation _rel;
 
-        public JoinSettings(FeatureSetColumn [] primaryColumns, AttributeRelateType rel)
+        public JoinSettings(FeatureSetColumn[] primaryColumns, IAttributeRelation rel)
             : this()
         {
             //FIXME: Initial load will set the correct secondary class, but not the correct
@@ -70,9 +70,14 @@
             cmbPrimary.ValueMember = "Name";
             cmbPrimary.DataSource = primaryColumns;
 
-            grdJoinKeys.DataSource = rel.RelateProperty;
+            UpdateJoinKeyList(rel);
         }
 
+        private void UpdateJoinKeyList(IAttributeRelation rel)
+        {
+            grdJoinKeys.DataSource = new List<IRelateProperty>(rel.RelateProperty);
+        }
+
         void txtFeatureSource_TextChanged(object sender, EventArgs e)
         {
             UpdateJoinClass();
@@ -161,7 +166,7 @@
         {
             //Invalidate
             if (!_init)
-                _rel.RelateProperty.Clear();
+                _rel.RemoveAllRelateProperties();
 
             var item = cmbFeatureClass.SelectedItem as FeatureSourceDescription.FeatureSourceSchema;
             if (item != null)
@@ -174,7 +179,7 @@
 
         private void lnkClear_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
         {
-            _rel.RelateProperty.Clear();
+            _rel.RemoveAllRelateProperties();
         }
 
         private void CheckAddStatus(object sender, EventArgs e)
@@ -198,7 +203,8 @@
                 string primary = ((FeatureSetColumn)cmbPrimary.SelectedItem).Name;
                 string secondary = ((FeatureSetColumn)cmbSecondary.SelectedItem).Name;
 
-                _rel.RelateProperty.Add(new RelatePropertyType() { FeatureClassProperty = primary, AttributeClassProperty = secondary });
+                _rel.AddRelateProperty(primary, secondary);
+                UpdateJoinKeyList(_rel);
             }
         }
 
@@ -206,7 +212,8 @@
         {
             if (grdJoinKeys.SelectedRows.Count == 1)
             {
-                _rel.RelateProperty.Remove((RelatePropertyType)grdJoinKeys.SelectedRows[0].DataBoundItem);
+                _rel.RemoveRelateProperty((IRelateProperty)grdJoinKeys.SelectedRows[0].DataBoundItem);
+                UpdateJoinKeyList(_rel);
             }
         }
     }

Modified: sandbox/maestro-3.0/Maestro.Editors/FeatureSource/ExtensionsCtrl.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Editors/FeatureSource/ExtensionsCtrl.cs	2010-10-11 07:19:07 UTC (rev 5268)
+++ sandbox/maestro-3.0/Maestro.Editors/FeatureSource/ExtensionsCtrl.cs	2010-10-11 15:31:19 UTC (rev 5269)
@@ -45,7 +45,7 @@
         const int IDX_CALC = 1;
         const int IDX_JOIN = 2;
 
-        private FeatureSourceType _fs;
+        private IFeatureSource _fs;
         private FeatureSourceDescription _cachedSchema;
 
         private IEditorService _edSvc;
@@ -54,7 +54,7 @@
         {
             _edSvc = service;
             _edSvc.Saved += OnResourceSaved;
-            _fs = (FeatureSourceType)_edSvc.GetEditedResource();
+            _fs = (IFeatureSource)_edSvc.GetEditedResource();
 
             //Build tree
             if (_fs.Extension != null)
@@ -146,6 +146,18 @@
             _cachedSchema = _fs.Describe();
         }
 
+        private FeatureSourceDescription CachedSchema()
+        {
+            if (_cachedSchema == null)
+            {
+                using (new WaitCursor(this))
+                {
+                    _cachedSchema = _fs.Describe();
+                }
+            }
+            return _cachedSchema;
+        }
+
         private void btnNewExtension_Click(object sender, EventArgs e)
         {
             if (_edSvc.IsNew)
@@ -154,12 +166,7 @@
                 return;
             }
 
-            if (_fs.Extension == null)
-            {
-                _fs.Extension = new BindingList<FeatureSourceTypeExtension>();
-            }
-
-            var ext = new FeatureSourceTypeExtension();
+            var ext = ObjectFactory.CreateFeatureSourceExtension();
             TreeNode node = new TreeNode();
             node.Tag = ext;
             node.ImageIndex = node.SelectedImageIndex = IDX_EXTENSION;
@@ -175,7 +182,7 @@
                 }
             };
 
-            _fs.Extension.Add(ext);
+            _fs.AddExtension(ext);
 
             trvExtensions.Nodes.Add(node);
             trvExtensions.SelectedNode = node;
@@ -192,10 +199,10 @@
             var node = trvExtensions.SelectedNode;
             if (node != null)
             {
-                var ext = node.Tag as FeatureSourceTypeExtension;
+                var ext = node.Tag as IFeatureSourceExtension;
                 if (ext != null)
                 {
-                    var calc = new CalculatedPropertyType();
+                    var calc = ObjectFactory.CreateCalculatedProperty();
                     var cNode = new TreeNode();
                     cNode.ImageIndex = cNode.SelectedImageIndex = IDX_CALC;
                     cNode.Tag = calc;
@@ -214,11 +221,8 @@
                     node.Nodes.Add(cNode);
                     node.Expand();
 
-                    if (ext.CalculatedProperty == null)
-                        ext.CalculatedProperty = new BindingList<CalculatedPropertyType>();
+                    ext.AddCalculatedProperty(calc);
 
-                    ext.CalculatedProperty.Add(calc);
-
                     trvExtensions.SelectedNode = cNode;
                 }
             }
@@ -235,11 +239,10 @@
             var node = trvExtensions.SelectedNode;
             if (node != null)
             {
-                var ext = node.Tag as FeatureSourceTypeExtension;
+                var ext = node.Tag as IFeatureSourceExtension;
                 if (ext != null)
                 {
-                    var join = new AttributeRelateType();
-                    join.RelateProperty = new BindingList<RelatePropertyType>();
+                    var join = ObjectFactory.CreateAttributeRelation();
                     var jNode = new TreeNode();
                     jNode.Tag = join;
                     jNode.ImageIndex = jNode.SelectedImageIndex = IDX_JOIN;
@@ -253,10 +256,8 @@
 
                     node.Nodes.Add(jNode);
                     node.Expand();
-                    if (ext.AttributeRelate == null)
-                        ext.AttributeRelate = new BindingList<AttributeRelateType>();
 
-                    ext.AttributeRelate.Add(join);
+                    ext.AddRelation(join);
 
                     trvExtensions.SelectedNode = jNode;
                 }
@@ -268,48 +269,37 @@
             var node = trvExtensions.SelectedNode;
             if (node != null)
             {
-                var ext = node.Tag as FeatureSourceTypeExtension;
-                var join = node.Tag as AttributeRelateType;
-                var calc = node.Tag as CalculatedPropertyType;
+                var ext = node.Tag as IFeatureSourceExtension;
+                var join = node.Tag as IAttributeRelation;
+                var calc = node.Tag as ICalculatedProperty;
                 if (ext != null)
                 {
-                    _fs.Extension.Remove(ext);
-
-                    if (_fs.Extension.Count == 0)
-                        _fs.Extension = null; //To prevent empty element when saving
+                    _fs.RemoveExtension(ext);
                 }
                 else if (join != null)
                 {
                     //Disassociate from parent
-                    ext = node.Parent.Tag as FeatureSourceTypeExtension;
+                    ext = node.Parent.Tag as IFeatureSourceExtension;
                     if (ext != null)
                     {
-                        ext.AttributeRelate.Remove(join);
+                        ext.RemoveRelation(join);
                         node.Parent.Nodes.Remove(node);
-
-                        //To prevent writing empty elements when saving
-                        if (ext.AttributeRelate.Count == 0)
-                            ext.AttributeRelate = null;
                     }
                 }
                 else if (calc != null)
                 {
                     //Disassociate from parent
-                    ext = node.Parent.Tag as FeatureSourceTypeExtension;
+                    ext = node.Parent.Tag as IFeatureSourceExtension;
                     if (ext != null)
                     {
-                        ext.CalculatedProperty.Remove(calc);
+                        ext.RemoveCalculatedProperty(calc);
                         node.Parent.Nodes.Remove(node);
-
-                        //To prevent writing empty elements when saving
-                        if (ext.CalculatedProperty.Count == 0)
-                            ext.CalculatedProperty = null;
                     }
                 }
             }
         }
 
-        private bool IsValidExtension(FeatureSourceTypeExtension ext)
+        private bool IsValidExtension(IFeatureSourceExtension ext)
         {
             //TODO: Check class name and extended class name for validity
             return !string.IsNullOrEmpty(ext.FeatureClass) && !string.IsNullOrEmpty(ext.Name);
@@ -322,12 +312,12 @@
                 return;
             }
 
-            var ext = e.Node.Tag as FeatureSourceTypeExtension;
-            var join = e.Node.Tag as AttributeRelateType;
-            var calc = e.Node.Tag as CalculatedPropertyType;
+            var ext = e.Node.Tag as IFeatureSourceExtension;
+            var join = e.Node.Tag as IAttributeRelation;
+            var calc = e.Node.Tag as ICalculatedProperty;
             if (ext != null)
             {
-                var ctl = new ExtendedClassSettings(_cachedSchema.Schemas, ext);
+                var ctl = new ExtendedClassSettings(CachedSchema().Schemas, ext);
                 ctl.Dock = DockStyle.Fill;
                 //If editing to something valid, update the toolbar
                 ctl.ResourceChanged += (s, evt) =>
@@ -342,11 +332,11 @@
             }
             else if (join != null)
             {
-                ext = e.Node.Parent.Tag as FeatureSourceTypeExtension;
+                ext = e.Node.Parent.Tag as IFeatureSourceExtension;
                 if (ext != null)
                 {
                     FeatureSourceDescription.FeatureSourceSchema cls = null;
-                    foreach (var c in _cachedSchema.Schemas)
+                    foreach (var c in CachedSchema().Schemas)
                     {
                         if (c.Fullname == ext.FeatureClass)
                         {
@@ -367,11 +357,11 @@
             }
             else if (calc != null)
             {
-                ext = e.Node.Parent.Tag as FeatureSourceTypeExtension;
+                ext = e.Node.Parent.Tag as IFeatureSourceExtension;
                 if (ext != null)
                 {
                     FeatureSourceDescription.FeatureSourceSchema cls = null;
-                    foreach (var c in _cachedSchema.Schemas)
+                    foreach (var c in CachedSchema().Schemas)
                     {
                         if (c.Fullname == ext.FeatureClass)
                         {

Modified: sandbox/maestro-3.0/Maestro.Editors/FeatureSource/FeatureSourceEditorCtrl.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Editors/FeatureSource/FeatureSourceEditorCtrl.cs	2010-10-11 07:19:07 UTC (rev 5268)
+++ sandbox/maestro-3.0/Maestro.Editors/FeatureSource/FeatureSourceEditorCtrl.cs	2010-10-11 15:31:19 UTC (rev 5269)
@@ -40,11 +40,11 @@
             InitializeComponent();
         }
 
-        private FeatureSourceType _fs;
+        private IFeatureSource _fs;
 
         public override void Bind(IEditorService service)
         {
-            _fs = service.GetEditedResource() as FeatureSourceType;
+            _fs = service.GetEditedResource() as IFeatureSource;
             service.RegisterCustomNotifier(this);
             Debug.Assert(_fs != null);
 

Modified: sandbox/maestro-3.0/Maestro.Editors/FeatureSource/Providers/FileBasedCtrl.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Editors/FeatureSource/Providers/FileBasedCtrl.cs	2010-10-11 07:19:07 UTC (rev 5268)
+++ sandbox/maestro-3.0/Maestro.Editors/FeatureSource/Providers/FileBasedCtrl.cs	2010-10-11 15:31:19 UTC (rev 5269)
@@ -53,6 +53,12 @@
             service.RegisterCustomNotifier(this);
             resDataCtrl.Init(service);
             resDataCtrl.DataListChanged += (sender, e) => { OnResourceChanged(); };
+            resDataCtrl.ResourceDataMarked += (sender, e) => { OnResourceMarked(e); };
         }
+
+        protected virtual void OnResourceMarked(string dataName)
+        {
+            
+        }
     }
 }

Modified: sandbox/maestro-3.0/Maestro.Editors/FeatureSource/Providers/GenericCtrl.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Editors/FeatureSource/Providers/GenericCtrl.cs	2010-10-11 07:19:07 UTC (rev 5268)
+++ sandbox/maestro-3.0/Maestro.Editors/FeatureSource/Providers/GenericCtrl.cs	2010-10-11 15:31:19 UTC (rev 5269)
@@ -40,14 +40,14 @@
             InitializeComponent();
         }
 
-        private FeatureSourceType _fs;
+        private IFeatureSource _fs;
         private IEditorService _service;
 
         public override void Bind(IEditorService service)
         {
             _service = service;
             _service.RegisterCustomNotifier(this);
-            _fs = _service.GetEditedResource() as FeatureSourceType;
+            _fs = _service.GetEditedResource() as IFeatureSource;
 
             txtProvider.Text = _fs.Provider;
 

Modified: sandbox/maestro-3.0/Maestro.Editors/FeatureSource/Providers/Rdbms/RdbmsBaseCtrl.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Editors/FeatureSource/Providers/Rdbms/RdbmsBaseCtrl.cs	2010-10-11 07:19:07 UTC (rev 5268)
+++ sandbox/maestro-3.0/Maestro.Editors/FeatureSource/Providers/Rdbms/RdbmsBaseCtrl.cs	2010-10-11 15:31:19 UTC (rev 5269)
@@ -43,13 +43,13 @@
         }
 
         private IEditorService _edsvc;
-        private FeatureSourceType _fs;
+        private IFeatureSource _fs;
 
         public override void Bind(IEditorService service)
         {
             _edsvc = service;
             _edsvc.RegisterCustomNotifier(this);
-            _fs = _edsvc.GetEditedResource() as FeatureSourceType;
+            _fs = _edsvc.GetEditedResource() as IFeatureSource;
 
             //Set the field values
             txtService.Text = _fs.GetConnectionProperty("Service");

Modified: sandbox/maestro-3.0/Maestro.Editors/FeatureSource/Providers/Sdf/SdfFileCtrl.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Editors/FeatureSource/Providers/Sdf/SdfFileCtrl.cs	2010-10-11 07:19:07 UTC (rev 5268)
+++ sandbox/maestro-3.0/Maestro.Editors/FeatureSource/Providers/Sdf/SdfFileCtrl.cs	2010-10-11 15:31:19 UTC (rev 5269)
@@ -36,15 +36,21 @@
             InitializeComponent();
         }
 
-        private FeatureSourceType _fs;
+        private IFeatureSource _fs;
 
         public override void Bind(IEditorService service)
         {
             base.Bind(service);
-            _fs = service.GetEditedResource() as FeatureSourceType;
+            _fs = service.GetEditedResource() as IFeatureSource;
             Debug.Assert(_fs != null);
 
             MarkSelected();
+
+            //HACK: Set ReadOnly property if not specified otherwise this will be an invalid feature source
+            if (string.IsNullOrEmpty(_fs.GetConnectionProperty("ReadOnly")))
+                _fs.SetConnectionProperty("ReadOnly", "FALSE");
+
+            chkReadOnly.Checked = _fs.GetConnectionProperty("ReadOnly").ToUpper().Equals(true.ToString().ToUpper());
         }
 
         private void MarkSelected()
@@ -74,7 +80,18 @@
 
         private void chkReadOnly_CheckedChanged(object sender, EventArgs e)
         {
-            _fs.SetConnectionProperty("ReadOnly", chkReadOnly.Checked.ToString().ToUpper());
+            var newValue = chkReadOnly.Checked.ToString().ToUpper();
+            var currValue = _fs.GetConnectionProperty("ReadOnly");
+            if (!newValue.Equals(currValue))
+                _fs.SetConnectionProperty("ReadOnly", newValue);
         }
+
+        protected override void OnResourceMarked(string dataName)
+        {
+            string fileProp = "%MG_DATA_FILE_PATH%" + dataName;
+            string currFileProp = _fs.GetConnectionProperty("File");
+            if (!currFileProp.Equals(fileProp))
+                _fs.SetConnectionProperty("File", fileProp);
+        }
     }
 }

Modified: sandbox/maestro-3.0/Maestro.Editors/FeatureSource/Providers/Shp/ShpFileCtrl.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Editors/FeatureSource/Providers/Shp/ShpFileCtrl.cs	2010-10-11 07:19:07 UTC (rev 5268)
+++ sandbox/maestro-3.0/Maestro.Editors/FeatureSource/Providers/Shp/ShpFileCtrl.cs	2010-10-11 15:31:19 UTC (rev 5269)
@@ -36,12 +36,12 @@
             InitializeComponent();
         }
 
-        private FeatureSourceType _fs;
+        private IFeatureSource _fs;
 
         public override void Bind(IEditorService service)
         {
             base.Bind(service);
-            _fs = service.GetEditedResource() as FeatureSourceType;
+            _fs = service.GetEditedResource() as IFeatureSource;
             Debug.Assert(_fs != null);
 
             MarkSelected();
@@ -71,5 +71,13 @@
             base.OnResourceChanged();
             MarkSelected();
         }
+
+        protected override void OnResourceMarked(string dataName)
+        {
+            var newValue = "%MG_DATA_FILE_PATH%" + dataName;
+            var currValue = _fs.GetConnectionProperty("DefaultFileLocation");
+            if (!newValue.Equals(currValue))
+                _fs.SetConnectionProperty("DefaultFileLocation", newValue);
+        }
     }
 }

Modified: sandbox/maestro-3.0/Maestro.Editors/LayerDefinition/Vector/StyleEditors/AreaFeatureStyleEditor.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Editors/LayerDefinition/Vector/StyleEditors/AreaFeatureStyleEditor.cs	2010-10-11 07:19:07 UTC (rev 5268)
+++ sandbox/maestro-3.0/Maestro.Editors/LayerDefinition/Vector/StyleEditors/AreaFeatureStyleEditor.cs	2010-10-11 15:31:19 UTC (rev 5269)
@@ -82,7 +82,7 @@
             m_schema = schema;
 
             _factory = (ILayerElementFactory)editor.GetEditedResource();
-            var fs = (FeatureSourceType)m_editor.ResourceService.GetResource(featureSource);
+            var fs = (IFeatureSource)m_editor.ResourceService.GetResource(featureSource);
 
             m_providername = fs.Provider;
             m_featureSource = featureSource;

Modified: sandbox/maestro-3.0/Maestro.Editors/LayerDefinition/Vector/StyleEditors/FontStyleEditor.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Editors/LayerDefinition/Vector/StyleEditors/FontStyleEditor.cs	2010-10-11 07:19:07 UTC (rev 5268)
+++ sandbox/maestro-3.0/Maestro.Editors/LayerDefinition/Vector/StyleEditors/FontStyleEditor.cs	2010-10-11 15:31:19 UTC (rev 5269)
@@ -115,7 +115,7 @@
             m_editor = editor;
             m_schema = schema;
 
-            var fs = (FeatureSourceType)editor.ResourceService.GetResource(featureSource);
+            var fs = (IFeatureSource)editor.ResourceService.GetResource(featureSource);
 
             _factory = (ILayerElementFactory)editor.GetEditedResource();
 

Modified: sandbox/maestro-3.0/Maestro.Editors/LayerDefinition/Vector/StyleEditors/LineFeatureStyleEditor.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Editors/LayerDefinition/Vector/StyleEditors/LineFeatureStyleEditor.cs	2010-10-11 07:19:07 UTC (rev 5268)
+++ sandbox/maestro-3.0/Maestro.Editors/LayerDefinition/Vector/StyleEditors/LineFeatureStyleEditor.cs	2010-10-11 15:31:19 UTC (rev 5269)
@@ -86,7 +86,7 @@
 
             _factory = (ILayerElementFactory)editor.GetEditedResource();
 
-            var fs = (FeatureSourceType)editor.ResourceService.GetResource(featureSource);
+            var fs = (IFeatureSource)editor.ResourceService.GetResource(featureSource);
 
             m_providername = fs.Provider;
             m_featureSource = featureSource;

Modified: sandbox/maestro-3.0/Maestro.Editors/LayerDefinition/Vector/StyleEditors/PointFeatureStyleEditor.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Editors/LayerDefinition/Vector/StyleEditors/PointFeatureStyleEditor.cs	2010-10-11 07:19:07 UTC (rev 5268)
+++ sandbox/maestro-3.0/Maestro.Editors/LayerDefinition/Vector/StyleEditors/PointFeatureStyleEditor.cs	2010-10-11 15:31:19 UTC (rev 5269)
@@ -121,7 +121,7 @@
             m_schema = schema;
 
             _factory = (ILayerElementFactory)editor.GetEditedResource();
-            var fs = (FeatureSourceType)editor.ResourceService.GetResource(featureSource);
+            var fs = (IFeatureSource)editor.ResourceService.GetResource(featureSource);
 
             m_providername = fs.Provider;
             m_featureSource = featureSource;

Modified: sandbox/maestro-3.0/Maestro.Editors/LayerDefinition/Vector/VectorLayerSettingsSectionCtrl.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Editors/LayerDefinition/Vector/VectorLayerSettingsSectionCtrl.cs	2010-10-11 07:19:07 UTC (rev 5268)
+++ sandbox/maestro-3.0/Maestro.Editors/LayerDefinition/Vector/VectorLayerSettingsSectionCtrl.cs	2010-10-11 15:31:19 UTC (rev 5269)
@@ -149,12 +149,12 @@
             return null;
         }
 
-        private FeatureSourceType _cachedFs;
+        private IFeatureSource _cachedFs;
 
-        private FeatureSourceType GetFeatureSource()
+        private IFeatureSource GetFeatureSource()
         {
             if (_cachedFs == null)
-                _cachedFs = (FeatureSourceType)_edsvc.ResourceService.GetResource(txtFeatureSource.Text);
+                _cachedFs = (IFeatureSource)_edsvc.ResourceService.GetResource(txtFeatureSource.Text);
 
             return _cachedFs;
         }

Modified: sandbox/maestro-3.0/Maestro.Editors/LayerDefinition/VectorLayerEditorCtrl.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Editors/LayerDefinition/VectorLayerEditorCtrl.cs	2010-10-11 07:19:07 UTC (rev 5268)
+++ sandbox/maestro-3.0/Maestro.Editors/LayerDefinition/VectorLayerEditorCtrl.cs	2010-10-11 15:31:19 UTC (rev 5269)
@@ -42,7 +42,7 @@
 
         internal string EditExpression(string expr)
         {
-            var fs = (FeatureSourceType)_edsvc.ResourceService.GetResource(_vl.ResourceId);
+            var fs = (IFeatureSource)_edsvc.ResourceService.GetResource(_vl.ResourceId);
 
             return _edsvc.EditExpression(expr, fs.GetClass(_vl.FeatureName), fs.Provider, _vl.ResourceId);
         }

Modified: sandbox/maestro-3.0/Maestro.Editors/WebLayout/Commands/SearchCmdCtrl.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Editors/WebLayout/Commands/SearchCmdCtrl.cs	2010-10-11 07:19:07 UTC (rev 5268)
+++ sandbox/maestro-3.0/Maestro.Editors/WebLayout/Commands/SearchCmdCtrl.cs	2010-10-11 15:31:19 UTC (rev 5269)
@@ -108,7 +108,7 @@
                 var ldf = (ILayerDefinition)_edsvc.ResourceService.GetResource(layer.ResourceId);
                 var vl = (IVectorLayerDefinition)ldf.SubLayer;
 
-                var fs = (FeatureSourceType)_edsvc.ResourceService.GetResource(vl.ResourceId);
+                var fs = (IFeatureSource)_edsvc.ResourceService.GetResource(vl.ResourceId);
                 
                 string expr = _edsvc.EditExpression(txtFilter.Text, _cls, fs.Provider, vl.ResourceId);
                 if (expr != null)

Modified: sandbox/maestro-3.0/Maestro.ResourceValidation/FeatureSourceValidator.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.ResourceValidation/FeatureSourceValidator.cs	2010-10-11 07:19:07 UTC (rev 5268)
+++ sandbox/maestro-3.0/Maestro.ResourceValidation/FeatureSourceValidator.cs	2010-10-11 15:31:19 UTC (rev 5269)
@@ -37,7 +37,7 @@
 
             List<ValidationIssue> issues = new List<ValidationIssue>();
 
-            FeatureSourceType feature = (FeatureSourceType)resource;
+            IFeatureSource feature = (IFeatureSource)resource;
             //Note: Must be saved!
             string s = feature.CurrentConnection.FeatureService.TestConnection(feature.ResourceID);
             if (s.Trim().ToUpper() != true.ToString().ToUpper())

Modified: sandbox/maestro-3.0/Maestro.ResourceValidation/MapDefinitionValidator.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.ResourceValidation/MapDefinitionValidator.cs	2010-10-11 07:19:07 UTC (rev 5268)
+++ sandbox/maestro-3.0/Maestro.ResourceValidation/MapDefinitionValidator.cs	2010-10-11 15:31:19 UTC (rev 5269)
@@ -95,7 +95,7 @@
                         {
                             try
                             {
-                                FeatureSourceType fs = (FeatureSourceType)layer.CurrentConnection.ResourceService.GetResource(vl.ResourceId);
+                                IFeatureSource fs = (IFeatureSource)layer.CurrentConnection.ResourceService.GetResource(vl.ResourceId);
                                 //The layer recurses on the FeatureSource
                                 //issues.AddRange(Validation.Validate(fs, true));
 

Modified: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Commands/ExecuteLoadProcedure.cs
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Commands/ExecuteLoadProcedure.cs	2010-10-11 07:19:07 UTC (rev 5268)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Commands/ExecuteLoadProcedure.cs	2010-10-11 15:31:19 UTC (rev 5269)
@@ -266,7 +266,7 @@
                             // 4. If no spatial contexts are detected, assign a default one from the load procedure and save the modified feature source.
 
                             //Step 1: Create feature source document
-                            FeatureSourceType fs = ObjectFactory.CreateFeatureSource(this.Parent, "OSGeo.SHP", "DefaultFileLocation=%MG_DATA_FILE_PATH%" + dataName);
+                            var fs = ObjectFactory.CreateFeatureSource(this.Parent, "OSGeo.SHP", "DefaultFileLocation=%MG_DATA_FILE_PATH%" + dataName);
                             fs.ResourceID = fsId;
 
                             this.Parent.ResourceService.SaveResource(fs);
@@ -304,7 +304,7 @@
                                 if (spatialContexts.SpatialContext.Count == 0 && !string.IsNullOrEmpty(shpl.CoordinateSystem))
                                 {
                                     //Register the default CS from the load procedure
-                                    fs.SupplementalSpatialContextInfo.Add(new SpatialContextType()
+                                    fs.AddSpatialContextOverride(new SpatialContextType()
                                     {
                                         Name = "Default",
                                         CoordinateSystem = shpl.CoordinateSystem
@@ -504,7 +504,7 @@
                             // 4. If no spatial contexts are detected, assign a default one from the load procedure and save the modified feature source.
 
                             //Step 1: Create feature source document
-                            FeatureSourceType fs = ObjectFactory.CreateFeatureSource(this.Parent, "OSGeo.SDF", "File=%MG_DATA_FILE_PATH%" + dataName);
+                            var fs = ObjectFactory.CreateFeatureSource(this.Parent, "OSGeo.SDF", "File=%MG_DATA_FILE_PATH%" + dataName);
                             fs.ResourceID = fsId;
 
                             this.Parent.ResourceService.SaveResource(fs);
@@ -531,7 +531,7 @@
                                 if (spatialContexts.SpatialContext.Count == 0 && !string.IsNullOrEmpty(sdfl.CoordinateSystem))
                                 {
                                     //Register the default CS from the load procedure
-                                    fs.SupplementalSpatialContextInfo.Add(new SpatialContextType()
+                                    fs.AddSpatialContextOverride(new SpatialContextType()
                                     {
                                         Name = "Default",
                                         CoordinateSystem = sdfl.CoordinateSystem

Modified: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/OSGeo.MapGuide.MaestroAPI.csproj
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/OSGeo.MapGuide.MaestroAPI.csproj	2010-10-11 07:19:07 UTC (rev 5268)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/OSGeo.MapGuide.MaestroAPI.csproj	2010-10-11 15:31:19 UTC (rev 5269)
@@ -189,6 +189,7 @@
     <Compile Include="Mapping\RuntimeMapBase.cs" />
     <Compile Include="ObjectModels\ApplicationDefinition.cs" />
     <Compile Include="ObjectModels\DrawingSource.cs" />
+    <Compile Include="ObjectModels\FeatureSourceInterfaces.cs" />
     <Compile Include="ObjectModels\GridLayerDefinitionImpl.cs" />
     <Compile Include="ObjectModels\IDynamicInvokable.cs" />
     <Compile Include="ObjectModels\Envelope.cs" />

Modified: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ObjectModels/FeatureSource.cs
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ObjectModels/FeatureSource.cs	2010-10-11 07:19:07 UTC (rev 5268)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ObjectModels/FeatureSource.cs	2010-10-11 15:31:19 UTC (rev 5269)
@@ -27,7 +27,7 @@
 
 namespace OSGeo.MapGuide.ObjectModels.FeatureSource
 {
-    partial class FeatureSourceType : IResource
+    partial class FeatureSourceType : IFeatureSource
     {
         internal FeatureSourceType() { }
 
@@ -256,69 +256,162 @@
             }
         }
 
-        /// <summary>
-        /// Convenience method to return the description of this feature source
-        /// </summary>
-        /// <returns></returns>
-        public FeatureSourceDescription Describe()
+        IEnumerable<ISpatialContextInfo> IFeatureSource.SupplementalSpatialContextInfo
         {
-            return this.CurrentConnection.FeatureService.DescribeFeatureSource(this.ResourceID);
+            get
+            {
+                foreach (var sc in this.SupplementalSpatialContextInfo)
+                {
+                    yield return sc;
+                }
+            }
         }
 
-        /// <summary>
-        /// Convenience method to retrieve the spatial context information of this feature source
-        /// </summary>
-        /// <returns></returns>
-        public OSGeo.MapGuide.ObjectModels.Common.FdoSpatialContextList GetSpatialInfo(bool activeOnly)
+        void IFeatureSource.AddSpatialContextOverride(ISpatialContextInfo sc)
         {
-            return this.CurrentConnection.FeatureService.GetSpatialContextInfo(this.ResourceID, activeOnly);
+            var sp = sc as SpatialContextType;
+            if (sp != null)
+                this.SupplementalSpatialContextInfo.Add(sp);
         }
 
-        /// <summary>
-        /// Convenience methods to get the identity properties of a given feature class (name)
-        /// </summary>
-        /// <param name="className"></param>
-        /// <returns></returns>
-        public string[] GetIdentityProperties(string className)
+        void IFeatureSource.RemoveSpatialContextOverride(ISpatialContextInfo sc)
         {
-            try
+            var sp = sc as SpatialContextType;
+            if (sp != null)
+                this.SupplementalSpatialContextInfo.Remove(sp);
+        }
+
+        IEnumerable<IFeatureSourceExtension> IFeatureSource.Extension
+        {
+            get
             {
-                return this.CurrentConnection.FeatureService.GetIdentityProperties(this.ResourceID, className);
+                foreach (var ext in this.Extension)
+                {
+                    yield return ext;
+                }
             }
-            catch (Exception ex)
+        }
+
+        void IFeatureSource.AddExtension(IFeatureSourceExtension ext)
+        {
+            var e = ext as FeatureSourceTypeExtension;
+            if (e != null)
             {
-                //MgClassNotFoundException is thrown for classes w/ no identity properties
-                //when the correct server response should be an empty array
-                if (ex.Message.IndexOf("MgClassNotFoundException") >= 0)
+                this.Extension.Add(e);
+            }
+        }
+
+        void IFeatureSource.RemoveExtension(IFeatureSourceExtension ext)
+        {
+            var e = ext as FeatureSourceTypeExtension;
+            if (e != null)
+            {
+                this.Extension.Remove(e);
+            }
+        }
+    }
+
+    partial class SpatialContextType : ISpatialContextInfo { }
+
+    partial class FeatureSourceTypeExtension : IFeatureSourceExtension
+    {
+        IEnumerable<ICalculatedProperty> IFeatureSourceExtension.CalculatedProperty
+        {
+            get 
+            {
+                foreach (var calc in this.CalculatedProperty)
                 {
-                    return new string[0];
+                    yield return calc;
                 }
-                else
+            }
+        }
+
+        void IFeatureSourceExtension.AddCalculatedProperty(ICalculatedProperty prop)
+        {
+            var calc = prop as CalculatedPropertyType;
+            if (calc != null)
+                this.CalculatedProperty.Add(calc);
+        }
+
+        void IFeatureSourceExtension.RemoveCalculatedProperty(ICalculatedProperty prop)
+        {
+            var calc = prop as CalculatedPropertyType;
+            if (calc != null)
+                this.CalculatedProperty.Remove(calc);
+        }
+
+        IEnumerable<IAttributeRelation> IFeatureSourceExtension.AttributeRelate
+        {
+            get 
+            {
+                foreach (var rel in this.AttributeRelate)
                 {
-                    throw;
+                    yield return rel;
                 }
             }
         }
 
-        /// <summary>
-        /// Convenience method to get the spatial extents of a given feature class
-        /// </summary>
-        /// <param name="className"></param>
-        /// <param name="geomProperty"></param>
-        /// <returns></returns>
-        public Envelope GetSpatialExtent(string className, string geomProperty)
+        void IFeatureSourceExtension.AddRelation(IAttributeRelation relate)
         {
-            return this.CurrentConnection.FeatureService.GetSpatialExtent(this.ResourceID, className, geomProperty);
+            var rel = relate as AttributeRelateType;
+            if (rel != null)
+                this.AttributeRelate.Add(rel);
         }
 
-        /// <summary>
-        /// Convenience method to get the feature class definition
-        /// </summary>
-        /// <param name="qualifiedName"></param>
-        /// <returns></returns>
-        public FeatureSourceDescription.FeatureSourceSchema GetClass(string qualifiedName)
+        void IFeatureSourceExtension.RemoveRelation(IAttributeRelation relate)
         {
-            return this.CurrentConnection.FeatureService.GetFeatureSourceSchema(this.ResourceID, qualifiedName);
+            var rel = relate as AttributeRelateType;
+            if (rel != null)
+                this.AttributeRelate.Remove(rel);
         }
     }
+
+    partial class CalculatedPropertyType : ICalculatedProperty { }
+
+    partial class AttributeRelateType : IAttributeRelation
+    {
+        bool? IAttributeRelation.ForceOneToOne
+        {
+            get
+            {
+                throw new NotImplementedException();
+            }
+            set
+            {
+                throw new NotImplementedException();
+            }
+        }
+
+        void IAttributeRelation.RemoveAllRelateProperties()
+        {
+            this.RelateProperty.Clear();
+        }
+
+        IEnumerable<IRelateProperty> IAttributeRelation.RelateProperty
+        {
+            get 
+            {
+                foreach (var rel in this.RelateProperty)
+                {
+                    yield return rel;
+                }
+            }
+        }
+
+        void IAttributeRelation.AddRelateProperty(IRelateProperty prop)
+        {
+            var rel = prop as RelatePropertyType;
+            if (rel != null)
+                this.RelateProperty.Add(rel);
+        }
+
+        void IAttributeRelation.RemoveRelateProperty(IRelateProperty prop)
+        {
+            var rel = prop as RelatePropertyType;
+            if (rel != null)
+                this.RelateProperty.Remove(rel);
+        }
+    }
+
+    partial class RelatePropertyType : IRelateProperty { }
 }

Added: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ObjectModels/FeatureSourceInterfaces.cs
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ObjectModels/FeatureSourceInterfaces.cs	                        (rev 0)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ObjectModels/FeatureSourceInterfaces.cs	2010-10-11 15:31:19 UTC (rev 5269)
@@ -0,0 +1,278 @@
+#region Disclaimer / License
+// Copyright (C) 2010, Jackie Ng
+// http://trac.osgeo.org/mapguide/wiki/maestro, jumpinjackie at gmail.com
+// 
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// 
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+// 
+#endregion
+using System;
+using System.Collections.Generic;
+using System.Text;
+using OSGeo.MapGuide.MaestroAPI.Resource;
+using OSGeo.MapGuide.ObjectModels.Common;
+using OSGeo.MapGuide.MaestroAPI;
+using System.ComponentModel;
+
+namespace OSGeo.MapGuide.ObjectModels.FeatureSource
+{
+    public interface IFeatureSource : IResource
+    {
+        string Provider { get; set; }
+
+        string GetConnectionProperty(string name);
+
+        void SetConnectionProperty(string name, string value);
+
+        string ConnectionString { get; set; }
+
+        /// <summary>
+        /// Gets the name of the embedded data resource. Can only be called if <see cref="UsesEmbeddedDataFiles"/> returns true.
+        /// </summary>
+        /// <returns></returns>
+        /// <exception cref="InvalidOperationException">If <see cref="UsesEmbeddedDataFiles"/> is false</exception>
+        string GetEmbeddedDataName();
+
+        /// <summary>
+        /// Gets the name of the alias. Can only be called if <see cref="UsesAliasedDataFiles"/> returns true
+        /// </summary>
+        /// <returns></returns>
+        /// <exception cref="InvalidOperationException">If <see cref="UsesAliasedDataFiles"/> is false </exception>
+        string GetAliasName();
+
+        /// <summary>
+        /// Gets the name of the aliased file. Can only be called if <see cref="UsesAliasedDataFiles"/> returns true. An
+        /// empty string is returned if it is a directory (ie. no file name was found)
+        /// </summary>
+        /// <returns></returns>
+        /// <exception cref="InvalidOperationException">If <see cref="UsesAliasedDataFiles"/> is false</exception>
+        string GetAliasedFileName();
+
+        bool UsesEmbeddedDataFiles{ get; }
+
+        bool UsesAliasedDataFiles { get; }
+
+        IEnumerable<ISpatialContextInfo> SupplementalSpatialContextInfo { get; }
+
+        void AddSpatialContextOverride(ISpatialContextInfo sc);
+
+        void RemoveSpatialContextOverride(ISpatialContextInfo sc);
+
+        IEnumerable<IFeatureSourceExtension> Extension { get; }
+
+        void AddExtension(IFeatureSourceExtension ext);
+
+        void RemoveExtension(IFeatureSourceExtension ext);
+    }
+
+    public interface ISpatialContextInfo
+    {
+        string Name { get; set; }
+
+        string CoordinateSystem { get; set; }
+    }
+
+    public interface IFeatureSourceExtension : INotifyPropertyChanged
+    {
+        string Name { get; set; }
+
+        string FeatureClass { get; set; }
+
+        IEnumerable<ICalculatedProperty> CalculatedProperty { get; }
+
+        void AddCalculatedProperty(ICalculatedProperty prop);
+
+        void RemoveCalculatedProperty(ICalculatedProperty prop);
+
+        IEnumerable<IAttributeRelation> AttributeRelate { get; }
+
+        void AddRelation(IAttributeRelation relate);
+
+        void RemoveRelation(IAttributeRelation relate);
+    }
+
+    public interface ICalculatedProperty : INotifyPropertyChanged
+    {
+        string Name { get; set; }
+
+        string Expression { get; set; }
+    }
+
+    [System.SerializableAttribute()]
+    public enum RelateTypeEnum
+    {
+
+        /// <remarks/>
+        LeftOuter,
+
+        /// <remarks/>
+        RightOuter,
+
+        /// <remarks/>
+        Inner,
+
+        /// <remarks/>
+        Association,
+    }
+
+    public interface IAttributeRelation : INotifyPropertyChanged
+    {
+        /// <summary>
+        /// Gets or sets whether to force 1:1 cardinality
+        /// </summary>
+        bool? ForceOneToOne { get; set; }
+
+        /// <summary>
+        /// Gets the type of join
+        /// </summary>
+        RelateTypeEnum RelateType { get; set; }
+
+        /// <summary>
+        /// Gets or sets the feature source id containing the feature class to extend
+        /// </summary>
+        string ResourceId { get; set; }
+
+        /// <summary>
+        /// Gets or sets the name of the feature class to extend
+        /// </summary>
+        string AttributeClass { get; set; }
+
+        /// <summary>
+        /// Gets or sets the name of the join
+        /// </summary>
+        string Name { get; set; }
+
+        /// <summary>
+        /// Gets or sets the prefix that prevents a naming collision on both sides of the join
+        /// </summary>
+        string AttributeNameDelimiter { get; set; }
+
+        IEnumerable<IRelateProperty> RelateProperty { get; }
+
+        void AddRelateProperty(IRelateProperty prop);
+
+        void RemoveRelateProperty(IRelateProperty prop);
+
+        void RemoveAllRelateProperties();
+    }
+
+    public interface IRelateProperty
+    {
+        string FeatureClassProperty { get; set; }
+
+        string AttributeClassProperty { get; set; }
+    }
+
+    public static class FeatureSourceExtensions
+    {
+        /// <summary>
+        /// Convenience method to return the description of this feature source
+        /// </summary>
+        /// <returns></returns>
+        public static FeatureSourceDescription Describe(this IFeatureSource fs)
+        {
+            Check.NotNull(fs, "fs");
+            return fs.CurrentConnection.FeatureService.DescribeFeatureSource(fs.ResourceID);
+        }
+
+        /// <summary>
+        /// Convenience method to retrieve the spatial context information of this feature source
+        /// </summary>
+        /// <returns></returns>
+        public static OSGeo.MapGuide.ObjectModels.Common.FdoSpatialContextList GetSpatialInfo(this IFeatureSource fs, bool activeOnly)
+        {
+            Check.NotNull(fs, "fs");
+            return fs.CurrentConnection.FeatureService.GetSpatialContextInfo(fs.ResourceID, activeOnly);
+        }
+
+        /// <summary>
+        /// Convenience methods to get the identity properties of a given feature class (name)
+        /// </summary>
+        /// <param name="className"></param>
+        /// <returns></returns>
+        public static string[] GetIdentityProperties(this IFeatureSource fs, string className)
+        {
+            Check.NotNull(fs, "fs");
+            try
+            {
+                return fs.CurrentConnection.FeatureService.GetIdentityProperties(fs.ResourceID, className);
+            }
+            catch (Exception ex)
+            {
+                //MgClassNotFoundException is thrown for classes w/ no identity properties
+                //when the correct server response should be an empty array
+                if (ex.Message.IndexOf("MgClassNotFoundException") >= 0)
+                {
+                    return new string[0];
+                }
+                else
+                {
+                    throw;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Convenience method to get the spatial extents of a given feature class
+        /// </summary>
+        /// <param name="className"></param>
+        /// <param name="geomProperty"></param>
+        /// <returns></returns>
+        public static Envelope GetSpatialExtent(this IFeatureSource fs, string className, string geomProperty)
+        {
+            Check.NotNull(fs, "fs");
+            return fs.CurrentConnection.FeatureService.GetSpatialExtent(fs.ResourceID, className, geomProperty);
+        }
+
+        /// <summary>
+        /// Convenience method to get the feature class definition
+        /// </summary>
+        /// <param name="qualifiedName"></param>
+        /// <returns></returns>
+        public static FeatureSourceDescription.FeatureSourceSchema GetClass(this IFeatureSource fs, string qualifiedName)
+        {
+            Check.NotNull(fs, "fs");
+            return fs.CurrentConnection.FeatureService.GetFeatureSourceSchema(fs.ResourceID, qualifiedName);
+        }
+
+        /// <summary>
+        /// Adds a spatial context override
+        /// </summary>
+        /// <param name="fs"></param>
+        /// <param name="name"></param>
+        /// <param name="coordSys"></param>
+        public static void AddSpatialContextOverride(this IFeatureSource fs, string name, string coordSys)
+        {
+            Check.NotNull(fs, "fs");
+            fs.AddSpatialContextOverride(new SpatialContextType() { Name = name, CoordinateSystem = coordSys });
+        }
+
+        /// <summary>
+        /// Tests the connection settings in this feature source
+        /// </summary>
+        /// <param name="fs"></param>
+        /// <returns></returns>
+        public static string TestConnection(this IFeatureSource fs)
+        {
+            Check.NotNull(fs, "fs");
+            return fs.CurrentConnection.FeatureService.TestConnection(fs.ResourceID);
+        }
+
+        public static void AddRelateProperty(this IAttributeRelation rel, string primary, string secondary)
+        {
+            Check.NotNull(rel, "rel");
+            rel.AddRelateProperty(new RelatePropertyType() { FeatureClassProperty = primary, AttributeClassProperty = secondary });
+        }
+    }
+}

Modified: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ObjectModels/LayerFactory.cs
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ObjectModels/LayerFactory.cs	2010-10-11 07:19:07 UTC (rev 5268)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ObjectModels/LayerFactory.cs	2010-10-11 15:31:19 UTC (rev 5269)
@@ -23,6 +23,8 @@
 using OSGeo.MapGuide.ObjectModels.LayerDefinition;
 using OSGeo.MapGuide.MaestroAPI;
 using System.Drawing;
+using OSGeo.MapGuide.MaestroAPI.Resource;
+using System.IO;
 
 #if LDF_110
 namespace OSGeo.MapGuide.ObjectModels.LayerDefinition_1_1_0
@@ -34,6 +36,28 @@
 namespace OSGeo.MapGuide.ObjectModels.LayerDefinition_1_0_0
 #endif
 {
+    /// <summary>
+    /// A publically accessible entry point primarily used for registration with the <see cref="ObjectFactory"/> and
+    /// <see cref="ResourceTypeRegistry"/> classes
+    /// </summary>
+    public static class LdfEntryPoint
+    {
+        public static ILayerDefinition CreateDefault(LayerType type)
+        {
+            return LayerDefinition.CreateDefault(type);
+        }
+
+        public static IResource Deserialize(string xml)
+        {
+            return LayerDefinition.Deserialize(xml);
+        }
+
+        public static Stream Serialize(IResource res)
+        {
+            return res.SerializeToStream();
+        }
+    }
+
     partial class LayerDefinition : ILayerElementFactory
     {
         public static ILayerDefinition CreateDefault(LayerType type)

Modified: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ObjectModels/ObjectFactory.cs
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ObjectModels/ObjectFactory.cs	2010-10-11 07:19:07 UTC (rev 5268)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ObjectModels/ObjectFactory.cs	2010-10-11 15:31:19 UTC (rev 5269)
@@ -43,6 +43,15 @@
     /// sensible default values. This is recommended over creating the objects directly
     /// as this ensures that there are no null child properties where the XML schema forbids
     /// it.
+    /// 
+    /// By default this class will only create v1.0.0 of any specified top-level resource. In order to be able to create
+    /// newer versions, you need to register the appropriate methods that can create resources of this version:
+    /// 
+    ///  - <see cref="RegisterLayerFactoryMethod"/> for Layer Definitions
+    ///  
+    /// This registration needs to be done as part of your application's startup/initialization phase.
+    /// 
+    /// In the context of Maestro, this registration is automatically done as part of the addin's startup process
     /// </summary>
     public static class ObjectFactory
     {
@@ -56,6 +65,14 @@
                 new LayerCreatorFunc(OSGeo.MapGuide.ObjectModels.LayerDefinition_1_0_0.LayerDefinition.CreateDefault));
         }
 
+        public static void RegisterLayerFactoryMethod(Version ver, LayerCreatorFunc method)
+        {
+            if (_layerFactories.ContainsKey(ver))
+                throw new ArgumentException("Factory method already registered for version: " + ver); //LOCALIZEME
+
+            _layerFactories[ver] = method;
+        }
+
         public static ILayerDefinition CreateDefaultLayer(IServerConnection owner, LayerType type, Version version)
         {
             Check.NotNull(owner, "owner");
@@ -76,7 +93,7 @@
             return new DrawingSource() { CurrentConnection = owner };
         }
 
-        public static FeatureSourceType CreateFeatureSource(IServerConnection owner, string provider)
+        public static IFeatureSource CreateFeatureSource(IServerConnection owner, string provider)
         {
             Check.NotNull(owner, "owner");
 
@@ -87,7 +104,7 @@
             };
         }
 
-        public static FeatureSourceType CreateFeatureSource(IServerConnection owner, string provider, string connectionString)
+        public static IFeatureSource CreateFeatureSource(IServerConnection owner, string provider, string connectionString)
         {
             var fs = CreateFeatureSource(owner, provider);
             fs.ConnectionString = connectionString;
@@ -823,5 +840,24 @@
                 TargetViewer = TargetViewerType.All
             };
         }
+
+        public static IFeatureSourceExtension CreateFeatureSourceExtension()
+        {
+            return new FeatureSourceTypeExtension()
+            {
+                CalculatedProperty = new System.ComponentModel.BindingList<CalculatedPropertyType>(),
+                AttributeRelate = new System.ComponentModel.BindingList<AttributeRelateType>()
+            };
+        }
+
+        public static ICalculatedProperty CreateCalculatedProperty()
+        {
+            return new CalculatedPropertyType();
+        }
+
+        public static IAttributeRelation CreateAttributeRelation()
+        {
+            return new AttributeRelateType() { RelateProperty = new System.ComponentModel.BindingList<RelatePropertyType>() };
+        }
     }
 }

Modified: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/BaseLayerDefinitionValidator.cs
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/BaseLayerDefinitionValidator.cs	2010-10-11 07:19:07 UTC (rev 5268)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/BaseLayerDefinitionValidator.cs	2010-10-11 15:31:19 UTC (rev 5269)
@@ -25,6 +25,11 @@
 
 namespace OSGeo.MapGuide.MaestroAPI.Resource
 {
+    /// <summary>
+    /// A base layer definition validator class the provides the common validation logic. Because this is working against
+    /// the layer definition interfaces, this common logic can apply to all versions of the layer definition schema (that
+    /// implement these interfaces)
+    /// </summary>
     public abstract class BaseLayerDefinitionValidator : IResourceValidator
     {
         public virtual ValidationIssue[] Validate(IResource resource, bool recurse)

Modified: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/IResource.cs
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/IResource.cs	2010-10-11 07:19:07 UTC (rev 5268)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/IResource.cs	2010-10-11 15:31:19 UTC (rev 5269)
@@ -74,6 +74,19 @@
             }
         }
 
+        public static void CopyResourceDataTo(this IResource source, string targetID)
+        {
+            Check.NotNull(source, "source");
+            Check.NotEmpty(targetID, "targetID");
+
+            foreach (var res in source.EnumerateResourceData())
+            {
+                var data = source.GetResourceData(res.Name);
+                data.Position = 0L; //Reset
+                source.CurrentConnection.ResourceService.SetResourceData(targetID, res.Name, res.Type, data);
+            }
+        }
+
         /// <summary>
         /// Convenience method for enumerating resource data of this resource
         /// </summary>

Modified: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/ValidationResultSet.cs
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/ValidationResultSet.cs	2010-10-11 07:19:07 UTC (rev 5268)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/ValidationResultSet.cs	2010-10-11 15:31:19 UTC (rev 5269)
@@ -55,7 +55,9 @@
         {
             Check.NotEmpty(resourceId, "resourceId");
 
-            return _issues[resourceId].Keys;
+            if (_issues.ContainsKey(resourceId))
+                return _issues[resourceId].Keys;
+            return new List<ValidationIssue>();
         }
 
         public ICollection<ValidationIssue> GetIssuesForResource(string resourceId, ValidationStatus statType)

Modified: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ResourceTypeRegistry.cs
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ResourceTypeRegistry.cs	2010-10-11 07:19:07 UTC (rev 5268)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ResourceTypeRegistry.cs	2010-10-11 15:31:19 UTC (rev 5269)
@@ -174,6 +174,11 @@
             _serializers.Add(desc, serializer);
         }
 
+        public static void RegisterResource(ResourceTypeDescriptor desc, ResourceSerializationCallback serializeMethod, ResourceDeserializationCallback deserializeMethod)
+        {
+            RegisterResource(desc, new ResourceSerializer() { Deserialize = deserializeMethod, Serialize = serializeMethod });
+        }
+
         internal static void Init() 
         { 
             //does nothing, it's just for kicking the static constructor into gear 

Modified: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ServerConnectionBase.cs
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ServerConnectionBase.cs	2010-10-11 07:19:07 UTC (rev 5268)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ServerConnectionBase.cs	2010-10-11 15:31:19 UTC (rev 5269)
@@ -373,18 +373,7 @@
 		/// <returns>The provider name without version numbers</returns>
 		virtual public string RemoveVersionFromProviderName(string providername)
 		{
-			double x;
-			string[] parts = providername.Split('.');
-			for(int i = parts.Length - 1; i >= 0; i--)
-			{
-				if (!double.TryParse(parts[i], System.Globalization.NumberStyles.Integer, null, out x))
-				{
-					if (i != 0)
-						return string.Join(".", parts, 0, i + 1);
-					break;
-				}
-			}
-			return providername;
+            return Utility.StripVersionFromProviderName(providername);
 		}
 
 		/// <summary>

Modified: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Utility.cs
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Utility.cs	2010-10-11 07:19:07 UTC (rev 5268)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Utility.cs	2010-10-11 15:31:19 UTC (rev 5269)
@@ -32,6 +32,22 @@
 		//Americans NEVER obey nationalization when outputting decimal values, so the rest of the world always have to work around their bugs :(
 		private static System.Globalization.CultureInfo m_enCI = new System.Globalization.CultureInfo("en-US");
 
+        public static string StripVersionFromProviderName(string providername)
+        {
+            double x;
+            string[] parts = providername.Split('.');
+            for (int i = parts.Length - 1; i >= 0; i--)
+            {
+                if (!double.TryParse(parts[i], System.Globalization.NumberStyles.Integer, null, out x))
+                {
+                    if (i != 0)
+                        return string.Join(".", parts, 0, i + 1);
+                    break;
+                }
+            }
+            return providername;
+        }
+
 		/// <summary>
 		/// Parses a color in HTML notation (ea. #ffaabbff)
 		/// </summary>



More information about the mapguide-commits mailing list