MaterializeFromAtom.cs :  » 2.6.4-mono-.net-core » System.Data » System » Data » Services » Client » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » 2.6.4 mono .net core » System.Data 
System.Data » System » Data » Services » Client » MaterializeFromAtom.cs
//Copyright 2010 Microsoft Corporation
//
//Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. 
//You may obtain a copy of the License at 
//
//http://www.apache.org/licenses/LICENSE-2.0 
//
//Unless required by applicable law or agreed to in writing, software distributed under the License 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.


namespace System.Data.Services.Client{
    #region Namespaces.

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Linq;
    using System.Xml;
    using System.Xml.Linq;
    using System.Text;
    using System.Linq.Expressions;

    #endregion Namespaces.

    internal class MaterializeAtom : IDisposable, IEnumerable, IEnumerator
    {
        internal readonly MergeOption MergeOptionValue;

        #region Private fields.

        private const long CountStateInitial = -1;

        private const long CountStateFailure = -2;

        private readonly bool ignoreMissingProperties;

        private readonly DataServiceContext context;

        private readonly Type elementType;

        private readonly bool expectingSingleValue;

        private readonly AtomMaterializer materializer;

        private readonly AtomParser parser;

        private XmlReader reader;

        private object current;

        private bool calledGetEnumerator;

        private long countValue;

        private bool moved;

#if DEBUG && !ASTORIA_LIGHT
        private System.IO.TextWriter writer = new System.IO.StringWriter(System.Globalization.CultureInfo.InvariantCulture);
#else
#pragma warning disable 649
        private System.IO.TextWriter writer;
#pragma warning restore 649
#endif

        #endregion Private fields.

        internal MaterializeAtom(DataServiceContext context, XmlReader reader, QueryComponents queryComponents, ProjectionPlan plan, MergeOption mergeOption)
        {
            Debug.Assert(queryComponents != null, "queryComponents != null");

            this.context = context;
            this.elementType = queryComponents.LastSegmentType;
            this.MergeOptionValue = mergeOption;
            this.ignoreMissingProperties = context.IgnoreMissingProperties;
            this.reader = (reader == null) ? null : new System.Data.Services.Client.Xml.XmlAtomErrorReader(reader);
            this.countValue = CountStateInitial;
            this.expectingSingleValue = ClientConvert.IsKnownNullableType(elementType);

            Debug.Assert(reader != null, "Materializer reader is null! Did you mean to use Materializer.ResultsWrapper/EmptyResults?");

            reader.Settings.NameTable.Add(context.DataNamespace);

            string typeScheme = this.context.TypeScheme.OriginalString;
            this.parser = new AtomParser(this.reader, AtomParser.XElementBuilderCallback, typeScheme, context.DataNamespace);
            AtomMaterializerLog log = new AtomMaterializerLog(this.context, mergeOption);
            Type implementationType;
            Type materializerType = GetTypeForMaterializer(this.expectingSingleValue, this.elementType, out implementationType);
            this.materializer = new AtomMaterializer(parser, context, materializerType, this.ignoreMissingProperties, mergeOption, log, this.MaterializedObjectCallback, queryComponents, plan);
        }

        private void MaterializedObjectCallback(object tag, object entity)
        {
            Debug.Assert(tag != null, "tag != null");
            Debug.Assert(entity != null, "entity != null");

            XElement data = (XElement)tag;
            if (this.context.HasReadingEntityHandlers)
            {
                XmlUtil.RemoveDuplicateNamespaceAttributes(data);
                this.context.FireReadingEntityEvent(entity, data);
            }
        }

        private MaterializeAtom()
        {
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        private MaterializeAtom(DataServiceContext context, XmlReader reader, Type type, MergeOption mergeOption)
            : this(context, reader, new QueryComponents(null, Util.DataServiceVersionEmpty, type, null, null), null, mergeOption)
        {
        }

        #region Current

        public object Current
        {
            get
            {
                object currentValue = this.current;
                return currentValue;
            }
        }

        #endregion

        internal static MaterializeAtom EmptyResults
        {
            get
            {
                return new ResultsWrapper(null, null);
            }
        }

        internal bool IsEmptyResults
        {
            get { return this.reader == null; }
        }

        internal DataServiceContext Context
        {
            get { return this.context; }
        }

        #region IDisposable
        public void Dispose()
        {
            this.current = null;

            if (null != this.reader)
            {
                ((IDisposable)this.reader).Dispose();
            }

            if (null != this.writer)
            {
                this.writer.Dispose();
            }

            GC.SuppressFinalize(this);
        }

        #endregion

        #region IEnumerable
        public virtual IEnumerator GetEnumerator()
        {
            this.CheckGetEnumerator();
            return this;
        }
        #endregion

        private static Type GetTypeForMaterializer(bool expectingSingleValue, Type elementType, out Type implementationType)
        {
            if (!expectingSingleValue && typeof(IEnumerable).IsAssignableFrom(elementType))
            {
                implementationType = ClientType.GetImplementationType(elementType, typeof(ICollection<>));
                if (implementationType != null)
                {
                    Type expectedType = implementationType.GetGenericArguments()[0];                    return expectedType;
                }
            }

            implementationType = null;
            return elementType;
        }

        public bool MoveNext()
        {
            bool applying = this.context.ApplyingChanges;
            try
            {
                this.context.ApplyingChanges = true;
                return this.MoveNextInternal();
            }
            finally
            {
                this.context.ApplyingChanges = applying;
            }
        }

        private bool MoveNextInternal()
        {
            if (this.reader == null)
            {
                Debug.Assert(this.current == null, "this.current == null -- otherwise this.reader should have some value.");
                return false;
            }

            this.current = null;
            this.materializer.Log.Clear();

            bool result = false;
            Type implementationType;
            GetTypeForMaterializer(this.expectingSingleValue, this.elementType, out implementationType);
            if (implementationType != null)
            {
                if (this.moved)
                {
                    return false;
                }

                Type expectedType = implementationType.GetGenericArguments()[0];                implementationType = this.elementType;
                if (implementationType.IsInterface)
                {
                    implementationType = typeof(System.Collections.ObjectModel.Collection<>).MakeGenericType(expectedType);
                }

                IList list = (IList)Activator.CreateInstance(implementationType);

                while (this.materializer.Read())
                {
                    this.moved = true;
                    list.Add(this.materializer.CurrentValue);
                }

                this.current = list;
                result = true;
            }

            if (null == this.current)
            {
                if (this.expectingSingleValue && this.moved)
                {
                    result = false;
                }
                else
                {
                    result = this.materializer.Read();
                    if (result)
                    {
                        this.current = this.materializer.CurrentValue;
                    }

                    this.moved = true;
                }
            }

            this.materializer.Log.ApplyToContext();

            return result;
        }

        void System.Collections.IEnumerator.Reset()
        {
            throw Error.NotSupported();
        }

        internal static MaterializeAtom CreateWrapper(IEnumerable results)
        {
            return new ResultsWrapper(results, null);
        }

        internal static MaterializeAtom CreateWrapper(IEnumerable results, DataServiceQueryContinuation continuation)
        {
            return new ResultsWrapper(results, continuation);
        }

        internal void SetInsertingObject(object addedObject)
        {
            this.materializer.TargetInstance = addedObject;
        }

        internal static void SkipToEnd(XmlReader reader)
        {
            Debug.Assert(reader != null, "reader != null");
            Debug.Assert(reader.NodeType == XmlNodeType.Element, "reader.NodeType == XmlNodeType.Element");

            if (reader.IsEmptyElement)
            {
                return;
            }

            int readerDepth = reader.Depth;
            while (reader.Read())
            {
                if (reader.NodeType == XmlNodeType.EndElement && reader.Depth == readerDepth)
                {
                    return;
                }
            }
        }

        internal long CountValue()
        {
            if (this.countValue == CountStateInitial)
            {
                this.ReadCountValue();
            }
            else if (this.countValue == CountStateFailure)
            {
                throw new InvalidOperationException(Strings.MaterializeFromAtom_CountNotPresent);
            }

            return this.countValue;
        }

        internal virtual DataServiceQueryContinuation GetContinuation(IEnumerable key)
        {
            Debug.Assert(this.materializer != null, "Materializer is null!");

            DataServiceQueryContinuation result;
            if (key == null)
            {
                if ((this.expectingSingleValue && !this.moved) || (!this.expectingSingleValue && !this.materializer.IsEndOfStream))
                {
                    throw new InvalidOperationException(Strings.MaterializeFromAtom_TopLevelLinkNotAvailable);
                }

                if (this.expectingSingleValue || this.materializer.CurrentFeed == null)
                {
                    result = null;
                }
                else
                {
                    result = DataServiceQueryContinuation.Create(
                        this.materializer.CurrentFeed.NextLink, 
                        this.materializer.MaterializeEntryPlan);
                }
            }
            else
            {
                if (!this.materializer.NextLinkTable.TryGetValue(key, out result))
                {
                    throw new ArgumentException(Strings.MaterializeFromAtom_CollectionKeyNotPresentInLinkTable);
                }
            }

            return result;
        }
            
        private void CheckGetEnumerator()
        {
            if (this.calledGetEnumerator)
            {
                throw Error.NotSupported(Strings.Deserialize_GetEnumerator);
            }

            this.calledGetEnumerator = true;
        }

        private void ReadCountValue()
        {
            Debug.Assert(this.countValue == CountStateInitial, "Count value is not in the initial state");

            if (this.materializer.CurrentFeed != null &&
                this.materializer.CurrentFeed.Count.HasValue)
            {
                this.countValue = this.materializer.CurrentFeed.Count.Value;
                return;
            }

            while (this.reader.NodeType != XmlNodeType.Element && this.reader.Read())
            {
            }

            if (this.reader.EOF)
            {
                throw new InvalidOperationException(Strings.MaterializeFromAtom_CountNotPresent);
            }

            Debug.Assert(
                (Util.AreSame(XmlConstants.AtomNamespace, this.reader.NamespaceURI) &&
                Util.AreSame(XmlConstants.AtomFeedElementName, this.reader.LocalName)) ||
                (Util.AreSame(XmlConstants.DataWebNamespace, this.reader.NamespaceURI) &&
                Util.AreSame(XmlConstants.LinkCollectionElementName, this.reader.LocalName)),
                "<feed> or <links> tag expected");

            XElement element = XElement.Load(this.reader);
            this.reader.Close();

            XElement countNode = element.Descendants(XNamespace.Get(XmlConstants.DataWebMetadataNamespace) + XmlConstants.RowCountElement).FirstOrDefault();

            if (countNode == null)
            {
                throw new InvalidOperationException(Strings.MaterializeFromAtom_CountNotPresent);
            }
            else
            {
                if (!long.TryParse(countNode.Value, System.Globalization.NumberStyles.Integer, System.Globalization.CultureInfo.InvariantCulture, out this.countValue))
                {
                    throw new FormatException(Strings.MaterializeFromAtom_CountFormatError);
                }

                if (this.countValue < 0)
                {
                    throw new FormatException(Strings.MaterializeFromAtom_CountFormatError);
                }
            }

            this.reader = new System.Data.Services.Client.Xml.XmlAtomErrorReader(element.CreateReader());
            this.parser.ReplaceReader(this.reader);
        }

        internal static ClientType GetEntryClientType(string typeName, DataServiceContext context, Type expectedType, bool checkAssignable)
        {
            Debug.Assert(context != null, "context != null");
            Type resolvedType = context.ResolveTypeFromName(typeName, expectedType, checkAssignable);
            ClientType result = ClientType.Create(resolvedType);
            Debug.Assert(result != null, "result != null -- otherwise ClientType.Create returned null");
            return result;
        }

        internal static string ReadElementString(XmlReader reader, bool checkNullAttribute)
        {
            Debug.Assert(reader != null, "reader != null");
            Debug.Assert(
                reader.NodeType == XmlNodeType.Element,
                "reader.NodeType == XmlNodeType.Element -- otherwise caller is confused as to where the reader is");

            string result = null;
            bool empty = checkNullAttribute && !Util.DoesNullAttributeSayTrue(reader);

            if (reader.IsEmptyElement)
            {
                return (empty ? String.Empty : null);
            }

            while (reader.Read())
            {
                switch (reader.NodeType)
                {
                    case XmlNodeType.EndElement:
                        return result ?? (empty ? String.Empty : null);
                    case XmlNodeType.CDATA:
                    case XmlNodeType.Text:
                    case XmlNodeType.SignificantWhitespace:
                        if (null != result)
                        {
                            throw Error.InvalidOperation(Strings.Deserialize_MixedTextWithComment);
                        }

                        result = reader.Value;
                        break;
                    case XmlNodeType.Comment:
                    case XmlNodeType.Whitespace:
                        break;

                    #region XmlNodeType error
                    case XmlNodeType.Element:
                        goto default;

                    default:
                        throw Error.InvalidOperation(Strings.Deserialize_ExpectingSimpleValue);
                    #endregion
                }
            }

            throw Error.InvalidOperation(Strings.Deserialize_ExpectingSimpleValue);
        }

        private class ResultsWrapper : MaterializeAtom
        {
            #region Private fields.

            private readonly IEnumerable results;

            private readonly DataServiceQueryContinuation continuation;

            #endregion Private fields.

            internal ResultsWrapper(IEnumerable results, DataServiceQueryContinuation continuation)
            {
                this.results = results ?? new object[0];
                this.continuation = continuation;
            }

            internal override DataServiceQueryContinuation GetContinuation(IEnumerable key)
            {
                if (key == null)
                {
                    return this.continuation;
                }
                else
                {
                    throw new InvalidOperationException(Strings.MaterializeFromAtom_GetNestLinkForFlatCollection);
                }
            }

            public override IEnumerator GetEnumerator()
            {
                return this.results.GetEnumerator();
            }
        }
    }
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.