2 // System.ComponentModel.Design.Serialization.CollectionCodeDomSerializer
5 // Ivan N. Zlatev (contact i-nZ.net)
7 // (C) 2007 Ivan N. Zlatev
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.
33 using System
.Collections
;
34 using System
.Reflection
;
35 using System
.ComponentModel
;
36 using System
.ComponentModel
.Design
;
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
)
55 public override object Serialize (IDesignerSerializationManager manager
, object value)
58 throw new ArgumentNullException ("value");
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");
93 throw new ArgumentNullException ("manager");
95 if (valuesToSerialize
.Count
== 0)
98 MethodInfo method
= null;
100 object sampleParam
= null;
101 IEnumerator e
= valuesToSerialize
.GetEnumerator ();
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 }
);
108 base.ReportError (manager
, "A compatible Add/AddRange method is missing in the collection type '"
109 + targetType
.Name
+ "'");
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
);
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)
148 types
[i
] = arguments
[i
].GetType ();
152 return type
.GetMethod (methodName
, types
);