#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) { } } }