public EdmDirectValueAnnotationsManager()
		{
			this.annotationsDictionaryLock = new object();
			this.unsortedElements = VersioningList<IEdmElement>.Create();
			this.unsortedElementsLock = new object();
			this.annotationsDictionary = VersioningDictionary<IEdmElement, object>.Create(new Func<IEdmElement, IEdmElement, int>(this.CompareElements));
		}
        /// <summary>
        /// Sets an annotation value for an EDM element. If the value is null, no annotation is added and an existing annotation with the same name is removed.
        /// </summary>
        /// <param name="element">The annotated element.</param>
        /// <param name="namespaceName">Namespace that the annotation belongs to.</param>
        /// <param name="localName">Name of the annotation within the namespace.</param>
        /// <param name="value">New annotation to set.</param>
        public void SetAnnotationValue(IEdmElement element, string namespaceName, string localName, object value)
        {
            lock (this.annotationsDictionaryLock)
            {
                // Use a local variable to store any interim changes to the annotations dictionary, and perform one atomic update
                // to the field. Otherwise, other threads could see a dictionary in an interim state.
                VersioningDictionary<IEdmElement, object> annotationsDictionary = this.annotationsDictionary;
                this.SetAnnotationValue(element, namespaceName, localName, value, ref annotationsDictionary);

                this.annotationsDictionary = annotationsDictionary;
            }
        }
		public void SetAnnotationValues(IEnumerable<IEdmDirectValueAnnotationBinding> annotations)
		{
			lock (this.annotationsDictionaryLock)
			{
				VersioningDictionary<IEdmElement, object> versioningDictionary = this.annotationsDictionary;
				foreach (IEdmDirectValueAnnotationBinding annotation in annotations)
				{
					this.SetAnnotationValue(annotation.Element, annotation.NamespaceUri, annotation.Name, annotation.Value, ref versioningDictionary);
				}
				this.annotationsDictionary = versioningDictionary;
			}
		}
示例#4
0
        private object GetAnnotationValue(IEdmElement element, string namespaceName, string localName, VersioningDictionary <IEdmElement, object> annotationsDictionary)
        {
            object value;
            IEdmDirectValueAnnotation edmDirectValueAnnotation = EdmDirectValueAnnotationsManager.FindTransientAnnotation(EdmDirectValueAnnotationsManager.GetTransientAnnotations(element, annotationsDictionary), namespaceName, localName);

            if (edmDirectValueAnnotation == null)
            {
                IEnumerable <IEdmDirectValueAnnotation> attachedAnnotations = this.GetAttachedAnnotations(element);
                if (attachedAnnotations != null)
                {
                    IEnumerator <IEdmDirectValueAnnotation> enumerator = attachedAnnotations.GetEnumerator();
                    using (enumerator)
                    {
                        while (enumerator.MoveNext())
                        {
                            IEdmDirectValueAnnotation current = enumerator.Current;
                            if (!(current.NamespaceUri == namespaceName) || !(current.Name == localName))
                            {
                                continue;
                            }
                            value = current.Value;
                            return(value);
                        }
                        return(null);
                    }
                    return(value);
                }
                return(null);
            }
            else
            {
                return(edmDirectValueAnnotation.Value);
            }
        }
示例#5
0
 /// <summary>
 /// Initializes a new instance of the <see cref="EdmDirectValueAnnotationsManager"/> class.
 /// </summary>
 public EdmDirectValueAnnotationsManager()
 {
     this.annotationsDictionary = VersioningDictionary <IEdmElement, object> .Create(this.CompareElements);
 }
示例#6
0
        private void SetAnnotationValue(IEdmElement element, string namespaceName, string localName, object value, ref VersioningDictionary <IEdmElement, object> annotationsDictionary)
        {
            object transientAnnotations          = GetTransientAnnotations(element, annotationsDictionary);
            object transientAnnotationsBeforeSet = transientAnnotations;

            SetAnnotation(this.GetAttachedAnnotations(element), ref transientAnnotations, namespaceName, localName, value);

            // There is at least one case (removing an annotation that was not present to begin with) where the transient annotations are not changed,
            // so test to see if updating the dictionary is necessary.
            if (transientAnnotations != transientAnnotationsBeforeSet)
            {
                annotationsDictionary = annotationsDictionary.Set(element, transientAnnotations);
            }
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="EdmDirectValueAnnotationsManager"/> class.
 /// </summary>
 public EdmDirectValueAnnotationsManager()
 {
     this.annotationsDictionary = VersioningDictionary<IEdmElement, object>.Create(this.CompareElements);
 }
        private void SetAnnotationValue(IEdmElement element, string namespaceName, string localName, object value, ref VersioningDictionary<IEdmElement, object> annotationsDictionary)
        {
            object transientAnnotations = GetTransientAnnotations(element, annotationsDictionary);
            object transientAnnotationsBeforeSet = transientAnnotations;
            SetAnnotation(this.GetAttachedAnnotations(element), ref transientAnnotations, namespaceName, localName, value);

            // There is at least one case (removing an annotation that was not present to begin with) where the transient annotations are not changed,
            // so test to see if updating the dictionary is necessary.
            if (transientAnnotations != transientAnnotationsBeforeSet)
            {
                annotationsDictionary = annotationsDictionary.Set(element, transientAnnotations);
            }
        }
        /// <summary>
        /// Sets an annotation value for an EDM element. If the value is null, no annotation is added and an existing annotation with the same name is removed.
        /// </summary>
        /// <param name="element">The annotated element.</param>
        /// <param name="namespaceName">Namespace that the annotation belongs to.</param>
        /// <param name="localName">Name of the annotation within the namespace.</param>
        /// <param name="value">New annotation to set.</param>
        public void SetAnnotationValue(IEdmElement element, string namespaceName, string localName, object value)
        {
            lock (this.annotationsDictionaryLock)
            {
                // Use a local variable to store any interim changes to the annotations dictionary, and perform one atomic update
                // to the field. Otherwise, other threads could see a dictionary in an interim state.
                VersioningDictionary <IEdmElement, VersioningList <IEdmDirectValueAnnotation> > annotationsDictionary = this.annotationsDictionary;
                this.SetAnnotationValue(element, namespaceName, localName, value, ref annotationsDictionary);

                this.annotationsDictionary = annotationsDictionary;
            }
        }
        /// <summary>
        /// Gets annotations associated with an element.
        /// </summary>
        /// <param name="element">The annotated element.</param>
        /// <returns>The immediate annotations for the element.</returns>
        public IEnumerable <IEdmDirectValueAnnotation> GetDirectValueAnnotations(IEdmElement element)
        {
            // Fetch the annotations dictionary once and only once, because this.annotationsDictionary might get updated by another thread.
            VersioningDictionary <IEdmElement, VersioningList <IEdmDirectValueAnnotation> > annotationsDictionary = this.annotationsDictionary;

            IEnumerable <IEdmDirectValueAnnotation>    immutableAnnotations = this.GetAttachedAnnotations(element);
            VersioningList <IEdmDirectValueAnnotation> transientAnnotations = GetTransientAnnotations(element, annotationsDictionary);

            if (immutableAnnotations != null)
            {
                foreach (IEdmDirectValueAnnotation existingAnnotation in immutableAnnotations)
                {
                    if (!IsDead(existingAnnotation.NamespaceUri, existingAnnotation.Name, transientAnnotations))
                    {
                        yield return(existingAnnotation);
                    }
                }
            }

            foreach (IEdmDirectValueAnnotation existingAnnotation in TransientAnnotations(transientAnnotations))
            {
                yield return(existingAnnotation);
            }
        }
        /// <summary>
        /// Retrieves the transient annotations for an EDM element.
        /// </summary>
        /// <param name="element">The annotated element.</param>
        /// <param name="annotationsDictionary">The dictionary for looking up the element's annotations.</param>
        /// <returns>The transient annotations for the element, in a form managed by the annotations manager.</returns>
        /// <remarks>This method is static to guarantee that the annotations dictionary is not fetched more than once per lookup operation.</remarks>
        private static VersioningList <IEdmDirectValueAnnotation> GetTransientAnnotations(IEdmElement element, VersioningDictionary <IEdmElement, VersioningList <IEdmDirectValueAnnotation> > annotationsDictionary)
        {
            VersioningList <IEdmDirectValueAnnotation> transientAnnotations;

            annotationsDictionary.TryGetValue(element, out transientAnnotations);
            return(transientAnnotations);
        }
        /// <summary>
        /// Retrieves a set of annotation values. For each requested value, returns null if no annotation with the given name exists for the given element.
        /// </summary>
        /// <param name="annotations">The set of requested annotations</param>
        /// <returns>Returns values that correspond to the provided annotations. A value is null if no annotation with the given name exists for the given element.</returns>
        public object[] GetAnnotationValues(IEnumerable <IEdmDirectValueAnnotationBinding> annotations)
        {
            // Fetch the annotations dictionary once and only once, because this.annotationsDictionary might get updated by another thread.
            VersioningDictionary <IEdmElement, VersioningList <IEdmDirectValueAnnotation> > annotationsDictionary = this.annotationsDictionary;

            object[] values = new object[annotations.Count()];

            int index = 0;

            foreach (IEdmDirectValueAnnotationBinding annotation in annotations)
            {
                values[index++] = this.GetAnnotationValue(annotation.Element, annotation.NamespaceUri, annotation.Name, annotationsDictionary);
            }

            return(values);
        }
        /// <summary>
        /// Retrieves an annotation value for an EDM element. Returns null if no annotation with the given name exists for the given element.
        /// </summary>
        /// <param name="element">The annotated element.</param>
        /// <param name="namespaceName">Namespace that the annotation belongs to.</param>
        /// <param name="localName">Local name of the annotation.</param>
        /// <returns>Returns the annotation that corresponds to the provided name. Returns null if no annotation with the given name exists for the given element.</returns>
        public object GetAnnotationValue(IEdmElement element, string namespaceName, string localName)
        {
            // Fetch the annotations dictionary once and only once, because this.annotationsDictionary might get updated by another thread.
            VersioningDictionary <IEdmElement, VersioningList <IEdmDirectValueAnnotation> > annotationsDictionary = this.annotationsDictionary;

            return(this.GetAnnotationValue(element, namespaceName, localName, annotationsDictionary));
        }
        /// <summary>
        /// Sets a set of annotation values. If a supplied value is null, no annotation is added and an existing annotation with the same name is removed.
        /// </summary>
        /// <param name="annotations">The annotations to set</param>
        public void SetAnnotationValues(IEnumerable <IEdmDirectValueAnnotationBinding> annotations)
        {
            lock (this.annotationsDictionaryLock)
            {
                // Use a local variable to store any interim changes to the annotations dictionary, and perform one atomic update
                // to the field. Otherwise, other threads could see a dictionary in an interim state.
                VersioningDictionary <IEdmElement, VersioningList <IEdmDirectValueAnnotation> > annotationsDictionary = this.annotationsDictionary;

                foreach (IEdmDirectValueAnnotationBinding annotation in annotations)
                {
                    this.SetAnnotationValue(annotation.Element, annotation.NamespaceUri, annotation.Name, annotation.Value, ref annotationsDictionary);
                }

                this.annotationsDictionary = annotationsDictionary;
            }
        }
示例#15
0
        private void SetAnnotationValue(IEdmElement element, string namespaceName, string localName, object value, ref VersioningDictionary <IEdmElement, object> annotationsDictionary)
        {
            object transientAnnotations = EdmDirectValueAnnotationsManager.GetTransientAnnotations(element, annotationsDictionary);
            object obj = transientAnnotations;

            EdmDirectValueAnnotationsManager.SetAnnotation(this.GetAttachedAnnotations(element), ref transientAnnotations, namespaceName, localName, value);
            if (transientAnnotations != obj)
            {
                annotationsDictionary = annotationsDictionary.Set(element, transientAnnotations);
            }
        }
        /// <summary>
        /// Sets a set of annotation values. If a supplied value is null, no annotation is added and an existing annotation with the same name is removed.
        /// </summary>
        /// <param name="annotations">The annotations to set</param>
        public void SetAnnotationValues(IEnumerable<IEdmDirectValueAnnotationBinding> annotations)
        {
            lock (this.annotationsDictionaryLock)
            {
                // Use a local variable to store any interim changes to the annotations dictionary, and perform one atomic update
                // to the field. Otherwise, other threads could see a dictionary in an interim state.
                VersioningDictionary<IEdmElement, object> annotationsDictionary = this.annotationsDictionary;

                foreach (IEdmDirectValueAnnotationBinding annotation in annotations)
                {
                    this.SetAnnotationValue(annotation.Element, annotation.NamespaceUri, annotation.Name, annotation.Value, ref annotationsDictionary);
                }

                this.annotationsDictionary = annotationsDictionary;
            }
        }
 /// <summary>
 /// Retrieves the transient annotations for an EDM element.
 /// </summary>
 /// <param name="element">The annotated element.</param>
 /// <param name="annotationsDictionary">The dictionary for looking up the element's annotations.</param>
 /// <returns>The transient annotations for the element, in a form managed by the annotations manager.</returns>
 /// <remarks>This method is static to guarantee that the annotations dictionary is not fetched more than once per lookup operation.</remarks>
 private static object GetTransientAnnotations(IEdmElement element, VersioningDictionary<IEdmElement, object> annotationsDictionary)
 {
     object transientAnnotations;
     annotationsDictionary.TryGetValue(element, out transientAnnotations);
     return transientAnnotations;
 }
示例#18
0
        public void MapIntegerInsertionAndDeletion()
        {
            VersioningDictionary <int, int> map = VersioningDictionary <int, int> .Create(CompareIntegers);

            int value;

            Assert.IsTrue(map is VersioningDictionary <int, int> .EmptyVersioningDictionary, "Dictionary type");
            Assert.IsFalse(map.TryGetValue(0, out value), "Zero key");

            // Test conversions back and forth between EmptyDictionary, OneKeyDictionary, and TwoKeyDictionary.

            map = map.Set(1, 10);
            Assert.IsTrue(map is VersioningDictionary <int, int> .OneKeyDictionary, "Dictionary type");
            Assert.AreEqual(map.Get(1), 10, "Key value");
            Assert.IsFalse(map.TryGetValue(0, out value), "Zero key");

            map = map.Set(1, 100);
            Assert.IsTrue(map is VersioningDictionary <int, int> .OneKeyDictionary, "Dictionary type");
            Assert.AreEqual(map.Get(1), 100, "Key value");
            Assert.IsFalse(map.TryGetValue(0, out value), "Zero key");

            map = map.Remove(1);
            Assert.IsTrue(map is VersioningDictionary <int, int> .EmptyVersioningDictionary, "Dictionary type");

            map = map.Set(1, 10);
            map = map.Set(2, 20);
            Assert.IsTrue(map is VersioningDictionary <int, int> .TwoKeyDictionary, "Dictionary type");
            Assert.AreEqual(map.Get(1), 10, "Key value");
            Assert.AreEqual(map.Get(2), 20, "Key value");
            Assert.IsFalse(map.TryGetValue(0, out value), "Zero key");

            map = map.Set(1, 100);
            Assert.IsTrue(map is VersioningDictionary <int, int> .TwoKeyDictionary, "Dictionary type");
            Assert.AreEqual(map.Get(1), 100, "Key value");
            Assert.AreEqual(map.Get(2), 20, "Key value");

            map = map.Set(2, 200);
            Assert.IsTrue(map is VersioningDictionary <int, int> .TwoKeyDictionary, "Dictionary type");
            Assert.AreEqual(map.Get(1), 100, "Key value");
            Assert.AreEqual(map.Get(2), 200, "Key value");

            VersioningDictionary <int, int> oneMap = map.Remove(1);

            Assert.IsTrue(oneMap is VersioningDictionary <int, int> .OneKeyDictionary, "Dictionary type");
            Assert.AreEqual(oneMap.Get(2), 200, "Key value");

            Assert.IsTrue(map is VersioningDictionary <int, int> .TwoKeyDictionary, "Dictionary type");
            Assert.AreEqual(map.Get(1), 100, "Key value");
            Assert.AreEqual(map.Get(2), 200, "Key value");
            Assert.IsFalse(map.TryGetValue(0, out value), "Zero key");

            oneMap = map.Remove(2);
            Assert.IsTrue(oneMap is VersioningDictionary <int, int> .OneKeyDictionary, "Dictionary type");
            Assert.AreEqual(oneMap.Get(1), 100, "Key value");

            Assert.IsTrue(map is VersioningDictionary <int, int> .TwoKeyDictionary, "Dictionary type");
            Assert.AreEqual(map.Get(1), 100, "Key value");
            Assert.AreEqual(map.Get(2), 200, "Key value");

            // Test conversion to a TreeDictionary.

            map = map.Set(3, 30);
            Assert.IsTrue(map is VersioningDictionary <int, int> .TreeDictionary, "Dictionary type");
            Assert.AreEqual(map.Get(1), 100, "Key value");
            Assert.AreEqual(map.Get(2), 200, "Key value");
            Assert.AreEqual(map.Get(3), 30, "Key value");
            Assert.IsFalse(map.TryGetValue(0, out value), "Zero key");

            map = map.Set(3, 300);
            Assert.IsTrue(map is VersioningDictionary <int, int> .TreeDictionary, "Dictionary type");
            Assert.AreEqual(map.Get(1), 100, "Key value");
            Assert.AreEqual(map.Get(2), 200, "Key value");
            Assert.AreEqual(map.Get(3), 300, "Key value");

            // Test that a significant number of keys does not force conversion to a HashKeyDictionary.

            for (int i = 1; i <= 100; i++)
            {
                map = map.Set(i, i * 10);
            }
            Assert.IsTrue(map is VersioningDictionary <int, int> .TreeDictionary, "Dictionary type");
            for (int i = 1; i <= 100; i++)
            {
                Assert.AreEqual(i * 10, map.Get(i), "Key value");
            }
            Assert.IsFalse(map.TryGetValue(0, out value), "Zero key");

            // Test removing half the keys.

            for (int i = 1; i < 100; i += 2)
            {
                map = map.Remove(i);
            }
            Assert.IsTrue(map is VersioningDictionary <int, int> .TreeDictionary, "Dictionary type");
            for (int i = 1; i < 100; i += 2)
            {
                Assert.IsFalse(map.TryGetValue(i, out value), "Odd key");
                Assert.AreEqual((i + 1) * 10, map.Get(i + 1), "Even key value");
            }

            // Test conversion to a HashTreeDictionary.

            for (int i = 1; i <= 10000; i++)
            {
                map = map.Set(i, i * 2);
            }
            Assert.IsTrue(map is VersioningDictionary <int, int> .HashTreeDictionary, "Dictionary type");
            for (int i = 1; i <= 10000; i++)
            {
                Assert.AreEqual(i * 2, map.Get(i), "Key value");
            }
            Assert.IsFalse(map.TryGetValue(0, out value), "Zero key");

            // Test removing half the keys.

            for (int i = 1; i < 10000; i += 2)
            {
                map = map.Remove(i);
            }
            Assert.IsTrue(map is VersioningDictionary <int, int> .HashTreeDictionary, "Dictionary type");
            for (int i = 1; i < 10000; i += 2)
            {
                Assert.IsFalse(map.TryGetValue(i, out value), "Odd key");
                Assert.AreEqual((i + 1) * 2, map.Get(i + 1), "Even key value");
            }
        }
        private object GetAnnotationValue(IEdmElement element, string namespaceName, string localName, VersioningDictionary<IEdmElement, object> annotationsDictionary)
        {
            IEdmDirectValueAnnotation annotation = FindTransientAnnotation(GetTransientAnnotations(element, annotationsDictionary), namespaceName, localName);
            if (annotation != null)
            {
                return annotation.Value;
            }

            IEnumerable<IEdmDirectValueAnnotation> immutableAnnotations = this.GetAttachedAnnotations(element);
            if (immutableAnnotations != null)
            {
                foreach (IEdmDirectValueAnnotation existingAnnotation in immutableAnnotations)
                {
                    if (existingAnnotation.NamespaceUri == namespaceName && existingAnnotation.Name == localName)
                    {
                        // No need to check that the immutable annotation isn't Dead, because if it were
                        // the tombstone would have been found in the transient annotations.
                        return existingAnnotation.Value;
                    }
                }
            }

            return null;
        }
		private object GetAnnotationValue(IEdmElement element, string namespaceName, string localName, VersioningDictionary<IEdmElement, object> annotationsDictionary)
		{
			object value;
			IEdmDirectValueAnnotation edmDirectValueAnnotation = EdmDirectValueAnnotationsManager.FindTransientAnnotation(EdmDirectValueAnnotationsManager.GetTransientAnnotations(element, annotationsDictionary), namespaceName, localName);
			if (edmDirectValueAnnotation == null)
			{
				IEnumerable<IEdmDirectValueAnnotation> attachedAnnotations = this.GetAttachedAnnotations(element);
				if (attachedAnnotations != null)
				{
					IEnumerator<IEdmDirectValueAnnotation> enumerator = attachedAnnotations.GetEnumerator();
					using (enumerator)
					{
						while (enumerator.MoveNext())
						{
							IEdmDirectValueAnnotation current = enumerator.Current;
							if (!(current.NamespaceUri == namespaceName) || !(current.Name == localName))
							{
								continue;
							}
							value = current.Value;
							return value;
						}
						return null;
					}
					return value;
				}
				return null;
			}
			else
			{
				return edmDirectValueAnnotation.Value;
			}
		}
        public static string GetNamespaceAlias(this IEdmModel model, string namespaceName)
        {
            VersioningDictionary <string, string> annotationValue = model.GetAnnotationValue <VersioningDictionary <string, string> >(model, "http://schemas.microsoft.com/ado/2011/04/edm/internal", "NamespaceAlias");

            return(annotationValue.Get(namespaceName));
        }
		public void SetAnnotationValue(IEdmElement element, string namespaceName, string localName, object value)
		{
			lock (this.annotationsDictionaryLock)
			{
				VersioningDictionary<IEdmElement, object> versioningDictionary = this.annotationsDictionary;
				this.SetAnnotationValue(element, namespaceName, localName, value, ref versioningDictionary);
				this.annotationsDictionary = versioningDictionary;
			}
		}
示例#23
0
        private object GetAnnotationValue(IEdmElement element, string namespaceName, string localName, VersioningDictionary <IEdmElement, object> annotationsDictionary)
        {
            IEdmDirectValueAnnotation annotation = FindTransientAnnotation(GetTransientAnnotations(element, annotationsDictionary), namespaceName, localName);

            if (annotation != null)
            {
                return(annotation.Value);
            }

            IEnumerable <IEdmDirectValueAnnotation> immutableAnnotations = this.GetAttachedAnnotations(element);

            if (immutableAnnotations != null)
            {
                foreach (IEdmDirectValueAnnotation existingAnnotation in immutableAnnotations)
                {
                    if (existingAnnotation.NamespaceUri == namespaceName && existingAnnotation.Name == localName)
                    {
                        // No need to check that the immutable annotation isn't Dead, because if it were
                        // the tombstone would have been found in the transient annotations.
                        return(existingAnnotation.Value);
                    }
                }
            }

            return(null);
        }
		private void SetAnnotationValue(IEdmElement element, string namespaceName, string localName, object value, ref VersioningDictionary<IEdmElement, object> annotationsDictionary)
		{
			object transientAnnotations = EdmDirectValueAnnotationsManager.GetTransientAnnotations(element, annotationsDictionary);
			object obj = transientAnnotations;
			EdmDirectValueAnnotationsManager.SetAnnotation(this.GetAttachedAnnotations(element), ref transientAnnotations, namespaceName, localName, value);
			if (transientAnnotations != obj)
			{
				annotationsDictionary = annotationsDictionary.Set(element, transientAnnotations);
			}
		}
        /// <summary>
        /// Gets the serialization alias for a given namespace.
        /// </summary>
        /// <param name="model">Model that will be serialized.</param>
        /// <param name="namespaceName">Namespace the alias is needed for.</param>
        /// <returns>The alias of the given namespace, or null if one does not exist.</returns>
        public static string GetNamespaceAlias(this IEdmModel model, string namespaceName)
        {
            VersioningDictionary <string, string> mappings = model.GetAnnotationValue <VersioningDictionary <string, string> >(model, EdmConstants.InternalUri, CsdlConstants.NamespaceAliasAnnotation);

            return(mappings.Get(namespaceName));
        }
示例#26
0
        public object GetAnnotationValue(IEdmElement element, string namespaceName, string localName)
        {
            VersioningDictionary <IEdmElement, object> versioningDictionary = this.annotationsDictionary;

            return(this.GetAnnotationValue(element, namespaceName, localName, versioningDictionary));
        }