Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.Netron/3.0.2672.12446/Netron.Diagramming.Core-3.0.2672.12446/IO/NML/NMLSerializer.cs @ 2769

Last change on this file since 2769 was 2769, checked in by mkommend, 14 years ago

added unused files for netron (ticket #867)

File size: 25.3 KB
Line 
1using System;
2using System.Xml;
3using System.Xml.Serialization;
4using System.Collections;
5using System.Reflection;
6using System.IO;
7using System.Diagnostics;
8using System.Xml.Schema;
9using Netron.GraphLib.Attributes;
10using Netron.GraphLib.UI;
11using System.Runtime.Remoting;
12using System.Windows.Forms;
13using System.Drawing;
14
15namespace Netron.GraphLib.IO.NML
16{
17  /// <summary>
18  /// NMLSerializer serializes a graph to NML
19  /// Thanks to Martin Cully for his work on this.
20  /// </summary>
21  public class NMLSerializer
22  {
23    #region Fields
24    private GraphControl site = null;
25    private string dtdPath = "http://nml.graphdrawing.org/dtds/1.0rc/nml.dtd";
26
27
28    //private Hashtable keyList = new Hashtable();
29
30    #endregion
31
32    #region Constructor
33    /// <summary>
34    /// Constructor
35    /// </summary>
36    private NMLSerializer()
37    {
38    }
39
40    /// <summary>
41    /// Constructor
42    /// </summary>
43    /// <param name="site"></param>
44    public NMLSerializer(GraphControl site)
45    {
46      this.site = site;
47    }
48
49    /// <summary>
50    /// Constructor
51    /// </summary>
52    /// <param name="dtdPath"></param>
53    public NMLSerializer(string dtdPath)
54    {
55      this.dtdPath = dtdPath;
56    }
57    #endregion
58
59    #region Methods
60
61    /// <summary>
62    /// Opens a NML serialized file
63    /// </summary>
64    /// <param name="filename"></param>
65    /// <param name="site"></param>
66    public static void Open(string filename, GraphControl site)
67    {
68      try
69      {
70      XmlTextReader reader = new XmlTextReader(filename);
71      IO.NML.NMLSerializer ser = new IO.NML.NMLSerializer(site);
72     
73      site.Abstract = ser.Deserialize(reader) as GraphAbstract;
74      reader.Close();
75      }
76      catch (System.IO.DirectoryNotFoundException exc)
77      {
78        System.Windows.Forms.MessageBox.Show(exc.Message);
79      }
80      catch(System.IO.FileLoadException exc)
81      {       
82        System.Windows.Forms.MessageBox.Show(exc.Message);
83      }
84      catch (System.IO.FileNotFoundException exc)
85      {
86        System.Windows.Forms.MessageBox.Show(exc.Message);
87      }
88      catch
89      {       
90        site.OutputInfo("Non-CLS exception caught.","BinarySerializer.SaveAs", OutputInfoLevels.Exception);
91      }
92    }
93
94    /// <summary>
95    /// Saves the diagram to NML format
96    /// </summary>
97    /// <param name="fileName">the file-path</param>
98    /// <param name="site">the graph-control instance to be serialized</param>
99    /// <returns></returns>
100    public static  bool SaveAs(string fileName, GraphControl site)
101    {
102      XmlTextWriter tw = null;
103      try
104      {
105
106        tw = new XmlTextWriter(fileName,System.Text.Encoding.Unicode);
107        tw.Formatting = System.Xml.Formatting.Indented;
108        IO.NML.NMLSerializer g = new IO.NML.NMLSerializer();
109        g.Serialize(tw,site.Abstract);
110       
111        return true;
112      }
113      catch(Exception exc)     
114      {       
115        //TODO: more specific exception handling here
116        Trace.WriteLine(exc.Message, "NMLSerializer.SaveAs");
117      }
118      catch
119      {
120        Trace.WriteLine("Non-CLS exception caught.","BinarySerializer.SaveAs");
121      }
122      finally
123      {
124        if(tw!=null) tw.Close();
125      }
126      return false;
127
128    }
129   
130   
131    #region Serialization
132    /// <summary>
133    /// Starts the serialization process. Takes the abstract of the graph and
134    /// constructs a NMLType proxy-like object which will be serialized via the
135    /// standard .Net XmlSerializer process.
136    /// </summary>
137    /// <param name="writer">An XmlWriter</param>
138    /// <param name="g">The GraphAbstract object to be serialized</param>
139    public void Serialize(XmlWriter writer, GraphAbstract g )
140    {
141      try
142      {
143        //the root of the NML
144        NMLType nml = new NMLType();
145        //add the version node
146        nml.Version = Assembly.GetExecutingAssembly().GetName().Version.ToString();
147        //the graph node
148        GraphType graph = new GraphType(); 
149        nml.Graph = graph;       
150        //add the graph information       
151        graph.GraphInformation = new GraphInformationType(g.GraphInformation);
152        //serialize the shapes
153        foreach ( Shape s in g.Shapes )       
154          graph.Items.Add(SerializeNode(s));       
155        //serialize the connections
156        foreach(Connection c in g.Connections)
157          graph.Items.Add(SerializeEdge(c));
158       
159        //      foreach(DictionaryEntry de in keyList)
160        //      {
161        //        nml.Key.Add(BuildKeyType((String)de.Key));
162        //      }
163
164     
165        // serialize
166        XmlSerializer ser = new XmlSerializer(typeof(NMLType));
167       
168        ser.Serialize(writer,nml);
169 
170      }
171
172     
173      catch(Exception exc)
174      {
175        site.OutputInfo(exc.Message, "NMLSerializer.Serialize", OutputInfoLevels.Exception);
176      }
177      catch
178      {
179        site.OutputInfo("Non-CLS exception caught.", "BinarySerializer.Serialize", OutputInfoLevels.Exception);
180      }
181      finally
182      {
183           
184      }
185    }
186
187    /// <summary>
188    /// Returns the NML representation of the given GraphAbstract
189    /// </summary> 
190    /// <returns></returns>
191    public string Serialize()
192    {
193      try
194      {
195        GraphAbstract g = this.site.Abstract;
196        System.Text.ASCIIEncoding asciiEncoding = new System.Text.ASCIIEncoding();
197
198        MemoryStream stream = new MemoryStream();
199        XmlTextWriter writer = new XmlTextWriter(stream, System.Text.ASCIIEncoding.ASCII);
200        writer.Formatting = System.Xml.Formatting.Indented;
201        this.Serialize(writer,g);
202
203       
204        //StringReader reader = new StringReader();
205        int count = 0;
206        stream.Seek(0, SeekOrigin.Begin);
207
208        byte[] byteArray = new byte[stream.Length];
209
210        while(count < stream.Length)
211        {
212          byteArray[count++] = Convert.ToByte(stream.ReadByte());
213        }
214
215        // Decode the byte array into a char array
216        // and write it to the console.
217        char[] charArray = new char[asciiEncoding.GetCharCount(byteArray, 0, count)];
218        asciiEncoding.GetDecoder().GetChars(byteArray, 0, count, charArray, 0);
219
220        string s = new string(charArray);
221       
222       
223        writer.Close();
224
225        stream.Close();
226        return s;
227      }
228      catch(Exception exc)
229      {
230        Trace.WriteLine(exc.Message,"NMLSerializer.Serialize");
231        return string.Empty;
232      }
233    }
234
235    /// <summary>
236    /// Serializes a node
237    /// </summary>
238    /// <param name="s"></param>
239    /// <returns></returns>
240    private ShapeType SerializeNode(Shape s)
241    {
242      PropertiesHashtable properties = GraphMLDataAttribute.GetValuesOfTaggedFields(s);
243
244      ShapeType node = new ShapeType();
245      node.UID = FormatID(s);     
246      node.InstanceKey = s.Summary.Key;
247      foreach(Connector c in s.Connectors)
248      {
249        ConnectorType ct = new ConnectorType();
250        ct.Name = c.Name;
251        ct.UID = c.UID.ToString();
252        node.Data.Add(ct);
253      }
254
255
256      //--------------------------------------
257      foreach(DataType data in DataTypesFromAttributes(properties))
258      {
259        node.Data.Add(data);
260      }
261
262      return node;
263    }
264    /// <summary>
265    /// Serializes an edge
266    /// </summary>
267    /// <param name="c"></param>
268    /// <returns></returns>
269    private ConnectionType SerializeEdge(Connection c)
270    {
271      PropertiesHashtable properties = GraphMLDataAttribute.GetValuesOfTaggedFields(c);
272
273      ConnectionType edge = new ConnectionType();
274      edge.ID = FormatID(c);
275     
276      /* Save the connectors the Connection is connected to */
277      edge.Source = FormatID(c.From.BelongsTo);
278      edge.Target = FormatID(c.To.BelongsTo);
279      /* Save the connectors the Connection is connected to */
280      edge.Sourceport = FormatID(c.From);
281      edge.Targetport = FormatID(c.To);     
282      edge.InstanceKey = c.Summary.Key;
283     
284      foreach(DataType dt in DataTypesFromAttributes(properties))
285      {
286        edge.Data.Add(dt);
287      }
288
289      return edge;
290    }
291    #endregion
292   
293    #region Deserialize
294    /// <summary>
295    /// Deserializes the graph's xml
296    /// </summary>
297    /// <returns></returns>
298    public GraphAbstract Deserialize(XmlReader reader)
299    {
300      //very important; always use the same instantiation parameter of the XmlSerializer as
301      //you used for serialization!
302      XmlSerializer ser = new XmlSerializer(typeof(NMLType));
303      if(ser.CanDeserialize(reader))
304      {
305        NMLType gtype = ser.Deserialize(reader) as NMLType;
306       
307        return Deserialize(gtype);
308      }
309      else
310        throw new Exception("The supplied file cannot be deserialized to a graph (check the XML)");
311    }
312
313    /// <summary>
314    /// Deserializes the presumed NML-string to a GraphAbstract object
315    /// </summary>
316    /// <param name="xml">NML compliant string</param>
317    /// <returns></returns>
318    public GraphAbstract Deserialize(string xml)
319    {
320      StringReader sr = new StringReader(xml);
321      XmlTextReader reader = new XmlTextReader(sr);
322      return Deserialize(reader);
323    }
324
325    /// <summary>
326    /// Deserializes the graphtype, here's where all the smart stuff happens
327    /// </summary>
328    /// <param name="gml">the graphtype which acts as an intermediate storage between XML and the GraphAbstract
329    /// </param>
330    /// <returns></returns>
331    private GraphAbstract Deserialize(NMLType gml)
332    {
333      GraphAbstract abs = new GraphAbstract();
334     
335      #region Load the graph information
336      GraphType g = gml.Graph;
337     
338      abs.GraphInformation = g.GraphInformation.ToGraphInformation();   
339
340      #endregion
341      Shape shape = null;
342      ShapeType node;
343      DataType dt;       
344      ConnectorType ct;
345      Connection con = null;
346      ConnectionType et;
347      string linePath = string.Empty; //see the split deserialization of the connection
348     
349      FromToCollection ftc = new FromToCollection(); //temporary store for from-to relations of connections
350      Hashtable connectors = new Hashtable(); //temporary collection of connector
351      #region Loop over all items
352
353     
354
355      for(int k =0; k<g.Items.Count;k++) //loop over all serialized items
356      {
357        try
358        {
359          if(g.Items[k] is ShapeType)
360          {
361            Trace.WriteLine("Node: " + (g.Items[k] as ShapeType).UID,"NMLSerializer.Deserialize");
362            node = g.Items[k] as ShapeType;
363
364            #region find out which type of shape needs to be instantiated
365            if(node!=null && node.InstanceKey!=string.Empty)
366              shape = GetShape(node.InstanceKey);
367            if(shape==null)
368            {
369              Trace.WriteLine("...but failed to instantiate the appropriate shape (missing or not loaded library?", "NMLSerializer.Deserialize");
370              continue;
371            }
372
373            #endregion
374            #region use the attribs again to reconstruct the props       
375            for(int m=0; m<node.Data.Count;m++) //loop over the serialized data
376            {
377              if(node.Data[m] is DataType)
378              {
379                #region Handle data node
380                dt = node.Data[m] as DataType;                       
381                if(dt==null) continue;
382
383                foreach (PropertyInfo pi in shape.GetType().GetProperties())
384                {
385                  if (Attribute.IsDefined(pi, typeof(GraphMLDataAttribute)))
386                  {
387                    try
388                    {
389                      if(pi.Name==dt.Name)
390                      {
391                             
392                        if(pi.GetIndexParameters().Length==0)
393                        {
394                          if(pi.PropertyType.Equals(typeof(int)))
395                            pi.SetValue(shape,Convert.ToInt32(dt.Value[0]),null);
396                          else if(pi.PropertyType.Equals(typeof(Color))) //Color is stored as an integer
397                            pi.SetValue(shape,Color.FromArgb(int.Parse(dt.Value[0].ToString())),null);
398                          else if(pi.PropertyType.Equals(typeof(string)))
399                            pi.SetValue(shape,(string)(dt.Value[0]),null);
400                          else if(pi.PropertyType.Equals(typeof(bool)))
401                            pi.SetValue(shape,Convert.ToBoolean(dt.Value[0]),null);
402                          else if(pi.PropertyType.Equals(typeof(Guid)))
403                            pi.SetValue(shape,new Guid((string) dt.Value[0]),null);
404                          else if(pi.PropertyType.Equals(typeof(float)))
405                            pi.SetValue(shape, Convert.ToSingle(dt.Value[0]),null);
406                          else if(pi.PropertyType.BaseType.Equals(typeof(Enum)))//yesyes, you can imp/exp enum types too
407                            pi.SetValue(shape, Enum.Parse(pi.PropertyType,dt.Value[0].ToString()),null);                         
408                          else if(dt.IsCollection)
409                          {
410                            #region Some explanations
411                            /* OK, here's the deal.
412                             * This part is related to the possibility to imp/exp property-collections from/to NML.
413                             * However, since (see more specifically the ClassShape) the collections will usually be defined
414                             * where the shapes is defined, i.e. in an external assembly, the collection-type is unknown.
415                             * Importing/exporting collections to NML is itsel a problem and in this part of the code the data is reflected again.
416                             * To bypass the problem that the collection-type is unknown I hereby assume that the collection can be built up again via
417                             * a public constructor of the collection with argument 'ArrayList'. In the ArrayList the collection-elements are of type string[]
418                             * whereby the order of the strings reflect the order of the GraphMLData-tagged properties of the collection elements.
419                             * For example, the ClassPropertiesCollection has the required constructor and the ClassProperty object is instantiated via the string[] elements in the
420                             * ArrayList.
421                             * Of course, this brings some restriction but it's for the moment the most flexible way I have found.
422                             * If the ClassProperty would itself have a property inheriting from CollectionBase this will not work...one has to draw a line somewhere.
423                             * It's the price to pay for using reflection and external assemblies. The whole story can be forgotten if you link the shape-classes at compile-time.
424                             * Remember; the Netron graphlib is more a toolkit than a all-in solution to all situations.
425                             * However, the current implementation will cover, I beleive, 90% of the needs.
426                             */
427                            #endregion
428                           
429                            ArrayList list = new ArrayList();
430                            for(int p =0; p<dt.Value.Count; p++) //loop over the collection elements
431                            {
432                              DataType dat = dt.Value[p] as DataType; //take a collection element
433                              if(dat.IsCollection)  //is it itself a collection?
434                              {
435                                string[] str = new string[dat.Value.Count];
436                                for(int l=0;l<dat.Value.Count;l++)
437                                {
438                                  if((dat.Value[l] as DataType).Value.Count>0)
439                                    str[l] = (string) (dat.Value[l] as DataType).Value[0];
440                                  else
441                                    str[l] = string.Empty;
442                                }
443                                list.Add(str);
444                              }
445                              else
446                              {
447                                list.Add(new string[]{(string) dat.Value[0]});
448                              }
449                             
450                            }
451                            object o;
452                            o = pi.PropertyType.GetConstructor(new Type[]{typeof(ArrayList)}).Invoke(new Object[]{list});
453                            pi.SetValue(shape,o,null);
454                            Trace.WriteLine("'" + dt.Name + "' is an array type","NMLSeriliazer.Deserialize");
455                          }
456
457                        }
458                        else
459                          pi.SetValue(shape,dt.Value,null);
460                        Trace.WriteLine("'" + dt.Name + "' deserialized.","NMLSeriliazer.Deserialize");
461                        break;
462                      }
463                    }
464                    catch(Exception exc)
465                    {
466                      Trace.WriteLine("Failed '" + dt.Name +"': " + exc.Message,"NMLSeriliazer.Deserialize");
467                      continue;//just try to make the best out of it
468                    }
469                           
470                  }
471               
472                }
473                #endregion
474              }
475              else if (node.Data[m] is ConnectorType)
476              {
477                #region Handle connector data
478                ct = node.Data[m] as ConnectorType;
479                foreach(Connector c in shape.Connectors)
480                  if(c.Name==ct.Name)
481                  {
482                    c.UID = new Guid(ct.UID);
483                    break;
484                  }
485                #endregion
486              }
487           
488            }
489            #endregion
490            //at this point the shape is fully deserialized
491            //but we still need to assign the ambient properties,
492            //i.e. the properties associated to the current hosting of the control
493            if(shape !=null)
494            {
495              shape.Site = site;
496              shape.PostDeserialization();
497              shape.Font = site.Font;
498              //shape.FitSize(false);
499              abs.Shapes.Add(shape);
500              //keep the references to the connectors, to be used when creating the connections
501              foreach(Connector cor in shape.Connectors)
502                connectors.Add(cor.UID.ToString(),cor);
503            }
504          }
505          else if(g.Items[k] is ConnectionType)
506          {
507            #region  handle the edge
508            //we cannot create the connection here since not all shapes have been instantiated yet
509            //keep the edges in temp collection, treated in next loop
510            et = g.Items[k] as ConnectionType;
511            con = new Connection(site);
512            con.Font = site.Font;
513            con.UID = new Guid(et.ID);
514            Trace.WriteLine("Connection: " + et.ID,"NMLSeriliazer.Deserialize");
515            #region use the attribs to reconstruct the props
516
517
518            for(int m=0; m<et.Data.Count;m++) //loop over the serialized data
519            {
520              if(et.Data[m] is DataType)
521              {
522                #region Handle data node, same as the shape
523                dt = et.Data[m] as DataType;                       
524                if(dt==null) continue;
525
526                foreach (PropertyInfo pi in con.GetType().GetProperties())
527                {
528                  if (Attribute.IsDefined(pi, typeof(GraphMLDataAttribute)))
529                  {
530                    try
531                    {
532                      if(pi.Name==dt.Name)
533                      {
534                        if(dt.Name=="LinePath")
535                        {
536                          //the LinePath will not work without non-null From and To, so set it afterwards
537                          linePath = dt.Value[0].ToString();
538                        }
539                        else if(pi.GetIndexParameters().Length==0)
540                        {
541                          if(pi.PropertyType.Equals(typeof(int)))
542                            pi.SetValue(con,Convert.ToInt32(dt.Value[0]),null);
543                          else if(pi.PropertyType.Equals(typeof(Color))) //Color is stored as an integer
544                            pi.SetValue(con,Color.FromArgb(int.Parse(dt.Value[0].ToString())),null);
545                          else if(pi.PropertyType.Equals(typeof(string)))
546                            pi.SetValue(con,(string)(dt.Value[0]),null);
547                          else if(pi.PropertyType.Equals(typeof(bool)))
548                            pi.SetValue(con,Convert.ToBoolean(dt.Value[0]),null);
549                          else if(pi.PropertyType.Equals(typeof(Guid)))
550                            pi.SetValue(con,new Guid((string) dt.Value[0]),null);
551                          else if(pi.PropertyType.Equals(typeof(float)))
552                            pi.SetValue(con, Convert.ToSingle(dt.Value[0]),null);
553                          else if (pi.PropertyType.Equals(typeof(ConnectionWeight)))
554                            pi.SetValue(con, Enum.Parse(typeof(ConnectionWeight),dt.Value[0].ToString()),null);
555                          else if (pi.PropertyType.Equals(typeof(System.Drawing.Drawing2D.DashStyle)))
556                            pi.SetValue(con, Enum.Parse(typeof(System.Drawing.Drawing2D.DashStyle),dt.Value[0].ToString()),null);
557
558                        }
559                        else
560                          pi.SetValue(con,dt.Value,null);
561                        Trace.WriteLine("'" + dt.Name + "' deserialized.","NMLSeriliazer.Deserialize");
562                        break;
563                      }
564                    }
565                    catch(Exception exc)
566                    {
567                      Trace.WriteLine("Failed '" + dt.Name +"': " + exc.Message,"NMLSeriliazer.Deserialize");
568                      continue;//just try to make the best out of it
569                    }
570                           
571                  }
572               
573                }
574                #endregion
575              }
576            }
577
578            #endregion
579            ftc.Add(new FromTo(et.Sourceport,et.Targetport, con));
580            #endregion
581          }
582        }
583        catch(Exception exc)
584        {
585          Trace.WriteLine(exc.Message,"NMLSeriliazer.Deserialize");
586          continue;
587        }
588
589      }//loop over items in the graph-XML
590      #endregion
591
592      #region now for the edges;
593      //loop over the FromTo collections and pick up the corresponding connectors
594      for(int k=0; k<ftc.Count; k++)
595      {
596        try
597        {
598          con = ftc[k].Connection;
599          con.From = connectors[ftc[k].From] as Connector;
600          con.To = connectors[ftc[k].To] as Connector;         
601          con.From.Connections.Add(con);//if From is null we'll fail in the catch and continue
602          con.LinePath = linePath; //only setable after the From and To are found
603          con.To.Connections.Add(con);       
604          abs.Insert(con);
605          Trace.WriteLine("Connection '" + con.UID + "' added.","NMLSeriliazer.Deserialize");
606        }
607        catch(Exception exc)
608        {
609          Trace.WriteLine("Connection failed: " + exc.Message,"NMLSeriliazer.Deserialize");
610          continue; //make the best of it
611        }
612      }
613      #endregion
614     
615
616      //      for(int n=0; n<pcs.Count; n++)
617      //      {
618      //        from = pcs[n].ChildShape;
619      //        to = abs.Shapes[pcs[n].Parent];
620      //        con = new Connection(from, to );
621      //        abs.Connections.Add(con);
622      //        con.site = site;
623      //        if(pcs[n].ChildShape.visible)
624      //          con.visible = true;
625      //        from.connection = con;  //a lot of crossing...to make life easy really
626      //        from.parentNode =to;
627      //        to.childNodes.Add(from);
628      //       
629      //       
630      //      }
631
632      return abs;
633
634    }
635
636    #endregion
637
638   
639 
640    #endregion
641
642    #region Helper Functions
643    /// <summary>
644    /// Validation of the XML
645    /// </summary>
646    /// <param name="reader"></param>
647    public static void Validate(XmlReader reader)
648    {
649      //TODO: looks a little odd this one
650      XmlValidatingReader vr = new XmlValidatingReader(reader);
651
652      vr.ValidationType = ValidationType.Auto;
653      vr.ValidationEventHandler += new ValidationEventHandler(ValidationHandler);
654
655      while (vr.Read()){};
656    }
657    /// <summary>
658    /// Outputs the validation of the XML
659    /// </summary>
660    /// <param name="sender"></param>
661    /// <param name="args"></param>
662    private static void ValidationHandler(object sender, ValidationEventArgs args)
663    {
664      Trace.WriteLine(args.ToString(),"NMLSeriliazer.ValidationHandler");
665    }
666
667    /// <summary>
668    /// Returns a shape on the basis of the unique instantiation key
669    /// </summary>
670    /// <param name="key"></param>
671    /// <returns></returns>
672    private Shape GetShape(string key)
673    {
674
675      ObjectHandle handle;
676      Shape shape;
677      for(int k=0; k<site.Libraries.Count;k++)
678      {
679        for(int m=0; m<site.Libraries[k].ShapeSummaries.Count; m++)
680        {
681          if(site.Libraries[k].ShapeSummaries[m].Key == key)
682          {
683            //Type shapeType = Type.GetType(site.Libraries[k].ShapeSummaries[m].ReflectionName);
684           
685            //object[] args = {this.site};
686            Directory.SetCurrentDirectory(Path.GetDirectoryName(Application.ExecutablePath));
687            handle = Activator.CreateInstanceFrom(site.Libraries[k].Path,site.Libraries[k].ShapeSummaries[m].ReflectionName);
688            shape = handle.Unwrap() as Shape;
689            return shape;
690           
691          }
692        }
693      }
694
695      return null;
696
697     
698    }
699   
700    /// <summary>
701    /// Returns the UID of the entity in string format
702    /// </summary>
703    /// <param name="e"></param>
704    /// <returns></returns>
705    private static string FormatID(Entity e)
706    {
707      return String.Format("{0}",e.UID.ToString());
708    }
709
710    private static KeyType BuildKeyType(String s)
711    {
712      KeyType kt = new KeyType();
713      kt.ID = s;
714      kt.For = KeyForType.All;
715     
716      return kt;
717    }
718
719   
720
721
722    /// <summary>
723    /// Converts the hashtable of GraphML-marked properties to types
724    /// </summary>
725    /// <param name="properties"></param>
726    /// <returns></returns>
727    private DataType[] DataTypesFromAttributes(PropertiesHashtable properties)
728    {
729      DataType[] dts = new DataType[properties.Count];
730      for(int k=0; k<properties.Count;k++)
731      {
732       
733        dts[k] = new DataType();
734        dts[k].Name = properties.Keys[k];
735        object val = null;
736        if ((val=properties[k]) != null)
737        {
738          //the color is a bit different
739          if(typeof(Color).IsInstanceOfType(val))
740          {
741            int num = ((Color) val).ToArgb();
742            dts[k].Value.Add(num.ToString());
743          }
744          else if(typeof(Shape).IsInstanceOfType(val))
745          {
746            dts[k].Value.Add((val as Shape).UID.ToString());
747          }
748          else if(typeof(Guid).IsInstanceOfType(val))
749          {
750            dts[k].Value.Add(((Guid) val ).ToString());
751          }
752          else if(typeof(CollectionBase).IsInstanceOfType(val))
753          {
754            CollectionBase col = val as CollectionBase;
755            IEnumerator enumer  = col.GetEnumerator();
756            while(enumer.MoveNext())
757            {
758              object obj = enumer.Current;
759              PropertiesHashtable props= GraphMLDataAttribute.GetValuesOfTaggedFields(obj);
760              DataType[] tps = DataTypesFromAttributes(props);
761              DataType dt = new DataType();
762              dt.Name=obj.GetType().Name;//the name of the collection element
763              dt.IsCollection = true;
764              for(int m =0; m<tps.Length; m++)
765                dt.Value.Add  (tps[m]);
766
767              dts[k].Value.Add(dt);
768              dts[k].IsCollection = true;
769             
770            }           
771          }
772          else
773            dts[k].Value.Add(val.ToString());
774        }
775        /*
776         * makes the union of all properties in the different shapes
777        if ( !keyList.Contains(properties.Keys[k]))
778          keyList.Add(properties.Keys[k],val);
779        */
780     
781      }
782      return dts;
783    }
784
785    /// <summary>
786    /// Returns qualified type name of o
787    /// </summary>
788    /// <param name="o"></param>
789    /// <returns></returns>
790    private static string GetTypeQualifiedName(object o)
791    {
792      if (o==null)
793        throw new ArgumentNullException("GetTypeQualifiedName(object) was called with null parameter");
794      return GetTypeQualifiedName(o.GetType());
795    }
796
797    /// <summary>
798    ///
799    /// </summary>
800    /// <param name="t"></param>
801    /// <returns></returns>
802    private static string GetTypeQualifiedName(Type t)
803    {
804      return Assembly.CreateQualifiedName(
805        t.Assembly.FullName,
806        t.FullName
807        );
808    }
809
810    private static Type ToType(string text)
811    {
812      return Type.GetType(text,true);
813    }
814
815    private static bool ToBool(string text)
816    {
817      return bool.Parse(text);
818    }
819    #endregion
820  }
821}
822
Note: See TracBrowser for help on using the repository browser.