ClientApiGenerator.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataEntityDesign / Design / System / Data / EntityModel / Emitters / ClientApiGenerator.cs / 1305376 / ClientApiGenerator.cs

                            //---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner       [....]
// @backupOwner [....] 
//--------------------------------------------------------------------- 

using System; 
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic; 
using System.Data;
using System.Data.EntityModel.Emitters; 
using SOM = System.Data.EntityModel.SchemaObjectModel; 
using System.Diagnostics;
using System.Data.Metadata.Edm; 
using System.Data.Entity.Design;
using System.IO;
using System.Data.EntityModel.SchemaObjectModel;
using System.Data.Entity.Design.SsdlGenerator; 
using System.Linq;
using System.Data.Entity.Design.Common; 
using System.Runtime.Versioning; 

namespace System.Data.EntityModel 
{
    /// 
    /// Summary description for ClientApiGenerator.
    ///  
    internal sealed class ClientApiGenerator
    { 
        #region Instance Fields 
        private string _codeNamespace = null;
        private CodeCompileUnit _compileUnit = null; 
        private bool _isLanguageCaseSensitive = true;

        private EdmItemCollection _edmItemCollection = null;
        private Schema _sourceSchema = null; 
        private FixUpCollection _fixUps = null;
        private AttributeEmitter _attributeEmitter = null; 
        EntityClassGenerator _generator; 
        List _errors;
        TypeReference _typeReference = new TypeReference(); 

        #endregion

        #region Public Methods 
        public ClientApiGenerator(Schema sourceSchema, EdmItemCollection edmItemCollection, EntityClassGenerator generator, List errors)
        { 
            Debug.Assert(sourceSchema != null, "sourceSchema is null"); 
            Debug.Assert(edmItemCollection != null, "edmItemCollection is null");
            Debug.Assert(generator != null, "generator is null"); 
            Debug.Assert(errors != null, "errors is null");

            _edmItemCollection = edmItemCollection;
            _sourceSchema = sourceSchema; 
            _generator = generator;
            _errors = errors; 
            _attributeEmitter = new AttributeEmitter(_typeReference); 
        }
 
        /// 
        /// Parses a source Schema and outputs client-side generated code to
        /// the output TextWriter.
        ///  
        /// The source Schema
        /// The TextWriter in which to write the output 
        /// The Uri for the output. Can be null. 
        /// A list of GeneratorErrors.
        [ResourceExposure(ResourceScope.None)] //No resource is exposed. 
        [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] //For Path.GetTempPath method.
                                                                            //We use tha path to create a temp file stream which is consistent with the resource consumption of machine.

        internal void GenerateCode(LazyTextWriterCreator target, string targetLocation) 
        {
            Debug.Assert(target != null, "target parameter is null"); 
 
            IndentedTextWriter indentedTextWriter = null;
            System.IO.Stream tempFileStream = null; 
            System.IO.StreamReader reader = null;
            System.IO.StreamWriter writer = null;
            TempFileCollection tempFiles = null;
            try 
            {
                CodeDomProvider provider = null; 
                switch (Language) 
                {
                    case LanguageOption.GenerateCSharpCode: 
                        provider = new Microsoft.CSharp.CSharpCodeProvider();
                        break;

                    case LanguageOption.GenerateVBCode: 
                        provider = new Microsoft.VisualBasic.VBCodeProvider();
                        break; 
                } 

                _isLanguageCaseSensitive = (provider.LanguageOptions & LanguageOptions.CaseInsensitive) == 0; 

                new NamespaceEmitter(this, _codeNamespace, target.TargetFilePath).Emit();

                // if there were errors we don't need the output file 
                if (RealErrorsExist)
                { 
                    return; 
                }
 
                if (FixUps.Count == 0 || !FixUpCollection.IsLanguageSupported(Language))
                {
                    indentedTextWriter = new IndentedTextWriter(target.GetOrCreateTextWriter(), "\t");
                } 
                else
                { 
                    // need to write to a temporary file so we can do fixups... 
                    tempFiles = new TempFileCollection(Path.GetTempPath());
                    string filename = Path.Combine(tempFiles.TempDir, "EdmCodeGenFixup-" + Guid.NewGuid().ToString() + ".tmp"); 
                    tempFiles.AddFile(filename, false);
                    tempFileStream = new System.IO.FileStream(filename, System.IO.FileMode.CreateNew, System.IO.FileAccess.ReadWrite,
                        System.IO.FileShare.None);
                    indentedTextWriter = new IndentedTextWriter(new System.IO.StreamWriter(tempFileStream), "\t"); 
                }
 
                CodeGeneratorOptions styleOptions = new CodeGeneratorOptions(); 
                styleOptions.BracingStyle = "C";
                styleOptions.BlankLinesBetweenMembers = false; 
                styleOptions.VerbatimOrder = true;
                provider.GenerateCodeFromCompileUnit(CompileUnit, indentedTextWriter, styleOptions);

                // if we wrote to a temp file need to post process the file... 
                if (tempFileStream != null)
                { 
                    indentedTextWriter.Flush(); 
                    tempFileStream.Seek(0, System.IO.SeekOrigin.Begin);
                    reader = new System.IO.StreamReader(tempFileStream); 
                    FixUps.Do(reader, target.GetOrCreateTextWriter(), Language, SourceObjectNamespaceName != string.Empty);
                }
            }
            catch (System.UnauthorizedAccessException ex) 
            {
                AddError(ModelBuilderErrorCode.SecurityError, EdmSchemaErrorSeverity.Error, ex); 
            } 
            catch (System.IO.FileNotFoundException ex)
            { 
                AddError(ModelBuilderErrorCode.FileNotFound, EdmSchemaErrorSeverity.Error, ex);
            }
            catch (System.Security.SecurityException ex)
            { 
                AddError(ModelBuilderErrorCode.SecurityError, EdmSchemaErrorSeverity.Error, ex);
            } 
            catch (System.IO.DirectoryNotFoundException ex) 
            {
                AddError(ModelBuilderErrorCode.DirectoryNotFound, EdmSchemaErrorSeverity.Error, ex); 
            }
            catch (System.IO.IOException ex)
            {
                AddError(ModelBuilderErrorCode.IOException, EdmSchemaErrorSeverity.Error, ex); 
            }
            finally 
            { 
                if (indentedTextWriter != null)
                { 
                    indentedTextWriter.Close();
                }
                if (tempFileStream != null)
                { 
                    tempFileStream.Close();
                } 
                if (tempFiles != null) 
                {
                    tempFiles.Delete(); 
                    ((IDisposable)tempFiles).Dispose();
                }
                if (reader != null)
                { 
                    reader.Close();
                } 
                if (writer != null) 
                {
                    writer.Close(); 
                }
            }
        }
 
        /// 
        /// Verification code invoked for types 
        ///  
        /// The type being generated
        internal void VerifyLanguageCaseSensitiveCompatibilityForType(GlobalItem item) 
        {
            if (_isLanguageCaseSensitive)
            {
                return; // no validation necessary 
            }
 
            try 
            {
                _edmItemCollection.GetItem( 
                                                        item.Identity,
                                                        true   // ignore case
                                                    );
            } 
            catch (InvalidOperationException)
            { 
                AddError(Strings.ItemExistsWithDifferentCase(item.BuiltInTypeKind.ToString(), item.Identity), ModelBuilderErrorCode.IncompatibleSettingForCaseSensitiveOption, 
                    EdmSchemaErrorSeverity.Error, item.Identity);
            } 
        }


        ///  
        /// Verification code invoked for properties
        ///  
        /// The property or navigation property being generated 
        internal void VerifyLanguageCaseSensitiveCompatibilityForProperty(EdmMember item)
        { 
            if (_isLanguageCaseSensitive)
            {
                return; // no validation necessary
            } 

            Debug.Assert(item != null); 
 
            ReadOnlyMetadataCollection members = item.DeclaringType.Members;
 
            HashSet set = new HashSet(StringComparer.OrdinalIgnoreCase);

            foreach (EdmMember member in members)
            { 
                if (set.Contains(member.Identity) &&
                    item.Identity.Equals(member.Identity, StringComparison.OrdinalIgnoreCase)) 
                { 
                    AddError(Strings.PropertyExistsWithDifferentCase(item.Identity), ModelBuilderErrorCode.IncompatibleSettingForCaseSensitiveOption,
                    EdmSchemaErrorSeverity.Error, item.DeclaringType.FullName, item.Identity); 
                }
                else
                {
                    set.Add(member.Identity); 
                }
            } 
        } 

        ///  
        /// Verification code invoked for entity sets
        /// 
        /// The entity container being generated
        internal void VerifyLanguageCaseSensitiveCompatibilityForEntitySet(System.Data.Metadata.Edm.EntityContainer item) 
        {
            if (_isLanguageCaseSensitive) 
            { 
                return; // no validation necessary
            } 

            Debug.Assert(item != null);

            HashSet set = new HashSet(StringComparer.OrdinalIgnoreCase); 

            foreach (EntitySetBase entitySetBase in item.BaseEntitySets) 
            { 
                if (MetadataUtil.IsEntitySet(entitySetBase))
                { 
                    EntitySet entitySet = (EntitySet)entitySetBase;
                    if (set.Contains(entitySet.Identity))
                    {
                        AddError(ModelBuilderErrorCode.IncompatibleSettingForCaseSensitiveOption, 
                        EdmSchemaErrorSeverity.Error, new InvalidOperationException(Strings.EntitySetExistsWithDifferentCase(entitySet.Identity)),
                        item.Name); 
                    } 
                    else
                    { 
                        set.Add(entitySet.Identity);
                    }
                }
            } 
        }
 
        internal IEnumerable GetDirectSubTypes(EdmType edmType) 
        {
            return _edmItemCollection.GetItems().Where(b => b.BaseType == edmType); 
        }

        private static System.Data.EntityModel.SchemaObjectModel.SchemaElement GetSchemaElement(
            System.Data.EntityModel.SchemaObjectModel.Schema schema, string itemIdentity) 
        {
            List schemaTypes = 
                           schema.SchemaTypes.Where(p => p.Identity == itemIdentity).ToList(); 
            if (null != schemaTypes && schemaTypes.Count > 0)
            { 
                return (System.Data.EntityModel.SchemaObjectModel.SchemaElement)schemaTypes.First();
            }
            else
            { 
                return null;
            } 
 
        }
 
        internal static void GetElementLocationInfo(System.Data.EntityModel.SchemaObjectModel.Schema schema, string itemIdentity, out int lineNumber, out int linePosition)
        {
            System.Data.EntityModel.SchemaObjectModel.SchemaElement element = GetSchemaElement(schema, itemIdentity);
 
            if(null != element)
            { 
                lineNumber = element.LineNumber; 
                linePosition = element.LinePosition;
            } 
            else
            {
                lineNumber = linePosition = -1;
            } 
        }
 
        internal static void GetElementLocationInfo(System.Data.EntityModel.SchemaObjectModel.Schema schema, string parentIdentity, string itemIdentity, out int lineNumber, out int linePosition) 
        {
            lineNumber = linePosition = -1; 

            System.Data.EntityModel.SchemaObjectModel.SchemaElement element = GetSchemaElement(schema, parentIdentity);
            System.Data.EntityModel.SchemaObjectModel.StructuredType elementWithProperty =
                element as System.Data.EntityModel.SchemaObjectModel.StructuredType; 

            if (null != elementWithProperty && elementWithProperty.Properties.ContainsKey(itemIdentity)) 
            { 
                    lineNumber = elementWithProperty.Properties[itemIdentity].LineNumber;
                    linePosition = elementWithProperty.Properties[itemIdentity].LinePosition; 
            }
            else if( null != element)
            {
                lineNumber = element.LineNumber; 
                linePosition = element.LinePosition;
            } 
        } 

        #endregion 

        #region Internal Properties

        internal LanguageOption Language 
        {
            get 
            { 
                return _generator.LanguageOption;
            } 
        }

        internal TypeReference TypeReference
        { 
            get { return _typeReference; }
        } 
 
        internal CodeCompileUnit CompileUnit
        { 
            get
            {
                if (_compileUnit == null)
                    _compileUnit = new CodeCompileUnit(); 

                return _compileUnit; 
            } 
        }
 
        public void AddError(string message, ModelBuilderErrorCode errorCode, EdmSchemaErrorSeverity severity)
        {
            _errors.Add(new EdmSchemaError(message, (int)errorCode, severity));
        } 

        public void AddError(ModelBuilderErrorCode errorCode, EdmSchemaErrorSeverity severity, Exception ex) 
        { 
            _errors.Add(new EdmSchemaError(ex.Message, (int)errorCode, severity, ex));
        } 

        internal void AddError(string message, ModelBuilderErrorCode errorCode, EdmSchemaErrorSeverity severity, Exception ex)
        {
            _errors.Add(new EdmSchemaError(message, (int)errorCode, severity, ex)); 
        }
 
        internal void AddError(ModelBuilderErrorCode errorCode, EdmSchemaErrorSeverity severity, Exception ex, string itemIdentity) 
        {
            int lineNumber, linePosition; 
            ClientApiGenerator.GetElementLocationInfo(this._sourceSchema, itemIdentity, out lineNumber, out linePosition);

            _errors.Add(new EdmSchemaError(ex.Message, (int)errorCode, severity, this._sourceSchema.Location, lineNumber, linePosition, ex));
        } 

        internal void AddError(string message, ModelBuilderErrorCode errorCode, EdmSchemaErrorSeverity severity, string itemIdentity) 
        { 
            int lineNumber, linePosition;
            ClientApiGenerator.GetElementLocationInfo(this._sourceSchema, itemIdentity, out lineNumber, out linePosition); 

            _errors.Add(new EdmSchemaError(message, (int)errorCode, severity, this._sourceSchema.Location, lineNumber, linePosition));
        }
 
        internal void AddError(string message, ModelBuilderErrorCode errorCode, EdmSchemaErrorSeverity severity, string parentIdentity, string itemIdentity)
        { 
            int lineNumber, linePosition; 
            ClientApiGenerator.GetElementLocationInfo(this._sourceSchema, parentIdentity, itemIdentity, out lineNumber, out linePosition);
 
            _errors.Add(new EdmSchemaError(message, (int)errorCode, severity, this._sourceSchema.Location, lineNumber, linePosition));
        }

        ///  
        /// Check collection for any real errors (Severity != Warning)
        ///  
        public bool RealErrorsExist 
        {
            get 
            {
                foreach (EdmSchemaError error in _errors)
                {
                    if (error.Severity != EdmSchemaErrorSeverity.Warning) 
                        return true;
                } 
                return false; 
            }
        } 

        public IEnumerable GetSourceTypes()
        {
            foreach (SOM.SchemaType type in _sourceSchema.SchemaTypes) 
            {
                if (type is SOM.ModelFunction) 
                { 
                    continue;
                } 

                yield return _edmItemCollection.GetItem(type.Identity);
            }
        } 

        public CodeTypeReference GetFullyQualifiedTypeReference(EdmType type) 
        { 
            string fullObjectName = CreateFullName(GetObjectNamespace(type.NamespaceName), type.Name);
            return TypeReference.FromString(fullObjectName); 
        }

        public CodeTypeReference GetFullyQualifiedTypeReference(EdmType type, bool addGlobalQualifier)
        { 
            string fullObjectName = CreateFullName(GetObjectNamespace(type.NamespaceName), type.Name);
            return TypeReference.FromString(fullObjectName, addGlobalQualifier); 
        } 

        private string CreateFullName(string namespaceName, string name) 
        {
            if (string.IsNullOrEmpty(namespaceName))
            {
                return name; 
            }
 
            return namespaceName + "." + name; 
        }
 
        public CodeTypeReference GetLeastPossibleQualifiedTypeReference(EdmType type)
        {
            string typeRef;
 
            if (type.BuiltInTypeKind == BuiltInTypeKind.PrimitiveType)
            { 
                return type.ClrType.IsValueType ? TypeReference.NullableForType(type.ClrType) : TypeReference.ForType(type.ClrType); 
            }
            else 
            {
                if (type.NamespaceName == SourceEdmNamespaceName)
                {
                    // we are already generating in this namespace, no need to qualify it 
                    typeRef = type.Name;
                } 
                else 
                {
                    typeRef = CreateFullName(GetObjectNamespace(type.NamespaceName), type.Name); 
                }
            }

            return TypeReference.FromString(typeRef); 
        }
 
        public string SourceEdmNamespaceName 
        {
            get 
            {
                return _sourceSchema.Namespace;
            }
        } 

        public string SourceObjectNamespaceName 
        { 
            get
            { 
                return GetObjectNamespace(SourceEdmNamespaceName);
            }
        }
 
        private string GetObjectNamespace(string csdlNamespaceName)
        { 
            Debug.Assert(csdlNamespaceName != null, "csdlNamespaceName is null"); 

            string objectNamespace; 
            if (_generator.EdmToObjectNamespaceMap.TryGetObjectNamespace(csdlNamespaceName, out objectNamespace))
            {
                return objectNamespace;
            } 

            return csdlNamespaceName; 
        } 

 
        /// 
        ///
        /// 
        ///  
        internal FixUpCollection FixUps
        { 
            get 
            {
                if (_fixUps == null) 
                    _fixUps = new FixUpCollection();

                return _fixUps;
            } 
        }
 
        internal AttributeEmitter AttributeEmitter 
        {
            get { return _attributeEmitter; } 
        }

        internal bool IsLanguageCaseSensitive
        { 
            get { return _isLanguageCaseSensitive; }
        } 
 
        internal StringComparison LanguageAppropriateStringComparer
        { 
            get
            {
                if (IsLanguageCaseSensitive)
                { 
                    return StringComparison.Ordinal;
                } 
                else 
                {
                    return StringComparison.OrdinalIgnoreCase; 
                }
            }
        }
 
        /// 
        /// Helper method that raises the TypeGenerated event 
        ///  
        /// The event arguments passed to the subscriber
        internal void RaiseTypeGeneratedEvent(TypeGeneratedEventArgs eventArgs) 
        {
            _generator.RaiseTypeGeneratedEvent(eventArgs);
        }
 
        /// 
        /// Helper method that raises the PropertyGenerated event 
        ///  
        /// The event arguments passed to the subscriber
        internal void RaisePropertyGeneratedEvent(PropertyGeneratedEventArgs eventArgs) 
        {
            _generator.RaisePropertyGeneratedEvent(eventArgs);
        }
 
        #endregion
 
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK