2010-04-06 Jb Evain <jbevain@novell.com>
[mcs.git] / class / System.Design / System.ComponentModel.Design.Serialization / CollectionCodeDomSerializer.cs
blobe70a2098f0ee2668e5e26c0909b8a2601c6141b2
1 //
2 // System.ComponentModel.Design.Serialization.CollectionCodeDomSerializer
3 //
4 // Authors:
5 // Ivan N. Zlatev (contact i-nZ.net)
6 //
7 // (C) 2007 Ivan N. Zlatev
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 #if NET_2_0
32 using System;
33 using System.Collections;
34 using System.Reflection;
35 using System.ComponentModel;
36 using System.ComponentModel.Design;
38 using System.CodeDom;
40 namespace System.ComponentModel.Design.Serialization
42 public class CollectionCodeDomSerializer : CodeDomSerializer
45 public CollectionCodeDomSerializer ()
49 // FIXME: What is this supposed to do?
50 protected bool MethodSupportsSerialization (MethodInfo method)
52 return true;
55 public override object Serialize (IDesignerSerializationManager manager, object value)
57 if (value == null)
58 throw new ArgumentNullException ("value");
59 if (manager == null)
60 throw new ArgumentNullException ("manager");
62 ICollection originalCollection = value as ICollection;
63 if (originalCollection == null)
64 throw new ArgumentException ("originalCollection is not an ICollection");
66 CodeExpression targetExpression = null;
68 ExpressionContext exprContext = manager.Context[typeof (ExpressionContext)] as ExpressionContext;
69 RootContext root = manager.Context[typeof (RootContext)] as RootContext;
71 if (exprContext != null && exprContext.PresetValue == value)
72 targetExpression = exprContext.Expression;
73 else if (root != null)
74 targetExpression = root.Expression;
76 ArrayList valuesToSerialize = new ArrayList ();
77 foreach (object o in originalCollection)
78 valuesToSerialize.Add (o);
80 return this.SerializeCollection (manager, targetExpression, value.GetType (), originalCollection, valuesToSerialize);
83 protected virtual object SerializeCollection (IDesignerSerializationManager manager, CodeExpression targetExpression,
84 Type targetType, ICollection originalCollection, ICollection valuesToSerialize)
86 if (valuesToSerialize == null)
87 throw new ArgumentNullException ("valuesToSerialize");
88 if (originalCollection == null)
89 throw new ArgumentNullException ("originalCollection");
90 if (targetType == null)
91 throw new ArgumentNullException ("targetType");
92 if (manager == null)
93 throw new ArgumentNullException ("manager");
95 if (valuesToSerialize.Count == 0)
96 return null;
98 MethodInfo method = null;
99 try {
100 object sampleParam = null;
101 IEnumerator e = valuesToSerialize.GetEnumerator ();
102 e.MoveNext ();
103 sampleParam = e.Current;
104 // try to find a method matching the type of the sample parameter.
105 // Assuming objects in the collection are from the same base type
106 method = GetExactMethod (targetType, "Add", new object [] { sampleParam });
107 } catch {
108 base.ReportError (manager, "A compatible Add/AddRange method is missing in the collection type '"
109 + targetType.Name + "'");
112 if (method == null)
113 return null;
115 CodeStatementCollection statements = new CodeStatementCollection ();
117 foreach (object value in valuesToSerialize) {
119 CodeMethodInvokeExpression methodInvoke = new CodeMethodInvokeExpression ();
120 methodInvoke.Method = new CodeMethodReferenceExpression (targetExpression, "Add");
122 CodeExpression expression = base.SerializeToExpression (manager, value);
123 if (expression != null) {
124 methodInvoke.Parameters.AddRange (new CodeExpression[] { expression });
125 statements.Add (methodInvoke);
129 return statements;
132 // Searches for a method on type that matches argument types
134 private MethodInfo GetExactMethod (Type type, string methodName, ICollection argsCollection)
136 object[] arguments = null;
137 Type[] types = Type.EmptyTypes;
139 if (argsCollection != null) {
140 arguments = new object[argsCollection.Count];
141 types = new Type[argsCollection.Count];
142 argsCollection.CopyTo (arguments, 0);
144 for (int i=0; i < arguments.Length; i++) {
145 if (arguments[i] == null)
146 types[i] = null;
147 else
148 types[i] = arguments[i].GetType ();
152 return type.GetMethod (methodName, types);
156 #endif