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 #if CONFIGURATION_DEP && !TARGET_JVM
25 extern alias PrebuiltSystem;
26 using NameValueCollection = PrebuiltSystem.System.Collections.Specialized.NameValueCollection;
30 using System.Xml.Serialization;
33 using System.ComponentModel;
34 using System.Reflection;
35 using System.Threading;
36 using System.Collections.Specialized;
38 namespace System.Configuration {
40 public abstract class ApplicationSettingsBase : SettingsBase, INotifyPropertyChanged
42 protected ApplicationSettingsBase ()
44 Initialize (Context, Properties, Providers);
47 protected ApplicationSettingsBase (IComponent owner)
48 : this (owner, String.Empty)
52 protected ApplicationSettingsBase (string settingsKey)
54 this.settingsKey = settingsKey;
56 Initialize (Context, Properties, Providers);
59 protected ApplicationSettingsBase (IComponent owner,
63 throw new ArgumentNullException ();
65 #if (CONFIGURATION_DEP)
66 providerService = (ISettingsProviderService)owner.Site.GetService(typeof (ISettingsProviderService));
68 this.settingsKey = settingsKey;
70 Initialize (Context, Properties, Providers);
73 public event PropertyChangedEventHandler PropertyChanged;
74 public event SettingChangingEventHandler SettingChanging;
75 public event SettingsLoadedEventHandler SettingsLoaded;
76 public event SettingsSavingEventHandler SettingsSaving;
78 public object GetPreviousVersion (string propertyName)
80 throw new NotImplementedException ();
85 #if (CONFIGURATION_DEP)
86 foreach (SettingsProvider provider in Providers) {
87 IApplicationSettingsProvider iasp = provider as IApplicationSettingsProvider;
96 #if (CONFIGURATION_DEP)
97 // Code bellow is identical to code in Reload().
98 // foreach (SettingsProvider provider in Providers) {
99 // IApplicationSettingsProvider iasp = provider as IApplicationSettingsProvider;
101 // iasp.Reset (Context);
108 public override void Save()
110 #if (CONFIGURATION_DEP)
111 Context.CurrentSettings = this;
112 /* ew.. this needs to be more efficient */
113 foreach (SettingsProvider provider in Providers) {
114 SettingsPropertyValueCollection cache = new SettingsPropertyValueCollection ();
116 foreach (SettingsPropertyValue val in PropertyValues) {
117 if (val.Property.Provider == provider)
122 provider.SetPropertyValues (Context, cache);
124 Context.CurrentSettings = null;
128 public virtual void Upgrade()
132 protected virtual void OnPropertyChanged (object sender,
133 PropertyChangedEventArgs e)
135 if (PropertyChanged != null)
136 PropertyChanged (sender, e);
139 protected virtual void OnSettingChanging (object sender,
140 SettingChangingEventArgs e)
142 if (SettingChanging != null)
143 SettingChanging (sender, e);
146 protected virtual void OnSettingsLoaded (object sender,
147 SettingsLoadedEventArgs e)
149 if (SettingsLoaded != null)
150 SettingsLoaded (sender, e);
153 protected virtual void OnSettingsSaving (object sender,
156 if (SettingsSaving != null)
157 SettingsSaving (sender, e);
161 public override SettingsContext Context {
164 Monitor.Enter (this);
167 if (context == null) {
168 context = new SettingsContext ();
169 context ["SettingsKey"] = "";
170 Type type = GetType ();
171 context ["GroupName"] = type.FullName;
172 context ["SettingsClassType"] = type;
183 void CacheValuesByProvider (SettingsProvider provider)
185 SettingsPropertyCollection col = new SettingsPropertyCollection ();
187 foreach (SettingsProperty p in Properties) {
188 if (p.Provider == provider)
193 SettingsPropertyValueCollection vals = provider.GetPropertyValues (Context, col);
194 PropertyValues.Add (vals);
197 OnSettingsLoaded (this, new SettingsLoadedEventArgs (provider));
200 void InitializeSettings (SettingsPropertyCollection settings)
204 object GetPropertyValue (string propertyName)
206 SettingsProperty prop = Properties [ propertyName ];
209 throw new SettingsPropertyNotFoundException (propertyName);
211 if (propertyValues == null)
212 InitializeSettings (Properties);
214 if (PropertyValues [ propertyName ] == null)
215 CacheValuesByProvider (prop.Provider);
217 return PropertyValues [ propertyName ].PropertyValue;
221 public override object this [ string propertyName ] {
223 if (IsSynchronized) {
225 return GetPropertyValue (propertyName);
229 return GetPropertyValue (propertyName);
232 SettingsProperty prop = Properties [ propertyName ];
235 throw new SettingsPropertyNotFoundException (propertyName);
238 throw new SettingsPropertyIsReadOnlyException (propertyName);
240 /* XXX check the type of the property vs the type of @value */
242 !prop.PropertyType.IsAssignableFrom (value.GetType()))
243 throw new SettingsPropertyWrongTypeException (propertyName);
245 if (PropertyValues [ propertyName ] == null)
246 CacheValuesByProvider (prop.Provider);
248 SettingChangingEventArgs changing_args = new SettingChangingEventArgs (propertyName,
254 OnSettingChanging (this, changing_args);
256 if (changing_args.Cancel == false) {
257 /* actually set the value */
258 PropertyValues [ propertyName ].PropertyValue = value;
260 /* then emit PropertyChanged */
261 OnPropertyChanged (this, new PropertyChangedEventArgs (propertyName));
266 #if (CONFIGURATION_DEP)
268 public override SettingsPropertyCollection Properties {
271 Monitor.Enter (this);
274 if (properties == null) {
275 LocalFileSettingsProvider local_provider = null;
277 properties = new SettingsPropertyCollection ();
279 foreach (PropertyInfo prop in GetType ().GetProperties ()) { // only public properties
280 SettingAttribute[] setting_attrs = (SettingAttribute[])prop.GetCustomAttributes (typeof (SettingAttribute), false);
281 if (setting_attrs == null || setting_attrs.Length == 0)
283 CreateSettingsProperty (prop, properties, ref local_provider);
295 void CreateSettingsProperty (PropertyInfo prop, SettingsPropertyCollection properties, ref LocalFileSettingsProvider local_provider)
297 SettingsAttributeDictionary dict = new SettingsAttributeDictionary ();
298 SettingsProvider provider = null;
299 object defaultValue = null;
300 SettingsSerializeAs serializeAs = SettingsSerializeAs.String;
301 bool explicitSerializeAs = false;
303 foreach (Attribute a in prop.GetCustomAttributes (false)) {
304 /* the attributes we handle natively here */
305 if (a is SettingsProviderAttribute) {
306 Type provider_type = Type.GetType (((SettingsProviderAttribute)a).ProviderTypeName);
307 provider = (SettingsProvider) Activator.CreateInstance (provider_type);
308 provider.Initialize (null, null);
310 else if (a is DefaultSettingValueAttribute) {
311 defaultValue = ((DefaultSettingValueAttribute)a).Value;
313 else if (a is SettingsSerializeAsAttribute) {
314 serializeAs = ((SettingsSerializeAsAttribute)a).SerializeAs;
315 explicitSerializeAs = true;
317 else if (a is ApplicationScopedSettingAttribute ||
318 a is UserScopedSettingAttribute) {
319 dict.Add (a.GetType(), a);
322 dict.Add (a.GetType(), a);
326 if (!explicitSerializeAs) {
327 // DefaultValue is a string and if we can't convert from string to the
328 // property type then the only other option left is for the string to
331 TypeConverter converter = TypeDescriptor.GetConverter (prop.PropertyType);
332 if (converter != null &&
333 (!converter.CanConvertFrom (typeof (string)) ||
334 !converter.CanConvertTo (typeof (string))))
335 serializeAs = SettingsSerializeAs.Xml;
338 SettingsProperty setting =
339 new SettingsProperty (prop.Name, prop.PropertyType, provider, false /* XXX */,
340 defaultValue /* XXX always a string? */, serializeAs, dict,
344 if (providerService != null)
345 setting.Provider = providerService.GetSettingsProvider (setting);
347 if (provider == null) {
348 if (local_provider == null) {
349 local_provider = new LocalFileSettingsProvider ();
350 local_provider.Initialize (null, null);
352 setting.Provider = local_provider;
353 // .NET ends up to set this to providers.
354 provider = local_provider;
357 if (provider != null) {
358 /* make sure we're using the same instance of a
359 given provider across multiple properties */
360 SettingsProvider p = Providers[provider.Name];
362 setting.Provider = p;
365 properties.Add (setting);
367 if (setting.Provider != null && Providers [setting.Provider.Name] == null)
368 Providers.Add (setting.Provider);
373 public override SettingsPropertyValueCollection PropertyValues {
376 Monitor.Enter (this);
379 if (propertyValues == null) {
380 propertyValues = new SettingsPropertyValueCollection ();
383 return propertyValues;
392 public override SettingsProviderCollection Providers {
395 Monitor.Enter (this);
398 if (providers == null)
399 providers = new SettingsProviderCollection ();
410 public string SettingsKey {
420 SettingsContext context;
421 #if (CONFIGURATION_DEP)
422 SettingsPropertyCollection properties;
423 ISettingsProviderService providerService;
425 SettingsPropertyValueCollection propertyValues;
426 SettingsProviderCollection providers;