/*******************************************************************************
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License"). You may not use
* this file except in compliance with the License. A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file.
* This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
* *****************************************************************************
* __ _ _ ___
* ( )( \/\/ )/ __)
* /__\ \ / \__ \
* (_)(_) \/\/ (___/
*
* AWS SDK for .NET
* API Version: 2006-03-01
*
*/
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using Amazon.Util.Internal;
namespace Amazon.Runtime
{
///
/// Base class for constant class that holds the value that will be sent to AWS for the static constants.
///
public class ConstantClass
{
static readonly object staticFieldsLock = new object();
static Dictionary> staticFields =
new Dictionary>();
protected ConstantClass(string value)
{
this.Value = value;
}
///
/// Gets the value that needs to be used when send the value to AWS
///
public string Value
{
get;
private set;
}
public override string ToString()
{
return this.Intern().Value;
}
public string ToString(IFormatProvider provider)
{
return this.Intern().Value;
}
public static implicit operator string(ConstantClass value)
{
if (value == null)
return null;
return value.Intern().Value;
}
///
/// Attempt to find correct-cased constant value using whatever cased value the user
/// has provided. This is primarily useful for mapping any-cased values from a CLI
/// tool to the specific casing required by the service, avoiding the need for the
/// user to (a) remember the specific case and (b) actually type it correctly.
///
/// The properly cased service constant matching the value
internal ConstantClass Intern()
{
if (!staticFields.ContainsKey(this.GetType()))
LoadFields(this.GetType());
var map = staticFields[this.GetType()];
ConstantClass foundValue;
return map.TryGetValue(this.Value, out foundValue) ? foundValue : this;
}
protected static T FindValue(string value) where T : ConstantClass
{
if (value == null)
return null;
if (!staticFields.ContainsKey(typeof(T)))
LoadFields(typeof (T));
var fields = staticFields[typeof(T)];
ConstantClass foundValue;
if (!fields.TryGetValue(value, out foundValue))
{
var typeInfo = TypeFactory.GetTypeInfo(typeof(T));
var constructor = typeInfo.GetConstructor(new ITypeInfo[] { TypeFactory.GetTypeInfo(typeof(string)) });
return constructor.Invoke(new object[] { value }) as T;
}
return foundValue as T;
}
private static void LoadFields(Type t)
{
if (staticFields.ContainsKey(t))
return;
lock (staticFieldsLock)
{
if (staticFields.ContainsKey(t)) return;
var map = new Dictionary(StringComparer.OrdinalIgnoreCase);
var typeInfo = TypeFactory.GetTypeInfo(t);
foreach (var fieldInfo in typeInfo.GetFields())
{
if (fieldInfo.IsStatic && fieldInfo.FieldType == t)
{
var cc = fieldInfo.GetValue(null) as ConstantClass;
map[cc.Value] = cc;
}
}
// create copy of dictionary with new value
var newDictionary = new Dictionary>(staticFields);
newDictionary[t] = map;
// swap in the new dictionary
staticFields = newDictionary;
}
}
public override int GetHashCode()
{
return this.Value.GetHashCode();
}
public override bool Equals(object obj)
{
if (obj == null)
{
// If obj is null, return false.
return false;
}
// If both are the same instance, return true.
if (System.Object.ReferenceEquals(this, obj))
{
return true;
}
var objConstantClass = obj as ConstantClass;
if (this.Equals(objConstantClass))
{
return true;
}
var objString = obj as string;
if (objString != null)
{
return Equals(objString);
}
// obj is of an incompatible type, return false.
return false;
}
public virtual bool Equals(ConstantClass obj)
{
if ((object)obj == null)
{
// If obj is null, return false.
return false;
}
return StringComparer.OrdinalIgnoreCase.Equals(this.Value, obj.Value);
}
protected virtual bool Equals(string value)
{
return StringComparer.OrdinalIgnoreCase.Equals(this.Value, value);
}
public static bool operator ==(ConstantClass a, ConstantClass b)
{
if (System.Object.ReferenceEquals(a, b))
{
// If both are null, or both are the same instance, return true.
return true;
}
if ((object)a == null)
{
// If either is null, return false.
return false;
}
else
{
return a.Equals(b);
}
}
public static bool operator !=(ConstantClass a, ConstantClass b)
{
return !(a == b);
}
public static bool operator ==(ConstantClass a, string b)
{
if ((object)a == null && b == null)
{
return true;
}
if ((object)a == null)
{
// If either is null, return false.
return false;
}
else
{
return a.Equals(b);
}
}
public static bool operator ==(string a, ConstantClass b)
{
return (b == a);
}
public static bool operator !=(ConstantClass a, string b)
{
return !(a == b);
}
public static bool operator !=(string a, ConstantClass b)
{
return !(a == b);
}
}
}