using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Data;
using CategoryTheory;
using MathGraph;
namespace DiagramUI
{
/// <summary>
/// Delegate of object checking
/// </summary>
/// <param name="obj">The object</param>
/// <returns>True if object is checked and false otherwise</returns>
public delegate bool CheckObject(object obj);
/// <summary>
/// Base class of desktop
/// </summary>
public class PureDesktop : IDesktop
{
#region Fields
protected ArrayList objects = new ArrayList();
protected ArrayList arrows = new ArrayList();
protected ArrayList components = new ArrayList();
protected Hashtable table = new Hashtable();
static private Hashtable resources;
#endregion
#region Ctor
public PureDesktop()
{
}
#endregion
#region IDesktop Members
public ArrayList Components
{
get
{
return components;
}
}
/// <summary>
/// All components
/// </summary>
public virtual ICollection AllComponents
{
get
{
return components;
}
}
public ArrayList Objects
{
get
{
return objects;
}
}
public ArrayList Arrows
{
get
{
return arrows;
}
}
public virtual void Copy(ArrayList objects, ArrayList arrows, bool associated)
{
PureObjectLabel.Wrappers = true;
foreach (IObjectLabel l in objects)
{
IObjectLabel lab = new PureObjectLabel(l.Name, l.Kind, l.Type, l.X, l.Y);
lab.Object = l.Object;
lab.Desktop = this;
this.objects.Add(lab);
components.Add(lab);
table[l.Name] = lab;
}
PureObjectLabel.Wrappers = false;
foreach (IArrowLabel l in arrows)
{
IArrowLabel lab = new PureArrowLabel(l.Name, l.Kind, l.Type, l.X, l.Y);
lab.Arrow = l.Arrow;
lab.Desktop = this;
this.arrows.Add(lab);
components.Add(lab);
table[l.Name] = lab;
int s = objects.IndexOf(l.Source);
int t = objects.IndexOf(l.Target);
IObjectLabel source = this.objects[s] as IObjectLabel;
IObjectLabel target = this.objects[t] as IObjectLabel;
lab.Source = source;
lab.Target = target;
}
if (!associated)
{
PureObjectLabel.Wrappers = false;
return;
}
PureObjectLabel.Wrappers = true;
PureObjectLabel.SetLabels(objects);
PureArrowLabel.SetLabels(arrows);
PureObjectLabel.Wrappers = false;
}
/// <summary>
/// Access to component
/// </summary>
/// <param name="name">Component name</param>
/// <returns>The component</returns>
public virtual INamedComponent this[string name]
{
get
{
if (!table.ContainsKey(name))
{
return null;
}
return table[name] as INamedComponent;
}
}
/// <summary>
/// Access to object
/// </summary>
/// <param name="name">Object name</param>
/// <returns>The object</returns>
public object GetObject(string name)
{
return GetAssociatedObject(this, name);
}
/// <summary>
/// Root desktop
/// </summary>
public virtual IDesktop Root
{
get
{
return this;
}
}
#endregion
#region Specific members
/// <summary>
/// Gets texts of elements
/// </summary>
/// <param name="element">Parent none</param>
/// <param name="tag">Tag name</param>
/// <returns>List of texts</returns>
public static List<string> GetTexts(XmlElement element, string tag)
{
List<string> l = new List<string>();
XmlNodeList list = element.GetElementsByTagName(tag);
foreach (XmlNode node in list)
{
l.Add(node.InnerText);
}
return l;
}
/// <summary>
/// Sets texts to childen elements
/// </summary>
/// <param name="doc">Parent document</param>
/// <param name="element">Parent element</param>
/// <param name="tag">Tag name</param>
/// <param name="list">List</param>
public static void SetTexts(XmlDocument doc, XmlElement element, string tag, List<string> list)
{
foreach (string s in list)
{
XmlElement e = doc.CreateElement(tag);
e.InnerText = s;
element.AppendChild(e);
}
}
/// <summary>
/// Creates table from Xml element
/// </summary>
/// <param name="element">The element</param>
/// <param name="tag">Tag</param>
/// <param name="attributes">Attributes</param>
/// <returns>The table</returns>
public static DataTable CreateTable(XmlElement element, string tag, string[] attributes)
{
DataTable table = new DataTable(tag);
foreach (string attr in attributes)
{
table.Columns.Add(attr, "".GetType());
}
XmlNodeList list = element.GetElementsByTagName(tag);
foreach (XmlElement e in list)
{
object[] o = new object[attributes.Length];
for (int i = 0; i < attributes.Length; i++)
{
o[i] = e.Attributes[attributes[i]].Value;
}
table.Rows.Add(o);
}
return table;
}
public static DataTable CreateTable(XmlElement element, string tag, string[] attributes, Type[] types)
{
DataTable table = new DataTable(tag);
for (int i = 0; i < attributes.Length; i++)
{
table.Columns.Add(attributes[i], types[i]);
}
XmlNodeList list = element.GetElementsByTagName(tag);
foreach (XmlElement e in list)
{
object[] o = new object[attributes.Length];
for (int i = 0; i < attributes.Length; i++)
{
string s = e.Attributes[attributes[i]].Value;
o[i] = Create(s, types[i]);
}
table.Rows.Add(o);
}
return table;
}
protected static object Create(string s, Type type)
{
if (type.Equals(typeof(string)))
{
return s;
}
if (type.Equals(typeof(int)))
{
return Int32.Parse(s);
}
return null;
}
/// <summary>
/// Create nodes from Xml element
/// </summary>
/// <param name="doc">Parent document</param>
/// <param name="element">Element</param>
/// <param name="tag">Tag</param>
/// <param name="table">Tablr</param>
public static void CreateNodes(XmlDocument doc, XmlElement element, string tag, DataTable table)
{
foreach (DataRow row in table.Rows)
{
XmlElement e = doc.CreateElement(tag);
element.AppendChild(e);
foreach (DataColumn c in table.Columns)
{
string n = c.ColumnName;
XmlAttribute attr = doc.CreateAttribute(n);
attr.Value = row[n] + "";
e.Attributes.Append(attr);
}
}
}
/// <summary>
/// Gets object name
/// </summary>
/// <param name="ao">Object</param>
/// <returns>The name</returns>
public static string GetObjectName(IAssociatedObject ao)
{
object o = ao.Object;
if (!(o is INamedComponent))
{
throw new Exception();
}
INamedComponent nc = o as INamedComponent;
return nc.Name + "";
}
/// <summary>
/// Gets relative name
/// </summary>
/// <param name="source">Source</param>
/// <param name="target">Target</param>
/// <returns>The relative name</returns>
static public string GetRelativeName(IAssociatedObject source, IAssociatedObject target)
{
INamedComponent cs = source.Object as INamedComponent;
INamedComponent ct = target.Object as INamedComponent;
return ct.GetName(ct.Desktop);
}
/// <summary>
/// Sets value of alias variable
/// </summary>
/// <param name="desktop">Desktop</param>
/// <param name="alias">The alias name</param>
/// <param name="val">The alias value</param>
static public void SetAliasValue(IDesktop desktop, string alias, object val)
{
int n = alias.LastIndexOf('.');
string cName = alias.Substring(0, n);
INamedComponent c = desktop[cName];
string alName = alias.Substring(n + 1);
IAlias al = null;
if (c is IObjectLabel)
{
IObjectLabel ol = c as IObjectLabel;
al = ol.Object as IAlias;
}
if (c is IArrowLabel)
{
IArrowLabel ar = c as IArrowLabel;
al = ar.Arrow as IAlias;
}
al[alName] = val;
}
/// <summary>
/// Gets alias value
/// </summary>
/// <param name="desktop">Desktop</param>
/// <param name="alias">The alias name</param>
/// <returns>The alias value</returns>
static public object GetAliasValue(IDesktop desktop, string alias)
{
int n = alias.IndexOf('.');
string cName = alias.Substring(0, n);
INamedComponent c = desktop[cName];
string alName = alias.Substring(n + 1);
IAlias al = null;
if (c is IObjectLabel)
{
IObjectLabel ol = c as IObjectLabel;
al = ol.Object as IAlias;
}
if (c is IArrowLabel)
{
IArrowLabel ar = c as IArrowLabel;
al = ar.Arrow as IAlias;
}
return al[alName];
}
static public IArrowLabel GetArrowLabel(IDesktop desktop, string name)
{
object o = desktop[name];
if (o == null)
{
return null;
}
if (!(o is IArrowLabel))
{
return null;
}
return o as IArrowLabel;
}
/// <summary>
/// Gets associated object of desktop component
/// </summary>
/// <param name="desktop">Desktop</param>
/// <param name="name">Component name</param>
/// <returns>Associated object</returns>
public static object GetAssociatedObject(IDesktop desktop, string name)
{
INamedComponent comp = desktop[name];
if (comp is IObjectLabel)
{
IObjectLabel lab = comp as IObjectLabel;
return lab.Object;
}
if (comp is IArrowLabel)
{
IArrowLabel lab = comp as IArrowLabel;
return lab.Arrow;
}
return null;
}
/// <summary>
/// Throws exception linked with object
/// </summary>
/// <param name="o">The linked object</param>
/// <param name="e">The parent exception</param>
public static void ThrowException(object o, Exception element)
{
if (element is DiagramException)
{
throw element;
}
if (o == null)
{
throw element;
}
if (o is INamedComponent)
{
INamedComponent n = o as INamedComponent;
throw new DiagramException(element, n);
}
if (o is IAssociatedObject)
{
IAssociatedObject ass = o as IAssociatedObject;
object ob = ass.Object;
if (ob is INamedComponent)
{
INamedComponent nc = ob as INamedComponent;
throw new DiagramException(element, nc);
}
}
throw element;
}
static public Hashtable Resources
{
set
{
foreach (object o in value.Keys)
{
if (!(o is string))
{
throw new Exception();
}
if (!(value[o] is String))
{
throw new Exception();
}
}
resources = value;
}
}
/// <summary>
/// Creates digraph from objects and arrows
/// </summary>
/// <param name="objects">Objects</param>
/// <param name="arrows">Arrows</param>
/// <param name="checkObject">Checks objects</param>
/// <param name="checkArrow">Checks arrows</param>
/// <returns>The digraph</returns>
static public Digraph CreateDigraph(List<IObjectLabel> objects, List<IArrowLabel> arrows,
CheckObject checkObject, CheckObject checkArrow)
{
Digraph graph = new Digraph();
foreach (IArrowLabel label in arrows)
{
if (checkArrow != null)
{
if (!checkArrow(label))
{
continue;
}
}
label.SourceNumber = objects.IndexOf(label.Source);
label.TargetNumber = objects.IndexOf(label.Target);
}
ArrayList vertices = new ArrayList();
foreach (IObjectLabel label in objects)
{
if (checkObject != null)
{
if (!checkObject(label))
{
continue;
}
}
DigraphVertex v = new DigraphVertex(graph);
vertices.Add(v);
v.Object = label;
}
foreach (IArrowLabel label in arrows)
{
if (checkArrow != null)
{
if (!checkArrow(label))
{
continue;
}
}
DigraphEdge edge = new DigraphEdge();
edge.Object = label;
if (label.SourceNumber is Int32 && label.TargetNumber is Int32)
{
int sourceNum = (int)label.SourceNumber;
DigraphVertex vs = vertices[sourceNum] as DigraphVertex;
edge.Source = vs;
int targetNum = (int)label.TargetNumber;
DigraphVertex vt = vertices[targetNum] as DigraphVertex;
edge.Target = vt;
}
}
return graph;
}
/// <summary>
/// Creates digraph from objects and arrows
/// </summary>
/// <param name="objects">Objects</param>
/// <param name="arrows">Arrows</param>
/// <returns>The digraph</returns>
static public Digraph CreateDigraph(ArrayList objects, ArrayList arrows)
{
Digraph graph = new Digraph();
foreach (IArrowLabel label in arrows)
{
label.SourceNumber = objects.IndexOf(label.Source);
label.TargetNumber = objects.IndexOf(label.Target);
}
ArrayList vertices = new ArrayList();
foreach (IObjectLabel label in objects)
{
DigraphVertex v = new DigraphVertex(graph);
vertices.Add(v);
v.Object = label;
}
foreach (IArrowLabel label in arrows)
{
DigraphEdge edge = new DigraphEdge();
edge.Object = label;
if (label.SourceNumber is Int32 && label.TargetNumber is Int32)
{
int sourceNum = (int)label.SourceNumber;
DigraphVertex vs = vertices[sourceNum] as DigraphVertex;
edge.Source = vs;
int targetNum = (int)label.TargetNumber;
DigraphVertex vt = vertices[targetNum] as DigraphVertex;
edge.Target = vt;
}
}
return graph;
}
/// <summary>
/// Composition of path arrows
/// </summary>
/// <param name="category">Category of arrows</param>
/// <param name="path">The path</param>
/// <returns>The composition</returns>
static public ICategoryArrow Composition(ICategory category, DigraphPath path)
{
IArrowLabel label = path[0].Object as IArrowLabel;
ICategoryArrow arrow = label.Arrow;
for (int i = 1; i < path.Count; i++)
{
label = path[i].Object as IArrowLabel;
arrow = label.Arrow.Compose(category, arrow);
}
return arrow;
}
/// <summary>
/// Gets resources string
/// </summary>
/// <param name="str">String name</param>
/// <returns>The resources string</returns>
static public string GetResourceString(string str)
{
if (resources != null)
{
if (resources.ContainsKey(str))
{
return resources[str] as string;
}
}
return str;
}
/// <summary>
/// Disposes desktop
/// </summary>
/// <param name="desktop">Desktop to dispose</param>
public static void Dispose(IDesktop desktop)
{
ICollection c = desktop.AllComponents;
foreach (object o in c)
{
disposeAssociatedObject(o);
}
}
/// <summary>
/// Disposes associated object
/// </summary>
/// <param name="obj">Object to dispose</param>
static private void disposeAssociatedObject(object obj)
{
if (obj is IAssociatedObject)
{
IAssociatedObject ao = obj as IAssociatedObject;
object ob = ao.Object;
if (ob is IDisposable)
{
IDisposable d = ob as IDisposable;
d.Dispose();
}
}
}
#endregion
}
}