Common Custom data source
Common_CustomDataSource_VBNet\REXMLDataSource_VBNet\MapResource.vb
' 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.
' 


Imports Microsoft.VisualBasic
Imports System
Namespace REXMLDataSource_VBNet
    ' 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
        Implements ESRI.ArcGIS.ADF.Web.DataSources.IMapResource
#Region "Instance Variables"

        Private m_mapInformation As ESRI.ArcGIS.ADF.Web.DataSources.IMapInformation = Nothing
        Private m_displaySettings As ESRI.ArcGIS.ADF.Web.DisplaySettings = Nothing
        Private m_initialized As Boolean = False
        Private m_name As String = String.Empty
        Private m_resourceDefinition As String = String.Empty
        Private m_gisDataSource As ESRI.ArcGIS.ADF.Web.DataSources.IGISDataSource = Nothing
        Private m_gisFunctionalityCollection As ESRI.ArcGIS.ADF.Web.DataSources.GISFunctionalityCollection = New ESRI.ArcGIS.ADF.Web.DataSources.GISFunctionalityCollection()
        Private m_validationTimeout As Integer = 0
        Private m_graphicsDataSet As ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsDataSet = Nothing

#End Region

#Region "Constructors"

        ' Allow instantiation without defining any properties
        Public Sub New()
        End Sub

        ' Explicitly set instance properties in cases where the class is instantiated with
        ' name and data source
        Public Sub New(ByVal name As String, ByVal dataSource As REXMLDataSource_VBNet.GISDataSource)
            m_name = name
            m_gisDataSource = dataSource
        End Sub

#End Region

#Region "REXML MapResource Members"

        ' Access to the graphics dataset containing the features specified by
        ' the REXML file underlying the data source
        Public ReadOnly Property Graphics() As ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsDataSet
            Get
                Return m_graphicsDataSet
            End Get
        End Property

        ' Key for storing and retrieving object state to and from the data source's state table
        Private ReadOnly Property ResourceStateKey() As String
            Get
                Dim tmp As String = Me.GetType().ToString() & ":" & m_name
                Return (tmp)
            End Get
        End Property

        ' Reads the data from the REXML file referenced by the data source and stores it in a
        ' Web ADF FeatureGraphicsLayer or ElementGraphicsLayer
        Private Sub ProcessREXML(ByVal dataSourceConfig As String)
            Try

                ' Get a reference to the REXML file underlying the data source
                Dim xmlDocument As System.Xml.XmlDocument = New System.Xml.XmlDocument()
                xmlDocument.Load(dataSourceConfig)

                ' Get the root node of the REXML document
                Dim rootXmlNode As System.Xml.XmlNode = xmlDocument.DocumentElement

                ' Get the layer name and id as defined in the REXML doc
                Dim layerXmlNode As System.Xml.XmlNode = rootXmlNode.SelectSingleNode("LAYER")
                Dim layerName As String = layerXmlNode.Attributes.GetNamedItem("name").Value
                Dim layerId As String = 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
                Dim layerVisible As Boolean = 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) Then
                    ' 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 TypeOf m_graphicsDataSet.Tables(layerName) Is ESRI.ArcGIS.ADF.Web.Display.Graphics.FeatureGraphicsLayer Then
                        ' Get a reference to the existing FeatureGraphicsLayer
                        Dim tempFeatureGraphicsLayer As ESRI.ArcGIS.ADF.Web.Display.Graphics.FeatureGraphicsLayer = CType(m_graphicsDataSet.Tables(layerName), ESRI.ArcGIS.ADF.Web.Display.Graphics.FeatureGraphicsLayer)
                        ' 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
                    End If

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

                ' Create a new instance of FeatureGraphicsLayer to store the REXML data
                Dim featureGraphicsLayer As ESRI.ArcGIS.ADF.Web.Display.Graphics.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
                Dim rendererXmlNode As System.Xml.XmlNode = layerXmlNode.SelectSingleNode("SIMPLERENDERER")
                Dim markerSymbolXmlNode As System.Xml.XmlNode = rendererXmlNode.SelectSingleNode("SIMPLEMARKERSYMBOL")
                ' Read the marker specifications from the REXML and store them in string variables
                Dim markerColor As String = markerSymbolXmlNode.Attributes.GetNamedItem("color").Value
                Dim markerType As String = markerSymbolXmlNode.Attributes.GetNamedItem("type").Value
                Dim markerWidthString As String = markerSymbolXmlNode.Attributes.GetNamedItem("width").Value
                Dim markerOutlineColor As String = markerSymbolXmlNode.Attributes.GetNamedItem("outlinecolor").Value

                ' Create a Web ADF SimpleMarkerSymbol to store the symbology specified by the REXML
                Dim adfSimpleMarkerSymbol As ESRI.ArcGIS.ADF.Web.Display.Symbol.SimpleMarkerSymbol = New ESRI.ArcGIS.ADF.Web.Display.Symbol.SimpleMarkerSymbol()

                ' Retrieve the red, green, and blue values from the marker color string
                Dim markerRGB As String() = markerColor.Split(","c)
                Dim markerRed As Integer = System.Int32.Parse(markerRGB(0))
                Dim markerGreen As Integer = System.Int32.Parse(markerRGB(1))
                Dim markerBlue As Integer = 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
                Select Case markerType
                    Case "circle"
                        adfSimpleMarkerSymbol.Type = ESRI.ArcGIS.ADF.Web.Display.Symbol.MarkerSymbolType.Circle
                    Case "square"
                        adfSimpleMarkerSymbol.Type = ESRI.ArcGIS.ADF.Web.Display.Symbol.MarkerSymbolType.Square
                    Case "triangle"
                        adfSimpleMarkerSymbol.Type = ESRI.ArcGIS.ADF.Web.Display.Symbol.MarkerSymbolType.Triangle
                    Case "star"
                        adfSimpleMarkerSymbol.Type = ESRI.ArcGIS.ADF.Web.Display.Symbol.MarkerSymbolType.Star
                    Case Else
                End Select

                ' Declare an integer to hold the marker width specified by the REXML
                Dim markerWidthInt As Integer
                ' Attempt to parse the marker width string to an integer
                If (Not System.Int32.TryParse(markerWidthString, markerWidthInt)) Then
                    ' If the marker width string could not be parsed to an integer, set it to 10
                    markerWidthInt = 10
                End If
                ' Set the marker symbol's width
                adfSimpleMarkerSymbol.Width = markerWidthInt

                ' Retrieve the red, green, and blue values from the marker outline color string
                Dim markerOutlineRGB As String() = markerOutlineColor.Split(","c)
                Dim markerOutlineRed As Integer = System.Int32.Parse(markerOutlineRGB(0))
                Dim markerOutlineGreen As Integer = System.Int32.Parse(markerOutlineRGB(1))
                Dim markerOutlineBlue As Integer = 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
                Dim adfSimplerRenderer As ESRI.ArcGIS.ADF.Web.Display.Renderer.SimpleRenderer = New ESRI.ArcGIS.ADF.Web.Display.Renderer.SimpleRenderer(adfSimpleMarkerSymbol)
                featureGraphicsLayer.Renderer = adfSimplerRenderer

                ' Retrieve the first feature XML node from the REXML file
                Dim featuresXmlNode As System.Xml.XmlNode = layerXmlNode.SelectSingleNode("FEATURES")
                Dim featureXmlNodeList As System.Xml.XmlNodeList = 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
                Dim t As Integer = 0
                Do While t < featureXmlNodeList.Count
                    ' Declare a DataRow object to reference the row corresponding to the feature
                    ' that will be created below
                    Dim featureDataRow As System.Data.DataRow = Nothing

                    ' Get the field nodes contained within the current feature node
                    Dim fieldsXmlNodeList As System.Xml.XmlNodeList = featureXmlNodeList(t).SelectNodes("FIELD")

                    ' Iterate through the field nodes
                    Dim s As Integer = 0
                    Do While s < fieldsXmlNodeList.Count
                        ' 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" Then
                            ' Get the field value nodes contained within the current field node
                            Dim fieldValuesXmlNodeList As System.Xml.XmlNodeList = 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 Then
                                Exit Do
                            ElseIf fieldValuesXmlNodeList.Count = 1 Then
                                ' Get the field value node
                                Dim fieldValueXmlNode As System.Xml.XmlNode = fieldValuesXmlNodeList(0)

                                ' Make sure the node name is POINT.  Other node names are not implemented.                                
                                If fieldValueXmlNode.Name = "POINT" Then
                                    ' Get the x and y values stored in the node
                                    Dim x As Double = Double.Parse(fieldValueXmlNode.Attributes("x").Value)
                                    Dim y As Double = Double.Parse(fieldValueXmlNode.Attributes("y").Value)

                                    ' Initialize a Web ADF Point with the retrieved x and y values
                                    Dim adfPoint As ESRI.ArcGIS.ADF.Web.Geometry.Point = 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)
                                End If
                            ElseIf fieldValuesXmlNodeList.Count > 1 Then
                                ' 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.
                            End If
                        Else
                            ' Get the field name from the current node
                            Dim fieldName As String = fieldsXmlNodeList(s).Attributes("name").Value

                            ' Make sure the resource's feature graphics layer doesn't already contain
                            ' a field of the same name
                            If (Not featureGraphicsLayer.Columns.Contains(fieldName)) Then
                                ' Create a new String DataColumn with the current field name
                                Dim dataColumn As System.Data.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)
                            End If

                            ' Get the field value nodes contained within the current field node
                            Dim fieldValueXmlNode As System.Xml.XmlNode = 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"
                            Dim fieldValue As String = 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 (Not fieldValue Is Nothing) AndAlso (fieldValue <> System.String.Empty) Then
                                featureDataRow(fieldName) = fieldValue
                            End If
                        End If
                        s += 1
                    Loop
                    t += 1
                Loop

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

                '        #End Region

                '        #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);
                '
                '        #End Region
            Catch ex As System.Exception
                ' 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)
            End Try
        End Sub

#End Region

#Region "IMapResource Members"

        ' Access to the resource's MapInformation object, which stores information such as 
        ' default extent, data reference, and tile cache info
        Public ReadOnly Property MapInformation() As ESRI.ArcGIS.ADF.Web.DataSources.IMapInformation Implements ESRI.ArcGIS.ADF.Web.DataSources.IMapResource.MapInformation
            Get
                Return m_mapInformation
            End Get
        End Property

        ' Access to the resource's DisplaySettings object, which determines the appearance
        ' of the map resource (e.g. transparency, map visibility, TOC visibility, etc.)
        Public Property DisplaySettings() As ESRI.ArcGIS.ADF.Web.DisplaySettings Implements ESRI.ArcGIS.ADF.Web.DataSources.IMapResource.DisplaySettings
            Get
                Return m_displaySettings
            End Get
            Set(ByVal value As ESRI.ArcGIS.ADF.Web.DisplaySettings)
                m_displaySettings = Value
            End Set
        End Property

#End Region

#Region "IGISResource Members"

#Region "IGISResource Properties"

        ' Access to the amount of time allowed for validating the resource
        Public Property ValidationTimeout() As Integer Implements ESRI.ArcGIS.ADF.Web.DataSources.IMapResource.ValidationTimeout
            Get
                Return m_validationTimeout
            End Get
            Set(ByVal value As Integer)
                m_validationTimeout = Value
            End Set
        End Property

        ' Access to the resource name
        Public Property Name() As String Implements ESRI.ArcGIS.ADF.Web.DataSources.IMapResource.Name
            Get
                Return m_name
            End Get
            Set(ByVal value As String)
                m_name = Value
            End Set
        End Property

        ' 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 Property ResourceDefinition() As String Implements ESRI.ArcGIS.ADF.Web.DataSources.IMapResource.ResourceDefinition
            Get
                Return m_resourceDefinition
            End Get
            Set(ByVal value As String)
                m_resourceDefinition = Value
            End Set
        End Property

        ' Access to the data source object used by the resource
        Public Property DataSource() As ESRI.ArcGIS.ADF.Web.DataSources.IGISDataSource Implements ESRI.ArcGIS.ADF.Web.DataSources.IMapResource.DataSource
            Get
                Return m_gisDataSource
            End Get
            Set(ByVal value As ESRI.ArcGIS.ADF.Web.DataSources.IGISDataSource)
                m_gisDataSource = Value
            End Set
        End Property

        ' Access to the functionality objects using the resource
        Public Property Functionalities() As ESRI.ArcGIS.ADF.Web.DataSources.GISFunctionalityCollection Implements ESRI.ArcGIS.ADF.Web.DataSources.IMapResource.Functionalities
            Get
                Return m_gisFunctionalityCollection
            End Get
            Set(ByVal value As ESRI.ArcGIS.ADF.Web.DataSources.GISFunctionalityCollection)
                m_gisFunctionalityCollection = Value
            End Set
        End Property

        ' Access to boolean indicating whether or not the resource has been initialized
        Public ReadOnly Property Initialized() As Boolean Implements ESRI.ArcGIS.ADF.Web.DataSources.IMapResource.Initialized
            Get
                Return m_initialized
            End Get
        End Property

#End Region

#Region "IGISResource Methods"

        ' Indicates whether the resource supports functionality of the passed-in type
        Public Function SupportsFunctionality(ByVal functionalityType As System.Type) As Boolean Implements ESRI.ArcGIS.ADF.Web.DataSources.IMapResource.SupportsFunctionality
            ' 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 Is GetType(ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality) Then
                Return True
            ElseIf functionalityType Is GetType(ESRI.ArcGIS.ADF.Web.DataSources.IMapTocFunctionality) Then
                Return True
            ElseIf functionalityType Is GetType(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality) Then
                Return True
            Else
                Return False
            End If
        End Function

        ' Creates a functionality object of the passed-in type
        Public Function CreateFunctionality(ByVal functionalityType As System.Type, ByVal functionalityName As String) As ESRI.ArcGIS.ADF.Web.DataSources.IGISFunctionality Implements ESRI.ArcGIS.ADF.Web.DataSources.IMapResource.CreateFunctionality
            ' Declare a generic functionality object to store the functionality to be returned
            Dim gisFunctionality As ESRI.ArcGIS.ADF.Web.DataSources.IGISFunctionality = Nothing

            ' 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 Is GetType(ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality) Then
                gisFunctionality = New REXMLDataSource_VBNet.MapFunctionality(functionalityName, Me)
            ElseIf functionalityType Is GetType(ESRI.ArcGIS.ADF.Web.DataSources.IMapTocFunctionality) Then
                gisFunctionality = New REXMLDataSource_VBNet.MapTocFunctionality(functionalityName, Me)
            ElseIf functionalityType Is GetType(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality) Then
                gisFunctionality = New REXMLDataSource_VBNet.QueryFunctionality(functionalityName, Me)
            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")
            End If
            ' return the instance of the data-source specific functionality wrapped in a generic
            ' functionality object
            Return gisFunctionality
        End Function

        ' Retrieves data source state from the GISDataSource object associated with the resource and
        ' applies relevant properties from saved state to the resource instance
        Public Sub LoadState() Implements ESRI.ArcGIS.ADF.Web.DataSources.IMapResource.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 Is Nothing Then
                Return
            End If
            If m_gisDataSource.State Is Nothing Then
                Return
            End If

            ' 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
            Dim resourceState As Object = m_gisDataSource.State(ResourceStateKey)

            ' Check whether a state for the resource has been stored in the state table
            If Not resourceState Is Nothing Then
                ' Cast the resource state to a REXML data-source specific MapResource instance
                Dim rexmlMapResource As REXMLDataSource_VBNet.MapResource = TryCast(resourceState, REXMLDataSource_VBNet.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
            End If
        End Sub

        ' 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 Sub Initialize() Implements ESRI.ArcGIS.ADF.Web.DataSources.IMapResource.Initialize
            ' Check whether the resource's MapInformation object is null and initialize it if so
            If m_mapInformation Is Nothing Then
                ' 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_VBNet.MapInformation(m_graphicsDataSet)
                If Not m_displaySettings Is Nothing Then
                    m_graphicsDataSet.ImageDescriptor = m_displaySettings.ImageDescriptor
                End If
            End If

            ' 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
            Dim dataSourceConfig As String = 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
        End Sub

        ' Stores the current resource instance in the GISDataSource's state table
        Public Sub SaveState() Implements ESRI.ArcGIS.ADF.Web.DataSources.IMapResource.SaveState
            ' Make sure the resource references a valid GISDataSource object
            If m_gisDataSource Is Nothing Then
                Return
            End If
            ' Make sure the referenced GISDataSource object has a valid state table
            If m_gisDataSource.State Is Nothing Then
                Return
            End If
            ' Store the resource instance in the GISDataSource's state table at the key provided
            ' by the resource's ResourceStateKey property
            m_gisDataSource.State(ResourceStateKey) = Me
        End Sub

        ' Sets the flag indicating whether the resource is initialized to false.
        Public Sub Dispose() Implements ESRI.ArcGIS.ADF.Web.DataSources.IMapResource.Dispose
            m_initialized = False
        End Sub

        ' Removes a reference to the current resource instance from the GISDataSource's state table
        Public Sub ClearState() Implements ESRI.ArcGIS.ADF.Web.DataSources.IMapResource.ClearState
            ' Make sure the resource references a valid GISDataSource object
            If m_gisDataSource Is Nothing Then
                Return
            End If
            ' Make sure the referenced GISDataSource object has a valid state table
            If m_gisDataSource.State Is Nothing Then
                Return
            End If
            ' 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) = Nothing
        End Sub

#End Region

#End Region

    End Class
End Namespace