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 SettingsProvider local_provider = null;
277 properties = new SettingsPropertyCollection ();
279 Type this_type = GetType();
280 SettingsProviderAttribute[] provider_attrs = (SettingsProviderAttribute[])this_type.GetCustomAttributes (typeof (SettingsProviderAttribute), false);;
281 if (provider_attrs != null && provider_attrs.Length != 0) {
282 Type provider_type = Type.GetType (provider_attrs[0].ProviderTypeName);
283 SettingsProvider provider = (SettingsProvider) Activator.CreateInstance (provider_type);
284 provider.Initialize (null, null);
285 if (provider != null && Providers [provider.Name] == null) {
286 Providers.Add (provider);
287 local_provider = provider;
291 PropertyInfo[] type_props = this_type.GetProperties ();
292 foreach (PropertyInfo prop in type_props) { // only public properties
293 SettingAttribute[] setting_attrs = (SettingAttribute[])prop.GetCustomAttributes (typeof (SettingAttribute), false);
294 if (setting_attrs == null || setting_attrs.Length == 0)
296 CreateSettingsProperty (prop, properties, ref local_provider);
308 void CreateSettingsProperty (PropertyInfo prop, SettingsPropertyCollection properties, ref SettingsProvider local_provider)
310 SettingsAttributeDictionary dict = new SettingsAttributeDictionary ();
311 SettingsProvider provider = null;
312 object defaultValue = null;
313 SettingsSerializeAs serializeAs = SettingsSerializeAs.String;
314 bool explicitSerializeAs = false;
316 foreach (Attribute a in prop.GetCustomAttributes (false)) {
317 /* the attributes we handle natively here */
318 if (a is SettingsProviderAttribute) {
319 Type provider_type = Type.GetType (((SettingsProviderAttribute)a).ProviderTypeName);
320 provider = (SettingsProvider) Activator.CreateInstance (provider_type);
321 provider.Initialize (null, null);
323 else if (a is DefaultSettingValueAttribute) {
324 defaultValue = ((DefaultSettingValueAttribute)a).Value;
326 else if (a is SettingsSerializeAsAttribute) {
327 serializeAs = ((SettingsSerializeAsAttribute)a).SerializeAs;
328 explicitSerializeAs = true;
330 else if (a is ApplicationScopedSettingAttribute ||
331 a is UserScopedSettingAttribute) {
332 dict.Add (a.GetType(), a);
335 dict.Add (a.GetType(), a);
339 if (!explicitSerializeAs) {
340 // DefaultValue is a string and if we can't convert from string to the
341 // property type then the only other option left is for the string to
344 TypeConverter converter = TypeDescriptor.GetConverter (prop.PropertyType);
345 if (converter != null &&
346 (!converter.CanConvertFrom (typeof (string)) ||
347 !converter.CanConvertTo (typeof (string))))
348 serializeAs = SettingsSerializeAs.Xml;
351 SettingsProperty setting =
352 new SettingsProperty (prop.Name, prop.PropertyType, provider, false /* XXX */,
353 defaultValue /* XXX always a string? */, serializeAs, dict,
357 if (providerService != null)
358 setting.Provider = providerService.GetSettingsProvider (setting);
360 if (provider == null) {
361 if (local_provider == null) {
362 local_provider = new LocalFileSettingsProvider () as SettingsProvider;
363 local_provider.Initialize (null, null);
365 setting.Provider = local_provider;
366 // .NET ends up to set this to providers.
367 provider = local_provider;
370 if (provider != null) {
371 /* make sure we're using the same instance of a
372 given provider across multiple properties */
373 SettingsProvider p = Providers[provider.Name];
375 setting.Provider = p;
378 properties.Add (setting);
380 if (setting.Provider != null && Providers [setting.Provider.Name] == null)
381 Providers.Add (setting.Provider);
386 public override SettingsPropertyValueCollection PropertyValues {
389 Monitor.Enter (this);
392 if (propertyValues == null) {
393 propertyValues = new SettingsPropertyValueCollection ();
396 return propertyValues;
405 public override SettingsProviderCollection Providers {
408 Monitor.Enter (this);
411 if (providers == null)
412 providers = new SettingsProviderCollection ();
423 public string SettingsKey {
433 SettingsContext context;
434 #if (CONFIGURATION_DEP)
435 SettingsPropertyCollection properties;
436 ISettingsProviderService providerService;
438 SettingsPropertyValueCollection propertyValues;
439 SettingsProviderCollection providers;