using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System.Reflection;
using CategoryTheory;
using DiagramUI.Labels;
using DiagramUI.Attributes;
using DiagramUI.Interfaces;
using SerializationInterface;
namespace DiagramUI
{
/// <summary>
/// Desktop for serialization
/// </summary>
[Serializable()]
public class PureDesktopPeer : PureDesktop, ISerializable
{
#region Fields
/// <summary>
/// Parent container
/// </summary>
private IObjectContainer parent;
/// <summary>
/// List of exceptios
/// </summary>
private static List<Exception> exceptions;
/// <summary>
/// Serialization binders
/// </summary>
private static SerializationBinder[] binders;
/// <summary>
/// The need change flag
/// </summary>
private static bool needChange;
/// <summary>
/// Comments
/// </summary>
private List<object> comments = new List<object>();
/// <summary>
/// Comment bytes
/// </summary>
private byte[] commentBytes;
/// <summary>
/// Stream position
/// </summary>
private long streamPosition;
/// <summary>
/// The "has parent" sign
/// </summary>
private bool hasParent = false;
#endregion
#region Constructors
/// <summary>
/// Default constructor
/// </summary>
public PureDesktopPeer()
{
}
/// <summary>
/// Deserialization constructor
/// </summary>
/// <param name="info">Serialization info</param>
/// <param name="context">Streaming context</param>
protected PureDesktopPeer(SerializationInfo info, StreamingContext context)
{
byte[] b = info.GetValue("Bytes", typeof(byte[])) as byte[];
MemoryStream ms = new MemoryStream(b);
Load(ms, true);
}
#endregion
#region ISerializable Members
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
MemoryStream ms = new MemoryStream();
Save(ms);
info.AddValue("Bytes", ms.GetBuffer(), typeof(byte[]));
}
#endregion
#region IDesktop Members
/// <summary>
/// Copies objects and arrows
/// </summary>
/// <param name="objects">Objects</param>
/// <param name="arrows">Arrows</param>
/// <param name="associated">Copy associated objects sign</param>
public override void Copy(IList<IObjectLabel> objects, IList<IArrowLabel> arrows, bool associated)
{
foreach (IObjectLabel l in objects)
{
string type = l.Type;
string st = l.Object.GetType() + "";
if (!type.Equals(st))
{
//type = st;
}
PureObjectLabelPeer lp = new PureObjectLabelPeer(l.Name, l.Kind, type, l.X, l.Y);
Type t = l.GetType();
object[] o = t.GetCustomAttributes(typeof(SerializableLabelAttribute), true);
if (o != null)
{
if (o.Length > 0)
{
IObjectLabelHolder lh = lp;
lh.Label = l;
}
}
IObjectLabel lab = lp;
lab.Object = l.Object;
lab.Desktop = this;
this.objects.Add(lab);
if (associated)
{
lab.Object.Object = lab;
}
table[l.Name] = lab;
}
//PureObjectLabel.Wrappers = false;
foreach (IArrowLabel l in arrows)
{
PureArrowLabelPeer lp = new PureArrowLabelPeer(l.Name, l.Kind, l.Type, l.X, l.Y);
Type t = l.GetType();
object[] o = t.GetCustomAttributes(typeof(SerializableLabelAttribute), true);
if (o != null)
{
if (o.Length > 0)
{
IArrowLabelHolder lh = lp;
lh.Label = l;
}
}
IArrowLabel lab = new PureArrowLabelPeer(l.Name, l.Kind, l.Type, l.X, l.Y);
lab.Arrow = l.Arrow;
if (associated)
{
lab.Arrow.Object = lab;
}
lab.Desktop = this;
this.arrows.Add(lab);
// components.Add(lab);
table[l.Name] = lab;
lab.Source = PureDesktop.Find(objects, this.Objects, l.Source, l.Desktop);
lab.Target = PureDesktop.Find(objects, this.Objects, l.Target, l.Desktop);
}
if (!associated)
{
return;
}
SetParents(this);
PureObjectLabel.SetLabels(objects);
PureArrowLabel.SetLabels(arrows);
//PureObjectLabel.Wrappers = true;
}
/// <summary>
/// Access to component
/// </summary>
/// <param name="name">Component name</param>
/// <returns>The component</returns>
public override INamedComponent this[string name]
{
get
{
INamedComponent nc = base[name];
if (nc != null)
{
return nc;
}
nc = GetFromRoot(this, name);
if (nc != null)
{
return nc;
}
nc = GetChild(this, name);
if (nc != null)
{
return nc;
}
return null;
}
}
/// <summary>
/// Parent desktop
/// </summary>
public override IDesktop ParentDesktop
{
get
{
return parentDesktop;
}
}
/// <summary>
/// Level of desktop
/// </summary>
public override int Level
{
get
{
if (parentDesktop == null)
{
return 0;
}
return parentDesktop.Level + 1;
}
}
/// <summary>
/// Root desktop
/// </summary>
public override IDesktop Root
{
get
{
IDesktop d = parentDesktop;
if (d == null)
{
return this;
}
return d.Root;
}
}
/// <summary>
/// Serialization bindres
/// </summary>
static public SerializationBinder[] Binders
{
get
{
return binders;
}
set
{
binders = value;
}
}
#endregion
#region Overriden
/// <summary>
/// Clears all content
/// </summary>
public override void ClearAll()
{
base.ClearAll();
comments.Clear();
commentBytes = null;
}
/// <summary>
/// Gets objects and arrows of associated object
/// </summary>
/// <param name="ao">The associated object</param>
/// <param name="objects">Objects</param>
/// <param name="arrows">Arrows</param>
protected override void GetObjects(IAssociatedObject ao, IList<ICategoryObject> objects, IList<ICategoryArrow> arrows)
{
if (ao is IObjectContainer)
{
IObjectContainer oc = ao as IObjectContainer;
IDesktop d = oc.Desktop;
ICollection<object> c = d.AllComponents;
foreach (object o in c)
{
if (o is IObjectLabel)
{
IObjectLabel ol = o as IObjectLabel;
GetObjects(ol.Object, objects, arrows);
}
if (o is IArrowLabel)
{
IArrowLabel al = o as IArrowLabel;
GetObjects(al.Arrow, objects, arrows);
}
}
}
else
{
base.GetObjects(ao, objects, arrows);
}
}
/// <summary>
/// All components
/// </summary>
public override ICollection<object> AllComponents
{
get
{
return GetAllObjects(this);
}
}
#endregion
#region Specific members
/// <summary>
/// The need change sign
/// </summary>
static public bool NeedChange
{
get
{
return needChange;
}
set
{
needChange = value;
}
}
/// <summary>
/// Saves all aliases of desktop to stream
/// </summary>
/// <param name="desktop">The desktop</param>
/// <param name="stream">The stream</param>
static public void SaveAllAliases(IDesktop desktop, Stream stream)
{
Dictionary<string, object> d = desktop.GetAllAliases();
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(stream, d);
}
/// <summary>
/// Content
/// </summary>
public byte[] Content
{
get
{
MemoryStream ms = new MemoryStream();
Save(ms);
return ms.GetBuffer();
}
}
/// <summary>
/// Comments
/// </summary>
public List<object> Comments
{
get
{
if (commentBytes != null)
{
MemoryStream ms = new MemoryStream(commentBytes);
BinaryFormatter bf = new BinaryFormatter();
comments = bf.Deserialize(ms) as List<object>;
commentBytes = null;
}
return comments;
}
}
/// <summary>
/// Checks desktop
/// </summary>
/// <param name="desktop">The desktop</param>
/// <param name="binders">The serialization binders</param>
/// <returns>List of exceptions or null if right</returns>
public static List<Exception> Check(IDesktop desktop, SerializationBinder[] binders)
{
exceptions = new List<Exception>();
bool b = false;
try
{
IList<IObjectLabel> objects = desktop.Objects;
IList<IArrowLabel> arrows = desktop.Arrows;
PureDesktopPeer d = new PureDesktopPeer();
d.Copy(objects, arrows, true);
SetParents(d);
Stream stream = new MemoryStream();
d.Save(stream);
PureDesktopPeer dnew = new PureDesktopPeer();
b = dnew.Load(stream);
dnew.Dispose();
}
catch (Exception e)
{
e.Log();
if (exceptions != null)
{
exceptions.Add(e);
}
else
{
if (errorHandler != null)
{
errorHandler.ShowError(e);
}
}
}
List<Exception> res = b ? null : exceptions;
exceptions = null;
SetParents(desktop);
return res;
}
/// <summary>
/// Checks loading from stream
/// </summary>
/// <param name="stream">The stream</param>
/// <returns>List of exceptions</returns>
public static List<Exception> Check(Stream stream)
{
bool b = false;
exceptions = new List<Exception>();
try
{
PureDesktopPeer d = new PureDesktopPeer();
d.Load(stream, binders, true);
SetParents(d);
Stream s = new MemoryStream();
d.Save(s);
d.Dispose();
PureDesktopPeer dnew = new PureDesktopPeer();
b = dnew.Load(s, binders, true);
dnew.Dispose();
}
catch (Exception e)
{
e.Log();
if (exceptions != null)
{
exceptions.Add(e);
}
else
{
if (errorHandler != null)
{
errorHandler.ShowError(e);
}
}
}
List<Exception> res = b ? null : exceptions;
if (res != null)
{
if (res.Count == 0)
{
res = null;
}
}
exceptions = null;
return res;
}
/// <summary>
/// Transforms
/// </summary>
/// <param name="instream">Input stream</param>
/// <param name="outstream">Output strem</param>
public void Transform(Stream instream, Stream outstream)
{
Load(instream);
SetParents(this);
Save(outstream);
}
/// <summary>
/// Checks loading from bytes
/// </summary>
/// <param name="bytes">The bytes</param>
/// <returns>Result of cheking</returns>
public static List<Exception> Check(byte[] bytes)
{
MemoryStream stream = new MemoryStream(bytes);
return Check(stream);
}
/// <summary>
/// Saves itself
/// </summary>
/// <param name="stream">Stream to save</param>
public void Save(Stream stream)
{
PreSave();
BinaryFormatter bformatter = new BinaryFormatter();
//PureObjectLabel.Wrappers = true;
bformatter.Serialize(stream, objects);
bformatter.Serialize(stream, arrows);
if (commentBytes != null)
{
bformatter.Serialize(stream, commentBytes);
return;
}
BinaryFormatter bf = new BinaryFormatter();
MemoryStream str = new MemoryStream();
bf.Serialize(str, comments);
bformatter.Serialize(stream, str.GetBuffer());
}
/// <summary>
/// The Pre Save operation
/// </summary>
public void PreSave()
{
SetParents(this);
PureObjectLabel.SetType(objects);
PureArrowLabel.SetType(arrows);
foreach (IArrowLabel label in arrows)
{
if (objects.Contains(label.Source))
{
label.SourceNumber = objects.IndexOf(label.Source);
}
else
{
IObjectLabel ls = label.Source.GetRoot(this) as IObjectLabel;
int sn = objects.IndexOf(ls);
IObjectContainer scont = ls.Object as IObjectContainer;
string ns = scont.GetName(label.Source);
label.SourceNumber = new object[] { sn, ns };
}
if (objects.Contains(label.Target))
{
label.TargetNumber = objects.IndexOf(label.Target);
}
else
{
IObjectLabel lt = label.Target.GetRoot(this) as IObjectLabel;
int tn = objects.IndexOf(lt);
IObjectContainer tcont = lt.Object as IObjectContainer;
string nt = tcont.GetName(label.Target);
label.TargetNumber = new object[] { tn, nt };
}
}
}
/// <summary>
/// Refreshes itself
/// </summary>
public void Refresh()
{
MemoryStream stream = new MemoryStream();
Save(stream);
objects.Clear();
arrows.Clear();
stream.Position = 0;
Load(stream);
}
/// <summary>
/// Gets all objects of desktop
/// </summary>
/// <param name="desktop">The desktop</param>
/// <returns>Collection of all objects including children</returns>
public static ICollection<object> GetAllObjects(IDesktop desktop)
{
List<object> l = new List<object>();
ICollection<object> components = desktop.Components;
l.AddRange(components);
ICollection<IObjectLabel> objs = desktop.Objects;
foreach (IObjectLabel o in objs)
{
if (o.Object is IObjectContainer)
{
IObjectContainer oc = o.Object as IObjectContainer;
l.AddRange(oc.AllObjects);
}
}
return l;
}
/// <summary>
/// Loading from stream
/// </summary>
/// <param name="stream">The stream</param>
/// <param name="binders">Serialization binders</param>
/// <param name="post">The "post" sign</param>
/// <returns>True in success and false otherwise</returns>
public bool Load(Stream stream, SerializationBinder[] binders, bool post)
{
if (!loadBinders(stream, binders, post))
{
return false;
}
LoadComments(stream);
return true;
}
/// <summary>
/// Loads from bytes
/// </summary>
/// <param name="buffer">Buffer</param>
/// <param name="binders">Serialization binders</param>
/// <returns>True in success and false otherwise</returns>
public bool Load(byte[] buffer, SerializationBinder[] binders)
{
return Load(buffer, binders, true);
}
/// <summary>
/// Loading from stream
/// </summary>
/// <param name="stream">The stream</param>
/// <returns>True in success and false otherwise</returns>
public bool Load(Stream stream)
{
return Load(stream, binders, true);
}
/// <summary>
/// Loads from bytes
/// </summary>
/// <param name="buffer">Buffer</param>
/// <returns>True in success and false otherwise</returns>
public bool Load(byte[] buffer)
{
return Load(buffer, true);
}
/// <summary>
/// Adds arrow with existing source and target
/// </summary>
/// <param name="arrow">Arrow</param>
/// <param name="source">Source</param>
/// <param name="target">Target</param>
/// <param name="name">Arrow name</param>
/// <param name="kind">Arrow kind</param>
/// <returns>Added arrow</returns>
public IArrowLabel AddArrowWithExistingLabels(ICategoryArrow arrow,
IObjectLabel source, IObjectLabel target, string name, string kind)
{
source.Object.Object = source;
target.Object.Object = target;
IArrowLabel arrowLabel = new PureArrowLabelPeer(name, kind, arrow.GetType().FullName, 0, 0);
arrowLabel.Desktop = this;
arrowLabel.Arrow = arrow;
arrow.Object = arrowLabel;
arrowLabel.Source = source;
arrowLabel.Target = target;
arrowLabel.Arrow = arrow;
arrow.Source = source.Object;
arrow.Target = target.Object;
arrows.Add(arrowLabel);
return arrowLabel;
}
/// <summary>
/// Sets parents of objects of desktop
/// </summary>
/// <param name="desktop">The desktop</param>
public static void SetParents(IDesktop desktop)
{
ICollection<IObjectLabel> objects = desktop.Objects;
foreach (IObjectLabel ol in objects)
{
if (ol.Object is IObjectContainer)
{
IObjectContainer oc = ol.Object as IObjectContainer;
oc.SetParents(desktop);
}
}
}
internal bool Load(byte[] buffer, SerializationBinder[] binders, bool post)
{
MemoryStream stream = new MemoryStream(buffer);
return Load(stream, binders, post);
}
internal bool Load(Stream stream, bool post)
{
return Load(stream, binders, post);
}
internal bool Load(byte[] buffer, bool post)
{
return Load(buffer, binders, post);
}
/// <summary>
/// The post load operation
/// </summary>
/// <returns></returns>
internal bool PostLoad()
{
try
{
PureObjectLabel.SetLabels(this.Objects);
PureArrowLabel.SetLabels(this.Arrows);
SetParents(this);
ICollection<object> components = Components;
foreach (INamedComponent nc in components)
{
nc.Desktop = this;
table[nc.Name] = nc;
if (nc is IObjectLabel)
{
IObjectLabel ol = nc as IObjectLabel;
if (ol.Object is IObjectContainer)
{
IObjectContainer oc = ol.Object as IObjectContainer;
bool b = oc.PostLoad();
if (!b)
{
return false;
}
}
}
}
foreach (IArrowLabel arrow in arrows)
{
IObjectLabel source = null;
IObjectLabel target = null;
if (arrow.SourceNumber is Int32)
{
source = objects[(int)arrow.SourceNumber] as IObjectLabel;
}
else
{
object[] os = arrow.SourceNumber as object[];
IObjectLabel so = objects[(int)os[0]] as IObjectLabel;
IObjectContainer sc = so.Object as IObjectContainer;
source = sc[os[1] as string] as IObjectLabel;
}
if (arrow.TargetNumber is Int32)
{
target = objects[(int)arrow.TargetNumber] as IObjectLabel;
}
else
{
object[] ot = arrow.TargetNumber as object[];
IObjectLabel to = objects[(int)ot[0]] as IObjectLabel;
IObjectContainer tc = to.Object as IObjectContainer;
target = tc[ot[1] as string] as IObjectLabel;
}
arrow.Arrow.Source = source.Object;
arrow.Arrow.Target = target.Object;
arrow.Source = source;
arrow.Target = target;
IAssociatedObject ass = arrow.Arrow as IAssociatedObject;
ass.Object = arrow;
}
return true;
}
catch (Exception ex)
{
ex.Log();
if (exceptions != null)
{
exceptions.Add(ex);
}
else
{
if (errorHandler != null)
{
errorHandler.ShowError(ex);
}
}
}
return false;
}
/// <summary>
/// Gets full list of desktop components
/// </summary>
/// <param name="desktop">The desktop</param>
/// <param name="list">The list</param>
static public void GetFullList(IDesktop desktop, List<INamedComponent> list)
{
ICollection<object> l = desktop.AllComponents;
foreach (INamedComponent c in l)
{
list.Add(c);
IAssociatedObject ao = c as IAssociatedObject;
if (ao.Object is IObjectContainer)
{
IObjectContainer cont = ao.Object as IObjectContainer;
IDesktop d = cont.Desktop;
GetFullList(d, list);
}
}
}
/// <summary>
/// Gets full list of desktop components
/// </summary>
/// <param name="desktop">Desktop</param>
/// <param name="objects">Objects</param>
/// <param name="arrows">Arrows</param>
static public void GetFullList(IDesktop desktop, out List<IObjectLabel> objects, out List<IArrowLabel> arrows)
{
objects = new List<IObjectLabel>();
arrows = new List<IArrowLabel>();
List<INamedComponent> list = new List<INamedComponent>();
foreach (INamedComponent c in list)
{
if (c is IObjectLabel)
{
IObjectLabel l = c as IObjectLabel;
objects.Add(l);
}
if (c is IArrowLabel)
{
IArrowLabel l = c as IArrowLabel;
arrows.Add(l);
}
}
}
/// <summary>
/// Gets type that implements interface
/// </summary>
/// <param name="interfaceName">Name of interface</param>
/// <param name="assemblyBuffer">Bytes of assembly</param>
/// <returns>Type that implements interface</returns>
public static Type GetInterface(string interfaceName, byte[] assemblyBuffer)
{
Assembly ass = Assembly.Load(assemblyBuffer);
Type[] types = ass.GetTypes();
foreach (Type t in types)
{
object o = t.GetInterface(interfaceName);
if (o != null)
{
return t;
}
}
return null;
}
/// <summary>
/// Serializes object
/// </summary>
/// <param name="o">Object to serialize</param>
/// <returns></returns>
static public byte[] Serialize(object o)
{
if (o == null)
{
return null;
}
BinaryFormatter bf = new BinaryFormatter();
MemoryStream stream = new MemoryStream();
bf.Serialize(stream, o);
return stream.GetBuffer();
}
/// <summary>
/// Deserializes buffer
/// </summary>
/// <param name="buffer">The buffer</param>
/// <returns>Dezerialized object</returns>
static public object Deserialize(byte[] buffer)
{
if (buffer == null)
{
return null;
}
BinaryFormatter bf = new BinaryFormatter();
MemoryStream stream = new MemoryStream(buffer);
return bf.Deserialize(stream);
}
/// <summary>
/// Saves propreties
/// </summary>
/// <param name="properties">Properties</param>
/// <param name="bytes">Bytes</param>
/// <param name="info">Serialization info</param>
public static void SaveProperties(object properties, byte[] bytes, SerializationInfo info)
{
if (properties != null)
{
Serialization.Serialize<object>("Properties", info, properties);
return;
}
byte[] b = bytes;
if (b == null)
{
b = new byte[0];
}
info.AddValue("Properties", b, typeof(byte[]));
}
/// <summary>
/// Clones object by serialization
/// </summary>
/// <typeparam name="T">Type of object</typeparam>
/// <param name="obj">The prototype object</param>
/// <returns>A clone</returns>
public static T Clone<T>(T obj) where T : class
{
MemoryStream ms = new MemoryStream();
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(ms, obj);
ms.Position = 0;
return bf.Deserialize(ms) as T;
}
/// <summary>
/// Loads bytes
/// </summary>
/// <param name="name">name</param>
/// <param name="info">info</param>
/// <returns>The bytes</returns>
public static byte[] LoadBytes(string name, SerializationInfo info)
{
return info.GetValue(name, typeof(byte[])) as byte[];
}
/// <summary>
/// Loads bytes properties
/// </summary>
/// <param name="info">Info</param>
/// <returns>Propreties</returns>
public static byte[] LoadProperties(SerializationInfo info)
{
return LoadBytes("Properties", info);
}
/// <summary>
/// Loads label bytes
/// </summary>
/// <param name="info">Info</param>
/// <returns>Butes</returns>
public static byte[] LoadLabel(SerializationInfo info)
{
return LoadBytes("Label", info);
}
/// <summary>
/// Saves label
/// </summary>
/// <param name="label">Label to save</param>
/// <param name="bytes">Bytes of label</param>
/// <param name="info">Info</param>
public static void SaveLabel(object label, byte[] bytes, SerializationInfo info)
{
if (label != null)
{
Serialization.Serialize<object>("Label", info, label);
return;
}
byte[] b = bytes;
if (b == null)
{
b = new byte[0];
}
info.AddValue("Label", b, typeof(byte[]));
}
/// <summary>
/// Gets object from bytes
/// </summary>
/// <typeparam name="T">Type of object</typeparam>
/// <param name="obj">The object</param>
/// <param name="bytes">Bytes</param>
/// <returns>The object</returns>
public static T GetObject<T>(ref T obj, byte[] bytes) where T : class
{
if (obj != null)
{
return obj;
}
if (bytes == null)
{
return null;
}
if (bytes.Length == 0)
{
return null;
}
MemoryStream ms = new MemoryStream(bytes);
BinaryFormatter bf = new BinaryFormatter();
SerializationBinder[] binders = PureDesktopPeer.Binders;
if (binders == null)
{
try
{
obj = bf.Deserialize(ms) as T;
}
catch (Exception ex)
{
ex.Log();
return null;
}
}
else
{
try
{
obj = bf.Deserialize(ms) as T;
}
catch (Exception exc)
{
exc.Log();
if (binders != null)
{
foreach (SerializationBinder binder in binders)
{
bf.Binder = binder;
try
{
obj = bf.Deserialize(ms) as T;
break;
}
catch (Exception exce)
{
exce.Log();
}
}
}
}
}
return obj;
}
/// <summary>
/// Gets properties
/// </summary>
/// <param name="properties">Properties</param>
/// <param name="bytes">Bytes</param>
/// <returns>Properties</returns>
public static object GetProperties(object properties, byte[] bytes)
{
if (properties != null)
{
return properties;
}
if (bytes == null)
{
return null;
}
if (bytes.Length == 0)
{
return null;
}
MemoryStream ms = new MemoryStream(bytes);
BinaryFormatter bf = new BinaryFormatter();
return bf.Deserialize(ms);
}
/// <summary>
/// Checks whether object can be setialized
/// </summary>
/// <param name="o">Object to check</param>
public static void CheckSerialization(object o)
{
MemoryStream ms = new MemoryStream();
BinaryFormatter bf = new BinaryFormatter();
try
{
bf.Serialize(ms, o);
}
catch (Exception e)
{
e.Log();
throw e;
}
}
/// <summary>
/// Parent desktop
/// </summary>
internal IDesktop parentDesktop
{
get
{
if (parent == null)
{
return null;
}
IAssociatedObject obj = parent as IAssociatedObject;
INamedComponent nc = obj.Object as INamedComponent;
return nc.Desktop;
}
}
/// <summary>
/// Post deserialization operation
/// </summary>
/// <returns>True in success and false otherwise</returns>
internal bool PostDeserialize()
{
try
{
IList<ICategoryArrow> arrows = CategoryArrows;
foreach (ICategoryArrow arrow in arrows)
{
PureDesktop.PostSetArrow(arrow);
}
IList<ICategoryObject> objects = CategoryObjects;
foreach (ICategoryObject lab in objects)
{
PureDesktop.PostSetArrow(lab);
}
foreach (ICategoryArrow lab in arrows)
{
if (lab is IPostSerialize)
{
IPostSerialize post = lab as IPostSerialize;
post.PostSerialize();
}
}
if (!hasParent)
{
PureDesktop.PostLoad(this);
}
return true;
}
catch (Exception ex)
{
ex.Log();
if (exceptions != null)
{
exceptions.Add(ex);
}
else
{
if (errorHandler != null)
{
errorHandler.ShowError(ex);
}
}
}
return false;
}
internal void setParent(IObjectContainer parent)
{
this.parent = parent;
}
internal bool loadBinders(Stream stream, SerializationBinder[] binders, bool post)
{
if (load(stream, null, post))
{
return true;
}
if (binders == null)
{
return false;
}
ObjectContainerBase.Binders = binders;
foreach (SerializationBinder binder in binders)
{
if (load(stream, binder, post))
{
return true;
}
}
return false;
}
private static int GetOrder(INamedComponent nc, IDesktop desktop)
{
if (nc.Desktop == desktop)
{
return nc.Ord;
}
IObjectContainer oc = ParentContainer(nc);
IAssociatedObject ao = oc as IAssociatedObject;
INamedComponent comp = ao.Object as INamedComponent;
return GetOrder(comp, desktop);
}
/// <summary>
/// Path of component desktops
/// </summary>
/// <param name="component">The component</param>
/// <returns>Desktop path</returns>
static public List<IDesktop> GetPath(INamedComponent component)
{
List<IDesktop> l = new List<IDesktop>();
IDesktop d = component.Desktop;
while (true)
{
if (d == null)
{
break;
}
l.Add(d);
d = d.ParentDesktop;
}
return l;
}
/// <summary>
/// Common desktop of two components
/// </summary>
/// <param name="c1">First component</param>
/// <param name="c2">Second component</param>
/// <returns>Common desktop</returns>
public static IDesktop GetCommonDesktop(INamedComponent c1, INamedComponent c2)
{
List<IDesktop> l1 = GetPath(c1);
List<IDesktop> l2 = GetPath(c2);
foreach (IDesktop d in l1)
{
if (l2.Contains(d))
{
return d;
}
}
return null;
}
/// <summary>
/// Gets difference between components
/// </summary>
/// <param name="nc1">First component</param>
/// <param name="nc2">Second component</param>
/// <returns>Difference</returns>
public static int GetDifference(INamedComponent nc1, INamedComponent nc2)
{
IDesktop d = GetCommonDesktop(nc1, nc2);
return GetOrder(nc1, d) - GetOrder(nc2, d);
}
private static IObjectContainer ParentContainer(INamedComponent nc)
{
IDesktop d = nc.Desktop;
if (!(d is PureDesktopPeer))
{
return null;
}
PureDesktopPeer pd = d as PureDesktopPeer;
return pd.parent;
}
private bool load(Stream stream, SerializationBinder binder, bool post)
{
stream.Position = 0;
BinaryFormatter bformatter = new BinaryFormatter();
if (binder != null)
{
bformatter.Binder = binder;
}
try
{
// PureObjectLabel.Wrappers = true;
objects = bformatter.Deserialize(stream) as ArrayList;
arrows = bformatter.Deserialize(stream) as ArrayList;
if (objects == null)
{
objects = new ArrayList();
}
if (arrows == null)
{
arrows = new ArrayList();
}
foreach (object o in objects)
{
if (o is INamedComponent)
{
INamedComponent nc = o as INamedComponent;
nc.Desktop = this;
string n = nc.Name;
if (!table.ContainsKey(n))
{
table[n] = nc;
}
}
if (o is IObjectLabel)
{
IObjectLabel l = o as IObjectLabel;
object os = l.Object;
if (os is IAssociatedObject)
{
IAssociatedObject ass = os as IAssociatedObject;
ass.Object = l;
}
if (os is IObjectContainer)
{
IObjectContainer oc = os as IObjectContainer;
bool lb = oc.Load();
if (!lb)
{
return false;
}
}
}
}
foreach (object o in arrows)
{
if (o is INamedComponent)
{
if (o is IArrowLabel)
{
IArrowLabel l = o as IArrowLabel;
object os = l.Arrow;
if (os is IAssociatedObject)
{
IAssociatedObject ass = os as IAssociatedObject;
ass.Object = l;
}
}
INamedComponent nc = o as INamedComponent;
string n = nc.Name;
if (!table.ContainsKey(n))
{
table[n] = nc;
}
nc.Desktop = this;
}
}
if (post)
{
bool b = PostLoad();
if (!b)
{
return false;
}
return PostDeserialize();
}
return true;
}
catch (Exception ex)
{
ex.Log();
if (exceptions != null)
{
exceptions.Add(ex);
}
else
{
if (errorHandler != null)
{
errorHandler.ShowError(ex);
}
}
}
return false;
}
/// <summary>
/// Gets child named component
/// </summary>
/// <param name="desktop">Desktop</param>
/// <param name="name">Name of object</param>
/// <returns>The child component</returns>
static public INamedComponent GetChild(IDesktop desktop, string name)
{
IList<IObjectLabel> c = desktop.Objects;
foreach (IObjectLabel l in c)
{
object ob = l.Object;
if (!(ob is IObjectContainer))
{
continue;
}
IObjectContainer cont = ob as IObjectContainer;
ICollection<object> all = cont.AllObjects;
foreach (INamedComponent nc in all)
{
string n = nc.GetName(desktop);
if (n.Equals(name))
{
return nc;
}
}
}
return null;
}
/// <summary>
/// Gets child named component form root desktop
/// </summary>
/// <param name="desktop">Root desktop</param>
/// <param name="name">Name of object</param>
/// <returns>The child component</returns>
static public INamedComponent GetFromRoot(IDesktop desktop, string name)
{
if (name.Length >= 3)
{
if (name.Substring(0, 3).Equals("../"))
{
PureDesktopPeer d = desktop as PureDesktopPeer;
IObjectContainer cont = d.parent;
IAssociatedObject ao = cont as IAssociatedObject;
INamedComponent cnc = ao.Object as INamedComponent;
INamedComponent nc = cnc.Desktop[name.Substring(3)];
if (nc != null)
{
return nc;
}
}
}
return null;
}
/// <summary>
/// Position of stream
/// </summary>
public long StreamPosition
{
get
{
return streamPosition;
}
}
/// <summary>
/// The "has parent" sign
/// </summary>
public bool HasParent
{
get { return hasParent; }
set { hasParent = value; }
}
/// <summary>
/// Loads Comments from stream
/// </summary>
/// <param name="stream">The stream</param>
private void LoadComments(Stream stream)
{
streamPosition = stream.Position;
try
{
BinaryFormatter bf = new BinaryFormatter();
commentBytes = bf.Deserialize(stream) as byte[];
if (commentBytes != null)
{
streamPosition = stream.Position;
}
}
catch (Exception ex)
{
ex.Log();
stream.Position = streamPosition;
}
}
/// <summary>
/// Global error handler
/// </summary>
private static IErrorHandler errorHandler
{
get
{
return PureDesktop.ErrorHandler;
}
}
#endregion
}
}