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