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:
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
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.
20 // Copyright (C) 2005, 2006 Novell, Inc (http://www.novell.com)
23 #if CONFIGURATION_DEP && !TARGET_JVM
24 extern alias PrebuiltSystem;
25 using NameValueCollection = PrebuiltSystem.System.Collections.Specialized.NameValueCollection;
29 using System.Xml.Serialization;
32 using System.ComponentModel;
33 using System.Reflection;
34 using System.Threading;
35 using System.Collections.Specialized;
37 namespace System.Configuration {
39 public abstract class ApplicationSettingsBase : SettingsBase, INotifyPropertyChanged
41 protected ApplicationSettingsBase ()
43 Initialize (Context, Properties, Providers);
46 protected ApplicationSettingsBase (IComponent owner)
47 : this (owner, String.Empty)
51 protected ApplicationSettingsBase (string settingsKey)
53 this.settingsKey = settingsKey;
55 Initialize (Context, Properties, Providers);
58 protected ApplicationSettingsBase (IComponent owner,
62 throw new ArgumentNullException ();
64 #if (CONFIGURATION_DEP)
65 providerService = (ISettingsProviderService)owner.Site.GetService(typeof (ISettingsProviderService));
67 this.settingsKey = settingsKey;
69 Initialize (Context, Properties, Providers);
72 public event PropertyChangedEventHandler PropertyChanged;
73 public event SettingChangingEventHandler SettingChanging;
74 public event SettingsLoadedEventHandler SettingsLoaded;
75 public event SettingsSavingEventHandler SettingsSaving;
77 public object GetPreviousVersion (string propertyName)
79 throw new NotImplementedException ();
84 #if (CONFIGURATION_DEP)
85 foreach (SettingsProvider provider in Providers) {
86 IApplicationSettingsProvider iasp = provider as IApplicationSettingsProvider;
95 #if (CONFIGURATION_DEP)
96 // Code bellow is identical to code in Reload().
97 // foreach (SettingsProvider provider in Providers) {
98 // IApplicationSettingsProvider iasp = provider as IApplicationSettingsProvider;
100 // iasp.Reset (Context);
107 public override void Save()
109 #if (CONFIGURATION_DEP)
110 Context.CurrentSettings = this;
111 /* ew.. this needs to be more efficient */
112 foreach (SettingsProvider provider in Providers) {
113 SettingsPropertyValueCollection cache = new SettingsPropertyValueCollection ();
115 foreach (SettingsPropertyValue val in PropertyValues) {
116 if (val.Property.Provider == provider)
121 provider.SetPropertyValues (Context, cache);
123 Context.CurrentSettings = null;
127 public virtual void Upgrade()
131 protected virtual void OnPropertyChanged (object sender,
132 PropertyChangedEventArgs e)
134 if (PropertyChanged != null)
135 PropertyChanged (sender, e);
138 protected virtual void OnSettingChanging (object sender,
139 SettingChangingEventArgs e)
141 if (SettingChanging != null)
142 SettingChanging (sender, e);
145 protected virtual void OnSettingsLoaded (object sender,
146 SettingsLoadedEventArgs e)
148 if (SettingsLoaded != null)
149 SettingsLoaded (sender, e);
152 protected virtual void OnSettingsSaving (object sender,
155 if (SettingsSaving != null)
156 SettingsSaving (sender, e);
160 public override SettingsContext Context {
163 Monitor.Enter (this);
166 if (context == null) {
167 context = new SettingsContext ();
168 context ["SettingsKey"] = "";
169 Type type = GetType ();
170 context ["GroupName"] = type.FullName;
171 context ["SettingsClassType"] = type;
182 void CacheValuesByProvider (SettingsProvider provider)
184 SettingsPropertyCollection col = new SettingsPropertyCollection ();
186 foreach (SettingsProperty p in Properties) {
187 if (p.Provider == provider)
192 SettingsPropertyValueCollection vals = provider.GetPropertyValues (Context, col);
193 PropertyValues.Add (vals);
196 OnSettingsLoaded (this, new SettingsLoadedEventArgs (provider));
199 void InitializeSettings (SettingsPropertyCollection settings)
203 object GetPropertyValue (string propertyName)
205 SettingsProperty prop = Properties [ propertyName ];
208 throw new SettingsPropertyNotFoundException (propertyName);
210 if (propertyValues == null)
211 InitializeSettings (Properties);
213 if (PropertyValues [ propertyName ] == null)
214 CacheValuesByProvider (prop.Provider);
216 return PropertyValues [ propertyName ].PropertyValue;
220 public override object this [ string propertyName ] {
222 if (IsSynchronized) {
224 return GetPropertyValue (propertyName);
228 return GetPropertyValue (propertyName);
231 SettingsProperty prop = Properties [ propertyName ];
234 throw new SettingsPropertyNotFoundException (propertyName);
237 throw new SettingsPropertyIsReadOnlyException (propertyName);
239 /* XXX check the type of the property vs the type of @value */
241 !prop.PropertyType.IsAssignableFrom (value.GetType()))
242 throw new SettingsPropertyWrongTypeException (propertyName);
244 if (PropertyValues [ propertyName ] == null)
245 CacheValuesByProvider (prop.Provider);
247 SettingChangingEventArgs changing_args = new SettingChangingEventArgs (propertyName,
253 OnSettingChanging (this, changing_args);
255 if (changing_args.Cancel == false) {
256 /* actually set the value */
257 PropertyValues [ propertyName ].PropertyValue = value;
259 /* then emit PropertyChanged */
260 OnPropertyChanged (this, new PropertyChangedEventArgs (propertyName));
265 #if (CONFIGURATION_DEP)
267 public override SettingsPropertyCollection Properties {
270 Monitor.Enter (this);
273 if (properties == null) {
274 SettingsProvider local_provider = null;
276 properties = new SettingsPropertyCollection ();
278 Type this_type = GetType();
279 SettingsProviderAttribute[] provider_attrs = (SettingsProviderAttribute[])this_type.GetCustomAttributes (typeof (SettingsProviderAttribute), false);;
280 if (provider_attrs != null && provider_attrs.Length != 0) {
281 Type provider_type = Type.GetType (provider_attrs[0].ProviderTypeName);
282 SettingsProvider provider = (SettingsProvider) Activator.CreateInstance (provider_type);
283 provider.Initialize (null, null);
284 if (provider != null && Providers [provider.Name] == null) {
285 Providers.Add (provider);
286 local_provider = provider;
290 PropertyInfo[] type_props = this_type.GetProperties ();
291 foreach (PropertyInfo prop in type_props) { // only public properties
292 SettingAttribute[] setting_attrs = (SettingAttribute[])prop.GetCustomAttributes (typeof (SettingAttribute), false);
293 if (setting_attrs == null || setting_attrs.Length == 0)
295 CreateSettingsProperty (prop, properties, ref local_provider);
307 void CreateSettingsProperty (PropertyInfo prop, SettingsPropertyCollection properties, ref SettingsProvider local_provider)
309 SettingsAttributeDictionary dict = new SettingsAttributeDictionary ();
310 SettingsProvider provider = null;
311 object defaultValue = null;
312 SettingsSerializeAs serializeAs = SettingsSerializeAs.String;
313 bool explicitSerializeAs = false;
315 foreach (Attribute a in prop.GetCustomAttributes (false)) {
316 /* the attributes we handle natively here */
317 if (a is SettingsProviderAttribute) {
318 Type provider_type = Type.GetType (((SettingsProviderAttribute)a).ProviderTypeName);
319 provider = (SettingsProvider) Activator.CreateInstance (provider_type);
320 provider.Initialize (null, null);
322 else if (a is DefaultSettingValueAttribute) {
323 defaultValue = ((DefaultSettingValueAttribute)a).Value;
325 else if (a is SettingsSerializeAsAttribute) {
326 serializeAs = ((SettingsSerializeAsAttribute)a).SerializeAs;
327 explicitSerializeAs = true;
329 else if (a is ApplicationScopedSettingAttribute ||
330 a is UserScopedSettingAttribute) {
331 dict.Add (a.GetType(), a);
334 dict.Add (a.GetType(), a);
338 if (!explicitSerializeAs) {
339 // DefaultValue is a string and if we can't convert from string to the
340 // property type then the only other option left is for the string to
343 TypeConverter converter = TypeDescriptor.GetConverter (prop.PropertyType);
344 if (converter != null &&
345 (!converter.CanConvertFrom (typeof (string)) ||
346 !converter.CanConvertTo (typeof (string))))
347 serializeAs = SettingsSerializeAs.Xml;
350 SettingsProperty setting =
351 new SettingsProperty (prop.Name, prop.PropertyType, provider, false /* XXX */,
352 defaultValue /* XXX always a string? */, serializeAs, dict,
356 if (providerService != null)
357 setting.Provider = providerService.GetSettingsProvider (setting);
359 if (provider == null) {
360 if (local_provider == null) {
361 local_provider = new LocalFileSettingsProvider () as SettingsProvider;
362 local_provider.Initialize (null, null);
364 setting.Provider = local_provider;
365 // .NET ends up to set this to providers.
366 provider = local_provider;
369 if (provider != null) {
370 /* make sure we're using the same instance of a
371 given provider across multiple properties */
372 SettingsProvider p = Providers[provider.Name];
374 setting.Provider = p;
377 properties.Add (setting);
379 if (setting.Provider != null && Providers [setting.Provider.Name] == null)
380 Providers.Add (setting.Provider);
385 public override SettingsPropertyValueCollection PropertyValues {
388 Monitor.Enter (this);
391 if (propertyValues == null) {
392 propertyValues = new SettingsPropertyValueCollection ();
395 return propertyValues;
404 public override SettingsProviderCollection Providers {
407 Monitor.Enter (this);
410 if (providers == null)
411 providers = new SettingsProviderCollection ();
422 public string SettingsKey {
432 SettingsContext context;
433 #if (CONFIGURATION_DEP)
434 SettingsPropertyCollection properties;
435 ISettingsProviderService providerService;
437 SettingsPropertyValueCollection propertyValues;
438 SettingsProviderCollection providers;