In corlib/System.Runtime.InteropServices:
[mono.git] / mcs / class / System / System.Configuration / ApplicationSettingsBase.cs
1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
8 // 
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
11 // 
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 //
20 // Copyright (C) 2005, 2006 Novell, Inc (http://www.novell.com)
21 //
22
23 #if NET_2_0
24 #if CONFIGURATION_DEP && !TARGET_JVM
25 extern alias PrebuiltSystem;
26 using NameValueCollection = PrebuiltSystem.System.Collections.Specialized.NameValueCollection;
27 #endif
28 #if CONFIGURATION_DEP
29 using System.IO;
30 using System.Xml.Serialization;
31 #endif
32
33 using System.ComponentModel;
34 using System.Reflection;
35 using System.Collections.Specialized;
36
37 namespace System.Configuration {
38
39         public abstract class ApplicationSettingsBase : SettingsBase, INotifyPropertyChanged
40         {
41
42                 protected ApplicationSettingsBase ()
43                 {
44                         Initialize (Context, Properties, Providers);
45                 }
46
47                 protected ApplicationSettingsBase (IComponent owner)
48                         : this (owner, String.Empty)
49                 {
50                 }
51
52  
53                 protected ApplicationSettingsBase (string settingsKey)
54                 {
55                         this.settingsKey = settingsKey;
56
57                         Initialize (Context, Properties, Providers);
58                 }
59
60                 protected ApplicationSettingsBase (IComponent owner, 
61                                                    string settingsKey)
62                 {
63                         if (owner == null)
64                                 throw new ArgumentNullException ();
65
66                         providerService = (ISettingsProviderService)owner.Site.GetService(typeof (ISettingsProviderService));
67
68                         this.settingsKey = settingsKey;
69
70                         Initialize (Context, Properties, Providers);
71                 }
72
73                 public event PropertyChangedEventHandler PropertyChanged;
74                 public event SettingChangingEventHandler SettingChanging;
75                 public event SettingsLoadedEventHandler SettingsLoaded;
76                 public event SettingsSavingEventHandler SettingsSaving;
77
78                 public object GetPreviousVersion (string propertyName)
79                 {
80                         throw new NotImplementedException ();
81                 }
82
83                 public void Reload ()
84                 {
85 #if (CONFIGURATION_DEP)
86                         foreach (SettingsProvider provider in Providers) {
87                                 IApplicationSettingsProvider iasp = provider as IApplicationSettingsProvider;
88                                 if (iasp != null)
89                                         iasp.Reset (Context);
90                         }
91 #endif
92                 }
93
94                 public void Reset()
95                 {
96 #if (CONFIGURATION_DEP)
97                         foreach (SettingsProvider provider in Providers) {
98                                 IApplicationSettingsProvider iasp = provider as IApplicationSettingsProvider;
99                                 if (iasp != null)
100                                         iasp.Reset (Context);
101                         }
102
103                         Reload ();
104 #endif
105                 }
106
107                 public override void Save()
108                 {
109 #if (CONFIGURATION_DEP)
110                         /* ew.. this needs to be more efficient */
111                         foreach (SettingsProvider provider in Providers) {
112                                 SettingsPropertyValueCollection cache = new SettingsPropertyValueCollection ();
113
114                                 foreach (SettingsPropertyValue val in PropertyValues) {
115                                         if (val.Property.Provider == provider)
116                                                 cache.Add (val);
117                                 }
118
119                                 if (cache.Count > 0)
120                                         provider.SetPropertyValues (Context, cache);
121                         }
122 #endif
123                 }
124
125                 public virtual void Upgrade()
126                 {
127                 }
128
129                 protected virtual void OnPropertyChanged (object sender, 
130                                                           PropertyChangedEventArgs e)
131                 {
132                         if (PropertyChanged != null)
133                                 PropertyChanged (sender, e);
134                 }
135
136                 protected virtual void OnSettingChanging (object sender, 
137                                                           SettingChangingEventArgs e)
138                 {
139                         if (SettingChanging != null)
140                                 SettingChanging (sender, e);
141                 }
142
143                 protected virtual void OnSettingsLoaded (object sender, 
144                                                          SettingsLoadedEventArgs e)
145                 {
146                         if (SettingsLoaded != null)
147                                 SettingsLoaded (sender, e);
148                 }
149
150                 protected virtual void OnSettingsSaving (object sender, 
151                                                          CancelEventArgs e)
152                 {
153                         if (SettingsSaving != null)
154                                 SettingsSaving (sender, e);
155                 }
156
157                 [Browsable (false)]
158                 public override SettingsContext Context {
159                         get {
160                                 if (context == null)
161                                         context = new SettingsContext ();
162
163                                 return context;
164                         }
165                 }
166
167                 void CacheValuesByProvider (SettingsProvider provider)
168                 {
169                         SettingsPropertyCollection col = new SettingsPropertyCollection ();
170
171                         foreach (SettingsProperty p in Properties) {
172                                 if (p.Provider == provider)
173                                         col.Add (p);
174                         }
175
176                         if (col.Count > 0) {
177                                 SettingsPropertyValueCollection vals = provider.GetPropertyValues (Context, col);
178                                 PropertyValues.Add (vals);
179                         }
180
181                         OnSettingsLoaded (this, new SettingsLoadedEventArgs (provider));
182                 }
183
184                 void InitializeSettings (SettingsPropertyCollection settings)
185                 {
186                 }
187
188                 object GetPropertyValue (string propertyName)
189                 {
190                         SettingsProperty prop = Properties [ propertyName ];
191
192                         if (prop == null)
193                                 throw new SettingsPropertyNotFoundException (propertyName);
194
195                         if (propertyValues == null)
196                                 InitializeSettings (Properties);
197
198                         if (PropertyValues [ propertyName ] == null)
199                                 CacheValuesByProvider (prop.Provider);
200
201                         return PropertyValues [ propertyName ].PropertyValue;
202                 }
203
204                 [MonoTODO]
205                 public override object this [ string propertyName ] {
206                         get {
207                                 return GetPropertyValue (propertyName);
208                         }
209                         set {
210                                 SettingsProperty prop = Properties [ propertyName ];
211
212                                 if (prop == null)
213                                         throw new SettingsPropertyNotFoundException (propertyName);
214
215                                 if (prop.IsReadOnly)
216                                         throw new SettingsPropertyIsReadOnlyException (propertyName);
217
218                                 /* XXX check the type of the property vs the type of @value */
219                                 if (value != null &&
220                                     !prop.PropertyType.IsAssignableFrom (value.GetType()))
221                                         throw new SettingsPropertyWrongTypeException (propertyName);
222
223                                 if (PropertyValues [ propertyName ] == null)
224                                         CacheValuesByProvider (prop.Provider);
225
226                                 SettingChangingEventArgs changing_args = new SettingChangingEventArgs (propertyName,
227                                                                                                        GetType().FullName,
228                                                                                                        settingsKey,
229                                                                                                        value,
230                                                                                                        false);
231
232                                 OnSettingChanging (this, changing_args);
233
234                                 if (changing_args.Cancel == false) {
235                                         /* actually set the value */
236                                         PropertyValues [ propertyName ].PropertyValue = value;
237
238                                         /* then emit PropertyChanged */
239                                         OnPropertyChanged (this, new PropertyChangedEventArgs (propertyName));
240                                 }
241                         }
242                 }
243
244 #if (CONFIGURATION_DEP)
245                 [Browsable (false)]
246                 public override SettingsPropertyCollection Properties {
247                         get {
248                                 if (properties == null) {
249                                         LocalFileSettingsProvider local_provider = null;
250
251                                         properties = new SettingsPropertyCollection ();
252
253                                         foreach (PropertyInfo prop in GetType().GetProperties (/* only public properties? */)) {
254                                                 SettingAttribute[] setting_attrs = (SettingAttribute[])prop.GetCustomAttributes (typeof (SettingAttribute), false);
255                                                 if (setting_attrs != null && setting_attrs.Length > 0) {
256                                                         SettingsAttributeDictionary dict = new SettingsAttributeDictionary ();
257                                                         SettingsProvider provider = null;
258                                                         object defaultValue = null;
259                                                         SettingsSerializeAs serializeAs = SettingsSerializeAs.String;
260
261                                                         foreach (Attribute a in prop.GetCustomAttributes (false)) {
262                                                                 /* the attributes we handle natively here */
263                                                                 if (a is SettingsProviderAttribute) {
264                                                                         Type provider_type = Type.GetType (((SettingsProviderAttribute)a).ProviderTypeName);
265                                                                         provider = (SettingsProvider) Activator.CreateInstance (provider_type);
266                                                                         provider.Initialize (null, null);
267                                                                 }
268                                                                 else if (a is DefaultSettingValueAttribute) {
269                                                                         defaultValue = ((DefaultSettingValueAttribute)a).Value; /* XXX this is a string.. do we convert? */
270                                                                         // note: for StringCollection, TypeDescriptor.GetConverter(prop.PropertyType) returns
271                                                                         // CollectionConverter, however this class cannot handle the XML serialized strings
272                                                                         if (prop.PropertyType == typeof(StringCollection)) {
273                                                                                 XmlSerializer xs = new XmlSerializer (typeof (string[]));
274                                                                                 string[] values = (string[]) xs.Deserialize (new StringReader ((string)defaultValue));
275                                                                                 StringCollection sc = new StringCollection ();
276                                                                                 sc.AddRange (values);
277                                                                                 defaultValue = sc;
278                                                                         } else if (prop.PropertyType != typeof(string)) {
279                                                                                 defaultValue = TypeDescriptor.GetConverter(prop.PropertyType).ConvertFromString((string)defaultValue);
280                                                                         }
281                                                                 }
282                                                                 else if (a is SettingsSerializeAsAttribute) {
283                                                                         serializeAs = ((SettingsSerializeAsAttribute)a).SerializeAs;
284                                                                 }
285                                                                 else if (a is ApplicationScopedSettingAttribute ||
286                                                                          a is UserScopedSettingAttribute) {
287                                                                         dict.Add (a.GetType(), a);
288                                                                 }
289                                                                 else {
290                                                                         dict.Add (a.GetType(), a);
291                                                                 }
292                                                         }
293
294                                                         SettingsProperty setting = new SettingsProperty (prop.Name,
295                                                                                                          prop.PropertyType,
296                                                                                                          provider,
297                                                                                                          false /* XXX */,
298                                                                                                          defaultValue /* XXX always a string? */,
299                                                                                                          serializeAs,
300                                                                                                          dict,
301                                                                                                          false, false);
302
303
304                                                         if (providerService != null)
305                                                                 setting.Provider = providerService.GetSettingsProvider (setting);
306
307                                                         if (provider == null) {
308                                                                 if (local_provider == null) {
309                                                                         local_provider = new LocalFileSettingsProvider ();
310                                                                         local_provider.Initialize (null, null);
311                                                                 }
312                                                                 setting.Provider = local_provider;
313                                                         }
314
315                                                         if (provider != null) {
316                                                                 /* make sure we're using the same instance of a
317                                                                    given provider across multiple properties */
318                                                                 SettingsProvider p = Providers[provider.Name];
319                                                                 if (p != null)
320                                                                         setting.Provider = p;
321                                                         }
322
323                                                         properties.Add (setting);
324
325                                                         if (setting.Provider != null && Providers [setting.Provider.Name] == null)
326                                                                 Providers.Add (setting.Provider);
327                                                 }
328                                         }
329                                 }
330
331                                 return properties;
332                         }
333                 }
334 #endif
335
336                 [Browsable (false)]
337                 public override SettingsPropertyValueCollection PropertyValues {
338                         get {
339                                 if (propertyValues == null) {
340                                         propertyValues = new SettingsPropertyValueCollection ();
341                                 }
342
343                                 return propertyValues;
344                         }
345                 }
346
347                 [Browsable (false)]
348                 public override SettingsProviderCollection Providers {
349                         get {
350                                 if (providers == null)
351                                         providers = new SettingsProviderCollection ();
352
353                                 return providers;
354                         }
355                 }
356
357                 [Browsable (false)]
358                 public string SettingsKey {
359                         get {
360                                 return settingsKey;
361                         }
362                         set {
363                                 settingsKey = value;
364                         }
365                 }
366
367                 string settingsKey;
368                 SettingsContext context;
369                 SettingsPropertyCollection properties;
370                 SettingsPropertyValueCollection propertyValues;
371                 SettingsProviderCollection providers;
372                 ISettingsProviderService providerService;
373         }
374
375 }
376 #endif
377