using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization;
using CategoryTheory;
using DiagramUI;
using DiagramUI.Labels;
using DiagramUI.Attributes;
using DiagramUI.Interfaces;
using DataPerformer.Interfaces;
namespace DataPerformer
{
/// <summary>
/// The link with data provider
/// </summary>
[Serializable()]
public class DataLink : ICategoryArrow, ISerializable,
IRemovableObject, IDataLinkFactory
{
#region Fields
/// <summary>
/// Error message
/// </summary>
public static readonly string SetProviderBefore = "You should create measurements source before consumer";
/// <summary>
/// DataLink checker
/// </summary>
private static Action<DataLink> checker;
/// <summary>
/// The source of this arrow
/// </summary>
private IDataConsumer source;
/// <summary>
/// The target of this arrow
/// </summary>
private IMeasurements target;
/// <summary>
/// Auxiliary field
/// </summary>
private int a = 0;
/// <summary>
/// Linked object
/// </summary>
protected object obj;
/// <summary>
/// Data link factory
/// </summary>
private static IDataLinkFactory dataLinkFactory = new DataLink();
#endregion
#region Ctor
/// <summary>
/// Default constructor
/// </summary>
public DataLink()
{
}
/// <summary>
/// Deserialization constructor
/// </summary>
/// <param name="info">Serialization info</param>
/// <param name="context">Streaming context</param>
public DataLink(SerializationInfo info, StreamingContext context)
{
a = (int)info.GetValue("A", typeof(int));
}
#endregion
#region ISerializable Members
/// <summary>
/// ISerializable interface implementation
/// </summary>
/// <param name="info">Serialization info</param>
/// <param name="context">Streaming context</param>
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("A", a);
}
#endregion
#region ICategoryArrow Members
/// <summary>
/// The source of this arrow
/// </summary>
public ICategoryObject Source
{
set
{
if (source != null)
{
throw new Exception();
}
IDataLinkFactory f = this;
source = f.GetConsumer(value);
}
get
{
return source as ICategoryObject;
}
}
/// <summary>
/// The target of this arrow
/// </summary>
public ICategoryObject Target
{
get
{
return target as ICategoryObject;
}
set
{
if (target != null)
{
throw new Exception();
}
IDataLinkFactory f = this;
IMeasurements t = f.GetMeasurements(value);
/* ICategoryObject s = source as ICategoryObject;
Type ts = s.GetType();
Type tt = t.GetType();
object[] asa = ts.GetCustomAttributes(typeof(ExceptionalOrderAttribute), true);
object[] ata = tt.GetCustomAttributes(typeof(ExceptionalOrderAttribute), true);
*/
bool check = true;
/*if ((asa != null) & (ata != null))
{
if ((asa.Length > 0) | (ata.Length > 0))
{
check = false;
}
}*/
IAssociatedObject s = source as IAssociatedObject;
if (s.Object != null & value.Object != null)
{
if (check)
{
INamedComponent ns = s.Object as INamedComponent;
INamedComponent nt = value.Object as INamedComponent;
if (nt != null & ns != null)
{
if (PureDesktopPeer.GetDifference(nt, ns) >= 0)
{
throw new Exception(SetProviderBefore);
}
}
}
target = t;
source.Add(target);
}
if (!check)
{
return;
}
try
{
if (checker != null)
{
checker(this);
}
}
catch (Exception e)
{
e.ShowError(10);
source.Remove(target);
throw e;
}
}
}
/// <summary>
/// The "is monomorhpism" sign
/// </summary>
public bool IsMonomorphism
{
get
{
return false;
}
}
/// <summary>
/// The "is epimorhpism" sign
/// </summary>
public bool IsEpimorphism
{
get
{
return false;
}
}
/// <summary>
/// The "is isomorhpism" sign
/// </summary>
public bool IsIsomorphism
{
get
{
return false;
}
}
/// <summary>
/// Composes this arrow "f" with next arrow "g"
/// </summary>
/// <param name="category"> The category of arrow</param>
/// <param name="next"> The next arrow "g" </param>
/// <returns>Composition "fg" </returns>
public ICategoryArrow Compose(ICategory category, ICategoryArrow next)
{
return null;
}
#endregion
#region IAssociatedObject Members
/// <summary>
/// Associated object
/// </summary>
public object Object
{
get
{
return obj;
}
set
{
obj = value;
}
}
#endregion
#region IRemovableObject Members
/// <summary>
/// The post remove operation
/// </summary>
public void RemoveObject()
{
if (source == null | target == null)
{
return;
}
source.Remove(target);
}
#endregion
#region IDataLinkFactory Members
IDataConsumer IDataLinkFactory.GetConsumer(ICategoryObject source)
{
IAssociatedObject ao = source;
object o = ao.Object;
if (o is INamedComponent)
{
IDataConsumer dcl = null;
INamedComponent comp = o as INamedComponent;
IDesktop desktop = comp.Root.Desktop;
desktop.ForEach<DataLink>(delegate(DataLink dl)
{
if (dcl != null)
{
return;
}
object dt = dl.Source;
if (dt is IAssociatedObject)
{
IAssociatedObject aot = dt as IAssociatedObject;
if (aot.Object == o)
{
dcl = dl.source as IDataConsumer;
}
}
});
if (dcl != null)
{
return dcl;
}
}
IDataConsumer dc = DataConsumerWrapper.Create(source);
if (dc == null)
{
CategoryException.ThrowIllegalTargetException();
}
return dc;
}
IMeasurements IDataLinkFactory.GetMeasurements(ICategoryObject target)
{
IAssociatedObject ao = target;
object o = ao.Object;
if (o is INamedComponent)
{
IMeasurements ml = null;
INamedComponent comp = o as INamedComponent;
IDesktop d = null;
INamedComponent r = comp.Root;
if (r != null)
{
d = r.Desktop;
}
else
{
d = comp.Desktop;
}
if (d != null)
{
d.ForEach<DataLink>(delegate(DataLink dl)
{
if (ml != null)
{
return;
}
object dt = dl.Target;
if (dt is IAssociatedObject)
{
IAssociatedObject aot = dt as IAssociatedObject;
if (aot.Object == o)
{
ml = dl.Target as IMeasurements;
}
}
});
if (ml != null)
{
return ml;
}
}
}
IMeasurements m = MeasurementsWrapper.Create(target);
if (m == null)
{
CategoryException.ThrowIllegalTargetException();
}
return m;
}
#endregion
#region Public Members
/// <summary>
/// Checker of data link
/// </summary>
public static Action<DataLink> Checker
{
set
{
checker = value;
}
}
/// <summary>
/// Data link factory
/// </summary>
public static IDataLinkFactory DataLinkFactory
{
get
{
return dataLinkFactory;
}
set
{
dataLinkFactory = value;
}
}
/// <summary>
/// Measurements provider
/// </summary>
public IMeasurements Measurements
{
get
{
return target;
}
}
#endregion
}
}