1 //---------------------------------------------------------------------
2 // <copyright file="MetadataItem.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
7 // @backupOwner Microsoft
8 //---------------------------------------------------------------------
10 using System.Collections.Generic;
11 using System.Collections.ObjectModel;
12 using System.Diagnostics;
14 using System.Xml.Serialization;
15 using System.Xml.Schema;
17 using System.Globalization;
19 namespace System.Data.Metadata.Edm
22 /// Represents the base item class for all the metadata
24 public abstract partial class MetadataItem
28 /// Implementing this internal constructor so that this class can't be derived
29 /// outside this assembly
31 internal MetadataItem()
34 internal MetadataItem(MetadataFlags flags)
42 internal enum MetadataFlags {
44 None = 0, // DataSpace flags are off by one so that zero can be the uninitialized state
45 CSpace = 1, // (1 << 0)
46 OSpace = 2, // (1 << 1)
47 OCSpace = 3, // CSpace | OSpace
48 SSpace = 4, // (1 << 2)
49 CSSpace = 5, // CSpace | SSpace
51 DataSpace = OSpace | CSpace | SSpace | OCSpace | CSSpace,
57 IsAbstract = (1 << 4),
63 ReturnValue = (1 << 11),
65 ParameterMode = (In | Out | InOut | ReturnValue),
67 private MetadataFlags _flags;
68 private object _flagsLock = new object();
69 private MetadataCollection<MetadataProperty> _itemAttributes;
70 private Documentation _documentation;
76 /// Returns the kind of the type
78 public abstract BuiltInTypeKind BuiltInTypeKind
84 /// List of item attributes on this type
86 [MetadataProperty(BuiltInTypeKind.MetadataProperty, true)]
87 public ReadOnlyMetadataCollection<MetadataProperty> MetadataProperties
91 if (null == _itemAttributes)
93 MetadataPropertyCollection itemAttributes = new MetadataPropertyCollection(this);
96 itemAttributes.SetReadOnly();
98 System.Threading.Interlocked.CompareExchange<MetadataCollection<MetadataProperty>>(
99 ref _itemAttributes, itemAttributes, null);
101 return _itemAttributes.AsReadOnlyMetadataCollection();
106 /// List of item attributes on this type
108 internal MetadataCollection<MetadataProperty> RawMetadataProperties
112 return _itemAttributes;
117 /// List of item attributes on this type
119 public Documentation Documentation
123 return _documentation;
127 _documentation = value;
132 /// Identity of the item
134 internal abstract String Identity { get; }
137 /// Just checks for identities to be equal
139 /// <param name="item"></param>
140 /// <returns></returns>
141 internal virtual bool EdmEquals(MetadataItem item)
143 return ((null != item) &&
144 ((this == item) || // same reference
145 (this.BuiltInTypeKind == item.BuiltInTypeKind &&
146 this.Identity == item.Identity)));
150 /// Returns true if this item is not-changeable. Otherwise returns false.
152 internal bool IsReadOnly
156 return GetFlag(MetadataFlags.Readonly);
163 /// Validates the types and sets the readOnly property to true. Once the type is set to readOnly,
164 /// it can never be changed.
166 internal virtual void SetReadOnly()
170 if (null != _itemAttributes)
172 _itemAttributes.SetReadOnly();
174 SetFlag(MetadataFlags.Readonly, true);
179 /// Builds identity string for this item. By default, the method calls the identity property.
181 /// <param name="builder"></param>
182 internal virtual void BuildIdentity(StringBuilder builder)
184 builder.Append(this.Identity);
188 /// Adds the given metadata property to the metadata property collection
190 /// <param name="metadataProperty"></param>
191 internal void AddMetadataProperties(List<MetadataProperty> metadataProperties)
193 this.MetadataProperties.Source.AtomicAddRange(metadataProperties);
197 #region MetadataFlags
198 internal DataSpace GetDataSpace()
200 switch (_flags & MetadataFlags.DataSpace)
202 default: return (DataSpace)(-1);
203 case MetadataFlags.CSpace: return DataSpace.CSpace;
204 case MetadataFlags.OSpace: return DataSpace.OSpace;
205 case MetadataFlags.SSpace: return DataSpace.SSpace;
206 case MetadataFlags.OCSpace: return DataSpace.OCSpace;
207 case MetadataFlags.CSSpace: return DataSpace.CSSpace;
210 internal void SetDataSpace(DataSpace space)
212 _flags = (_flags & ~MetadataFlags.DataSpace) | (MetadataFlags.DataSpace & Convert(space));
214 private static MetadataFlags Convert(DataSpace space) {
217 default: return MetadataFlags.None; // invalid
218 case DataSpace.CSpace: return MetadataFlags.CSpace;
219 case DataSpace.OSpace: return MetadataFlags.OSpace;
220 case DataSpace.SSpace: return MetadataFlags.SSpace;
221 case DataSpace.OCSpace: return MetadataFlags.OCSpace;
222 case DataSpace.CSSpace: return MetadataFlags.CSSpace;
226 internal ParameterMode GetParameterMode()
228 switch (_flags & MetadataFlags.ParameterMode)
230 default: return (ParameterMode)(-1); // invalid
231 case MetadataFlags.In: return ParameterMode.In;
232 case MetadataFlags.Out: return ParameterMode.Out;
233 case MetadataFlags.InOut: return ParameterMode.InOut;
234 case MetadataFlags.ReturnValue: return ParameterMode.ReturnValue;
237 internal void SetParameterMode(ParameterMode mode)
239 _flags = (_flags & ~MetadataFlags.ParameterMode) | (MetadataFlags.ParameterMode & Convert(mode));
241 private static MetadataFlags Convert(ParameterMode mode)
245 default: return MetadataFlags.ParameterMode; // invalid
246 case ParameterMode.In: return MetadataFlags.In;
247 case ParameterMode.Out: return MetadataFlags.Out;
248 case ParameterMode.InOut: return MetadataFlags.InOut;
249 case ParameterMode.ReturnValue: return MetadataFlags.ReturnValue;
253 internal bool GetFlag(MetadataFlags flag)
255 return (flag == (_flags & flag));
257 internal void SetFlag(MetadataFlags flag, bool value)
259 if ((flag & MetadataFlags.Readonly) == MetadataFlags.Readonly)
261 Debug.Assert(System.Convert.ToInt32(flag & ~MetadataFlags.Readonly,CultureInfo.InvariantCulture) == 0,
262 "SetFlag() invoked with Readonly and additional flags.");
267 // an attempt to set the ReadOnly flag on a MetadataItem that is already read-only
270 if (IsReadOnly && ((flag & MetadataFlags.Readonly) == MetadataFlags.Readonly))
275 Util.ThrowIfReadOnly(this);