ClientApiGenerator.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / ndp / fx / src / DataWeb / Design / system / Data / EntityModel / Emitters / ClientApiGenerator.cs / 4 / ClientApiGenerator.cs

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

using System.CodeDom; 
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.Data.Services.Design; 
using System.Data.EntityModel.Emitters;
using System.Data.EntityModel.SchemaObjectModel; 
using SOM = System.Data.EntityModel.SchemaObjectModel; 
using System.Data.Metadata.Edm;
using System.Diagnostics; 
using System.IO;
using System.Linq;

namespace System.Data.Metadata.Edm 
{
    internal static partial class Helper 
    { 
        internal static bool IsCollectionType(GlobalItem item)
        { 
            return (BuiltInTypeKind.CollectionType == item.BuiltInTypeKind);
        }
        internal static bool IsComplexType(EdmType type)
        { 
            return (BuiltInTypeKind.ComplexType == type.BuiltInTypeKind);
        } 
        internal static bool IsEntitySet(EntitySetBase entitySetBase) 
        {
            return BuiltInTypeKind.EntitySet == entitySetBase.BuiltInTypeKind; 
        }
        internal static bool IsPrimitiveType(EdmType type)
        {
            return (BuiltInTypeKind.PrimitiveType == type.BuiltInTypeKind); 
        }
    } 
 
    internal static class TypeSemantics
    { 
        internal static bool IsComplexType(TypeUsage type)
        {
            return Helper.IsComplexType(type.EdmType);
        } 
    }
 
    internal static class EdmProviderManifest 
    {
        // System Facet Info 
        /// 
        /// Name of the MaxLength Facet
        /// 
        internal const string MaxLengthFacetName = "MaxLength"; 

        ///  
        /// Name of the Unicode Facet 
        /// 
        internal const string UnicodeFacetName = "Unicode"; 

        /// 
        /// Name of the FixedLength Facet
        ///  
        internal const string FixedLengthFacetName = "FixedLength";
 
        ///  
        /// Name of the DateTimeKind Facet
        ///  
        internal const string DateTimeKindFacetName = "DateTimeKind";

        /// 
        /// Name of the PreserveSeconds Facet 
        /// 
        internal const string PreserveSecondsFacetName = "PreserveSeconds"; 
 
        /// 
        /// Name of the Precision Facet 
        /// 
        internal const string PrecisionFacetName = "Precision";

        ///  
        /// Name of the Scale Facet
        ///  
        internal const string ScaleFacetName = "Scale"; 

        ///  
        /// Name of the Nullable Facet
        /// 
        internal const string NullableFacetName = "Nullable";
 
        /// 
        /// Name of the DefaultValue Facet 
        ///  
        internal const string DefaultValueFacetName = "DefaultValue";
 
        ///// 
        ///// Name of the DefaultType metadata property
        ///// 
        //internal const string DefaultTypeMetadataPropertyName = "DefaultType"; 

        ///  
        /// Name of the Collation Facet 
        /// 
        internal const string CollationFacetName = "Collation"; 
    }

    internal static class TypeSystem
    { 
        private static readonly System.Reflection.MethodInfo s_getDefaultMethod = typeof(TypeSystem).GetMethod("GetDefault", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
        private static T GetDefault() { return default(T); } 
        internal static object GetDefaultValue(Type type) 
        {
            // null is always the default for non value types and Nullable<> 
            if (!type.IsValueType ||
                (type.IsGenericType &&
                 typeof(Nullable<>) == type.GetGenericTypeDefinition()))
            { 
                return null;
            } 
            System.Reflection.MethodInfo getDefaultMethod = s_getDefaultMethod.MakeGenericMethod(type); 
            object defaultValue = getDefaultMethod.Invoke(null, new object[] { });
            return defaultValue; 
        }
    }

    internal static class Schema 
    {
        public const string CodeGenerationSchemaNamespace = "http://schemas.microsoft.com/ado/2006/04/codegeneration"; 
    } 
}
 
namespace System.Data.EntityModel
{
    /// 
    /// Summary description for ClientApiGenerator. 
    /// 
    internal sealed class ClientApiGenerator 
    { 
        #region Instance Fields
        private CodeCompileUnit _compileUnit; 
        private bool _isLanguageCaseSensitive = true;

        private EdmItemCollection _edmItemCollection;
        private FixUpCollection _fixUps; 
        private AttributeEmitter _attributeEmitter;
        private EntityClassGenerator _generator; 
        private List _errors; 
        private TypeReference _typeReference = new TypeReference();
        private string _sourceEdmNamespaceName; 
        private string _defaultContainerNamespace;
        private string _namespacePrefix;
        private Dictionary _namespaceMap;
        #endregion 

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

            _edmItemCollection = edmItemCollection; 
            _generator = generator;
            _errors = errors; 
            _attributeEmitter = new AttributeEmitter(_typeReference); 
            _namespacePrefix = namespacePrefix;
 
            // generate map for inherited types and prefixed types
            _namespaceMap = new Dictionary();
        }
 
        internal EdmItemCollection EdmItemCollection
        { 
            get { return this._edmItemCollection; } 
        }
 
        public string NamespacePrefix
        {
            get { return this._namespacePrefix; }
        } 

        public Dictionary NamespaceMap 
        { 
            get { return this._namespaceMap; }
        } 

        /// 
        /// 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. 
        internal void GenerateCode(LazyTextWriterCreator target)
        {
            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, this.NamespacePrefix, 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, !String.IsNullOrEmpty(SourceObjectNamespaceName)); 
                }
            } 
            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( 
                                                        Identity(item), 
                                                        true   // ignore case
                                                    ); 
            }
            catch (InvalidOperationException ex)
            {
                AddError(ModelBuilderErrorCode.IncompatibleSettingForCaseSensitiveOption, EdmSchemaErrorSeverity.Error, ex); 
            }
        } 
 
        /// 
        /// 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(Identity(member)) &&
                    String.Equals(Identity(item), Identity(member), StringComparison.OrdinalIgnoreCase)) 
                {
                    AddError(ModelBuilderErrorCode.IncompatibleSettingForCaseSensitiveOption, EdmSchemaErrorSeverity.Error,
                                new InvalidOperationException(Strings.PropertyExistsWithDifferentCase(Identity(item))));
                } 
                else
                { 
                    set.Add(Identity(member)); 
                }
            } 
        }

        /// 
        /// 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 (Helper.IsEntitySet(entitySetBase))
                {
                    EntitySet entitySet = (EntitySet)entitySetBase; 
                    if (set.Contains(Identity(entitySet)))
                    { 
                        AddError(ModelBuilderErrorCode.IncompatibleSettingForCaseSensitiveOption, EdmSchemaErrorSeverity.Error, 
                                    new InvalidOperationException(Strings.EntitySetExistsWithDifferentCase(Identity(entitySet))));
                    } 
                    else
                    {
                        set.Add(Identity(entitySet));
                    } 
                }
            } 
        } 

        #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)
        {
        }
 
        public void AddError(ModelBuilderErrorCode errorCode, EdmSchemaErrorSeverity severity, Exception ex)
        { 
        } 

        internal void AddError(string message, ModelBuilderErrorCode errorCode, EdmSchemaErrorSeverity severity, Exception ex) 
        {
        }

        ///  
        /// 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 (EntityContainer container in _edmItemCollection.GetItems()) 
            {
                BuiltInTypeKind kind = container.BuiltInTypeKind; 
                yield return container; 
            }
 
            foreach (EdmType item in _edmItemCollection.GetItems())
            {
                switch (item.BuiltInTypeKind)
                { 
                    case BuiltInTypeKind.AssociationType:
                    case BuiltInTypeKind.ComplexType: 
                    case BuiltInTypeKind.EntityType: 
                        yield return item;
                        break; 
                    case BuiltInTypeKind.EdmFunction:
                    case BuiltInTypeKind.PrimitiveType:
                        break;
                    default: 
                        Debug.Assert(false, item.BuiltInTypeKind.ToString());
                        break; 
                } 
            }
        } 

        public string GetClientTypeNamespace(string serviceTypeNamespace)
        {
            if (string.IsNullOrEmpty(this.NamespacePrefix)) return serviceTypeNamespace; 

            if (string.IsNullOrEmpty(serviceTypeNamespace) || 
                ((this.DefaultContainerNamespace != null) && (this.DefaultContainerNamespace == serviceTypeNamespace))) 
            {
                return this.NamespacePrefix; 
            }
            else
            {
                return this.NamespacePrefix + "." + serviceTypeNamespace; 
            }
        } 
 
        public string GetContainerNamespace(EntityContainer container)
        { 
            if (container == null) return null;

            string namespaceName = null;
            EntitySetBase baseEntitySet = container.BaseEntitySets.FirstOrDefault(); 
            if (null != baseEntitySet)
            { 
                namespaceName = baseEntitySet.ElementType.NamespaceName; 
            }
 
            return namespaceName;
        }

        public CodeTypeReference GetLeastPossibleQualifiedTypeReference(EdmType type) 
        {
            string typeRef; 
            string clientNamespace = GetClientTypeNamespace(type.NamespaceName); 
            if (clientNamespace == SourceEdmNamespaceName)
            { 
                // we are already generating in this namespace, no need to qualify it
                typeRef = type.Name;
            }
            else 
            {
                typeRef = GetObjectNamespace(clientNamespace) + "." + type.Name; 
            } 

            return TypeReference.FromString(typeRef); 
        }

        public string SourceEdmNamespaceName
        { 
            get
            { 
                if (null != _sourceEdmNamespaceName) 
                {
                    return _sourceEdmNamespaceName; 
                }

                //
                foreach (GlobalItem item in GetSourceTypes()) 
                {
                    EdmType edm = item as EdmType; 
                    if (null != edm) 
                    {
                        return edm.NamespaceName; 
                    }
                }

                return null; 
            }
            set 
            { 
                _sourceEdmNamespaceName = value;
            } 
        }

        public string DefaultContainerNamespace
        { 
            get { return _defaultContainerNamespace; }
            set { _defaultContainerNamespace = value; } 
        } 

        public string SourceObjectNamespaceName 
        {
            get
            {
                string sourceEdmNamespaceName = SourceEdmNamespaceName; 
                if (!String.IsNullOrEmpty(sourceEdmNamespaceName))
                { 
                    return GetObjectNamespace(sourceEdmNamespaceName); 
                }
 
                return null;
            }
        }
 
        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
 
        private static string Identity(EdmMember member) 
        {
            return member.ToString(); 
        }
        private static string Identity(EntitySetBase entitySet)
        {
            return entitySet.ToString(); 
        }
        private static string Identity(MetadataItem item) 
        { 
            return item.ToString();
        } 
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner       [....]
// @backupOwner [....] 
//--------------------------------------------------------------------- 

using System.CodeDom; 
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.Data.Services.Design; 
using System.Data.EntityModel.Emitters;
using System.Data.EntityModel.SchemaObjectModel; 
using SOM = System.Data.EntityModel.SchemaObjectModel; 
using System.Data.Metadata.Edm;
using System.Diagnostics; 
using System.IO;
using System.Linq;

namespace System.Data.Metadata.Edm 
{
    internal static partial class Helper 
    { 
        internal static bool IsCollectionType(GlobalItem item)
        { 
            return (BuiltInTypeKind.CollectionType == item.BuiltInTypeKind);
        }
        internal static bool IsComplexType(EdmType type)
        { 
            return (BuiltInTypeKind.ComplexType == type.BuiltInTypeKind);
        } 
        internal static bool IsEntitySet(EntitySetBase entitySetBase) 
        {
            return BuiltInTypeKind.EntitySet == entitySetBase.BuiltInTypeKind; 
        }
        internal static bool IsPrimitiveType(EdmType type)
        {
            return (BuiltInTypeKind.PrimitiveType == type.BuiltInTypeKind); 
        }
    } 
 
    internal static class TypeSemantics
    { 
        internal static bool IsComplexType(TypeUsage type)
        {
            return Helper.IsComplexType(type.EdmType);
        } 
    }
 
    internal static class EdmProviderManifest 
    {
        // System Facet Info 
        /// 
        /// Name of the MaxLength Facet
        /// 
        internal const string MaxLengthFacetName = "MaxLength"; 

        ///  
        /// Name of the Unicode Facet 
        /// 
        internal const string UnicodeFacetName = "Unicode"; 

        /// 
        /// Name of the FixedLength Facet
        ///  
        internal const string FixedLengthFacetName = "FixedLength";
 
        ///  
        /// Name of the DateTimeKind Facet
        ///  
        internal const string DateTimeKindFacetName = "DateTimeKind";

        /// 
        /// Name of the PreserveSeconds Facet 
        /// 
        internal const string PreserveSecondsFacetName = "PreserveSeconds"; 
 
        /// 
        /// Name of the Precision Facet 
        /// 
        internal const string PrecisionFacetName = "Precision";

        ///  
        /// Name of the Scale Facet
        ///  
        internal const string ScaleFacetName = "Scale"; 

        ///  
        /// Name of the Nullable Facet
        /// 
        internal const string NullableFacetName = "Nullable";
 
        /// 
        /// Name of the DefaultValue Facet 
        ///  
        internal const string DefaultValueFacetName = "DefaultValue";
 
        ///// 
        ///// Name of the DefaultType metadata property
        ///// 
        //internal const string DefaultTypeMetadataPropertyName = "DefaultType"; 

        ///  
        /// Name of the Collation Facet 
        /// 
        internal const string CollationFacetName = "Collation"; 
    }

    internal static class TypeSystem
    { 
        private static readonly System.Reflection.MethodInfo s_getDefaultMethod = typeof(TypeSystem).GetMethod("GetDefault", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
        private static T GetDefault() { return default(T); } 
        internal static object GetDefaultValue(Type type) 
        {
            // null is always the default for non value types and Nullable<> 
            if (!type.IsValueType ||
                (type.IsGenericType &&
                 typeof(Nullable<>) == type.GetGenericTypeDefinition()))
            { 
                return null;
            } 
            System.Reflection.MethodInfo getDefaultMethod = s_getDefaultMethod.MakeGenericMethod(type); 
            object defaultValue = getDefaultMethod.Invoke(null, new object[] { });
            return defaultValue; 
        }
    }

    internal static class Schema 
    {
        public const string CodeGenerationSchemaNamespace = "http://schemas.microsoft.com/ado/2006/04/codegeneration"; 
    } 
}
 
namespace System.Data.EntityModel
{
    /// 
    /// Summary description for ClientApiGenerator. 
    /// 
    internal sealed class ClientApiGenerator 
    { 
        #region Instance Fields
        private CodeCompileUnit _compileUnit; 
        private bool _isLanguageCaseSensitive = true;

        private EdmItemCollection _edmItemCollection;
        private FixUpCollection _fixUps; 
        private AttributeEmitter _attributeEmitter;
        private EntityClassGenerator _generator; 
        private List _errors; 
        private TypeReference _typeReference = new TypeReference();
        private string _sourceEdmNamespaceName; 
        private string _defaultContainerNamespace;
        private string _namespacePrefix;
        private Dictionary _namespaceMap;
        #endregion 

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

            _edmItemCollection = edmItemCollection; 
            _generator = generator;
            _errors = errors; 
            _attributeEmitter = new AttributeEmitter(_typeReference); 
            _namespacePrefix = namespacePrefix;
 
            // generate map for inherited types and prefixed types
            _namespaceMap = new Dictionary();
        }
 
        internal EdmItemCollection EdmItemCollection
        { 
            get { return this._edmItemCollection; } 
        }
 
        public string NamespacePrefix
        {
            get { return this._namespacePrefix; }
        } 

        public Dictionary NamespaceMap 
        { 
            get { return this._namespaceMap; }
        } 

        /// 
        /// 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. 
        internal void GenerateCode(LazyTextWriterCreator target)
        {
            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, this.NamespacePrefix, 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, !String.IsNullOrEmpty(SourceObjectNamespaceName)); 
                }
            } 
            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( 
                                                        Identity(item), 
                                                        true   // ignore case
                                                    ); 
            }
            catch (InvalidOperationException ex)
            {
                AddError(ModelBuilderErrorCode.IncompatibleSettingForCaseSensitiveOption, EdmSchemaErrorSeverity.Error, ex); 
            }
        } 
 
        /// 
        /// 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(Identity(member)) &&
                    String.Equals(Identity(item), Identity(member), StringComparison.OrdinalIgnoreCase)) 
                {
                    AddError(ModelBuilderErrorCode.IncompatibleSettingForCaseSensitiveOption, EdmSchemaErrorSeverity.Error,
                                new InvalidOperationException(Strings.PropertyExistsWithDifferentCase(Identity(item))));
                } 
                else
                { 
                    set.Add(Identity(member)); 
                }
            } 
        }

        /// 
        /// 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 (Helper.IsEntitySet(entitySetBase))
                {
                    EntitySet entitySet = (EntitySet)entitySetBase; 
                    if (set.Contains(Identity(entitySet)))
                    { 
                        AddError(ModelBuilderErrorCode.IncompatibleSettingForCaseSensitiveOption, EdmSchemaErrorSeverity.Error, 
                                    new InvalidOperationException(Strings.EntitySetExistsWithDifferentCase(Identity(entitySet))));
                    } 
                    else
                    {
                        set.Add(Identity(entitySet));
                    } 
                }
            } 
        } 

        #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)
        {
        }
 
        public void AddError(ModelBuilderErrorCode errorCode, EdmSchemaErrorSeverity severity, Exception ex)
        { 
        } 

        internal void AddError(string message, ModelBuilderErrorCode errorCode, EdmSchemaErrorSeverity severity, Exception ex) 
        {
        }

        ///  
        /// 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 (EntityContainer container in _edmItemCollection.GetItems()) 
            {
                BuiltInTypeKind kind = container.BuiltInTypeKind; 
                yield return container; 
            }
 
            foreach (EdmType item in _edmItemCollection.GetItems())
            {
                switch (item.BuiltInTypeKind)
                { 
                    case BuiltInTypeKind.AssociationType:
                    case BuiltInTypeKind.ComplexType: 
                    case BuiltInTypeKind.EntityType: 
                        yield return item;
                        break; 
                    case BuiltInTypeKind.EdmFunction:
                    case BuiltInTypeKind.PrimitiveType:
                        break;
                    default: 
                        Debug.Assert(false, item.BuiltInTypeKind.ToString());
                        break; 
                } 
            }
        } 

        public string GetClientTypeNamespace(string serviceTypeNamespace)
        {
            if (string.IsNullOrEmpty(this.NamespacePrefix)) return serviceTypeNamespace; 

            if (string.IsNullOrEmpty(serviceTypeNamespace) || 
                ((this.DefaultContainerNamespace != null) && (this.DefaultContainerNamespace == serviceTypeNamespace))) 
            {
                return this.NamespacePrefix; 
            }
            else
            {
                return this.NamespacePrefix + "." + serviceTypeNamespace; 
            }
        } 
 
        public string GetContainerNamespace(EntityContainer container)
        { 
            if (container == null) return null;

            string namespaceName = null;
            EntitySetBase baseEntitySet = container.BaseEntitySets.FirstOrDefault(); 
            if (null != baseEntitySet)
            { 
                namespaceName = baseEntitySet.ElementType.NamespaceName; 
            }
 
            return namespaceName;
        }

        public CodeTypeReference GetLeastPossibleQualifiedTypeReference(EdmType type) 
        {
            string typeRef; 
            string clientNamespace = GetClientTypeNamespace(type.NamespaceName); 
            if (clientNamespace == SourceEdmNamespaceName)
            { 
                // we are already generating in this namespace, no need to qualify it
                typeRef = type.Name;
            }
            else 
            {
                typeRef = GetObjectNamespace(clientNamespace) + "." + type.Name; 
            } 

            return TypeReference.FromString(typeRef); 
        }

        public string SourceEdmNamespaceName
        { 
            get
            { 
                if (null != _sourceEdmNamespaceName) 
                {
                    return _sourceEdmNamespaceName; 
                }

                //
                foreach (GlobalItem item in GetSourceTypes()) 
                {
                    EdmType edm = item as EdmType; 
                    if (null != edm) 
                    {
                        return edm.NamespaceName; 
                    }
                }

                return null; 
            }
            set 
            { 
                _sourceEdmNamespaceName = value;
            } 
        }

        public string DefaultContainerNamespace
        { 
            get { return _defaultContainerNamespace; }
            set { _defaultContainerNamespace = value; } 
        } 

        public string SourceObjectNamespaceName 
        {
            get
            {
                string sourceEdmNamespaceName = SourceEdmNamespaceName; 
                if (!String.IsNullOrEmpty(sourceEdmNamespaceName))
                { 
                    return GetObjectNamespace(sourceEdmNamespaceName); 
                }
 
                return null;
            }
        }
 
        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
 
        private static string Identity(EdmMember member) 
        {
            return member.ToString(); 
        }
        private static string Identity(EntitySetBase entitySet)
        {
            return entitySet.ToString(); 
        }
        private static string Identity(MetadataItem item) 
        { 
            return item.ToString();
        } 
    }
}

// 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