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)
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;
87 CacheValuesByProvider(provider);
94 #if (CONFIGURATION_DEP)
96 foreach (SettingsPropertyValue pv in PropertyValues)
97 pv.PropertyValue = pv.Reset();
101 public override void Save()
103 #if (CONFIGURATION_DEP)
104 Context.CurrentSettings = this;
105 /* ew.. this needs to be more efficient */
106 foreach (SettingsProvider provider in Providers) {
107 SettingsPropertyValueCollection cache = new SettingsPropertyValueCollection ();
109 foreach (SettingsPropertyValue val in PropertyValues) {
110 if (val.Property.Provider == provider)
115 provider.SetPropertyValues (Context, cache);
117 Context.CurrentSettings = null;
121 public virtual void Upgrade()
125 protected virtual void OnPropertyChanged (object sender,
126 PropertyChangedEventArgs e)
128 if (PropertyChanged != null)
129 PropertyChanged (sender, e);
132 protected virtual void OnSettingChanging (object sender,
133 SettingChangingEventArgs e)
135 if (SettingChanging != null)
136 SettingChanging (sender, e);
139 protected virtual void OnSettingsLoaded (object sender,
140 SettingsLoadedEventArgs e)
142 if (SettingsLoaded != null)
143 SettingsLoaded (sender, e);
146 protected virtual void OnSettingsSaving (object sender,
149 if (SettingsSaving != null)
150 SettingsSaving (sender, e);
154 public override SettingsContext Context {
157 Monitor.Enter (this);
160 if (context == null) {
161 context = new SettingsContext ();
162 context ["SettingsKey"] = "";
163 Type type = GetType ();
164 context ["GroupName"] = type.FullName;
165 context ["SettingsClassType"] = type;
176 void CacheValuesByProvider (SettingsProvider provider)
178 SettingsPropertyCollection col = new SettingsPropertyCollection ();
180 foreach (SettingsProperty p in Properties) {
181 if (p.Provider == provider)
186 SettingsPropertyValueCollection vals = provider.GetPropertyValues (Context, col);
187 foreach (SettingsPropertyValue prop in vals) {
188 if (PropertyValues [prop.Name] != null)
189 PropertyValues [prop.Name].PropertyValue = prop.PropertyValue;
191 PropertyValues.Add (prop);
195 OnSettingsLoaded (this, new SettingsLoadedEventArgs (provider));
198 void InitializeSettings (SettingsPropertyCollection settings)
202 object GetPropertyValue (string propertyName)
204 SettingsProperty prop = Properties [ propertyName ];
207 throw new SettingsPropertyNotFoundException (propertyName);
209 if (propertyValues == null)
210 InitializeSettings (Properties);
212 if (PropertyValues [ propertyName ] == null)
213 CacheValuesByProvider (prop.Provider);
215 return PropertyValues [ propertyName ].PropertyValue;
219 public override object this [ string propertyName ] {
221 if (IsSynchronized) {
223 return GetPropertyValue (propertyName);
227 return GetPropertyValue (propertyName);
230 SettingsProperty prop = Properties [ propertyName ];
233 throw new SettingsPropertyNotFoundException (propertyName);
236 throw new SettingsPropertyIsReadOnlyException (propertyName);
238 /* XXX check the type of the property vs the type of @value */
240 !prop.PropertyType.IsAssignableFrom (value.GetType()))
241 throw new SettingsPropertyWrongTypeException (propertyName);
243 if (PropertyValues [ propertyName ] == null)
244 CacheValuesByProvider (prop.Provider);
246 SettingChangingEventArgs changing_args = new SettingChangingEventArgs (propertyName,
252 OnSettingChanging (this, changing_args);
254 if (changing_args.Cancel == false) {
255 /* actually set the value */
256 PropertyValues [ propertyName ].PropertyValue = value;
258 /* then emit PropertyChanged */
259 OnPropertyChanged (this, new PropertyChangedEventArgs (propertyName));
264 #if (CONFIGURATION_DEP)
266 public override SettingsPropertyCollection Properties {
269 Monitor.Enter (this);
272 if (properties == null) {
273 SettingsProvider local_provider = null;
275 properties = new SettingsPropertyCollection ();
277 Type this_type = GetType();
278 SettingsProviderAttribute[] provider_attrs = (SettingsProviderAttribute[])this_type.GetCustomAttributes (typeof (SettingsProviderAttribute), false);;
279 if (provider_attrs != null && provider_attrs.Length != 0) {
280 Type provider_type = Type.GetType (provider_attrs[0].ProviderTypeName);
281 SettingsProvider provider = (SettingsProvider) Activator.CreateInstance (provider_type);
282 provider.Initialize (null, null);
283 if (provider != null && Providers [provider.Name] == null) {
284 Providers.Add (provider);
285 local_provider = provider;
289 PropertyInfo[] type_props = this_type.GetProperties ();
290 foreach (PropertyInfo prop in type_props) { // only public properties
291 SettingAttribute[] setting_attrs = (SettingAttribute[])prop.GetCustomAttributes (typeof (SettingAttribute), false);
292 if (setting_attrs == null || setting_attrs.Length == 0)
294 CreateSettingsProperty (prop, properties, ref local_provider);
306 void CreateSettingsProperty (PropertyInfo prop, SettingsPropertyCollection properties, ref SettingsProvider local_provider)
308 SettingsAttributeDictionary dict = new SettingsAttributeDictionary ();
309 SettingsProvider provider = null;
310 object defaultValue = null;
311 SettingsSerializeAs serializeAs = SettingsSerializeAs.String;
312 bool explicitSerializeAs = false;
314 foreach (Attribute a in prop.GetCustomAttributes (false)) {
315 /* the attributes we handle natively here */
316 if (a is SettingsProviderAttribute) {
317 Type provider_type = Type.GetType (((SettingsProviderAttribute)a).ProviderTypeName);
318 provider = (SettingsProvider) Activator.CreateInstance (provider_type);
319 provider.Initialize (null, null);
321 else if (a is DefaultSettingValueAttribute) {
322 defaultValue = ((DefaultSettingValueAttribute)a).Value;
324 else if (a is SettingsSerializeAsAttribute) {
325 serializeAs = ((SettingsSerializeAsAttribute)a).SerializeAs;
326 explicitSerializeAs = true;
328 else if (a is ApplicationScopedSettingAttribute ||
329 a is UserScopedSettingAttribute) {
330 dict.Add (a.GetType(), a);
333 dict.Add (a.GetType(), a);
337 if (!explicitSerializeAs) {
338 // DefaultValue is a string and if we can't convert from string to the
339 // property type then the only other option left is for the string to
342 TypeConverter converter = TypeDescriptor.GetConverter (prop.PropertyType);
343 if (converter != null &&
344 (!converter.CanConvertFrom (typeof (string)) ||
345 !converter.CanConvertTo (typeof (string))))
346 serializeAs = SettingsSerializeAs.Xml;
349 SettingsProperty setting =
350 new SettingsProperty (prop.Name, prop.PropertyType, provider, false /* XXX */,
351 defaultValue /* XXX always a string? */, serializeAs, dict,
355 if (providerService != null)
356 setting.Provider = providerService.GetSettingsProvider (setting);
358 if (provider == null) {
359 if (local_provider == null) {
360 local_provider = new LocalFileSettingsProvider () as SettingsProvider;
361 local_provider.Initialize (null, null);
363 setting.Provider = local_provider;
364 // .NET ends up to set this to providers.
365 provider = local_provider;
368 if (provider != null) {
369 /* make sure we're using the same instance of a
370 given provider across multiple properties */
371 SettingsProvider p = Providers[provider.Name];
373 setting.Provider = p;
376 properties.Add (setting);
378 if (setting.Provider != null && Providers [setting.Provider.Name] == null)
379 Providers.Add (setting.Provider);
384 public override SettingsPropertyValueCollection PropertyValues {
387 Monitor.Enter (this);
390 if (propertyValues == null) {
391 propertyValues = new SettingsPropertyValueCollection ();
394 return propertyValues;
403 public override SettingsProviderCollection Providers {
406 Monitor.Enter (this);
409 if (providers == null)
410 providers = new SettingsProviderCollection ();
421 public string SettingsKey {
431 SettingsContext context;
432 #if (CONFIGURATION_DEP)
433 SettingsPropertyCollection properties;
434 ISettingsProviderService providerService;
436 SettingsPropertyValueCollection propertyValues;
437 SettingsProviderCollection providers;