#region Disclaimer / License
// Copyright (C) 2010, Jackie Ng
// http://trac.osgeo.org/mapguide/wiki/maestro, jumpinjackie@gmail.com
//
// 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.Collections.Generic;
using System.Text;
using System.Collections.ObjectModel;
using System.Xml;
namespace OSGeo.MapGuide.MaestroAPI.Schema
{
///
/// Contains all of the classes and relationships that make up a particular data model. This class is used to
/// represent the internal logical structure of a Feature Source
///
public class FeatureSchema : SchemaElement, IFdoSerializable
{
private List _classes;
internal FeatureSchema() { _classes = new List(); }
///
/// Initializes a new instance of the class.
///
/// The name.
/// The description.
public FeatureSchema(string name, string description)
: this()
{
this.Name = name;
this.Description = description;
}
///
/// Gets the class definitions
///
public ReadOnlyCollection Classes
{
get { return _classes.AsReadOnly(); }
}
///
/// Adds the specified class definition
///
///
public void AddClass(ClassDefinition cls)
{
_classes.Add(cls);
cls.Parent = this;
}
///
/// Removes the specified class definition
///
///
///
public bool RemoveClass(ClassDefinition cls)
{
if (_classes.Remove(cls))
{
cls.Parent = null;
return true;
}
return false;
}
///
/// Returns the Class Definition by its name
///
///
/// The matching Class Definition. null if it doesn't exist
public ClassDefinition GetClass(string name)
{
foreach (var cls in _classes)
{
if (cls.Name.Equals(name))
return cls;
}
return null;
}
///
/// Gets the index of the specified class definition
///
///
///
public int IndexOf(ClassDefinition cls) { return _classes.IndexOf(cls); }
///
/// Gets the class definition at the specified index
///
///
///
public ClassDefinition this[int index]
{
get { return GetItem(index); }
}
///
/// Gets the class definition at the specified index
///
///
///
public ClassDefinition GetItem(int index) { return _classes[index]; }
///
/// Writes the current element's content
///
///
///
public void WriteXml(System.Xml.XmlDocument doc, System.Xml.XmlNode currentNode)
{
var schema = doc.CreateElement("xs", "schema", XmlNamespaces.XS);
schema.SetAttribute("xmlns:xs", XmlNamespaces.XS);
schema.SetAttribute("targetNamespace", XmlNamespaces.FDO + "/feature/" + this.Name);
schema.SetAttribute("xmlns:fdo", XmlNamespaces.FDO);
schema.SetAttribute("xmlns:" + this.Name, XmlNamespaces.FDO + "/feature/" + this.Name);
schema.SetAttribute("elementFormDefault", "qualified");
schema.SetAttribute("attributeFormDefault", "unqualified");
//Write description node
var anno = doc.CreateElement("xs", "annotation", XmlNamespaces.XS); //NOXLATE
var docN = doc.CreateElement("xs", "documentation", XmlNamespaces.XS); //NOXLATE
docN.InnerText = this.Description;
schema.AppendChild(anno);
anno.AppendChild(docN);
foreach (var cls in this.Classes)
{
cls.WriteXml(doc, schema);
}
currentNode.AppendChild(schema);
}
///
/// Set the current element's content from the current XML node
///
///
///
public void ReadXml(System.Xml.XmlNode node, System.Xml.XmlNamespaceManager mgr)
{
if (!node.Name.Equals("xs:schema"))
throw new Exception("Bad document. Expected element: xs:schema"); //LOCALIZEME
//Description
var docNode = node.SelectSingleNode("xs:annotation/xs:documentation", mgr); //NOXLATE
if (docNode != null)
this.Description = docNode.InnerText;
var tns = node.Attributes["targetNamespace"];
if (tns == null)
throw new Exception("Bad document. Expected attribute: targetNamespace"); //LOCALIZEME
int lidx = tns.Value.LastIndexOf("/") + 1;
this.Name = tns.Value.Substring(lidx);
//TODO: Description
//Now handle classes
if (node.ChildNodes.Count > 0)
{
XmlNodeList clsNodes = node.SelectNodes("xs:complexType", mgr);
foreach (XmlNode clsNode in clsNodes)
{
var nn = clsNode.Attributes["name"];
if (nn == null)
throw new Exception("Bad document. Expected attribute: name"); //LOCALIZEME
string name = Utility.DecodeFDOName(nn.Value.Substring(0, nn.Value.Length - "Type".Length));
ClassDefinition cls = new ClassDefinition(name, string.Empty); //TODO: Description
cls.ReadXml(clsNode, mgr);
this.AddClass(cls);
}
}
}
///
/// Removes a class definition by its name
///
///
public void RemoveClass(string className)
{
var cls = GetClass(className);
if (cls != null)
RemoveClass(cls);
}
}
}