Update Reference Sources to .NET Framework 4.6.1
[mono.git] / mcs / class / referencesource / System.Data.Entity / System / Data / Metadata / Edm / Facet.cs
1 //---------------------------------------------------------------------
2 // <copyright file="Facet.cs" company="Microsoft">
3 //      Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>
5 //
6 // @owner       [....]
7 // @backupOwner [....]
8 //---------------------------------------------------------------------
9
10 namespace System.Data.Metadata.Edm
11 {
12     using System;
13     using System.Diagnostics;
14     using System.Globalization;
15
16     /// <summary>
17     /// Class for representing a Facet object
18     /// This object is Immutable (not just set to readonly) and 
19     /// some parts of the system are depending on that behavior
20     /// </summary>
21     [DebuggerDisplay("{Name,nq}={Value}")]
22     public sealed class Facet : MetadataItem
23     {
24         #region Constructors
25         
26         /// <summary>
27         /// The constructor for constructing a Facet object with the facet description and a value
28         /// </summary>
29         /// <param name="facetDescription">The object describing this facet</param>
30         /// <param name="value">The value of the facet</param>
31         /// <exception cref="System.ArgumentNullException">Thrown if facetDescription argument is null</exception>
32         private Facet(FacetDescription facetDescription, object value)
33             :base(MetadataFlags.Readonly)
34         {
35             EntityUtil.GenericCheckArgumentNull(facetDescription, "facetDescription");
36
37             _facetDescription = facetDescription;
38             _value = value;
39         }
40         
41         /// <summary>
42         /// Creates a Facet instance with the specified value for the given 
43         /// facet description.
44         /// </summary>
45         /// <param name="facetDescription">The object describing this facet</param>
46         /// <param name="value">The value of the facet</param>
47         /// <exception cref="System.ArgumentNullException">Thrown if facetDescription argument is null</exception>
48         internal static Facet Create(FacetDescription facetDescription, object value)
49         {
50             return Create(facetDescription, value, false);
51         }
52
53         /// <summary>
54         /// Creates a Facet instance with the specified value for the given 
55         /// facet description.
56         /// </summary>
57         /// <param name="facetDescription">The object describing this facet</param>
58         /// <param name="value">The value of the facet</param>
59         /// <param name="bypassKnownValues">true to bypass caching and known values; false otherwise.</param>
60         /// <exception cref="System.ArgumentNullException">Thrown if facetDescription argument is null</exception>
61         internal static Facet Create(FacetDescription facetDescription, object value, bool bypassKnownValues)
62         {
63             EntityUtil.CheckArgumentNull(facetDescription, "facetDescription");
64
65             if (!bypassKnownValues)
66             {
67                 // Reuse facets with a null value.
68                 if (object.ReferenceEquals(value, null))
69                 {
70                     return facetDescription.NullValueFacet;
71                 }
72
73                 // Reuse facets with a default value.
74                 if (object.Equals(facetDescription.DefaultValue, value))
75                 {
76                     return facetDescription.DefaultValueFacet;
77                 }
78
79                 // Special case boolean facets.
80                 if (facetDescription.FacetType.Identity == "Edm.Boolean")
81                 {
82                     bool boolValue = (bool)value;
83                     return facetDescription.GetBooleanFacet(boolValue);
84                 }
85             }
86
87             Facet result = new Facet(facetDescription, value);
88
89             // Check the type of the value only if we know what the correct CLR type is
90             if (value != null && !Helper.IsUnboundedFacetValue(result) && !Helper.IsVariableFacetValue(result) && result.FacetType.ClrType != null)
91             {
92                 Type valueType = value.GetType();
93                 Debug.Assert(
94                     valueType == result.FacetType.ClrType 
95                     || result.FacetType.ClrType.IsAssignableFrom(valueType),
96                     string.Format(CultureInfo.CurrentCulture, "The facet {0} has type {1}, but a value of type {2} was supplied.", result.Name, result.FacetType.ClrType, valueType)
97                 );
98             }
99
100             return result;
101         }
102         
103         #endregion
104
105         #region Fields
106         
107         /// <summary>The object describing this facet.</summary>
108         private readonly FacetDescription _facetDescription;
109         
110         /// <summary>The value assigned to this facet.</summary>
111         private readonly object _value;
112         
113         #endregion
114
115         #region Properties
116
117         /// <summary>
118         /// Returns the kind of the type
119         /// </summary>
120         public override BuiltInTypeKind BuiltInTypeKind { get { return BuiltInTypeKind.Facet; } }
121
122         /// <summary>
123         /// Gets the description object for describing the facet
124         /// </summary>
125         public FacetDescription Description
126         {
127             get
128             {
129                 return _facetDescription;
130             }
131         }
132
133         /// <summary>
134         /// Gets/Sets the name of the facet
135         /// </summary>
136         [MetadataProperty(PrimitiveTypeKind.String, false)]
137         public String Name
138         {
139             get
140             {
141                 return _facetDescription.FacetName;
142             }
143         }
144
145         /// <summary>
146         /// Gets/Sets the type of the facet
147         /// </summary>
148         [MetadataProperty(BuiltInTypeKind.EdmType, false)]
149         public EdmType FacetType
150         {
151             get
152             {
153                 return _facetDescription.FacetType;
154             }
155         }
156
157         /// <summary>
158         /// Gets/Sets the value of the facet
159         /// </summary>
160         /// <exception cref="System.InvalidOperationException">Thrown if the Facet instance is in ReadOnly state</exception>
161         [MetadataProperty(typeof(Object), false)]
162         public Object Value
163         {
164             get
165             {
166                 return _value;
167             }
168         }
169
170         /// <summary>
171         /// Gets the identity for this item as a string
172         /// </summary>
173         internal override string Identity
174         {
175             get
176             {
177                 return _facetDescription.FacetName;
178             }
179         }
180
181         /// <summary>
182         /// Indicates whether the value of the facet is unbounded
183         /// </summary>
184         public bool IsUnbounded
185         {
186             get
187             {
188                 return object.ReferenceEquals(Value, EdmConstants.UnboundedValue);
189             }
190         }
191         #endregion
192
193         #region Methods
194         /// <summary>
195         /// Overriding System.Object.ToString to provide better String representation 
196         /// for this type.
197         /// </summary>
198         public override string ToString()
199         {
200             return this.Name;
201         }
202         #endregion
203     }
204 }