#region Disclaimer / License
// Copyright (C) 2009, Kenneth Skovhede
// http://www.hexad.dk, opensource@hexad.dk
//
// 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.Xml;
using System.Collections.Generic;
namespace OSGeo.MapGuide.MaestroAPI
{
///
/// Dummy class that represents an unknown data type
///
public class UnmappedDataType
{
}
///
/// Class that represents a the layout of a datasource
///
public class FeatureSourceDescription
{
private FeatureSourceSchema[] m_schemas;
public FeatureSourceDescription(System.IO.Stream stream)
{
XmlDocument doc = new XmlDocument();
doc.Load(stream);
if (doc.FirstChild.Name != "xml")
throw new Exception("Bad document");
XmlNode root;
if (doc.ChildNodes.Count == 2 && doc.ChildNodes[1].Name == "fdo:DataStore")
root = doc.ChildNodes[1];
else if (doc.ChildNodes.Count != 2 || doc.ChildNodes[1].Name != "xs:schema")
throw new Exception("Bad document");
else
root = doc;
XmlNamespaceManager mgr = new XmlNamespaceManager(doc.NameTable);
mgr.AddNamespace("xs", "http://www.w3.org/2001/XMLSchema");
mgr.AddNamespace("gml", "http://www.opengis.net/gml");
mgr.AddNamespace("fdo", "http://fdo.osgeo.org/schemas");
var keys = new Dictionary();
var classMap = new Dictionary();
XmlNodeList lst = root.SelectNodes("xs:schema/xs:complexType[@abstract='false']", mgr);
m_schemas = new FeatureSourceSchema[lst.Count];
for (int i = 0; i < m_schemas.Length; i++)
{
m_schemas[i] = new FeatureSourceSchema(lst[i], mgr);
classMap.Add(m_schemas[i].FullnameDecoded, m_schemas[i]);
}
XmlNodeList keyNodes = root.SelectNodes("xs:schema/xs:element[@abstract='false']", mgr);
foreach (XmlNode keyNode in keyNodes)
{
var typeAttr = keyNode.Attributes["type"];
if (typeAttr != null)
{
string clsName = typeAttr.Value.Substring(0, typeAttr.Value.Length - 4); //class name is suffixed with type
if (classMap.ContainsKey(clsName))
{
List keyFieldNames = new List();
var cls = classMap[clsName];
XmlNodeList keyFields = keyNode.SelectNodes("xs:key/xs:field", mgr);
foreach (XmlNode keyField in keyFields)
{
var xpathAttr = keyField.Attributes["xpath"];
if (xpathAttr != null)
{
keyFieldNames.Add(xpathAttr.Value);
}
}
cls.MarkIdentityProperties(keyFieldNames);
}
}
}
}
public FeatureSourceSchema[] Schemas { get { return m_schemas; } }
public FeatureSourceSchema this[int index] { get { return m_schemas[index]; } }
public FeatureSourceSchema this[string index]
{
get
{
for(int i =0 ;i 0)
m_schema = m_schema.Substring(m_schema.LastIndexOf("/") + 1);
m_name = node.Attributes["name"].Value;
if (m_name.EndsWith("Type"))
m_name = m_name.Substring(0, m_name.Length - "Type".Length);
XmlNodeList lst;
if (node.ChildNodes.Count == 0)
{
m_columns = new FeatureSetColumn[0];
return;
}
else if (node.FirstChild.Name == "xs:sequence")
lst = node.SelectNodes("xs:sequence/xs:element", mgr);
else
lst = node.SelectNodes("xs:complexContent/xs:extension/xs:sequence/xs:element", mgr);
m_columns = new FeatureSetColumn[lst.Count];
for(int i = 0;i keyFieldNames)
{
foreach (var name in keyFieldNames)
{
foreach (var col in m_columns)
{
if (col.Name.Equals(name))
{
col.IsIdentity = true;
}
}
}
}
public string[] GetIdentityProperties()
{
List keys = new List();
foreach (var col in m_columns)
{
if (col.IsIdentity)
keys.Add(col.Name);
}
return keys.ToArray();
}
}
}
internal class ClassPropertyColumn : XmlFeatureSetColumn
{
internal ClassPropertyColumn(XmlNode node) : base(node) { }
}
}