[mapguide-commits] r5240 - in sandbox/maestro-3.0: ExtendedModels/LayerDefinition-1.1.0 ExtendedModels/LayerDefinition-1.2.0 ExtendedModels/LayerDefinition-1.3.0 Maestro.Base Maestro.Base/Editor Maestro.Base/Properties Maestro.Base/Templates Maestro.ResourceValidation MaestroAPITests OSGeo.MapGuide.MaestroAPI/ObjectModels OSGeo.MapGuide.MaestroAPI/Resource OSGeo.MapGuide.MaestroAPI.Http

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Mon Oct 4 07:44:04 EDT 2010


Author: jng
Date: 2010-10-04 11:44:03 +0000 (Mon, 04 Oct 2010)
New Revision: 5240

Added:
   sandbox/maestro-3.0/Maestro.Base/Editor/ResourcePreviewEngine.cs
Modified:
   sandbox/maestro-3.0/ExtendedModels/LayerDefinition-1.1.0/LayerDefinition.cs
   sandbox/maestro-3.0/ExtendedModels/LayerDefinition-1.2.0/LayerDefinition.cs
   sandbox/maestro-3.0/ExtendedModels/LayerDefinition-1.3.0/LayerDefinition.cs
   sandbox/maestro-3.0/Maestro.Base/Editor/EditorContentBase.cs
   sandbox/maestro-3.0/Maestro.Base/Editor/FeatureSourceEditor.cs
   sandbox/maestro-3.0/Maestro.Base/Editor/IEditorViewContent.cs
   sandbox/maestro-3.0/Maestro.Base/Editor/LayerDefinitionEditor.cs
   sandbox/maestro-3.0/Maestro.Base/Editor/WebLayoutEditor.cs
   sandbox/maestro-3.0/Maestro.Base/Editor/XmlEditor.cs
   sandbox/maestro-3.0/Maestro.Base/Maestro.Base.csproj
   sandbox/maestro-3.0/Maestro.Base/Properties/Resources.Designer.cs
   sandbox/maestro-3.0/Maestro.Base/Properties/Resources.resx
   sandbox/maestro-3.0/Maestro.Base/Templates/MapDefinitionItemTemplate.cs
   sandbox/maestro-3.0/Maestro.ResourceValidation/FeatureSourceValidator.cs
   sandbox/maestro-3.0/Maestro.ResourceValidation/MapDefinitionValidator.cs
   sandbox/maestro-3.0/MaestroAPITests/ResourceTests.cs
   sandbox/maestro-3.0/MaestroAPITests/ValidationTests.cs
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI.Http/HttpServerConnection.cs
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ObjectModels/ApplicationDefinition.cs
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ObjectModels/FeatureSource.cs
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ObjectModels/LayerDefinition.cs
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ObjectModels/MapDefinition.cs
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ObjectModels/ObjectFactory.cs
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/IResource.cs
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/ValidationResultSet.cs
Log:
This submission includes the following changes:
 - Add AJAX viewer previewing support (in specialized editor and XML editor) for:
   - Feature Sources 
   - Layer Definition
   - Map Definition
   - Web Layout
 - Update ValidationResultSet to allow querying by issue type (info, warning, error)
 - Extend IEditorViewContent to support cancellation of view closing
 - Fix some ObjectFactory methods which would create incomplete objects when saved as XML
 - Update pre-save logic to be as follows:
   - Validate edited resources for errors (not info or warnings)
   - If errors found show them in Validation dialog and cancel save

Modified: sandbox/maestro-3.0/ExtendedModels/LayerDefinition-1.1.0/LayerDefinition.cs
===================================================================
--- sandbox/maestro-3.0/ExtendedModels/LayerDefinition-1.1.0/LayerDefinition.cs	2010-10-04 05:51:06 UTC (rev 5239)
+++ sandbox/maestro-3.0/ExtendedModels/LayerDefinition-1.1.0/LayerDefinition.cs	2010-10-04 11:44:03 UTC (rev 5240)
@@ -98,6 +98,32 @@
             get { return this.ResourceId; }
             set { this.ResourceId = value; }
         }
+
+        [XmlIgnore]
+        string Ldf.IRasterLayerDefinition.FullQualifiedClassName
+        {
+            get
+            {
+                return this.FeatureName;
+            }
+            set
+            {
+                this.FeatureName = value;
+            }
+        }
+
+        [XmlIgnore]
+        string Ldf.IRasterLayerDefinition.GeometryProperty
+        {
+            get
+            {
+                return this.Geometry;
+            }
+            set
+            {
+                this.Geometry = value;
+            }
+        }
     }
 
     partial class DrawingLayerDefinitionType : Ldf.IDrawingLayerDefinition

Modified: sandbox/maestro-3.0/ExtendedModels/LayerDefinition-1.2.0/LayerDefinition.cs
===================================================================
--- sandbox/maestro-3.0/ExtendedModels/LayerDefinition-1.2.0/LayerDefinition.cs	2010-10-04 05:51:06 UTC (rev 5239)
+++ sandbox/maestro-3.0/ExtendedModels/LayerDefinition-1.2.0/LayerDefinition.cs	2010-10-04 11:44:03 UTC (rev 5240)
@@ -98,6 +98,32 @@
             get { return this.ResourceId; }
             set { this.ResourceId = value; }
         }
+
+        [XmlIgnore]
+        string Ldf.IRasterLayerDefinition.FullQualifiedClassName
+        {
+            get
+            {
+                return this.FeatureName;
+            }
+            set
+            {
+                this.FeatureName = value;
+            }
+        }
+
+        [XmlIgnore]
+        string Ldf.IRasterLayerDefinition.GeometryProperty
+        {
+            get
+            {
+                return this.Geometry;
+            }
+            set
+            {
+                this.Geometry = value;
+            }
+        }
     }
 
     partial class DrawingLayerDefinitionType : Ldf.IDrawingLayerDefinition

Modified: sandbox/maestro-3.0/ExtendedModels/LayerDefinition-1.3.0/LayerDefinition.cs
===================================================================
--- sandbox/maestro-3.0/ExtendedModels/LayerDefinition-1.3.0/LayerDefinition.cs	2010-10-04 05:51:06 UTC (rev 5239)
+++ sandbox/maestro-3.0/ExtendedModels/LayerDefinition-1.3.0/LayerDefinition.cs	2010-10-04 11:44:03 UTC (rev 5240)
@@ -98,6 +98,32 @@
             get { return this.ResourceId; }
             set { this.ResourceId = value; }
         }
+
+        [XmlIgnore]
+        string Ldf.IRasterLayerDefinition.FullQualifiedClassName
+        {
+            get
+            {
+                return this.FeatureName;
+            }
+            set
+            {
+                this.FeatureName = value;
+            }
+        }
+
+        [XmlIgnore]
+        string Ldf.IRasterLayerDefinition.GeometryProperty
+        {
+            get
+            {
+                return this.Geometry;
+            }
+            set
+            {
+                this.Geometry = value;
+            }
+        }
     }
 
     partial class DrawingLayerDefinitionType : Ldf.IDrawingLayerDefinition

Modified: sandbox/maestro-3.0/Maestro.Base/Editor/EditorContentBase.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Editor/EditorContentBase.cs	2010-10-04 05:51:06 UTC (rev 5239)
+++ sandbox/maestro-3.0/Maestro.Base/Editor/EditorContentBase.cs	2010-10-04 11:44:03 UTC (rev 5240)
@@ -49,11 +49,25 @@
             }
         }
 
-        protected virtual string GetXmlContent()
+        /// <summary>
+        /// Gets the XML content of the edited resource
+        /// </summary>
+        /// <returns></returns>
+        public virtual string GetXmlContent()
         {
             return this.Resource.Serialize();
         }
 
+        /// <summary>
+        /// Performs any pre-save validation logic. The base implementation performs
+        /// a <see cref="ResourceValidatorSet"/> validation (non-casccading) on the 
+        /// edited resource before attempting a save into the session repository 
+        /// (triggering any errors relating to invalid XML content). Override this
+        /// method if the base implementation just described does not cover your 
+        /// validation needs.
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
         protected virtual void OnBeforeSave(object sender, CancelEventArgs e) 
         {
             //We've been editing an in-memory model of the session copy
@@ -61,9 +75,19 @@
             //commits the changes back to the original resource
             try
             {
-                ValidateEditedResource();
-                _svc.UpdateResourceContent(GetXmlContent());
-                e.Cancel = false;
+                var errors = new List<ValidationIssue>(ValidateEditedResource()).ToArray();
+                if (errors.Length > 0)
+                {
+                    MessageService.ShowError(Properties.Resources.FixErrorsBeforeSaving);
+                    ValidationResultsDialog diag = new ValidationResultsDialog(this.Resource.ResourceID, errors);
+                    diag.ShowDialog(Workbench.Instance);
+                    e.Cancel = true;
+                }
+                else
+                {
+                    _svc.UpdateResourceContent(GetXmlContent());
+                    e.Cancel = false;
+                }
             }
             catch (Exception ex)
             {
@@ -73,10 +97,20 @@
         }
 
         /// <summary>
-        /// Performs any pre-save validation on the currently edited resource
+        /// Performs any pre-save validation on the currently edited resource, by default
+        /// this returns the results of a non-cascading <see cref="ResourceValidatorSet"/>
+        /// validation run. Override this if you have a custom method of validation.
         /// </summary>
-        protected virtual void ValidateEditedResource() { }
+        protected virtual ICollection<ValidationIssue> ValidateEditedResource() 
+        {
+            //Don't recurse as we only want to validate the current resource
+            var issues = ResourceValidatorSet.Validate(this.Resource, false);
+            var set = new ValidationResultSet(issues);
 
+            var errors = set.GetIssuesForResource(this.Resource.ResourceID, ValidationStatus.Error);
+            return errors;
+        }
+
         void OnSaved(object sender, EventArgs e)
         {
             UpdateTitle();
@@ -109,7 +143,8 @@
 
         /// <summary>
         /// Binds the specified resource to this control. This effectively initializes
-        /// all the fields in this control and sets up databinding on all fields.
+        /// all the fields in this control and sets up databinding on all fields. All
+        /// subclasses *must* override this method
         /// </summary>
         /// <param name="value"></param>
         protected virtual void Bind(IEditorService service) 
@@ -117,15 +152,6 @@
             throw new NotImplementedException();
         }
 
-        private static ResourceTypes[] PREVIEWABLE_RESOURCE_TYPES = new ResourceTypes[] 
-        {
-            ResourceTypes.FeatureSource,
-            ResourceTypes.ApplicationDefinition,
-            ResourceTypes.LayerDefinition,
-            ResourceTypes.MapDefinition,
-            ResourceTypes.WebLayout
-        };
-
         public virtual bool CanBePreviewed
         {
             get
@@ -134,7 +160,7 @@
                 if (res != null)
                 {
                     var rt = res.ResourceType;
-                    return Array.IndexOf(PREVIEWABLE_RESOURCE_TYPES, rt) >= 0 && res.CurrentConnection.Capabilities.SupportsResourcePreviews;
+                    return ResourcePreviewEngine.IsPreviewableType(rt) && res.CurrentConnection.Capabilities.SupportsResourcePreviews;                    
                 }
                 return false;
             }
@@ -178,7 +204,7 @@
 
         public virtual string SetupPreviewUrl(string mapguideRootUrl)
         {
-            throw new NotSupportedException();
+            return new ResourcePreviewEngine(mapguideRootUrl, this.EditorService).GeneratePreviewUrl(this.Resource);
         }
     }
 }

Modified: sandbox/maestro-3.0/Maestro.Base/Editor/FeatureSourceEditor.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Editor/FeatureSourceEditor.cs	2010-10-04 05:51:06 UTC (rev 5239)
+++ sandbox/maestro-3.0/Maestro.Base/Editor/FeatureSourceEditor.cs	2010-10-04 11:44:03 UTC (rev 5240)
@@ -46,18 +46,5 @@
             _res = _edsvc.GetEditedResource();
             fsEditorCtrl.Bind(service);
         }
-
-        public override string SetupPreviewUrl(string mapguideRootUrl)
-        {
-            string url = mapguideRootUrl;
-            if (!url.EndsWith("/"))
-                url += "/";
-
-            var resId = this.EditorService.GetEditedResource().ResourceID;
-            var sessionId = this.EditorService.SessionID;
-            url += "schemareport/describeschema.php?viewer=basic&resId=" + resId + "&sessionId=" + sessionId;
-
-            return url;
-        }
     }
 }

Modified: sandbox/maestro-3.0/Maestro.Base/Editor/IEditorViewContent.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Editor/IEditorViewContent.cs	2010-10-04 05:51:06 UTC (rev 5239)
+++ sandbox/maestro-3.0/Maestro.Base/Editor/IEditorViewContent.cs	2010-10-04 11:44:03 UTC (rev 5240)
@@ -39,6 +39,12 @@
         IResource Resource { get; }
 
         /// <summary>
+        /// Gets the XML content of the edited resource
+        /// </summary>
+        /// <returns></returns>
+        string GetXmlContent();
+
+        /// <summary>
         /// Indicates whether this current resource is a newly created resource
         /// </summary>
         bool IsNew { get; }

Modified: sandbox/maestro-3.0/Maestro.Base/Editor/LayerDefinitionEditor.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Editor/LayerDefinitionEditor.cs	2010-10-04 05:51:06 UTC (rev 5239)
+++ sandbox/maestro-3.0/Maestro.Base/Editor/LayerDefinitionEditor.cs	2010-10-04 11:44:03 UTC (rev 5240)
@@ -30,6 +30,8 @@
 using OSGeo.MapGuide.MaestroAPI.Resource;
 using Maestro.Editors;
 using ICSharpCode.Core;
+using OSGeo.MapGuide.MaestroAPI.ObjectModels;
+using Maestro.Base.UI.Preferences;
 
 namespace Maestro.Base.Editor
 {

Added: sandbox/maestro-3.0/Maestro.Base/Editor/ResourcePreviewEngine.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Editor/ResourcePreviewEngine.cs	                        (rev 0)
+++ sandbox/maestro-3.0/Maestro.Base/Editor/ResourcePreviewEngine.cs	2010-10-04 11:44:03 UTC (rev 5240)
@@ -0,0 +1,206 @@
+#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 Maestro.Editors;
+using OSGeo.MapGuide.ObjectModels.LayerDefinition;
+using OSGeo.MapGuide.MaestroAPI.ObjectModels;
+using OSGeo.MapGuide.MaestroAPI.Resource;
+using Maestro.Base.UI.Preferences;
+using ICSharpCode.Core;
+using OSGeo.MapGuide.ObjectModels.MapDefinition;
+using OSGeo.MapGuide.ObjectModels.WebLayout;
+using OSGeo.MapGuide.MaestroAPI;
+using OSGeo.MapGuide.ObjectModels.ApplicationDefinition;
+
+namespace Maestro.Base.Editor
+{
+    internal class ResourcePreviewEngine
+    {
+        private string _rootUrl;
+        private IEditorService _edSvc;
+
+        public ResourcePreviewEngine(string rootUrl, IEditorService edSvc)
+        {
+            _rootUrl = rootUrl;
+            _edSvc = edSvc;
+        }
+
+        private string GenerateFeatureSourcePreviewUrl(IResource res)
+        {
+            string url = _rootUrl;
+            if (!url.EndsWith("/"))
+                url += "/";
+
+            var resId = res.ResourceID;
+            var sessionId = _edSvc.SessionID;
+            url += "schemareport/describeschema.php?viewer=basic&resId=" + resId + "&sessionId=" + sessionId;
+
+            return url;
+        }
+
+        private string GenerateLayerPreviewUrl(IResource res)
+        {
+            string url = _rootUrl;
+            if (!url.EndsWith("/"))
+                url += "/";
+
+            var ldf = (ILayerDefinition)res;
+            var sessionId = _edSvc.SessionID;
+            var conn = res.CurrentConnection;
+
+            //Create temp map definition to house our current layer
+            var mdfId = "Session:" + sessionId + "//" + Guid.NewGuid() + ".MapDefinition";
+            var mdf = ObjectFactory.CreateMapDefinition(conn, "Preview Map", ldf.GetCoordinateSystemWkt(), ldf.GetSpatialExtent(true)); //LOCALIZEME
+
+            mdf.AddLayer(null, ResourceIdentifier.GetName(ldf.ResourceID), ldf.ResourceID);
+
+            conn.ResourceService.SaveResourceAs(mdf, mdfId);
+
+            if (PropertyService.Get(ConfigProperties.PreviewViewerType, "AJAX").Equals("AJAX"))
+            {
+                //Create temp web layout to house this map
+                var wl = ObjectFactory.CreateWebLayout(_edSvc.GetEditedResource().CurrentConnection, mdfId);
+                var resId = "Session:" + sessionId + "//" + Guid.NewGuid() + ".WebLayout";
+
+                conn.ResourceService.SaveResourceAs(wl, resId);
+                url += "mapviewerajax/?WEBLAYOUT=" + resId + "&SESSION=" + sessionId;
+            }
+            else
+            {
+                throw new NotImplementedException();
+                ////Create temp flex layout
+                //var appDef = ObjectFactory.CreatePreviewFlexLayout(conn);
+                //var resId = "Session:" + sessionId + "//" + Guid.NewGuid() + ".ApplicationDefinition";
+                //appDef.AddMapGroup("previewmap", true, mdfId);
+
+                //conn.ResourceService.SaveResourceAs(appDef, resId);
+                //url += "fusion/templates/mapguide/preview/index.html?Session=" + sessionId + "&ApplicationDefinition=" + resId;
+            }
+
+            return url;
+        }
+
+        private string GenerateMapPreviewUrl(IResource res)
+        {
+            string url = _rootUrl;
+            if (!url.EndsWith("/"))
+                url += "/";
+
+            var sessionId = _edSvc.SessionID;
+            var mdfId = "Session:" + sessionId + "//" + Guid.NewGuid() + ".MapDefinition";
+            var mdf = (MapDefinition)res;
+
+            var conn = mdf.CurrentConnection;
+            conn.ResourceService.SaveResourceAs(mdf, mdfId);
+
+            if (PropertyService.Get(ConfigProperties.PreviewViewerType, "AJAX").Equals("AJAX"))
+            {
+                //Create temp web layout to house this map
+                var wl = ObjectFactory.CreateWebLayout(_edSvc.GetEditedResource().CurrentConnection, mdfId);
+                var resId = "Session:" + sessionId + "//" + Guid.NewGuid() + ".WebLayout";
+
+                conn.ResourceService.SaveResourceAs(wl, resId);
+                url += "mapviewerajax/?WEBLAYOUT=" + resId + "&SESSION=" + sessionId;
+            }
+            else
+            {
+                throw new NotImplementedException();
+                ////Create temp flex layout
+                //var appDef = ObjectFactory.CreateFlexibleLayout(conn);
+                //var resId = "Session:" + sessionId + "//" + Guid.NewGuid() + ".ApplicationDefinition";
+                //appDef.AddMapGroup("previewmap", true, mdfId);
+
+                //conn.ResourceService.SaveResourceAs(appDef, resId);
+                //url += "fusion/templates/mapguide/preview/index.html?Session=" + sessionId + "&ApplicationDefinition=" + resId;
+            }
+
+            return url;
+        }
+
+        private string GenerateWebLayoutPreviewUrl(IResource res)
+        {
+            string url = _rootUrl;
+            if (!url.EndsWith("/"))
+                url += "/";
+
+            var sessionId = _edSvc.SessionID;
+            var resId = "Session:" + sessionId + "//" + Guid.NewGuid() + ".WebLayout";
+            var wl = (WebLayoutType)res;
+            var conn = wl.CurrentConnection;
+
+            conn.ResourceService.SaveResourceAs(wl, resId);
+            url += "mapviewerajax/?WEBLAYOUT=" + resId + "&SESSION=" + sessionId;
+
+            return url;
+        }
+
+        private string GenerateFlexLayoutPreviewUrl(IResource res)
+        {
+            string url = _rootUrl;
+            if (!url.EndsWith("/"))
+                url += "/";
+
+            //Create temp flex layout
+            var sessionId = _edSvc.SessionID;
+            var appDef = (ApplicationDefinitionType)res;
+            var conn = appDef.CurrentConnection;
+            var resId = "Session:" + sessionId + "//" + Guid.NewGuid() + ".ApplicationDefinition";
+            
+            conn.ResourceService.SaveResourceAs(appDef, resId);
+            url += "fusion/templates/mapguide/preview/index.html?Session=" + sessionId + "&ApplicationDefinition=" + resId;
+            return url;
+        }
+
+        public string GeneratePreviewUrl(IResource res)
+        {
+            switch (res.ResourceType)
+            {
+                case ResourceTypes.FeatureSource:
+                    return GenerateFeatureSourcePreviewUrl(res);
+                case ResourceTypes.ApplicationDefinition:
+                    return GenerateFlexLayoutPreviewUrl(res);
+                case ResourceTypes.LayerDefinition:
+                    return GenerateLayerPreviewUrl(res);
+                case ResourceTypes.MapDefinition:
+                    return GenerateMapPreviewUrl(res);
+                case ResourceTypes.WebLayout:
+                    return GenerateWebLayoutPreviewUrl(res);
+                default:
+                    throw new InvalidOperationException("This resource type cannot be previewed"); //LOCALIZEME
+            }
+        }
+
+        private static ResourceTypes[] PREVIEWABLE_RESOURCE_TYPES = new ResourceTypes[] 
+        {
+            ResourceTypes.FeatureSource,
+            ResourceTypes.ApplicationDefinition,
+            ResourceTypes.LayerDefinition,
+            ResourceTypes.MapDefinition,
+            ResourceTypes.WebLayout
+        };
+
+        internal static bool IsPreviewableType(OSGeo.MapGuide.MaestroAPI.ResourceTypes rt)
+        {
+            return Array.IndexOf(PREVIEWABLE_RESOURCE_TYPES, rt) >= 0;
+        }
+    }
+}

Modified: sandbox/maestro-3.0/Maestro.Base/Editor/WebLayoutEditor.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Editor/WebLayoutEditor.cs	2010-10-04 05:51:06 UTC (rev 5239)
+++ sandbox/maestro-3.0/Maestro.Base/Editor/WebLayoutEditor.cs	2010-10-04 11:44:03 UTC (rev 5240)
@@ -34,8 +34,11 @@
             InitializeComponent();
         }
 
+        private Maestro.Editors.IEditorService _edSvc;
+
         protected override void Bind(Maestro.Editors.IEditorService service)
         {
+            _edSvc = service;
             webLayoutEditorCtrl.Bind(service);
         }
     }

Modified: sandbox/maestro-3.0/Maestro.Base/Editor/XmlEditor.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Editor/XmlEditor.cs	2010-10-04 05:51:06 UTC (rev 5239)
+++ sandbox/maestro-3.0/Maestro.Base/Editor/XmlEditor.cs	2010-10-04 11:44:03 UTC (rev 5240)
@@ -31,6 +31,7 @@
 using OSGeo.MapGuide.MaestroAPI;
 using System.Xml;
 using Maestro.Editors;
+using OSGeo.MapGuide.MaestroAPI.ObjectModels;
 
 namespace Maestro.Base.Editor
 {
@@ -85,16 +86,40 @@
             warnings = warn.ToArray();
         }
 
+        private IEditorService _edSvc;
+
         protected override void Bind(IEditorService service)
         {
-            service.RegisterCustomNotifier(editor);
-            editor.Bind(service);
+            _edSvc = service;
+            _edSvc.RegisterCustomNotifier(editor);
+            editor.Bind(_edSvc);
             editor.ReadyForEditing(); //This turns on event broadcasting
             this.Title = "XML Editor: " + ResourceIdentifier.GetName(this.EditorService.ResourceID); //LOCALIZE
         }
 
-        protected override string GetXmlContent()
+        protected override ICollection<ValidationIssue> ValidateEditedResource()
         {
+            string[] warnings;
+            string[] errors;
+
+            ValidateXml(out errors, out warnings);
+            var issues = new List<ValidationIssue>();
+            foreach (string err in errors)
+            {
+                issues.Add(new ValidationIssue(this.Resource, ValidationStatus.Error, err));
+            }
+            foreach (string warn in warnings)
+            {
+                issues.Add(new ValidationIssue(this.Resource, ValidationStatus.Warning, warn));
+            }
+
+            //Put through ValidationResultSet to weed out redundant messages
+            var set = new ValidationResultSet(issues);
+            return set.GetAllIssues();
+        }
+
+        public override string GetXmlContent()
+        {
             return this.XmlContent;
         }
 
@@ -111,5 +136,22 @@
                 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/Maestro.Base.csproj
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Maestro.Base.csproj	2010-10-04 05:51:06 UTC (rev 5239)
+++ sandbox/maestro-3.0/Maestro.Base/Maestro.Base.csproj	2010-10-04 11:44:03 UTC (rev 5240)
@@ -129,6 +129,7 @@
       <DependentUpon>PrintLayoutEditor.cs</DependentUpon>
     </Compile>
     <Compile Include="Editor\ResourceEditorService.cs" />
+    <Compile Include="Editor\ResourcePreviewEngine.cs" />
     <Compile Include="Editor\SymbolDefinitionEditor.cs">
       <SubType>UserControl</SubType>
     </Compile>

Modified: sandbox/maestro-3.0/Maestro.Base/Properties/Resources.Designer.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Properties/Resources.Designer.cs	2010-10-04 05:51:06 UTC (rev 5239)
+++ sandbox/maestro-3.0/Maestro.Base/Properties/Resources.Designer.cs	2010-10-04 11:44:03 UTC (rev 5240)
@@ -485,6 +485,15 @@
             }
         }
         
+        /// <summary>
+        ///   Looks up a localized string similar to Validation detected errors in your resource, please fix them before saving this resource.
+        /// </summary>
+        internal static string FixErrorsBeforeSaving {
+            get {
+                return ResourceManager.GetString("FixErrorsBeforeSaving", resourceCulture);
+            }
+        }
+        
         internal static System.Drawing.Bitmap folder__plus {
             get {
                 object obj = ResourceManager.GetObject("folder__plus", resourceCulture);
@@ -500,6 +509,15 @@
         }
         
         /// <summary>
+        ///   Looks up a localized string similar to Error.
+        /// </summary>
+        internal static string Global_ErrorText {
+            get {
+                return ResourceManager.GetString("Global.ErrorText", resourceCulture);
+            }
+        }
+        
+        /// <summary>
         ///   Looks up a localized string similar to Question.
         /// </summary>
         internal static string Global_QuestionText {

Modified: sandbox/maestro-3.0/Maestro.Base/Properties/Resources.resx
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Properties/Resources.resx	2010-10-04 05:51:06 UTC (rev 5239)
+++ sandbox/maestro-3.0/Maestro.Base/Properties/Resources.resx	2010-10-04 11:44:03 UTC (rev 5240)
@@ -676,4 +676,10 @@
   <data name="CloseUnsavedResource" xml:space="preserve">
     <value>This resource has unsaved changes. Close and discard these changes?</value>
   </data>
+  <data name="FixErrorsBeforeSaving" xml:space="preserve">
+    <value>Validation detected errors in your resource, please fix them before saving this resource</value>
+  </data>
+  <data name="Global.ErrorText" xml:space="preserve">
+    <value>Error</value>
+  </data>
 </root>
\ No newline at end of file

Modified: sandbox/maestro-3.0/Maestro.Base/Templates/MapDefinitionItemTemplate.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Templates/MapDefinitionItemTemplate.cs	2010-10-04 05:51:06 UTC (rev 5239)
+++ sandbox/maestro-3.0/Maestro.Base/Templates/MapDefinitionItemTemplate.cs	2010-10-04 11:44:03 UTC (rev 5240)
@@ -41,7 +41,7 @@
 
         public override IResource CreateItem(IServerConnection conn)
         {
-            return ObjectFactory.CreateMapDefinition(conn);
+            return ObjectFactory.CreateMapDefinition(conn, "New Map"); //LOCALIZEME
         }
     }
 }

Modified: sandbox/maestro-3.0/Maestro.ResourceValidation/FeatureSourceValidator.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.ResourceValidation/FeatureSourceValidator.cs	2010-10-04 05:51:06 UTC (rev 5239)
+++ sandbox/maestro-3.0/Maestro.ResourceValidation/FeatureSourceValidator.cs	2010-10-04 11:44:03 UTC (rev 5240)
@@ -46,7 +46,7 @@
             try
             {
                 System.Globalization.CultureInfo ci = System.Globalization.CultureInfo.InvariantCulture;
-                FdoSpatialContextList lst = feature.GetSpatialInfo();
+                FdoSpatialContextList lst = feature.GetSpatialInfo(false);
                 if (lst == null || lst.SpatialContext == null || lst.SpatialContext.Count == 0)
                     issues.Add(new ValidationIssue(feature, ValidationStatus.Warning, Properties.Resources.FS_NoSpatialContextWarning));
                 else

Modified: sandbox/maestro-3.0/Maestro.ResourceValidation/MapDefinitionValidator.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.ResourceValidation/MapDefinitionValidator.cs	2010-10-04 05:51:06 UTC (rev 5239)
+++ sandbox/maestro-3.0/Maestro.ResourceValidation/MapDefinitionValidator.cs	2010-10-04 11:44:03 UTC (rev 5240)
@@ -101,7 +101,7 @@
 
                                 try
                                 {
-                                    FdoSpatialContextList context = fs.GetSpatialInfo();
+                                    FdoSpatialContextList context = fs.GetSpatialInfo(false);
                                     if (context.SpatialContext == null || context.SpatialContext.Count == 0)
                                         issues.Add(new ValidationIssue(fs, ValidationStatus.Warning, string.Format(Properties.Resources.MDF_MissingSpatialContextWarning, fs.ResourceID)));
                                     else

Modified: sandbox/maestro-3.0/MaestroAPITests/ResourceTests.cs
===================================================================
--- sandbox/maestro-3.0/MaestroAPITests/ResourceTests.cs	2010-10-04 05:51:06 UTC (rev 5239)
+++ sandbox/maestro-3.0/MaestroAPITests/ResourceTests.cs	2010-10-04 11:44:03 UTC (rev 5240)
@@ -158,7 +158,7 @@
             }
             #endregion
 
-            res = ObjectFactory.CreateMapDefinition(conn);
+            res = ObjectFactory.CreateMapDefinition(conn, "Test Map");
             #region Map Definition
             try
             {
@@ -477,7 +477,7 @@
             var ld2 = conv.Upgrade(ld, targetVer);
             Assert.AreSame(ld, ld2);
 
-            var md = ObjectFactory.CreateMapDefinition(conn);
+            var md = ObjectFactory.CreateMapDefinition(conn, "Test Map");
             var md2 = conv.Upgrade(md, targetVer);
             Assert.AreSame(md, md2);
 

Modified: sandbox/maestro-3.0/MaestroAPITests/ValidationTests.cs
===================================================================
--- sandbox/maestro-3.0/MaestroAPITests/ValidationTests.cs	2010-10-04 05:51:06 UTC (rev 5239)
+++ sandbox/maestro-3.0/MaestroAPITests/ValidationTests.cs	2010-10-04 11:44:03 UTC (rev 5240)
@@ -88,6 +88,7 @@
             var totalIssues = set.GetAllIssues();
             Assert.AreEqual(totalIssues.Length, 2);
             Assert.AreEqual(set.ResourceIDs.Length, 1);
+            Assert.AreEqual(set.GetIssuesForResource("Library://Test.FeatureSource", ValidationStatus.Error).Count, 2);
         }
 
         [Test]

Modified: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ObjectModels/ApplicationDefinition.cs
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ObjectModels/ApplicationDefinition.cs	2010-10-04 05:51:06 UTC (rev 5239)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ObjectModels/ApplicationDefinition.cs	2010-10-04 11:44:03 UTC (rev 5240)
@@ -44,12 +44,90 @@
         }
     }
 
+    /// <summary>
+    /// Defines the stock fusion template names that come with a standard MapGuide installation
+    /// </summary>
+    public static class FusionTemplateNames
+    { 
+        /// <summary>
+        /// The preview template. Used for previewing other resources
+        /// </summary>
+        public const string Preview = "Preview";
+        /// <summary>
+        /// The Aqua template
+        /// </summary>
+        public const string Aqua = "Aqua";
+        /// <summary>
+        /// The Maroon template
+        /// </summary>
+        public const string Maroon = "Maroon";
+        /// <summary>
+        /// The Slate template
+        /// </summary>
+        public const string Slate = "Slate";
+        /// <summary>
+        /// The LimeGold template
+        /// </summary>
+        public const string LimeGold = "LimeGold";
+        /// <summary>
+        /// The TurquoiseYellow template
+        /// </summary>
+        public const string TurquoiseYellow = "TurquoiseYellow";
+    }
+
     partial class ApplicationDefinitionType : IResource
     {
         internal ApplicationDefinitionType() { }
 
         private static readonly Version RES_VERSION = new Version(1, 0, 0);
 
+        private XmlDocument _doc;
+
+        internal XmlDocument Doc
+        {
+            get
+            {
+                if (_doc == null)
+                    _doc = new XmlDocument();
+
+                return _doc;
+            }
+        }
+
+        public MapGroupType AddMapGroup(string id, bool singleTile, string mapDefinitionId)
+        {
+            var map = new MapGroupType()
+            {
+                id = id,
+                Map = new System.ComponentModel.BindingList<MapType>()
+                {
+                    new MapType()
+                    {
+                        Type = "MapGuide",
+                        SingleTile = singleTile.ToString(),
+                        Extension = new CustomContentType()
+                        {
+                            Any = new XmlElement[1]
+                        }
+                    }
+                },
+            };
+            map.Map[0].Extension.Any[0] = Doc.CreateElement("ResourceId");
+            map.Map[0].Extension.Any[0].InnerText = mapDefinitionId;
+
+            this.MapSet.Add(map);
+
+            return map;
+        }
+
+        public MapGroupType AddMapGroup(string id, bool singleTile, string mapDefinitionId, double centerX, double centerY, double scale)
+        {
+            var map = AddMapGroup(id, singleTile, mapDefinitionId);
+            map.InitialView = new MapViewType() { CenterX = centerX, CenterY = centerY, Scale = scale };
+
+            return map;
+        }
+
         [XmlIgnore]
         public OSGeo.MapGuide.MaestroAPI.IServerConnection CurrentConnection
         {

Modified: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ObjectModels/FeatureSource.cs
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ObjectModels/FeatureSource.cs	2010-10-04 05:51:06 UTC (rev 5239)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ObjectModels/FeatureSource.cs	2010-10-04 11:44:03 UTC (rev 5240)
@@ -269,9 +269,9 @@
         /// Convenience method to retrieve the spatial context information of this feature source
         /// </summary>
         /// <returns></returns>
-        public OSGeo.MapGuide.ObjectModels.Common.FdoSpatialContextList GetSpatialInfo()
+        public OSGeo.MapGuide.ObjectModels.Common.FdoSpatialContextList GetSpatialInfo(bool activeOnly)
         {
-            return this.CurrentConnection.FeatureService.GetSpatialContextInfo(this.ResourceID, false);
+            return this.CurrentConnection.FeatureService.GetSpatialContextInfo(this.ResourceID, activeOnly);
         }
 
         /// <summary>

Modified: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ObjectModels/LayerDefinition.cs
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ObjectModels/LayerDefinition.cs	2010-10-04 05:51:06 UTC (rev 5239)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ObjectModels/LayerDefinition.cs	2010-10-04 11:44:03 UTC (rev 5240)
@@ -25,6 +25,9 @@
 using OSGeo.MapGuide.MaestroAPI;
 using OSGeo.MapGuide.ObjectModels.Common;
 using System.ComponentModel;
+using OSGeo.MapGuide.MaestroAPI.Services;
+using OSGeo.MapGuide.MaestroAPI.ObjectModels;
+using OSGeo.MapGuide.ObjectModels.FeatureSource;
 
 namespace OSGeo.MapGuide.ObjectModels.LayerDefinition
 {
@@ -37,11 +40,100 @@
 
     public interface ILayerDefinition : IResource
     {
-        Envelope GetSpatialExtent(bool allowFallbackToContextInformation);
-
         ISubLayerDefinition SubLayer { get; }
     }
 
+    public static class LayerDefinitionExtensions
+    {
+        public static string GetCoordinateSystemWkt(this ILayerDefinition layer)
+        {
+            Check.NotNull(layer, "layer");
+            if (layer.CurrentConnection == null)
+                throw new System.Exception("No server set for object");
+
+            var conn = layer.CurrentConnection;
+            switch (layer.SubLayer.LayerType)
+            {
+                case LayerType.Raster:
+                    {
+                        var rl = (IRasterLayerDefinition)layer.SubLayer;
+                        var fs = (FeatureSourceType)conn.ResourceService.GetResource(rl.FeatureSourceID);
+                        var scList = fs.GetSpatialInfo(true);
+                        if (scList.SpatialContext.Count > 0)
+                            return scList.SpatialContext[0].CoordinateSystemWkt;
+                    }
+                    break;
+                case LayerType.Vector:
+                    {
+                        var vl = (IVectorLayerDefinition)layer.SubLayer;
+                        var fs = (FeatureSourceType)conn.ResourceService.GetResource(vl.FeatureSourceID);
+                        var scList = fs.GetSpatialInfo(true);
+                        if (scList.SpatialContext.Count > 0)
+                            return scList.SpatialContext[0].CoordinateSystemWkt;
+                    }
+                    break;
+                case LayerType.Drawing:
+                    {
+                        int[] services = conn.Capabilities.SupportedServices;
+                        if (Array.IndexOf(services, (int)ServiceType.Drawing) >= 0)
+                        {
+                            var sheet = ((IDrawingLayerDefinition)layer.SubLayer).Sheet;
+                            var dws = (DrawingSource)conn.ResourceService.GetResource(((IDrawingLayerDefinition)layer.SubLayer).DrawingSourceID);
+
+                            var csCat = conn.CoordinateSystemCatalog;
+                            return csCat.ConvertCoordinateSystemCodeToWkt(dws.CoordinateSpace);
+                        }
+                    }
+                    break;
+            }
+            return string.Empty;
+        }
+
+        /// <summary>
+        /// Returns the spatial extent of the data. 
+        /// This is calculated by asking the underlying featuresource for the minimum rectangle that
+        /// contains all the features in the specified table. If the <paramref name="allowFallbackToContextInformation"/>
+        /// is set to true, and the query fails, the code will attempt to read this information
+        /// from the spatial context information instead.
+        /// </summary>
+        /// <param name="allowFallbackToContextInformation">True to allow reading spatial extents from the spatial context information, if the spatial query fails.</param>
+        /// <returns>The envelope for the data in the table</returns>
+        public static Envelope GetSpatialExtent(this ILayerDefinition layer, bool allowFallbackToContextInformation)
+        {
+            Check.NotNull(layer, "layer");
+            if (layer.CurrentConnection == null)
+                throw new System.Exception("No server set for object");
+
+            var conn = layer.CurrentConnection;
+            switch (layer.SubLayer.LayerType)
+            {
+                case LayerType.Vector:
+                    return conn.FeatureService.GetSpatialExtent(((IVectorLayerDefinition)layer.SubLayer).FeatureSourceID, ((IVectorLayerDefinition)layer.SubLayer).FullQualifiedClassName, ((IVectorLayerDefinition)layer.SubLayer).GeometryProperty);
+                case LayerType.Raster:
+                    return conn.FeatureService.GetSpatialExtent(((IRasterLayerDefinition)layer.SubLayer).FeatureSourceID, ((IRasterLayerDefinition)layer.SubLayer).FullQualifiedClassName, ((IRasterLayerDefinition)layer.SubLayer).GeometryProperty);
+                default:
+                    {
+                        int[] services = conn.Capabilities.SupportedServices;
+                        if (Array.IndexOf(services, (int)ServiceType.Drawing) >= 0)
+                        {
+                            var sheet = ((IDrawingLayerDefinition)layer.SubLayer).Sheet;
+                            var dws = (DrawingSource)conn.ResourceService.GetResource(((IDrawingLayerDefinition)layer.SubLayer).DrawingSourceID);
+
+                            //find matching sheet
+                            foreach (var sht in dws.Sheet)
+                            {
+                                if (sheet.Equals(sht.Name))
+                                {
+                                    return ObjectFactory.CreateEnvelope(sht.Extent.MinX, sht.Extent.MinY, sht.Extent.MaxX, sht.Extent.MaxY);
+                                }
+                            }
+                        }
+                        return null;
+                    }
+            }
+        }
+    }
+
     public interface ISubLayerDefinition
     {
         LayerType LayerType { get; } 
@@ -80,11 +172,23 @@
 
     public interface IRasterLayerDefinition : ISubLayerDefinition
     {
+        string FullQualifiedClassName { get; set; }
+
+        string GeometryProperty { get; set; }
+
         string FeatureSourceID { get; set; }
     }
 
     public interface IDrawingLayerDefinition : ISubLayerDefinition
     {
+        string Sheet { get; set; }
+
+        string LayerFilter { get; set; }
+
+        double MinScale { get; set; }
+
+        double MaxScale { get; set; }
+
         string DrawingSourceID { get; set; }
     }
 
@@ -164,6 +268,32 @@
             get { return this.ResourceId; }
             set { this.ResourceId = value; }
         }
+
+        [XmlIgnore]
+        string IRasterLayerDefinition.FullQualifiedClassName
+        {
+            get
+            {
+                return this.FeatureName;
+            }
+            set
+            {
+                this.FeatureName = value;
+            }
+        }
+
+        [XmlIgnore]
+        string IRasterLayerDefinition.GeometryProperty
+        {
+            get
+            {
+                return this.Geometry;
+            }
+            set
+            {
+                this.Geometry = value;
+            }
+        }
     }
 
     partial class DrawingLayerDefinitionType : IDrawingLayerDefinition
@@ -365,28 +495,6 @@
             get { return true; }
         }
 
-        /// <summary>
-        /// Returns the spatial extent of the data. 
-        /// This is calculated by asking the underlying featuresource for the minimum rectangle that
-        /// contains all the features in the specified table. If the <paramref name="allowFallbackToContextInformation"/>
-        /// is set to true, and the query fails, the code will attempt to read this information
-        /// from the spatial context information instead.
-        /// </summary>
-        /// <param name="allowFallbackToContextInformation">True to allow reading spatial extents from the spatial context information, if the spatial query fails.</param>
-        /// <returns>The envelope for the data in the table</returns>
-        public Envelope GetSpatialExtent(bool allowFallbackToContextInformation)
-        {
-            if (this.CurrentConnection == null)
-                throw new System.Exception("No server set for object");
-
-            if (this.Item as VectorLayerDefinitionType != null)
-                return this.CurrentConnection.FeatureService.GetSpatialExtent(this.Item.ResourceId, (this.Item as VectorLayerDefinitionType).FeatureName, (this.Item as VectorLayerDefinitionType).Geometry, allowFallbackToContextInformation);
-            else if (this.Item as GridLayerDefinitionType != null)
-                return this.CurrentConnection.FeatureService.GetSpatialExtent(this.Item.ResourceId, (this.Item as GridLayerDefinitionType).FeatureName, (this.Item as GridLayerDefinitionType).Geometry, allowFallbackToContextInformation);
-            else
-                return null;
-        }
-
         public ISubLayerDefinition SubLayer
         {
             get { return this.Item; }

Modified: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ObjectModels/MapDefinition.cs
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ObjectModels/MapDefinition.cs	2010-10-04 05:51:06 UTC (rev 5239)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ObjectModels/MapDefinition.cs	2010-10-04 11:44:03 UTC (rev 5240)
@@ -119,10 +119,48 @@
         {
             get { return true; }
         }
+
+        public MapLayerGroupType AddGroup(string groupName)
+        {
+            if (this.MapLayerGroup == null)
+                this.MapLayerGroup = new System.ComponentModel.BindingList<MapLayerGroupType>();
+
+            var group = new MapLayerGroupType()
+            {
+                Parent = this,
+                ExpandInLegend = true,
+                LegendLabel = groupName,
+                Name = groupName,
+                ShowInLegend = true,
+                Visible = true
+            };
+            this.MapLayerGroup.Add(group);
+            return group;
+        }
+
+        public MapLayerType AddLayer(string groupName, string layerName, string resourceId)
+        { 
+            var layer = new MapLayerType() { 
+                Parent = this,
+                ExpandInLegend = true,
+                LegendLabel = layerName,
+                Name = layerName,
+                ResourceId = resourceId,
+                ShowInLegend = true,
+                Visible = true,
+                Selectable = true
+            };
+            //TODO: Throw exception if adding to non-existent group?
+            layer.Group = string.IsNullOrEmpty(groupName) ? string.Empty : groupName;
+
+            this.MapLayer.Add(layer);
+            return layer;
+        }
     }
 
     partial class MapLayerType
     {
+        [XmlIgnore]
         public MapDefinition Parent
         {
             get;
@@ -132,6 +170,7 @@
 
     partial class BaseMapLayerType
     {
+        [XmlIgnore]
         public MapDefinition Parent
         {
             get;
@@ -141,6 +180,7 @@
 
     partial class MapLayerGroupType
     {
+        [XmlIgnore]
         public MapDefinition Parent
         {
             get;

Modified: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ObjectModels/ObjectFactory.cs
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ObjectModels/ObjectFactory.cs	2010-10-04 05:51:06 UTC (rev 5239)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ObjectModels/ObjectFactory.cs	2010-10-04 11:44:03 UTC (rev 5240)
@@ -32,6 +32,7 @@
 using OSGeo.MapGuide.ObjectModels.LoadProcedure;
 using OSGeo.MapGuide.ObjectModels.Common;
 using System.Drawing;
+using OSGeo.MapGuide.MaestroAPI.Services;
 
 namespace OSGeo.MapGuide.MaestroAPI.ObjectModels
 {
@@ -103,29 +104,31 @@
             return fs;
         }
 
-        public static MapDefinition CreateMapDefinition(IServerConnection owner)
+        public static MapDefinition CreateMapDefinition(IServerConnection owner, string name)
         {
             Check.NotNull(owner, "owner");
 
             return new MapDefinition() { 
                 CurrentConnection = owner,
+                Name = name,
+                BackgroundColor = Color.White,
                 MapLayer = new System.ComponentModel.BindingList<MapLayerType>(),
-                MapLayerGroup = new System.ComponentModel.BindingList<MapLayerGroupType>(),
+                //MapLayerGroup = new System.ComponentModel.BindingList<MapLayerGroupType>(),
             };
         }
 
-        public static MapDefinition CreateMapDefinition(IServerConnection owner, string coordinateSystemWkt)
+        public static MapDefinition CreateMapDefinition(IServerConnection owner, string name, string coordinateSystemWkt)
         {
-            var map = CreateMapDefinition(owner);
+            var map = CreateMapDefinition(owner, name);
             map.CoordinateSystem = coordinateSystemWkt;
 
             return map;
         }
 
-        public static MapDefinition CreateMapDefinition(IServerConnection owner, string coordinateSystemWkt, Envelope env)
+        public static MapDefinition CreateMapDefinition(IServerConnection owner, string name, string coordinateSystemWkt, Envelope env)
         {
-            var map = CreateMapDefinition(owner, coordinateSystemWkt);
-            map.Extents = new Box2DType() { MinX = env.MinY, MaxX = env.MaxX, MinY = env.MinY, MaxY = env.MaxY };
+            var map = CreateMapDefinition(owner, name, coordinateSystemWkt);
+            map.Extents = new Box2DType() { MinX = env.MinX, MaxX = env.MaxX, MinY = env.MinY, MaxY = env.MaxY };
 
             return map;
         }
@@ -568,13 +571,89 @@
             return new SymbolLibraryType() { CurrentConnection = conn };
         }
 
+        //TODO: Just deserialize from an embedded resource. The content model for a fusion
+        //flexible layout is just too loose to programmatically build reliably.
         public static ApplicationDefinitionType CreateFlexibleLayout(IServerConnection owner)
         {
             Check.NotNull(owner, "owner");
 
-            return new ApplicationDefinitionType() { CurrentConnection = owner };
+            return new ApplicationDefinitionType()
+            {
+                CurrentConnection = owner,
+                MapSet = new System.ComponentModel.BindingList<MapGroupType>(),
+                WidgetSet = CreateStandardWidgetSet()
+            };
         }
 
+        private static System.ComponentModel.BindingList<WidgetSetType> CreateStandardWidgetSet()
+        {
+            return new System.ComponentModel.BindingList<WidgetSetType>();
+        }
+
+        private static System.ComponentModel.BindingList<WidgetSetType> CreatePreviewWidgetSet()
+        {
+            return new System.ComponentModel.BindingList<WidgetSetType>();
+        }
+
+        public static ApplicationDefinitionType CreateFlexibleLayout(IServerConnection owner, string title)
+        {
+            Check.NotNull(owner, "owner");
+
+            var appDef = CreateFlexibleLayout(owner);
+            appDef.Title = title;
+            return appDef;
+        }
+
+        public static ApplicationDefinitionType CreatePreviewFlexLayout(IServerConnection owner)
+        {
+            Check.NotNull(owner, "owner");
+            var appDef = new ApplicationDefinitionType()
+            {
+                CurrentConnection = owner,
+                Title = "Preview",
+                MapSet = new System.ComponentModel.BindingList<MapGroupType>(),
+                WidgetSet = CreatePreviewWidgetSet()
+            };
+            appDef.TemplateUrl = "fusion/templates/mapguide/preview/index.html";
+            return appDef;
+        }
+
+        /// <summary>
+        /// Creates a fusion flexible layout
+        /// </summary>
+        /// <param name="owner"></param>
+        /// <param name="title"></param>
+        /// <param name="templateName">The name of the template. Consult <see cref="FusionTemplateNames"/> for a list of stock templates</param>
+        /// <returns></returns>
+        public static ApplicationDefinitionType CreateFlexibleLayout(IServerConnection owner, string title, string templateName)
+        {
+            Check.NotNull(owner, "owner");
+
+            string url = string.Empty;
+
+            int[] services = owner.Capabilities.SupportedServices;
+            if (Array.IndexOf(services, (int)ServiceType.Fusion) >= 0)
+            {
+                IFusionService fsvc = (IFusionService)owner.GetService((int)ServiceType.Fusion);
+                var templates = fsvc.GetApplicationTemplates();
+                foreach (var tpl in templates.TemplateInfo)
+                {
+                    if (tpl.Name.ToUpper().Equals(templateName.ToUpper()))
+                    {
+                        url = tpl.LocationUrl;
+                        continue;
+                    }
+                }
+            }
+
+            if (string.IsNullOrEmpty(url))
+                throw new InvalidOperationException("Could not find template url for template: " + templateName); //LOCALIZEME
+
+            var appDef = CreateFlexibleLayout(owner, title);
+            appDef.TemplateUrl = url;
+            return appDef;
+        }
+
         public static PrintLayout CreatePrintLayout(IServerConnection owner)
         {
             Check.NotNull(owner, "owner");

Modified: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/IResource.cs
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/IResource.cs	2010-10-04 05:51:06 UTC (rev 5239)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/IResource.cs	2010-10-04 11:44:03 UTC (rev 5240)
@@ -60,6 +60,19 @@
             return new ResourceTypeDescriptor(res.ResourceType, res.ResourceVersion.ToString());
         }
 
+        public static void CopyResourceDataTo(this IResource source, IResource target)
+        {
+            Check.NotNull(source, "source");
+            Check.NotNull(target, "target");
+
+            foreach (var res in source.EnumerateResourceData())
+            {
+                var data = source.GetResourceData(res.Name);
+                data.Position = 0L; //Reset
+                target.SetResourceData(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-04 05:51:06 UTC (rev 5239)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/ValidationResultSet.cs	2010-10-04 11:44:03 UTC (rev 5240)
@@ -39,7 +39,7 @@
             _issues = new Dictionary<string, Dictionary<ValidationIssue, ValidationIssue>>();
         }
 
-        public ValidationResultSet(List<ValidationIssue> issues) : this()
+        public ValidationResultSet(IEnumerable<ValidationIssue> issues) : this()
         {
             Check.NotNull(issues, "issues");
 
@@ -58,6 +58,17 @@
             return _issues[resourceId].Keys;
         }
 
+        public ICollection<ValidationIssue> GetIssuesForResource(string resourceId, ValidationStatus statType)
+        {
+            var issues = new List<ValidationIssue>();
+            foreach (var issue in GetIssuesForResource(resourceId))
+            {
+                if (issue.Status == statType)
+                    issues.Add(issue);
+            }
+            return issues;
+        }
+
         public ValidationIssue[] GetAllIssues()
         {
             var issues = new List<ValidationIssue>();

Modified: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI.Http/HttpServerConnection.cs
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI.Http/HttpServerConnection.cs	2010-10-04 05:51:06 UTC (rev 5239)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI.Http/HttpServerConnection.cs	2010-10-04 11:44:03 UTC (rev 5240)
@@ -513,8 +513,15 @@
                     Utility.CopyStream(outStream, rs);
                     rs.Flush();
                 }
-                using (System.IO.Stream resp = req.GetResponse().GetResponseStream())
+                var wresp = req.GetResponse();
+                if (wresp is HttpWebResponse)
                 {
+                    HttpWebResponse httpresp = (HttpWebResponse)wresp;
+                    LogResponse(httpresp);
+                }
+
+                using (System.IO.Stream resp = wresp.GetResponseStream())
+                {
                     //Do nothing... there is no return value
                 }
             }
@@ -540,6 +547,11 @@
 #endif
         }
 
+        private void LogResponse(HttpWebResponse httpresp)
+        {
+            OnRequestDispatched(string.Format("{0:d} {1} {2} {3}", httpresp.StatusCode, httpresp.StatusDescription, httpresp.Method, new Uri(this.BaseURL).MakeRelativeUri(httpresp.ResponseUri)));
+        }
+
         public FeatureSetReader ExecuteSqlQuery(string featureSourceID, string sql)
         {
             ResourceIdentifier.Validate(featureSourceID, ResourceTypes.FeatureSource);
@@ -1243,7 +1255,7 @@
 			{
                 var httpreq = HttpWebRequest.Create(req);
                 var httpresp = (HttpWebResponse)httpreq.GetResponse();
-                OnRequestDispatched(string.Format("{0:d} {1} {2} {3}", httpresp.StatusCode, httpresp.StatusDescription, httpresp.Method, httpresp.ResponseUri));
+                LogResponse(httpresp);
                 using (var st = httpresp.GetResponseStream())
                 {
                     using (var ms = new MemoryStream())
@@ -1297,7 +1309,7 @@
                 if (_cred != null)
                     httpreq.Credentials = _cred;
                 var httpresp = (HttpWebResponse)httpreq.GetResponse();
-                OnRequestDispatched(string.Format("{0:d} {1} {2} {3}", httpresp.StatusCode, httpresp.StatusDescription, httpresp.Method, httpresp.ResponseUri));
+                LogResponse(httpresp);
                 return httpresp.GetResponseStream();
 			}
 			catch (Exception ex)
@@ -1736,7 +1748,12 @@
 
         ApplicationDefinitionTemplateInfoSet IFusionService.GetApplicationTemplates()
         {
-            throw new NotImplementedException();
+            string req = m_reqBuilder.EnumerateApplicationTemplates();
+            using (var s = this.OpenRead(req))
+            {
+                var list = this.DeserializeObject<OSGeo.MapGuide.ObjectModels.ApplicationDefinition.ApplicationDefinitionTemplateInfoSet>(s);
+                return list;
+            }
         }
 
         ApplicationDefinitionWidgetInfoSet IFusionService.GetApplicationWidgets()



More information about the mapguide-commits mailing list