~ubuntu-branches/ubuntu/oneiric/monodevelop/oneiric-updates

« back to all changes in this revision

Viewing changes to src/core/MonoDevelop.Core/MonoDevelop.Core.Serialization/ItemProperty.cs

  • Committer: Bazaar Package Importer
  • Author(s): Jo Shields
  • Date: 2009-02-18 08:40:51 UTC
  • mfrom: (1.2.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20090218084051-gh8m6ukvokbwj7cf
Tags: 1.9.2+dfsg-1ubuntu1
* Merge from Debian Experimental (LP: #330519), remaining Ubuntu changes:
  + debian/control:
    - Update for Gnome# 2.24
    - Add libmono-cairo1.0-cil to build-deps to fool pkg-config check

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//
 
2
// ItemProperty.cs
 
3
//
 
4
// Author:
 
5
//   Lluis Sanchez Gual
 
6
//
 
7
// Copyright (C) 2005 Novell, Inc (http://www.novell.com)
 
8
//
 
9
// Permission is hereby granted, free of charge, to any person obtaining
 
10
// a copy of this software and associated documentation files (the
 
11
// "Software"), to deal in the Software without restriction, including
 
12
// without limitation the rights to use, copy, modify, merge, publish,
 
13
// distribute, sublicense, and/or sell copies of the Software, and to
 
14
// permit persons to whom the Software is furnished to do so, subject to
 
15
// the following conditions:
 
16
// 
 
17
// The above copyright notice and this permission notice shall be
 
18
// included in all copies or substantial portions of the Software.
 
19
// 
 
20
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 
21
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 
22
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 
23
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 
24
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 
25
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 
26
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
27
//
 
28
 
 
29
using System;
 
30
using System.Reflection;
 
31
 
 
32
namespace MonoDevelop.Core.Serialization
 
33
{
 
34
        public class ItemProperty
 
35
        {
 
36
                string name;
 
37
                MemberInfo member;
 
38
                DataType dataType;
 
39
                Type propType;
 
40
                object defaultValue;
 
41
                DataContext ctx;
 
42
                object mapData;
 
43
                bool expandedCollection;
 
44
                ICollectionHandler expandedCollectionHandler;
 
45
                string[] nameList;
 
46
                bool readOnly;
 
47
                bool writeOnly;
 
48
                bool unsorted;
 
49
                bool external;
 
50
                object initValue;
 
51
                
 
52
                public ItemProperty ()
 
53
                {
 
54
                }
 
55
                
 
56
                public ItemProperty (string name, Type propType)
 
57
                {
 
58
                        this.name = name;
 
59
                        this.propType = propType;
 
60
                        BuildNameList ();
 
61
                }
 
62
                
 
63
                void BuildNameList ()
 
64
                {
 
65
                        if (name.IndexOf ('/') != -1) {
 
66
                                nameList = name.Split ('/');
 
67
                        }
 
68
                }
 
69
                
 
70
                internal void SetContext (DataContext ctx)
 
71
                {
 
72
                        this.ctx = ctx;
 
73
                        if (dataType == null) {
 
74
                                if (propType == null) throw new InvalidOperationException ("Property type not specified");
 
75
                                dataType = ctx.GetConfigurationDataType (propType);
 
76
                        }
 
77
                }
 
78
                
 
79
                internal void Initialize (object[] attributes, string scope)
 
80
                {
 
81
                        mapData = dataType.GetMapData (attributes, scope);
 
82
                }
 
83
                
 
84
                internal MemberInfo Member {
 
85
                        get { return member; }
 
86
                        set { CheckReadOnly (); member = value; }
 
87
                }
 
88
                
 
89
                internal virtual string MemberName {
 
90
                        get { return member != null ? member.Name : null; }
 
91
                }
 
92
                
 
93
                public string Name {
 
94
                        get { return name; }
 
95
                        set { CheckReadOnly (); name = value; BuildNameList (); }
 
96
                }
 
97
                
 
98
                public object DefaultValue {
 
99
                        get {
 
100
                                // Workaround for a bug in mono 1.0 (enum values are encoded as ints in attributes)
 
101
                                if (defaultValue != null && propType != null && propType.IsEnum && !(propType.IsInstanceOfType (defaultValue)))
 
102
                                        defaultValue = Enum.ToObject (propType, defaultValue);
 
103
                                return defaultValue;
 
104
                        }
 
105
                        set { CheckReadOnly (); defaultValue = value; }
 
106
                }
 
107
                
 
108
                public Type PropertyType {
 
109
                        get { return propType; }
 
110
                        set { CheckReadOnly (); propType = value; }
 
111
                }
 
112
                
 
113
                public bool ExpandedCollection {
 
114
                        get { return expandedCollection; }
 
115
                        set { expandedCollection = value; }
 
116
                }
 
117
                
 
118
                internal ICollectionHandler ExpandedCollectionHandler {
 
119
                        get { return expandedCollectionHandler; }
 
120
                        set { expandedCollectionHandler = value; }
 
121
                }
 
122
                
 
123
                public bool ReadOnly {
 
124
                        get { return readOnly; }
 
125
                        set { readOnly = value; }
 
126
                }
 
127
                
 
128
                public bool WriteOnly {
 
129
                        get { return writeOnly; }
 
130
                        set { writeOnly = value; }
 
131
                }
 
132
                
 
133
                public DataType DataType {
 
134
                        get { return dataType; }
 
135
                        set { CheckReadOnly (); dataType = value; }
 
136
                }
 
137
                
 
138
                public bool SkipEmpty { get; set; }
 
139
                
 
140
                public bool IsExtendedProperty (Type forType)
 
141
                {
 
142
                        if (member == null)
 
143
                                return true;
 
144
                        else
 
145
                                return !member.DeclaringType.IsAssignableFrom (forType);
 
146
                }
 
147
                
 
148
                internal string[] NameList {
 
149
                        get { return nameList; }
 
150
                }
 
151
                
 
152
                internal bool IsNested {
 
153
                        get { return nameList != null; }
 
154
                }
 
155
                
 
156
                internal string SingleName {
 
157
                        get { return nameList != null ? nameList [nameList.Length-1] : name; }
 
158
                }
 
159
                
 
160
                internal DataContext Context {
 
161
                        get { return ctx; }
 
162
                }
 
163
                
 
164
                internal virtual object GetValue (object obj)
 
165
                {
 
166
                        if (member != null) {
 
167
                                FieldInfo field = member as FieldInfo;
 
168
                                if (field != null) return field.GetValue (obj);
 
169
                                else return ((PropertyInfo)member).GetValue (obj, null);
 
170
                        } else if (obj is IExtendedDataItem) {
 
171
                                IExtendedDataItem eitem = (IExtendedDataItem) obj;
 
172
                                if (initValue == null)
 
173
                                        return eitem.ExtendedProperties [Name];
 
174
                                else {
 
175
                                        if (!eitem.ExtendedProperties.Contains (Name))
 
176
                                                return initValue;
 
177
                                        else
 
178
                                                return eitem.ExtendedProperties [Name];
 
179
                                }
 
180
                        }
 
181
                        else if (initValue != null)
 
182
                                return initValue;
 
183
                        else
 
184
                                throw new InvalidOperationException ("Invalid object property: " + obj.GetType() + "." + Name);
 
185
                }
 
186
 
 
187
                internal virtual void SetValue (object obj, object value)
 
188
                {
 
189
                        if (member != null) {
 
190
                                FieldInfo field = member as FieldInfo;
 
191
                                if (field != null)
 
192
                                        field.SetValue (obj, value);
 
193
                                else {
 
194
                                        PropertyInfo pi = member as PropertyInfo;
 
195
                                        pi.SetValue (obj, value, null);
 
196
                                }
 
197
                        }
 
198
                        else if (obj is IExtendedDataItem)
 
199
                                ((IExtendedDataItem)obj).ExtendedProperties [Name] = value;
 
200
                        else if (initValue == null)
 
201
                                throw new InvalidOperationException ("Invalid object property: " + obj.GetType() + "." + Name);
 
202
                }
 
203
                
 
204
                internal bool HasSetter {
 
205
                        get { return member == null || (member is FieldInfo) || ((member is PropertyInfo) && ((PropertyInfo)member).CanWrite); }
 
206
                }
 
207
 
 
208
                internal bool Unsorted {
 
209
                        get {
 
210
                                return unsorted;
 
211
                        }
 
212
                        set {
 
213
                                unsorted = value;
 
214
                        }
 
215
                }
 
216
 
 
217
                public bool IsExternal {
 
218
                        get {
 
219
                                return external;
 
220
                        }
 
221
                        set {
 
222
                                external = value;
 
223
                        }
 
224
                }
 
225
 
 
226
                public object InitValue {
 
227
                        get {
 
228
                                return initValue;
 
229
                        }
 
230
                        set {
 
231
                                initValue = value;
 
232
                        }
 
233
                }
 
234
                
 
235
                internal bool CanSerialize (SerializationContext serCtx, object instance)
 
236
                {
 
237
                        return serCtx.Serializer.CanSerializeProperty (this, serCtx, instance);
 
238
                }
 
239
 
 
240
                internal DataNode Serialize (SerializationContext serCtx, object instance, object value)
 
241
                {
 
242
                        return serCtx.Serializer.OnSerializeProperty (this, serCtx, instance, value);
 
243
                }
 
244
                
 
245
                internal DataNode OnSerialize (SerializationContext serCtx, object value)
 
246
                {
 
247
                        DataNode data = dataType.Serialize (serCtx, mapData, value);
 
248
                        
 
249
                        if (data != null) {
 
250
                                // Don't write empty collections or empty objects with the SkipEmpty flag
 
251
                                if (data is DataItem && !((DataItem)data).HasItemData && (DataType is CollectionDataType || SkipEmpty))
 
252
                                        return null;
 
253
                                data.Name = SingleName;
 
254
                        }
 
255
                        return data;
 
256
                }
 
257
                
 
258
                internal bool CanDeserialize (SerializationContext serCtx, object instance)
 
259
                {
 
260
                        return serCtx.Serializer.CanDeserializeProperty (this, serCtx, instance);
 
261
                }
 
262
                
 
263
                internal object Deserialize (SerializationContext serCtx, object instance, DataNode data)
 
264
                {
 
265
                        return serCtx.Serializer.OnDeserializeProperty (this, serCtx, instance, data);
 
266
                }
 
267
                
 
268
                internal object OnDeserialize (SerializationContext serCtx, DataNode data)
 
269
                {
 
270
                        return dataType.Deserialize (serCtx, mapData, data);
 
271
                }
 
272
                
 
273
                internal void Deserialize (SerializationContext serCtx, object instance, DataNode data, object valueInstance)
 
274
                {
 
275
                        serCtx.Serializer.OnDeserializeProperty (this, serCtx, instance, data, valueInstance);
 
276
                }
 
277
                
 
278
                internal void OnDeserialize (SerializationContext serCtx, DataNode data, object valueInstance)
 
279
                {
 
280
                        dataType.Deserialize (serCtx, mapData, data, valueInstance);
 
281
                }
 
282
                
 
283
                void CheckReadOnly ()
 
284
                {
 
285
                        if (ctx != null)
 
286
                                throw new InvalidOperationException ("Property can't be modified, it is already bound to a configuration context");
 
287
                }
 
288
        }
 
289
}