Xamarin Public Jenkins (auto-signing) 8fc30896db Imported Upstream version 5.12.0.220
Former-commit-id: c477e03582759447177c6d4bf412cd2355aad476
2018-04-24 09:31:23 +00:00

499 lines
14 KiB
C#

// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// Copyright (C) 2005, 2006 Novell, Inc (http://www.novell.com)
//
#if CONFIGURATION_DEP
using System.IO;
using System.Xml.Serialization;
#endif
using System.ComponentModel;
using System.Reflection;
using System.Threading;
using System.Collections.Specialized;
namespace System.Configuration {
public abstract class ApplicationSettingsBase : SettingsBase, INotifyPropertyChanged
{
protected ApplicationSettingsBase ()
{
Initialize (Context, Properties, Providers);
}
protected ApplicationSettingsBase (IComponent owner)
: this (owner, String.Empty)
{
}
protected ApplicationSettingsBase (string settingsKey)
{
this.settingsKey = settingsKey;
Initialize (Context, Properties, Providers);
}
protected ApplicationSettingsBase (IComponent owner,
string settingsKey)
{
if (owner == null)
throw new ArgumentNullException ();
#if (CONFIGURATION_DEP)
providerService = (ISettingsProviderService)owner.Site.GetService(typeof (ISettingsProviderService));
#endif
this.settingsKey = settingsKey;
Initialize (Context, Properties, Providers);
}
public event PropertyChangedEventHandler PropertyChanged;
public event SettingChangingEventHandler SettingChanging;
public event SettingsLoadedEventHandler SettingsLoaded;
public event SettingsSavingEventHandler SettingsSaving;
public object GetPreviousVersion (string propertyName)
{
throw new NotImplementedException ();
}
public void Reload ()
{
#if (CONFIGURATION_DEP)
/* Clear out the old property values so they will be reloaded on request */
if (PropertyValues != null) {
PropertyValues.Clear();
}
foreach(SettingsProperty prop in Properties) {
/* emit PropertyChanged for every property */
OnPropertyChanged(this, new PropertyChangedEventArgs(prop.Name));
}
#endif
}
public void Reset()
{
#if (CONFIGURATION_DEP)
if (Properties != null) {
foreach (SettingsProvider provider in Providers) {
IApplicationSettingsProvider iasp = provider as IApplicationSettingsProvider;
if (iasp != null)
iasp.Reset (Context);
}
InternalSave ();
}
Reload ();
#endif
}
public override void Save ()
{
var e = new CancelEventArgs ();
OnSettingsSaving (this, e);
if (e.Cancel)
return;
InternalSave ();
}
void InternalSave ()
{
#if (CONFIGURATION_DEP)
Context.CurrentSettings = this;
/* ew.. this needs to be more efficient */
foreach (SettingsProvider provider in Providers) {
SettingsPropertyValueCollection cache = new SettingsPropertyValueCollection ();
foreach (SettingsPropertyValue val in PropertyValues) {
if (val.Property.Provider == provider)
cache.Add (val);
}
if (cache.Count > 0)
provider.SetPropertyValues (Context, cache);
}
Context.CurrentSettings = null;
#else
throw new NotImplementedException("No useful Save implemented.");
#endif
}
public virtual void Upgrade ()
{
#if (CONFIGURATION_DEP)
// if there is a current property, then for each settings
// provider in the providers collection, upgrade(ssp)
if (Properties != null) {
foreach (SettingsProvider provider in Providers) {
var appSettingsProvider = provider as IApplicationSettingsProvider;
if(appSettingsProvider != null) {
appSettingsProvider.Upgrade (Context, GetPropertiesForProvider (provider));
}
}
}
Reload ();
#else
throw new NotImplementedException ("No useful Upgrade implemented");
#endif
}
private SettingsPropertyCollection GetPropertiesForProvider (SettingsProvider provider)
{
SettingsPropertyCollection properties = new SettingsPropertyCollection ();
foreach (SettingsProperty sp in Properties) {
if (sp.Provider == provider) {
properties.Add(sp);
}
}
return properties;
}
protected virtual void OnPropertyChanged (object sender,
PropertyChangedEventArgs e)
{
if (PropertyChanged != null)
PropertyChanged (sender, e);
}
protected virtual void OnSettingChanging (object sender,
SettingChangingEventArgs e)
{
if (SettingChanging != null)
SettingChanging (sender, e);
}
protected virtual void OnSettingsLoaded (object sender,
SettingsLoadedEventArgs e)
{
if (SettingsLoaded != null)
SettingsLoaded (sender, e);
}
protected virtual void OnSettingsSaving (object sender,
CancelEventArgs e)
{
if (SettingsSaving != null)
SettingsSaving (sender, e);
}
[Browsable (false)]
public override SettingsContext Context {
get {
if (IsSynchronized)
Monitor.Enter (this);
try {
if (context == null) {
context = new SettingsContext ();
context ["SettingsKey"] = "";
Type type = GetType ();
context ["GroupName"] = type.FullName;
context ["SettingsClassType"] = type;
}
return context;
} finally {
if (IsSynchronized)
Monitor.Exit (this);
}
}
}
void CacheValuesByProvider (SettingsProvider provider)
{
SettingsPropertyCollection col = new SettingsPropertyCollection ();
foreach (SettingsProperty p in Properties) {
if (p.Provider == provider)
col.Add (p);
}
if (col.Count > 0) {
SettingsPropertyValueCollection vals = provider.GetPropertyValues (Context, col);
foreach (SettingsPropertyValue prop in vals) {
if (PropertyValues [prop.Name] != null)
PropertyValues [prop.Name].PropertyValue = prop.PropertyValue;
else
PropertyValues.Add (prop);
}
}
OnSettingsLoaded (this, new SettingsLoadedEventArgs (provider));
}
void InitializeSettings (SettingsPropertyCollection settings)
{
}
object GetPropertyValue (string propertyName)
{
SettingsProperty prop = Properties [ propertyName ];
if (prop == null)
throw new SettingsPropertyNotFoundException (propertyName);
if (propertyValues == null)
InitializeSettings (Properties);
if (PropertyValues [ propertyName ] == null)
CacheValuesByProvider (prop.Provider);
return PropertyValues [ propertyName ].PropertyValue;
}
[MonoTODO]
public override object this [ string propertyName ] {
get {
if (IsSynchronized) {
lock (this) {
return GetPropertyValue (propertyName);
}
}
return GetPropertyValue (propertyName);
}
set {
SettingsProperty prop = Properties [ propertyName ];
if (prop == null)
throw new SettingsPropertyNotFoundException (propertyName);
if (prop.IsReadOnly)
throw new SettingsPropertyIsReadOnlyException (propertyName);
/* XXX check the type of the property vs the type of @value */
if (value != null &&
!prop.PropertyType.IsAssignableFrom (value.GetType()))
throw new SettingsPropertyWrongTypeException (propertyName);
if (PropertyValues [ propertyName ] == null)
CacheValuesByProvider (prop.Provider);
SettingChangingEventArgs changing_args = new SettingChangingEventArgs (propertyName,
GetType().FullName,
settingsKey,
value,
false);
OnSettingChanging (this, changing_args);
if (changing_args.Cancel == false) {
/* actually set the value */
PropertyValues [ propertyName ].PropertyValue = value;
/* then emit PropertyChanged */
OnPropertyChanged (this, new PropertyChangedEventArgs (propertyName));
}
}
}
#if (CONFIGURATION_DEP)
[Browsable (false)]
public override SettingsPropertyCollection Properties {
get {
if (IsSynchronized)
Monitor.Enter (this);
try {
if (properties == null) {
SettingsProvider local_provider = null;
properties = new SettingsPropertyCollection ();
Type this_type = GetType();
SettingsProviderAttribute[] provider_attrs = (SettingsProviderAttribute[])this_type.GetCustomAttributes (typeof (SettingsProviderAttribute), false);;
if (provider_attrs != null && provider_attrs.Length != 0) {
Type provider_type = Type.GetType (provider_attrs[0].ProviderTypeName);
SettingsProvider provider = (SettingsProvider) Activator.CreateInstance (provider_type);
provider.Initialize (null, null);
if (provider != null && Providers [provider.Name] == null) {
Providers.Add (provider);
local_provider = provider;
}
}
PropertyInfo[] type_props = this_type.GetProperties ();
foreach (PropertyInfo prop in type_props) { // only public properties
SettingAttribute[] setting_attrs = (SettingAttribute[])prop.GetCustomAttributes (typeof (SettingAttribute), false);
if (setting_attrs == null || setting_attrs.Length == 0)
continue;
CreateSettingsProperty (prop, properties, ref local_provider);
}
}
return properties;
} finally {
if (IsSynchronized)
Monitor.Exit (this);
}
}
}
void CreateSettingsProperty (PropertyInfo prop, SettingsPropertyCollection properties, ref SettingsProvider local_provider)
{
SettingsAttributeDictionary dict = new SettingsAttributeDictionary ();
SettingsProvider provider = null;
object defaultValue = null;
SettingsSerializeAs serializeAs = SettingsSerializeAs.String;
bool explicitSerializeAs = false;
foreach (Attribute a in prop.GetCustomAttributes (false)) {
/* the attributes we handle natively here */
if (a is SettingsProviderAttribute) {
var providerTypeName = ((SettingsProviderAttribute)a).ProviderTypeName;
Type provider_type = Type.GetType (providerTypeName);
if(provider_type == null) { // Type failed to find the type by name
var typeNameParts = providerTypeName.Split('.');
if(typeNameParts.Length > 1) { //Load the assembly that providerTypeName claims
var assy = Assembly.Load(typeNameParts[0]);
if(assy != null) {
provider_type = assy.GetType(providerTypeName); //try to get the type from that Assembly
}
}
}
provider = (SettingsProvider) Activator.CreateInstance (provider_type);
provider.Initialize (null, null);
}
else if (a is DefaultSettingValueAttribute) {
defaultValue = ((DefaultSettingValueAttribute)a).Value;
}
else if (a is SettingsSerializeAsAttribute) {
serializeAs = ((SettingsSerializeAsAttribute)a).SerializeAs;
explicitSerializeAs = true;
}
else if (a is ApplicationScopedSettingAttribute ||
a is UserScopedSettingAttribute) {
dict.Add (a.GetType(), a);
}
else {
dict.Add (a.GetType(), a);
}
}
if (!explicitSerializeAs) {
// DefaultValue is a string and if we can't convert from string to the
// property type then the only other option left is for the string to
// be XML.
//
TypeConverter converter = TypeDescriptor.GetConverter (prop.PropertyType);
if (converter != null &&
(!converter.CanConvertFrom (typeof (string)) ||
!converter.CanConvertTo (typeof (string))))
serializeAs = SettingsSerializeAs.Xml;
}
SettingsProperty setting =
new SettingsProperty (prop.Name, prop.PropertyType, provider, false /* XXX */,
defaultValue /* XXX always a string? */, serializeAs, dict,
false, false);
if (providerService != null)
setting.Provider = providerService.GetSettingsProvider (setting);
if (provider == null) {
if (local_provider == null) {
local_provider = new LocalFileSettingsProvider () as SettingsProvider;
local_provider.Initialize (null, null);
}
setting.Provider = local_provider;
// .NET ends up to set this to providers.
provider = local_provider;
}
if (provider != null) {
/* make sure we're using the same instance of a
given provider across multiple properties */
SettingsProvider p = Providers[provider.Name];
if (p != null)
setting.Provider = p;
}
properties.Add (setting);
if (setting.Provider != null && Providers [setting.Provider.Name] == null)
Providers.Add (setting.Provider);
}
#endif
[Browsable (false)]
public override SettingsPropertyValueCollection PropertyValues {
get {
if (IsSynchronized)
Monitor.Enter (this);
try {
if (propertyValues == null) {
propertyValues = new SettingsPropertyValueCollection ();
}
return propertyValues;
} finally {
if (IsSynchronized)
Monitor.Exit (this);
}
}
}
[Browsable (false)]
public override SettingsProviderCollection Providers {
get {
if (IsSynchronized)
Monitor.Enter (this);
try {
if (providers == null)
providers = new SettingsProviderCollection ();
return providers;
} finally {
if (IsSynchronized)
Monitor.Exit (this);
}
}
}
[Browsable (false)]
public string SettingsKey {
get {
return settingsKey;
}
set {
settingsKey = value;
}
}
string settingsKey;
SettingsContext context;
#if (CONFIGURATION_DEP)
SettingsPropertyCollection properties;
ISettingsProviderService providerService;
#endif
SettingsPropertyValueCollection propertyValues;
SettingsProviderCollection providers;
}
}