New test.
[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 Novell, Inc (http://www.novell.com)
21 //
22
23 #if NET_2_0
24 #if CONFIGURATION_DEP
25 extern alias PrebuiltSystem;
26 using NameValueCollection = PrebuiltSystem.System.Collections.Specialized.NameValueCollection;
27 #endif
28
29 using System.ComponentModel;
30 using System.Reflection;
31 using System.Collections.Specialized;
32
33 namespace System.Configuration {
34
35         public abstract class ApplicationSettingsBase : SettingsBase, INotifyPropertyChanged
36         {
37
38                 protected ApplicationSettingsBase ()
39                 {
40                         Initialize (Context, Properties, Providers);
41                 }
42
43                 protected ApplicationSettingsBase (IComponent owner)
44                         : this (owner, String.Empty)
45                 {
46                 }
47
48  
49                 protected ApplicationSettingsBase (string settingsKey)
50                 {
51                         this.settingsKey = settingsKey;
52
53                         Initialize (Context, Properties, Providers);
54                 }
55
56                 protected ApplicationSettingsBase (IComponent owner, 
57                                                    string settingsKey)
58                 {
59                         if (owner == null)
60                                 throw new ArgumentNullException ();
61
62                         providerService = (ISettingsProviderService)owner.Site.GetService(typeof (ISettingsProviderService));
63
64                         this.settingsKey = settingsKey;
65
66                         Initialize (Context, Properties, Providers);
67                 }
68
69                 public event PropertyChangedEventHandler PropertyChanged;
70                 public event SettingChangingEventHandler SettingChanging;
71                 public event SettingsLoadedEventHandler SettingsLoaded;
72                 public event SettingsSavingEventHandler SettingsSaving;
73
74                 public object GetPreviousVersion (string propertyName)
75                 {
76                         throw new NotImplementedException ();
77                 }
78
79                 public void Reload ()
80                 {
81 #if (CONFIGURATION_DEP)
82                         foreach (SettingsProvider provider in Providers) {
83                                 IApplicationSettingsProvider iasp = provider as IApplicationSettingsProvider;
84                                 if (iasp != null)
85                                         iasp.Reset (Context);
86                         }
87 #endif
88                 }
89
90                 public void Reset()
91                 {
92 #if (CONFIGURATION_DEP)
93                         foreach (SettingsProvider provider in Providers) {
94                                 IApplicationSettingsProvider iasp = provider as IApplicationSettingsProvider;
95                                 if (iasp != null)
96                                         iasp.Reset (Context);
97                         }
98
99                         Reload ();
100 #endif
101                 }
102
103                 public override void Save()
104                 {
105 #if (CONFIGURATION_DEP)
106                         /* ew.. this needs to be more efficient */
107                         foreach (SettingsProvider provider in Providers) {
108                                 SettingsPropertyValueCollection cache = new SettingsPropertyValueCollection ();
109
110                                 foreach (SettingsPropertyValue val in PropertyValues) {
111                                         if (val.Property.Provider == provider)
112                                                 cache.Add (val);
113                                 }
114
115                                 if (cache.Count > 0)
116                                         provider.SetPropertyValues (Context, cache);
117                         }
118 #endif
119                 }
120
121                 public virtual void Upgrade()
122                 {
123                 }
124
125                 protected virtual void OnPropertyChanged (object sender, 
126                                                           PropertyChangedEventArgs e)
127                 {
128                         if (PropertyChanged != null)
129                                 PropertyChanged (sender, e);
130                 }
131
132                 protected virtual void OnSettingChanging (object sender, 
133                                                           SettingChangingEventArgs e)
134                 {
135                         if (SettingChanging != null)
136                                 SettingChanging (sender, e);
137                 }
138
139                 protected virtual void OnSettingsLoaded (object sender, 
140                                                          SettingsLoadedEventArgs e)
141                 {
142                         if (SettingsLoaded != null)
143                                 SettingsLoaded (sender, e);
144                 }
145
146                 protected virtual void OnSettingsSaving (object sender, 
147                                                          CancelEventArgs e)
148                 {
149                         if (SettingsSaving != null)
150                                 SettingsSaving (sender, e);
151                 }
152
153                 [Browsable (false)]
154                 public override SettingsContext Context {
155                         get {
156                                 if (context == null)
157                                         context = new SettingsContext ();
158
159                                 return context;
160                         }
161                 }
162
163                 void CacheValuesByProvider (SettingsProvider provider)
164                 {
165                         SettingsPropertyCollection col = new SettingsPropertyCollection ();
166
167                         foreach (SettingsProperty p in Properties) {
168                                 if (p.Provider == provider)
169                                         col.Add (p);
170                         }
171
172                         if (col.Count > 0) {
173                                 SettingsPropertyValueCollection vals = provider.GetPropertyValues (Context, col);
174                                 PropertyValues.Add (vals);
175                         }
176
177                         OnSettingsLoaded (this, new SettingsLoadedEventArgs (provider));
178                 }
179
180                 void InitializeSettings (SettingsPropertyCollection settings)
181                 {
182                 }
183
184                 object GetPropertyValue (string propertyName)
185                 {
186                         SettingsProperty prop = Properties [ propertyName ];
187
188                         if (prop == null)
189                                 throw new SettingsPropertyNotFoundException (propertyName);
190
191                         if (propertyValues == null)
192                                 InitializeSettings (Properties);
193
194                         if (PropertyValues [ propertyName ] == null)
195                                 CacheValuesByProvider (prop.Provider);
196
197                         return PropertyValues [ propertyName ].PropertyValue;
198                 }
199
200                 [MonoTODO]
201                 public override object this [ string propertyName ] {
202                         get {
203                                 return GetPropertyValue (propertyName);
204                         }
205                         set {
206                                 SettingsProperty prop = Properties [ propertyName ];
207
208                                 if (prop == null)
209                                         throw new SettingsPropertyNotFoundException (propertyName);
210
211                                 if (prop.IsReadOnly)
212                                         throw new SettingsPropertyIsReadOnlyException (propertyName);
213
214                                 /* XXX check the type of the property vs the type of @value */
215                                 if (value != null &&
216                                     !prop.PropertyType.IsAssignableFrom (value.GetType()))
217                                         throw new SettingsPropertyWrongTypeException (propertyName);
218
219                                 if (PropertyValues [ propertyName ] == null)
220                                         CacheValuesByProvider (prop.Provider);
221
222                                 SettingChangingEventArgs changing_args = new SettingChangingEventArgs (propertyName,
223                                                                                                        GetType().FullName,
224                                                                                                        settingsKey,
225                                                                                                        value,
226                                                                                                        false);
227
228                                 OnSettingChanging (this, changing_args);
229
230                                 if (changing_args.Cancel == false) {
231                                         /* actually set the value */
232                                         PropertyValues [ propertyName ].PropertyValue = value;
233
234                                         /* then emit PropertyChanged */
235                                         OnPropertyChanged (this, new PropertyChangedEventArgs (propertyName));
236                                 }
237                         }
238                 }
239
240 #if (CONFIGURATION_DEP)
241                 [Browsable (false)]
242                 public override SettingsPropertyCollection Properties {
243                         get {
244                                 if (properties == null) {
245                                         LocalFileSettingsProvider local_provider = null;
246
247                                         properties = new SettingsPropertyCollection ();
248
249                                         foreach (PropertyInfo prop in GetType().GetProperties (/* only public properties? */)) {
250                                                 SettingAttribute[] setting_attrs = (SettingAttribute[])prop.GetCustomAttributes (typeof (SettingAttribute), false);
251                                                 if (setting_attrs != null && setting_attrs.Length > 0) {
252                                                         SettingsAttributeDictionary dict = new SettingsAttributeDictionary ();
253                                                         SettingsProvider provider = null;
254                                                         object defaultValue = null;
255                                                         SettingsSerializeAs serializeAs = SettingsSerializeAs.String;
256
257                                                         foreach (Attribute a in prop.GetCustomAttributes (false)) {
258                                                                 /* the attributes we handle natively here */
259                                                                 if (a is SettingsProviderAttribute) {
260                                                                         Type provider_type = Type.GetType (((SettingsProviderAttribute)a).ProviderTypeName);
261                                                                         provider = (SettingsProvider) Activator.CreateInstance (provider_type);
262                                                                         provider.Initialize (null, null);
263                                                                 }
264                                                                 else if (a is DefaultSettingValueAttribute) {
265                                                                         defaultValue = ((DefaultSettingValueAttribute)a).Value; /* XXX this is a string.. do we convert? */
266                                                                         if (prop.PropertyType != typeof(string)) {
267                                                                                 defaultValue = TypeDescriptor.GetConverter(prop.PropertyType).ConvertFromString((string)defaultValue);
268                                                                         }
269                                                                 }
270                                                                 else if (a is SettingsSerializeAsAttribute) {
271                                                                         serializeAs = ((SettingsSerializeAsAttribute)a).SerializeAs;
272                                                                 }
273                                                                 else if (a is ApplicationScopedSettingAttribute ||
274                                                                          a is UserScopedSettingAttribute) {
275                                                                         dict.Add (a.GetType(), a);
276                                                                 }
277                                                                 else {
278                                                                         dict.Add (a.GetType(), a);
279                                                                 }
280                                                         }
281
282                                                         SettingsProperty setting = new SettingsProperty (prop.Name,
283                                                                                                          prop.PropertyType,
284                                                                                                          provider,
285                                                                                                          false /* XXX */,
286                                                                                                          defaultValue /* XXX always a string? */,
287                                                                                                          serializeAs,
288                                                                                                          dict,
289                                                                                                          false, false);
290
291
292                                                         if (providerService != null)
293                                                                 setting.Provider = providerService.GetSettingsProvider (setting);
294
295                                                         if (provider == null) {
296                                                                 if (local_provider == null) {
297                                                                         local_provider = new LocalFileSettingsProvider ();
298                                                                         local_provider.Initialize (null, null);
299                                                                 }
300                                                                 setting.Provider = local_provider;
301                                                         }
302
303                                                         if (provider != null) {
304                                                                 /* make sure we're using the same instance of a
305                                                                    given provider across multiple properties */
306                                                                 SettingsProvider p = Providers[provider.Name];
307                                                                 if (p != null)
308                                                                         setting.Provider = p;
309                                                         }
310
311                                                         properties.Add (setting);
312
313                                                         if (setting.Provider != null && Providers [setting.Provider.Name] == null)
314                                                                 Providers.Add (setting.Provider);
315                                                 }
316                                         }
317                                 }
318
319                                 return properties;
320                         }
321                 }
322 #endif
323
324                 [Browsable (false)]
325                 public override SettingsPropertyValueCollection PropertyValues {
326                         get {
327                                 if (propertyValues == null) {
328                                         propertyValues = new SettingsPropertyValueCollection ();
329                                 }
330
331                                 return propertyValues;
332                         }
333                 }
334
335                 [Browsable (false)]
336                 public override SettingsProviderCollection Providers {
337                         get {
338                                 if (providers == null)
339                                         providers = new SettingsProviderCollection ();
340
341                                 return providers;
342                         }
343                 }
344
345                 [Browsable (false)]
346                 public string SettingsKey {
347                         get {
348                                 return settingsKey;
349                         }
350                         set {
351                                 settingsKey = value;
352                         }
353                 }
354
355                 string settingsKey;
356                 SettingsContext context;
357                 SettingsPropertyCollection properties;
358                 SettingsPropertyValueCollection propertyValues;
359                 SettingsProviderCollection providers;
360                 ISettingsProviderService providerService;
361         }
362
363 }
364 #endif
365