Common Custom data source
Common_CustomDataSource_CSharp\REXMLDataSource_CSharp\MapResource.cs
// Copyright 2010 ESRI
// 
// All rights reserved under the copyright laws of the United States
// and applicable international laws, treaties, and conventions.
// 
// You may freely redistribute and use this sample code, with or
// without modification, provided you include the original copyright
// notice and use restrictions.
// 
// See the use restrictions.
// 


namespace REXMLDataSource_CSharp
{
    // IGISResource is one of the three required interfaces for any Web ADF Common Data Source
    // implementation.  The class implementing this interface will be responsible for initializing
    // and allowing access to the data underlying the data source instance; creating and retrieving
    // functionalities associated with the data source; providing information about which 
    // functionalities the data source supports; and initializing and allowing access to the data 
    // underlying the data source instance.  Essentially, an IGISResource implementation can be 
    // thought of as describing what the data underlying the data source contains.
    //
    // This particular implementation inherits from IMapResource, which implements IGISResource.  
    // IMapResource specifies methods and properties that describe the underlying data in a way that 
    // allows the data to be rendered by a Web ADF Map Control.
    public class MapResource : ESRI.ArcGIS.ADF.Web.DataSources.IMapResource
    {
        #region Instance Variables

        private ESRI.ArcGIS.ADF.Web.DataSources.IMapInformation m_mapInformation = null;
        private ESRI.ArcGIS.ADF.Web.DisplaySettings m_displaySettings = null;
        private bool m_initialized = false;
        private string m_name = string.Empty;
        private string m_resourceDefinition = string.Empty;
        private ESRI.ArcGIS.ADF.Web.DataSources.IGISDataSource m_gisDataSource = null;
        private ESRI.ArcGIS.ADF.Web.DataSources.GISFunctionalityCollection m_gisFunctionalityCollection =
            new ESRI.ArcGIS.ADF.Web.DataSources.GISFunctionalityCollection();
        private int m_validationTimeout = 0;
        private ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsDataSet m_graphicsDataSet = null;

        #endregion

        #region Constructors

        // Allow instantiation without defining any properties
        public MapResource() { }

        // Explicitly set instance properties in cases where the class is instantiated with
        // name and data source
        public MapResource(string name, REXMLDataSource_CSharp.GISDataSource dataSource)
        {
            m_name = name;
            m_gisDataSource = dataSource;
        }

        #endregion

        #region REXML MapResource Members

        // Access to the graphics dataset containing the features specified by
        // the REXML file underlying the data source
        public ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsDataSet Graphics
        {
            get { return m_graphicsDataSet; }
        }

        // Key for storing and retrieving object state to and from the data source's state table
        private string ResourceStateKey
        {
            get
            {
                string tmp = this.GetType().ToString() + ":" + m_name;
                return (tmp);
            }
        }

        // Reads the data from the REXML file referenced by the data source and stores it in a
        // Web ADF FeatureGraphicsLayer or ElementGraphicsLayer
        private void ProcessREXML(string dataSourceConfig)
        {
            try
            {

                // Get a reference to the REXML file underlying the data source
                System.Xml.XmlDocument xmlDocument = new System.Xml.XmlDocument();
                xmlDocument.Load(dataSourceConfig);

                // Get the root node of the REXML document
                System.Xml.XmlNode rootXmlNode = xmlDocument.DocumentElement;

                // Get the layer name and id as defined in the REXML doc
                System.Xml.XmlNode layerXmlNode = rootXmlNode.SelectSingleNode("LAYER");
                string layerName = layerXmlNode.Attributes.GetNamedItem("name").Value;
                string layerId = layerXmlNode.Attributes.GetNamedItem("id").Value;

                // Comment out one of the two regions below, depending on whether you would like
                // to store the REXML data in a FeatureGraphicsLayer or an ElementGraphicsLayer.
                // 
                // An ElementGraphicsLayer can store multiple geometry types in the same layer,
                // and each element within the layer must have its own renderer defined.
                // ElementGraphicsLayers are essentially meant to store geometry and symbols, and
                // are recommended for use when the data stored in them does not have any attributes
                // in need of symbolization.
                //
                // FeatureGraphicsLayers are meant to emulate true feature layers.  They can only 
                // store one geometry type per layer, but this limitation allows a renderer to be
                // defined for the entire layer, rather than element-by-element.
                // FeatureGraphicsLayers are capable of storing attribute data, allowing renderers 
                // to be symbolized based on attribute values and enabling query functionality.  

                #region REXML data stored in a FeatureGraphicsLayer

                // Declare boolean to hold whether or not the layer is visible
                bool layerVisible = true;

                // Check whether the resource already has a layer with the layer name specified by the
                // REXML document.  If so, get the visibility of the layer and remove it from the
                // resource's graphics dataset so that it can be recreated from the REXML data.
                if (m_graphicsDataSet.Tables.Contains(layerName))
                {
                    // Make sure the DataTable in the graphics dataset's tables collection having the
                    // layer name specified in the REXML is of the appropriate type
                    if (m_graphicsDataSet.Tables[layerName] is
                        ESRI.ArcGIS.ADF.Web.Display.Graphics.FeatureGraphicsLayer)
                    {
                        // Get a reference to the existing FeatureGraphicsLayer
                        ESRI.ArcGIS.ADF.Web.Display.Graphics.FeatureGraphicsLayer tempFeatureGraphicsLayer =
                            (ESRI.ArcGIS.ADF.Web.Display.Graphics.FeatureGraphicsLayer)m_graphicsDataSet.Tables[layerName];
                        // Get visibility of existing layer so when it is recreated, it's visibility is correct.  
                        // This will allow 1) setting visibility of the layer (checking\unchecking the node) in the toc 
                        // and 2) data to be updated each time the map resource is initialized.
                        layerVisible = tempFeatureGraphicsLayer.Visible;
                    }

                    // Remove the DataTable with the name matching that specified by the REXML from the
                    // resource's graphics dataset
                    m_graphicsDataSet.Tables.Remove(layerName);
                }

                // Create a new instance of FeatureGraphicsLayer to store the REXML data
                ESRI.ArcGIS.ADF.Web.Display.Graphics.FeatureGraphicsLayer featureGraphicsLayer = 
                    new ESRI.ArcGIS.ADF.Web.Display.Graphics.FeatureGraphicsLayer();
                // Set the layer's name with that specified in the REXML
                featureGraphicsLayer.TableName = layerName;
                // Set the layer's geometry type to point.  Note that this sample only supports point
                // geometries.
                featureGraphicsLayer.FeatureType = ESRI.ArcGIS.ADF.Web.FeatureType.Point;
                // Set the layer's visibility to what it was previously, or to true if the layer had not
                // yet been created
                featureGraphicsLayer.Visible = layerVisible;

                // Get renderer and marker symbol nodes from the REXML doc
                System.Xml.XmlNode rendererXmlNode = layerXmlNode.SelectSingleNode("SIMPLERENDERER");
                System.Xml.XmlNode markerSymbolXmlNode = rendererXmlNode.SelectSingleNode("SIMPLEMARKERSYMBOL");
                // Read the marker specifications from the REXML and store them in string variables
                string markerColor = markerSymbolXmlNode.Attributes.GetNamedItem("color").Value;
                string markerType = markerSymbolXmlNode.Attributes.GetNamedItem("type").Value;
                string markerWidthString = markerSymbolXmlNode.Attributes.GetNamedItem("width").Value;
                string markerOutlineColor = markerSymbolXmlNode.Attributes.GetNamedItem("outlinecolor").Value;

                // Create a Web ADF SimpleMarkerSymbol to store the symbology specified by the REXML
                ESRI.ArcGIS.ADF.Web.Display.Symbol.SimpleMarkerSymbol adfSimpleMarkerSymbol =
                    new ESRI.ArcGIS.ADF.Web.Display.Symbol.SimpleMarkerSymbol();

                // Retrieve the red, green, and blue values from the marker color string
                string[] markerRGB = markerColor.Split(',');
                int markerRed = System.Int32.Parse(markerRGB[0]);
                int markerGreen = System.Int32.Parse(markerRGB[1]);
                int markerBlue = System.Int32.Parse(markerRGB[2]);
                // Set the marker symbol's color based on the REXML values
                adfSimpleMarkerSymbol.Color = 
                    System.Drawing.Color.FromArgb(markerRed, markerGreen, markerBlue);

                // Check the marker type string value and set the shape type of the marker symbol accordingly
                switch (markerType)
                {
                    case "circle":
                        adfSimpleMarkerSymbol.Type = 
                            ESRI.ArcGIS.ADF.Web.Display.Symbol.MarkerSymbolType.Circle;
                        break;
                    case "square":
                        adfSimpleMarkerSymbol.Type = 
                            ESRI.ArcGIS.ADF.Web.Display.Symbol.MarkerSymbolType.Square;
                        break;
                    case "triangle":
                        adfSimpleMarkerSymbol.Type = 
                            ESRI.ArcGIS.ADF.Web.Display.Symbol.MarkerSymbolType.Triangle;
                        break;
                    case "star":
                        adfSimpleMarkerSymbol.Type = 
                            ESRI.ArcGIS.ADF.Web.Display.Symbol.MarkerSymbolType.Star;
                        break;
                    default:
                        break;
                }

                // Declare an integer to hold the marker width specified by the REXML
                int markerWidthInt;
                // Attempt to parse the marker width string to an integer
                if (!System.Int32.TryParse(markerWidthString, out markerWidthInt))
                {
                    // If the marker width string could not be parsed to an integer, set it to 10
                    markerWidthInt = 10;
                }
                // Set the marker symbol's width
                adfSimpleMarkerSymbol.Width = markerWidthInt;

                // Retrieve the red, green, and blue values from the marker outline color string
                string[] markerOutlineRGB = markerOutlineColor.Split(',');
                int markerOutlineRed = System.Int32.Parse(markerOutlineRGB[0]);
                int markerOutlineGreen = System.Int32.Parse(markerOutlineRGB[1]);
                int markerOutlineBlue = System.Int32.Parse(markerOutlineRGB[2]);
                // Set the outline color of the marker symbol based on the retrieved values
                adfSimpleMarkerSymbol.OutlineColor = System.Drawing.Color.FromArgb(markerOutlineRed,
                    markerOutlineGreen, markerOutlineBlue);

                // Instantiate a Web ADF renderer based on the marker symbol initialized above and 
                // initialize the graphics layer's renderer with it
                ESRI.ArcGIS.ADF.Web.Display.Renderer.SimpleRenderer adfSimplerRenderer =
                    new ESRI.ArcGIS.ADF.Web.Display.Renderer.SimpleRenderer(adfSimpleMarkerSymbol);
                featureGraphicsLayer.Renderer = adfSimplerRenderer;

                // Retrieve the first feature XML node from the REXML file
                System.Xml.XmlNode featuresXmlNode = layerXmlNode.SelectSingleNode("FEATURES");
                System.Xml.XmlNodeList featureXmlNodeList = featuresXmlNode.SelectNodes("FEATURE");

                // Iterate through all the feature nodes contained in the REXML file, and create
                // a feature in the resource's graphics layer for each
                for (int t = 0; t < featureXmlNodeList.Count; t++)
                {
                    // Declare a DataRow object to reference the row corresponding to the feature
                    // that will be created below
                    System.Data.DataRow featureDataRow = null;

                    // Get the field nodes contained within the current feature node
                    System.Xml.XmlNodeList fieldsXmlNodeList = featureXmlNodeList[t].SelectNodes("FIELD");

                    // Iterate through the field nodes
                    for (int s = 0; s < fieldsXmlNodeList.Count; s++)
                    {
                        // Check whether the name of the current field is SHAPE.  This SHAPE field should be 
                        // first for each feature in the REXML file, and the code here assumes that this is
                        // the case.
                        if (fieldsXmlNodeList[s].Attributes["name"].Value == "SHAPE")
                        {
                            // Get the field value nodes contained within the current field node
                            System.Xml.XmlNodeList fieldValuesXmlNodeList =
                                fieldsXmlNodeList[s].SelectSingleNode("FIELDVALUE").ChildNodes;

                            // Check the number of field value nodes.  If there are none, exit the loop.
                            // If there is one, create a feature graphic with the data specified by the
                            // node.  If there is more than one, do nothing - this case is not implemented
                            // in the sample.
                            if (fieldValuesXmlNodeList.Count < 1)
                            {
                                break;
                            }
                            else if (fieldValuesXmlNodeList.Count == 1)
                            {
                                // Get the field value node
                                System.Xml.XmlNode fieldValueXmlNode = fieldValuesXmlNodeList[0];
                                
                                // Make sure the node name is POINT.  Other node names are not implemented.                                
                                if (fieldValueXmlNode.Name == "POINT")
                                {
                                    // Get the x and y values stored in the node
                                    double x = double.Parse(fieldValueXmlNode.Attributes["x"].Value);
                                    double y = double.Parse(fieldValueXmlNode.Attributes["y"].Value);

                                    // Initialize a Web ADF Point with the retrieved x and y values
                                    ESRI.ArcGIS.ADF.Web.Geometry.Point adfPoint =
                                        new ESRI.ArcGIS.ADF.Web.Geometry.Point(x, y);

                                    // Add the new point to the resource's feature graphics layer, and get
                                    // a reference to the DataRow corresponding to the new feature.
                                    featureDataRow = featureGraphicsLayer.Add(adfPoint);
                                }
                            }
                            else if (fieldValuesXmlNodeList.Count > 1)
                            {
                                // More than one value exists for the shape field.  This could be
                                // the case for non-point geometries, depending on the chosen
                                // implementation.  This case is not implemented here.
                            }
                        }
                        else
                        {
                            // Get the field name from the current node
                            string fieldName = fieldsXmlNodeList[s].Attributes["name"].Value;

                            // Make sure the resource's feature graphics layer doesn't already contain
                            // a field of the same name
                            if (!featureGraphicsLayer.Columns.Contains(fieldName))
                            {
                                // Create a new String DataColumn with the current field name
                                System.Data.DataColumn dataColumn =
                                    new System.Data.DataColumn(fieldName,
                                    System.Type.GetType("System.String"));
                                // Add the column to the resource's feature graphics layer
                                featureGraphicsLayer.Columns.Add(dataColumn);
                            }

                            // Get the field value nodes contained within the current field node
                            System.Xml.XmlNode fieldValueXmlNode =
                                fieldsXmlNodeList[s].SelectSingleNode("FIELDVALUE");

                            // Get the value from the current node.  Note that this code assumes the
                            // value is stored in an XML attribute with the name "valuestring"
                            string fieldValue = fieldValueXmlNode.Attributes["valuestring"].Value;

                            // If a valid field value was found, set the value of the appropriate
                            // field in the DataRow corresponding to the current feature to that
                            // value
                            if ((fieldValue != null) && (fieldValue != System.String.Empty))
                                featureDataRow[fieldName] = fieldValue;
                        }
                    }
                }

                // Add the newly created and initialized FeatureGraphicsLayer to the resource's
                // graphics dataset
                m_graphicsDataSet.Tables.Add(featureGraphicsLayer);

                #endregion

                #region REXML data stored in an ElementGraphicsLayer
                /*
                ESRI.ArcGIS.ADF.Web.Display.Graphics.ElementGraphicsLayer elementGraphicsLayer = null;
                elementGraphicsLayer = new ESRI.ArcGIS.ADF.Web.Display.Graphics.ElementGraphicsLayer();
                elementGraphicsLayer.TableName = layerName;

                bool layerVisible = true;

                // Create graphics layer to store features
                if (m_graphicsDataSet.Tables.Contains(layerName))
                {
                    if (m_graphicsDataSet.Tables[layerName] is
                        ESRI.ArcGIS.ADF.Web.Display.Graphics.ElementGraphicsLayer)
                    {
                        ESRI.ArcGIS.ADF.Web.Display.Graphics.ElementGraphicsLayer tempElementGraphicsLayer =
                            (ESRI.ArcGIS.ADF.Web.Display.Graphics.ElementGraphicsLayer)m_graphicsDataSet.Tables[layerName];
                        // Get visibility of existing layer so when it is recreated, it's visibility is correct.  
                        // This will allow 1) setting visibility of the layer (checking\unchecking the node) in the toc 
                        // and 2) data to be updated each time the map resource is initialized.
                        layerVisible = tempElementGraphicsLayer.Visible;
                    }

                    m_graphicsDataSet.Tables.Remove(layerName);
                }

                elementGraphicsLayer.Visible = layerVisible;

                // Get renderer information
                System.Xml.XmlNode rendererXmlNode = layerXmlNode.SelectSingleNode("SIMPLERENDERER");
                System.Xml.XmlNode markerXmlNode = rendererXmlNode.SelectSingleNode("SIMPLEMARKERSYMBOL");
                string markerColor = markerXmlNode.Attributes.GetNamedItem("color").Value;
                string markerType = markerXmlNode.Attributes.GetNamedItem("type").Value;
                string markerWidthString = markerXmlNode.Attributes.GetNamedItem("width").Value;
                string markerOutlineColor = markerXmlNode.Attributes.GetNamedItem("outlinecolor").Value;

                // Create symbol set
                ESRI.ArcGIS.ADF.Web.Display.Symbol.SimpleMarkerSymbol adfSimpleMarkerSymbol = 
                    new ESRI.ArcGIS.ADF.Web.Display.Symbol.SimpleMarkerSymbol();

                string[] markerRGB = markerColor.Split(',');
                int markerRed = System.Int32.Parse(markerRGB[0]);
                int markerGreen = System.Int32.Parse(markerRGB[1]);
                int markerBlue = System.Int32.Parse(markerRGB[2]);
                adfSimpleMarkerSymbol.Color = System.Drawing.Color.FromArgb(markerRed, markerGreen, markerBlue);

                switch (markerType)
                {
                    case "circle":
                        adfSimpleMarkerSymbol.Type = 
                            ESRI.ArcGIS.ADF.Web.Display.Symbol.MarkerSymbolType.Circle;
                        break;
                    case "square":
                        adfSimpleMarkerSymbol.Type = 
                            ESRI.ArcGIS.ADF.Web.Display.Symbol.MarkerSymbolType.Square;
                        break;
                    case "triangle":
                        adfSimpleMarkerSymbol.Type = 
                            ESRI.ArcGIS.ADF.Web.Display.Symbol.MarkerSymbolType.Triangle;
                        break;
                    case "star":
                        adfSimpleMarkerSymbol.Type = 
                            ESRI.ArcGIS.ADF.Web.Display.Symbol.MarkerSymbolType.Star;
                        break;
                    default:
                        break;
                }

                int markerWidthInt;
                if (!System.Int32.TryParse(markerWidthString, out markerWidthInt))
                {
                    markerWidthInt = 10;
                }
                adfSimpleMarkerSymbol.Width = markerWidthInt;

                string[] markerOutlineRGB = markerOutlineColor.Split(',');
                int markerOutlineRed = System.Int32.Parse(markerOutlineRGB[0]);
                int markerOutlineGreen = System.Int32.Parse(markerOutlineRGB[1]);
                int markerOutlineBlue = System.Int32.Parse(markerOutlineRGB[2]);
                adfSimpleMarkerSymbol.OutlineColor = System.Drawing.Color.FromArgb(markerOutlineRed, 
                    markerOutlineGreen, markerOutlineBlue);

                // Get features
                System.Xml.XmlNode featuresXmlNode = layerXmlNode.SelectSingleNode("FEATURES");
                System.Xml.XmlNodeList featureXmlNodeList = featuresXmlNode.SelectNodes("FEATURE");

                // Get shape field and create GraphicElement
                for (int t = 0; t < featureXmlNodeList.Count; t++)
                {
                    System.Xml.XmlNodeList fieldsXmlNodeList = featureXmlNodeList[t].SelectNodes("FIELD");
                    for (int s = 0; s < fieldsXmlNodeList.Count; s++)
                    {
                        if (fieldsXmlNodeList[s].Attributes["name"].Value == "SHAPE")
                        {
                            System.Xml.XmlNodeList fieldValuesXmlNodeList = 
                                fieldsXmlNodeList[s].SelectSingleNode("FIELDVALUE").ChildNodes;
                            if (fieldValuesXmlNodeList.Count < 1)
                            {
                                break;
                            }
                            else if (fieldValuesXmlNodeList.Count == 1)
                            {

                                System.Xml.XmlNode fieldValueXmlNode = fieldValuesXmlNodeList[0];
                                if (fieldValueXmlNode.Name == "POINT")
                                {
                                    double x = double.Parse(fieldValueXmlNode.Attributes["x"].Value);
                                    double y = double.Parse(fieldValueXmlNode.Attributes["y"].Value);

                                    ESRI.ArcGIS.ADF.Web.Geometry.Point point = 
                                        new ESRI.ArcGIS.ADF.Web.Geometry.Point(x, y);
                                    ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicElement graphicElement = 
                                        new ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicElement(point, 
                                        adfSimpleMarkerSymbol);
                                    elementGraphicsLayer.Add(graphicElement);
                                }
                            }
                            else if (fieldValuesXmlNodeList.Count > 1)
                            {

                            }
                        }
                    }
                }

                m_graphicsDataSet.Tables.Add(elementGraphicsLayer);
                */
                #endregion
            }
            catch (System.Exception ex)
            {
                // Throw an exception with a user-friendly error message if the REXML data couldn't be
                // processed
                throw new System.Exception("Exception: unable to load REXML data. " + ex.Message);
            }
        }

        #endregion

        #region IMapResource Members

        // Access to the resource's MapInformation object, which stores information such as 
        // default extent, data reference, and tile cache info
        public ESRI.ArcGIS.ADF.Web.DataSources.IMapInformation MapInformation
        {
            get { return m_mapInformation; }
            set { m_mapInformation = value; }
        }

        // Access to the resource's DisplaySettings object, which determines the appearance
        // of the map resource (e.g. transparency, map visibility, TOC visibility, etc.)
        public ESRI.ArcGIS.ADF.Web.DisplaySettings DisplaySettings
        {
            get { return m_displaySettings; }
            set { m_displaySettings = value; }
        }

        #endregion

        #region IGISResource Members

        #region IGISResource Properties

        // Access to the amount of time allowed for validating the resource
        public int ValidationTimeout
        {
            get { return m_validationTimeout; }
            set { m_validationTimeout = value; }
        }

        // Access to the resource name
        public string Name
        {
            get { return m_name; }
            set { m_name = value; }
        }

        // Access to the resource's definition string.  This property is not used in this data
        // source implementation, since the information necessary to access the data underlying
        // the data source (i.e. a file path) is contained in the data source definition.  Were
        // this data source based on a web service, the data source definition could be used
        // to store the host information, while the resource definition stores the service name.
        // There are, of course, many other ways of implementing these properties.
        public string ResourceDefinition
        {
            get { return m_resourceDefinition; }
            set { m_resourceDefinition = value; }
        }

        // Access to the data source object used by the resource
        public ESRI.ArcGIS.ADF.Web.DataSources.IGISDataSource DataSource
        {
            get { return m_gisDataSource; }
            set { m_gisDataSource = value; }
        }

        // Access to the functionality objects using the resource
        public ESRI.ArcGIS.ADF.Web.DataSources.GISFunctionalityCollection Functionalities
        {
            get { return m_gisFunctionalityCollection; }
            set { m_gisFunctionalityCollection = value; }
        }

        // Access to boolean indicating whether or not the resource has been initialized
        public bool Initialized
        {
            get { return m_initialized; }
        }

        #endregion

        #region IGISResource Methods

        // Indicates whether the resource supports functionality of the passed-in type
        public bool SupportsFunctionality(System.Type functionalityType)
        {
            // Check the type of the passed in functionality.  If it is IMapFunctionality, 
            // IMapTocFunctionality, or IQueryFunctionality, return true, as these are the functionalities
            // supported by this data source implementation.  If it is none of these, return false.
            if (functionalityType == typeof(ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality)) 
                return true;
            else if (functionalityType == typeof(ESRI.ArcGIS.ADF.Web.DataSources.IMapTocFunctionality)) 
                return true;
            else if (functionalityType == typeof(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality)) 
                return true;
            else 
                return false;
        }

        // Creates a functionality object of the passed-in type
        public ESRI.ArcGIS.ADF.Web.DataSources.IGISFunctionality 
            CreateFunctionality(System.Type functionalityType, string functionalityName)
        {
            // Declare a generic functionality object to store the functionality to be returned
            ESRI.ArcGIS.ADF.Web.DataSources.IGISFunctionality gisFunctionality = null;

            // Check the type of the passed-in functoinality.  If it is one of the types supported in
            // this data source implementation, instantiate the data-source specific functionality 
            // corresponding to the passed-in type and assign a reference to that object to 
            // gisFunctionality
            if (functionalityType == typeof(ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality))
            {
                gisFunctionality = new REXMLDataSource_CSharp.MapFunctionality(functionalityName, this);
            }
            else if (functionalityType == typeof(ESRI.ArcGIS.ADF.Web.DataSources.IMapTocFunctionality))
            {
                gisFunctionality = new REXMLDataSource_CSharp.MapTocFunctionality(functionalityName, this);
            }
            else if (functionalityType == typeof(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality))
            {
                gisFunctionality = new REXMLDataSource_CSharp.QueryFunctionality(functionalityName, this);
            }
            else
            {
                // the passed-in functionality is not supported in this data source implementation, so
                // throw an exception indicating this
                throw new System.ArgumentException("functionalityType not supported");
            }
            // return the instance of the data-source specific functionality wrapped in a generic
            // functionality object
            return gisFunctionality;
        }

        // Retrieves data source state from the GISDataSource object associated with the resource and
        // applies relevant properties from saved state to the resource instance
        public void LoadState()
        {
            // Make sure that (1) the resource is associated with a REXML data source object and
            // (2) that the data source has a saved state
            if (m_gisDataSource == null) return;
            if (m_gisDataSource.State == null) return;

            // Retrieve the resource state from the data source's state table.  The key needed to pull
            // the resource's state from the table is stored in the private property ResourceStateKey
            object resourceState = m_gisDataSource.State[ResourceStateKey];

            // Check whether a state for the resource has been stored in the state table
            if (resourceState != null)
            {
                // Cast the resource state to a REXML data-source specific MapResource instance
                REXMLDataSource_CSharp.MapResource rexmlMapResource = resourceState as 
                    REXMLDataSource_CSharp.MapResource;
                // Set properties of the current instance based on the properties of the instance
                // retrieved from the state table
                m_graphicsDataSet = rexmlMapResource.m_graphicsDataSet;
                m_mapInformation = rexmlMapResource.m_mapInformation;
                m_displaySettings = rexmlMapResource.m_displaySettings;
            }
        }

        // Sets up resource properties that are data-dependent, creating and populating internal 
        // instances of the objects that will describe the data to external clients (e.g. 
        // resource functionalities).
        public void Initialize()
        {
            // Check whether the resource's MapInformation object is null and initialize it if so
            if (m_mapInformation == null)
            {
                // Instantiate a graphics dataset for use by the resource.  In this implementation,
                // the data described by the REXML document specified by the data source definition
                // will be stored in this dataset.
                m_graphicsDataSet = new ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsDataSet();

                // To initialize once on load, use the following two lines
                //string dataSourceConfig = m_gisDataSource.DataSourceDefinition;
                //ProcessREXML(dataSourceConfig);

                m_mapInformation = new REXMLDataSource_CSharp.MapInformation(m_graphicsDataSet);
                if (m_displaySettings != null) 
                    m_graphicsDataSet.ImageDescriptor = m_displaySettings.ImageDescriptor;
            }
            
            // To initialize and read from the data source during each postback, use the following lines.  
            // This will be valuable when data source content changes during a session.           

            // Retrieve the underlying data source definition from the GISDataSource object referred
            // to by the resource instance
            string dataSourceConfig = m_gisDataSource.DataSourceDefinition;
            // Call the method that retrieves feature data from the REXML file underlying the data source
            // instance, creates Web ADF graphics based on that data, and populates the resource's graphics
            // data set with those graphics.
            ProcessREXML(dataSourceConfig);

            // Set the flag indicating whether the resource has been intialized to true
            m_initialized = true;
        }
        
        // Stores the current resource instance in the GISDataSource's state table
        public void SaveState()
        {
            // Make sure the resource references a valid GISDataSource object
            if (m_gisDataSource == null) return;
            // Make sure the referenced GISDataSource object has a valid state table
            if (m_gisDataSource.State == null) return;
            // Store the resource instance in the GISDataSource's state table at the key provided
            // by the resource's ResourceStateKey property
            m_gisDataSource.State[ResourceStateKey] = this;
        }

        // Sets the flag indicating whether the resource is initialized to false.
        public void Dispose()
        {
            m_initialized = false;
        }

        // Removes a reference to the current resource instance from the GISDataSource's state table
        public void ClearState()
        {
            // Make sure the resource references a valid GISDataSource object
            if (m_gisDataSource == null) return;
            // Make sure the referenced GISDataSource object has a valid state table
            if (m_gisDataSource.State == null) return;
            // Set the value in the GISDataSource's state table at the key provided by the resource's
            // ResourceStateKey property to null
            m_gisDataSource.State[ResourceStateKey] = null;
        }

        #endregion

        #endregion

    }
}