Changes between Initial Version and Version 1 of Maestro3ResourceOverhaul


Ignore:
Timestamp:
Jul 7, 2010, 6:22:46 AM (14 years ago)
Author:
jng
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Maestro3ResourceOverhaul

    v1 v1  
     1= Resource Object Model Overhaul =
     2
     3== The problem ==
     4
     5The current xml classes were generated via xsd.exe (from .net framework 1.1) from an old MapGuide xsd schema set. Support for newer version xsds (eg. WebLayout v1.1) is either not currently implemented, or support is currently monkey-patched in.
     6
     7Because these generated classes targeted a specific version, it makes moving from older to newer versions of a given resource very hard to accomplish. Unlike MapGuide Studio, support for older versions of MapGuide is something we want to maintain at all costs.
     8
     9Simply put, the current resource object code is un-workable and a cleaner way to meet our requirements is needed.
     10
     11== The solution ==
     12
     13=== Throw out xsd.exe ===
     14
     15xsd.exe generates really ugly code. Although the current version generates partial classes and has INotifyPropertyChanged support, it is still lacking in some areas. The limitations are described [http://themapguyde.blogspot.com/2010/05/xsd2code.html here]
     16
     17We will use [http://xsd2code.codeplex.com Xsd2Code] to generate our xml classes. Xsd2Code has been proven to generate much cleaner code than xsd.exe and allows for greater level of customisation and extension as a result.
     18
     19=== Have resource classes implement a base interface ===
     20
     21The current generated classes have no common base class or interface, which makes working with them generically a bit difficult as they have nothing in common. Maestro currently uses reflection to do this (ugly). Resource classes will implement the following interface:
     22
     23{{{
     24
     25public interface IResource : INotifyPropertyChanged
     26{
     27    string ResourceId { get; set; }
     28    string ResourceType { get; set; }
     29    Version ResourceVersion { get; }
     30    IServerConnection Connection { get; set; }
     31}
     32
     33}}}
     34
     35=== Partition implementations into separate namespaces and assemblies ===
     36
     37The problem with running xsd.exe (or any other code generator) against the mapguide xsd schema set is the very high possiblity of naming collisions from the generated code. As such, the classes generated for Maestro 3.0 will be partitioned into separated namespaces.
     38
     39Each xsd will be generated into its own namespace and assmebly.
     40
     41For example:
     42
     43 * !LayerDefinition-1.0.0.xsd classes will be in OSGeo.!MapGuide.!ObjectModel.!LayerDefinition-1.0.0.dll under the namespace OSGeo.!MapGuide!.ObjectModel.!LayerDefinition
     44 * !WebLayout-1.1.0.xsd classes will be in OSGeo.!MapGuide.!ObjectModel.!WebLayout-1.1.0.dll under the namespace OSGeo.!MapGuide.!ObjectModel.!WebLayout
     45
     46Not every xsd schema requires its own namespace and assembly. Things such as resource headers, data lists, etc. can be grouped together.
     47
     48The root resource object of each assembly will implement the IResource interface. All consuming clients will never reference these assemblies directly. They will use the IResource interface as a means of accessing these classes.
     49
     50[http://www.internetviz-newsletters.com/intertechtraining/e_article000333242.cfm?x=b4tbQ49,b2mW9yHJ Reference aliases] can be employed if we're working with identical types in identical namespaces in different assemblies.
     51
     52=== Version-specific resource editors ===
     53
     54The current resource editors try to handle as many versions of a given resource as much as possible. This makes maintenace a bit difficult to handle.
     55
     56Instead each version of a given resource will now have its own specific editor. Although this may/will result in lots of redundant code, it facilitates a "divide and conquer" approach to handling this problem and allows us to isolate specific editor functionality to specific editor versions.
     57
     58The current IResourceEditorControl interface will now become:
     59
     60{{{
     61
     62public interface IResourceEditor
     63{
     64    /// <summary>
     65    /// Gets or sets the resource in its current state
     66    /// </summary>
     67    IResource Resource { get; set; }
     68
     69    /// <summary>
     70    /// Determines if the currently edited resource is a new resource
     71    /// </summary>
     72    bool IsNew { get; }
     73
     74    /// <summary>
     75    /// Refreshes the display to reflect the current object
     76    /// </summary>
     77    void UpdateDisplay();
     78
     79    /// <summary>
     80    /// Initiates a preview, returns true if the call succeded
     81    /// </summary>
     82    bool Preview();
     83
     84    /// <summary>
     85    /// Validates the current resource, returns true if the call succeded
     86    /// </summary>
     87    bool ValidateResource(bool recursive);
     88
     89    /// <summary>
     90    /// Initiates profiling, returns true if the call succeded
     91    /// </summary>
     92    bool Profile();
     93
     94    /// <summary>
     95    /// Returns a value indicating if the editor supports previews
     96    /// </summary>
     97    bool SupportsPreview { get; }
     98
     99    /// <summary>
     100    /// Returns a value indicating if the editor supports validation
     101    /// </summary>
     102    bool SupportsValidate { get; }
     103
     104    /// <summary>
     105    /// Returns a value indicating if the editor supports profiling
     106    /// </summary>
     107    bool SupportsProfiling { get; }
     108
     109    /// <summary>
     110    /// Called before a save, to let the provider do the save, or some preliminary work.
     111    /// Return false to let the generic code handle the save.
     112    /// </summary>
     113    bool Save(string savename);
     114}
     115
     116}}}
     117
     118Basically the only change is that the Resource property is now a strongly typed object. Only the editor classes will ever know the underlying implementation.
     119
     120All resource editors will now inherit from the following base class:
     121
     122{{{
     123
     124public class ResourceEditorBase : UserControl, IResourceEditor
     125{
     126    protected ResourceEditorBase(IEditorService ed) { ... }
     127    protected ResourceEditorBase(IEditorService ed, string resourceID) { ... }
     128
     129    ...
     130}
     131
     132}}}
     133
     134IEditorService is the new name for the currently named EditorInterface interface.
     135
     136Maestro already uses a form pseudo of dependency injection to instantiate the correct editor for a given resources. We will now use a formal API for this approach:
     137
     138{{{
     139
     140public class ResourceEditorFactory
     141{
     142    IResourceEditor GetEditor(IResource resource) { ... }
     143    IResourceEditor GetEditor(string resourceType, Version requestedVersion) { ... }
     144}
     145
     146}}}
     147
     148The API allows us to request the right editor for the given version of this resource (the required information is in the IResource interface). In the event that Maestro cannot locate the right editor, the generic XML editor will be used (exactly how it's done right now).
     149
     150=== Site Profiles ===
     151
     152If the MapGuide Server we're connecting to supports a newer version of a resource type, we want to give the user the choice of whether to stay with the current version, or move up to the latest supported version. We will use a [http://trac.osgeo.org/mapguide/wiki/Maestro3Capabilities Capability concept] to programmatically determine if it is possible to upgrade any resource.
     153
     154{{{
     155
     156public interface IConnectionCapabilities
     157{
     158    bool IsKnownSiteVersion { get; }
     159    Version GetLatestSupportedVersion(string resourceType);
     160
     161    ...
     162}
     163
     164}}}
     165
     166All resource editors will have an upgrade option built in which will be enabled if the capabilities indicates a known site version returns a version higher than the current version of the edited resources. This is a reasonable balance between doing a silent upgrade (bad) and having to manually upgrade the resource (good, but cumbersome)
     167
     168The Maestro 3.0 API will be bundled with pre-configured capabilities for all known MapGuide versions. For unknown site versions, upgrading is turned off.
     169
     170=== Flexible upgrade paths ===
     171
     172To make resource upgrades/downgrades easy, we need API support to convert resources to different versions.
     173
     174{{{
     175
     176public interface IResourceConverter
     177{
     178    IResource Convert(IResource resource, Version version);
     179}
     180
     181}}}
     182
     183From a consuming client's perspective, they do not require direct references to the resource model assemblies. Only the implementor of this interface needs to know about this information.
     184
     185The resource upgrade strategies is simply: For upgrading, add new elements with default values. Check if content from the [http://trac.osgeo.org/mapguide/wiki/MapGuideRfc10 ExtendedData property] can provide these values.