You've already forked linux-packaging-mono
Imported Upstream version 4.6.0.125
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
This commit is contained in:
parent
a569aebcfd
commit
e79aa3c0ed
@ -0,0 +1,396 @@
|
||||
//---------------------------------------------------------------------
|
||||
// <copyright file="EntityClassGenerator.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//
|
||||
// @owner [....]
|
||||
// @backupOwner [....]
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Data;
|
||||
using System.Data.EntityModel.SchemaObjectModel;
|
||||
using System.Data.Metadata.Edm;
|
||||
using System.Data.EntityModel;
|
||||
using System.Data.Entity.Design.Common;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using System.Data.Entity.Design.SsdlGenerator;
|
||||
using Microsoft.Build.Utilities;
|
||||
using System.Runtime.Versioning;
|
||||
|
||||
namespace System.Data.Entity.Design
|
||||
{
|
||||
/// <summary>
|
||||
/// Event handler for the OnTypeGenerated event
|
||||
/// </summary>
|
||||
/// <param name="sender">The source of the event</param>
|
||||
/// <param name="e">The event args</param>
|
||||
public delegate void TypeGeneratedEventHandler(object sender, TypeGeneratedEventArgs e);
|
||||
|
||||
/// <summary>
|
||||
/// Event handler for the OnPropertyGenerated event
|
||||
/// </summary>
|
||||
/// <param name="sender">The source of the event</param>
|
||||
/// <param name="e">The event args</param>
|
||||
public delegate void PropertyGeneratedEventHandler(object sender, PropertyGeneratedEventArgs e);
|
||||
|
||||
/// <summary>
|
||||
/// Summary description for CodeGenerator.
|
||||
/// </summary>
|
||||
public sealed class EntityClassGenerator
|
||||
{
|
||||
#region Instance Fields
|
||||
LanguageOption _languageOption = LanguageOption.GenerateCSharpCode;
|
||||
EdmToObjectNamespaceMap _edmToObjectNamespaceMap = new EdmToObjectNamespaceMap();
|
||||
#endregion
|
||||
|
||||
#region Events
|
||||
|
||||
/// <summary>
|
||||
/// The event that is raised when a type is generated
|
||||
/// </summary>
|
||||
public event TypeGeneratedEventHandler OnTypeGenerated;
|
||||
|
||||
/// <summary>
|
||||
/// The event that is raised when a property is generated
|
||||
/// </summary>
|
||||
public event PropertyGeneratedEventHandler OnPropertyGenerated;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Methods
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public EntityClassGenerator()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public EntityClassGenerator(LanguageOption languageOption)
|
||||
{
|
||||
_languageOption = EDesignUtil.CheckLanguageOptionArgument(languageOption, "languageOption");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets and Sets the Language to use for code generation.
|
||||
/// </summary>
|
||||
public LanguageOption LanguageOption
|
||||
{
|
||||
get { return _languageOption; }
|
||||
set { _languageOption = EDesignUtil.CheckLanguageOptionArgument(value, "value"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the map entries use to customize the namespace of .net types that are generated
|
||||
/// and referenced by the generated code
|
||||
/// </summary>
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Edm")]
|
||||
public EdmToObjectNamespaceMap EdmToObjectNamespaceMap
|
||||
{
|
||||
get { return _edmToObjectNamespaceMap; }
|
||||
}
|
||||
|
||||
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Edm")]
|
||||
public IList<EdmSchemaError> GenerateCode(XmlReader sourceEdmSchema, TextWriter target)
|
||||
{
|
||||
EDesignUtil.CheckArgumentNull(sourceEdmSchema, "sourceEdmSchema");
|
||||
EDesignUtil.CheckArgumentNull(target, "target");
|
||||
return GenerateCode(sourceEdmSchema, target, new XmlReader[] { });
|
||||
}
|
||||
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Edm")]
|
||||
[ResourceExposure(ResourceScope.None)] //No resource is exposed since we pass in null as the target paath.
|
||||
[ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] //For GenerateCodeCommon method call. Since we use null as the path, we have not changed the scope of the resource.
|
||||
public IList<EdmSchemaError> GenerateCode(XmlReader sourceEdmSchema, TextWriter target, IEnumerable<XmlReader> additionalEdmSchemas)
|
||||
{
|
||||
EDesignUtil.CheckArgumentNull(sourceEdmSchema, "sourceEdmSchema");
|
||||
EDesignUtil.CheckArgumentNull(additionalEdmSchemas, "additionalEdmSchemas");
|
||||
EDesignUtil.CheckArgumentNull(target, "target");
|
||||
|
||||
List<EdmSchemaError> errors = new List<EdmSchemaError>();
|
||||
try
|
||||
{
|
||||
MetadataArtifactLoader sourceLoader = new MetadataArtifactLoaderXmlReaderWrapper(sourceEdmSchema);
|
||||
List<MetadataArtifactLoader> loaders = new List<MetadataArtifactLoader>();
|
||||
loaders.Add(sourceLoader);
|
||||
|
||||
int index = 0;
|
||||
foreach (XmlReader additionalEdmSchema in additionalEdmSchemas)
|
||||
{
|
||||
if (additionalEdmSchema == null)
|
||||
{
|
||||
throw EDesignUtil.Argument(Strings.NullAdditionalSchema("additionalEdmSchema", index));
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
MetadataArtifactLoader loader = new MetadataArtifactLoaderXmlReaderWrapper(additionalEdmSchema);
|
||||
Debug.Assert(loader != null, "when is the loader ever null?");
|
||||
loaders.Add(loader);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (MetadataUtil.IsCatchableExceptionType(e))
|
||||
{
|
||||
errors.Add(new EdmSchemaError(e.Message,
|
||||
(int)ModelBuilderErrorCode.CodeGenAdditionalEdmSchemaIsInvalid,
|
||||
EdmSchemaErrorSeverity.Error));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
index++;
|
||||
}
|
||||
ThrowOnAnyNonWarningErrors(errors);
|
||||
|
||||
GenerateCodeCommon(sourceLoader,
|
||||
loaders,
|
||||
new LazyTextWriterCreator(target),
|
||||
null, // source path
|
||||
null, // target file path
|
||||
false, // dispose readers?
|
||||
errors);
|
||||
}
|
||||
catch (TerminalErrorException)
|
||||
{
|
||||
// do nothing
|
||||
// just a place to jump when errors are detected
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Edm")]
|
||||
[ResourceExposure(ResourceScope.Machine)] //Exposes the sourceEdmSchemaFilePath which is a Machine resource
|
||||
[ResourceConsumption(ResourceScope.Machine)] //For GenerateCode method call. But the path is not created in this method.
|
||||
public IList<EdmSchemaError> GenerateCode(string sourceEdmSchemaFilePath, string targetFilePath)
|
||||
{
|
||||
return GenerateCode(sourceEdmSchemaFilePath, targetFilePath, new string[] { });
|
||||
}
|
||||
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Edm")]
|
||||
[ResourceExposure(ResourceScope.Machine)] //Exposes the sourceEdmSchemaFilePath which is a Machine resource
|
||||
[ResourceConsumption(ResourceScope.Machine)] //For MetadataArtifactLoader.Create method call. But the path is not created in this method.
|
||||
public IList<EdmSchemaError> GenerateCode(string sourceEdmSchemaFilePath, string targetPath, IEnumerable<string> additionalEdmSchemaFilePaths)
|
||||
{
|
||||
EDesignUtil.CheckStringArgument(sourceEdmSchemaFilePath, "sourceEdmSchemaFilePath");
|
||||
EDesignUtil.CheckArgumentNull(additionalEdmSchemaFilePaths, "additionalEdmSchemaFilePaths");
|
||||
EDesignUtil.CheckStringArgument(targetPath, "targetPath");
|
||||
|
||||
List<EdmSchemaError> errors = new List<EdmSchemaError>();
|
||||
try
|
||||
{
|
||||
// create a loader for the source
|
||||
HashSet<string> uriRegistry = new HashSet<string>();
|
||||
MetadataArtifactLoader sourceLoader;
|
||||
try
|
||||
{
|
||||
sourceLoader = MetadataArtifactLoader.Create(sourceEdmSchemaFilePath, MetadataArtifactLoader.ExtensionCheck.Specific,
|
||||
XmlConstants.CSpaceSchemaExtension, uriRegistry);
|
||||
}
|
||||
catch (MetadataException e)
|
||||
{
|
||||
errors.Add(CreateErrorForException(ModelBuilderErrorCode.CodeGenSourceFilePathIsInvalid, e, sourceEdmSchemaFilePath));
|
||||
return errors;
|
||||
}
|
||||
|
||||
if (sourceLoader.IsComposite)
|
||||
{
|
||||
throw new ArgumentException(Strings.CodeGenSourceFilePathIsNotAFile, "sourceEdmSchemaPath");
|
||||
}
|
||||
|
||||
// create loaders for all the additional schemas
|
||||
List<MetadataArtifactLoader> loaders = new List<MetadataArtifactLoader>();
|
||||
loaders.Add(sourceLoader);
|
||||
int index = 0;
|
||||
foreach (string additionalSchemaFilePath in additionalEdmSchemaFilePaths)
|
||||
{
|
||||
if (additionalSchemaFilePath == null)
|
||||
{
|
||||
throw EDesignUtil.Argument(Strings.NullAdditionalSchema("additionalEdmSchemaFilePaths", index));
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
MetadataArtifactLoader loader = MetadataArtifactLoader.Create(additionalSchemaFilePath,
|
||||
MetadataArtifactLoader.ExtensionCheck.Specific,
|
||||
XmlConstants.CSpaceSchemaExtension, uriRegistry);
|
||||
Debug.Assert(loader != null, "when is the loader ever null?");
|
||||
loaders.Add(loader);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if(MetadataUtil.IsCatchableExceptionType(e))
|
||||
{
|
||||
errors.Add(CreateErrorForException(ModelBuilderErrorCode.CodeGenAdditionalEdmSchemaIsInvalid, e, additionalSchemaFilePath));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
ThrowOnAnyNonWarningErrors(errors);
|
||||
try
|
||||
{
|
||||
using (LazyTextWriterCreator target = new LazyTextWriterCreator(targetPath))
|
||||
{
|
||||
GenerateCodeCommon(sourceLoader, loaders, target, sourceEdmSchemaFilePath, targetPath,
|
||||
true, // dispose readers
|
||||
errors);
|
||||
}
|
||||
}
|
||||
catch (System.IO.IOException ex)
|
||||
{
|
||||
errors.Add(CreateErrorForException(System.Data.EntityModel.SchemaObjectModel.ErrorCode.IOException, ex, targetPath));
|
||||
return errors;
|
||||
}
|
||||
}
|
||||
catch (TerminalErrorException)
|
||||
{
|
||||
// do nothing
|
||||
// just a place to jump when errors are detected
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
private void GenerateCodeCommon(MetadataArtifactLoader sourceLoader,
|
||||
List<MetadataArtifactLoader> loaders,
|
||||
LazyTextWriterCreator target,
|
||||
string sourceEdmSchemaFilePath,
|
||||
string targetFilePath,
|
||||
bool closeReaders,
|
||||
List<EdmSchemaError> errors)
|
||||
{
|
||||
MetadataArtifactLoaderComposite composite = new MetadataArtifactLoaderComposite(loaders);
|
||||
|
||||
// create the schema manager from the xml readers
|
||||
Dictionary<MetadataArtifactLoader, XmlReader> readerSourceMap = new Dictionary<MetadataArtifactLoader, XmlReader>();
|
||||
IList<Schema> schemas;
|
||||
List<XmlReader> readers = composite.GetReaders(readerSourceMap);
|
||||
|
||||
try
|
||||
{
|
||||
IList<EdmSchemaError> schemaManagerErrors =
|
||||
SchemaManager.ParseAndValidate(readers,
|
||||
composite.GetPaths(),
|
||||
SchemaDataModelOption.EntityDataModel,
|
||||
EdmProviderManifest.Instance,
|
||||
out schemas);
|
||||
errors.AddRange(schemaManagerErrors);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (closeReaders)
|
||||
{
|
||||
MetadataUtil.DisposeXmlReaders(readers);
|
||||
}
|
||||
}
|
||||
ThrowOnAnyNonWarningErrors(errors);
|
||||
Debug.Assert(readerSourceMap.ContainsKey(sourceLoader), "the source loader didn't produce any of the xml readers...");
|
||||
XmlReader sourceReader = readerSourceMap[sourceLoader];
|
||||
|
||||
|
||||
// use the index of the "source" xml reader as the index of the "source" schema
|
||||
Debug.Assert(readers.Contains(sourceReader), "the source reader is not in the list of readers");
|
||||
int index = readers.IndexOf(sourceReader);
|
||||
Debug.Assert(index >= 0, "couldn't find the source reader in the list of readers");
|
||||
|
||||
Debug.Assert(readers.Count == schemas.Count, "We have a different number of readers than schemas");
|
||||
Schema sourceSchema = schemas[index];
|
||||
Debug.Assert(sourceSchema != null, "sourceSchema is null");
|
||||
|
||||
// create the EdmItemCollection from the schemas
|
||||
EdmItemCollection itemCollection = new EdmItemCollection(schemas);
|
||||
if (EntityFrameworkVersionsUtil.ConvertToVersion(itemCollection.EdmVersion) >= EntityFrameworkVersions.Version2)
|
||||
{
|
||||
throw EDesignUtil.InvalidOperation(Strings.TargetEntityFrameworkVersionToNewForEntityClassGenerator);
|
||||
}
|
||||
|
||||
// generate code
|
||||
ClientApiGenerator generator = new ClientApiGenerator(sourceSchema, itemCollection, this, errors);
|
||||
generator.GenerateCode(target, targetFilePath);
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Methods
|
||||
private static EdmSchemaError CreateErrorForException(System.Data.EntityModel.SchemaObjectModel.ErrorCode errorCode, System.Exception exception, string sourceLocation)
|
||||
{
|
||||
Debug.Assert(exception != null);
|
||||
Debug.Assert(sourceLocation != null);
|
||||
|
||||
return new EdmSchemaError(exception.Message, (int)errorCode, EdmSchemaErrorSeverity.Error, sourceLocation, 0, 0, exception);
|
||||
}
|
||||
|
||||
internal static EdmSchemaError CreateErrorForException(ModelBuilderErrorCode errorCode, System.Exception exception, string sourceLocation)
|
||||
{
|
||||
Debug.Assert(exception != null);
|
||||
Debug.Assert(sourceLocation != null);
|
||||
|
||||
return new EdmSchemaError(exception.Message, (int)errorCode, EdmSchemaErrorSeverity.Error, sourceLocation, 0, 0, exception);
|
||||
}
|
||||
|
||||
internal static EdmSchemaError CreateErrorForException(ModelBuilderErrorCode errorCode, System.Exception exception)
|
||||
{
|
||||
Debug.Assert(exception != null);
|
||||
|
||||
return new EdmSchemaError(exception.Message, (int)errorCode, EdmSchemaErrorSeverity.Error, null, 0, 0, exception);
|
||||
}
|
||||
|
||||
private void ThrowOnAnyNonWarningErrors(List<EdmSchemaError> errors)
|
||||
{
|
||||
foreach (EdmSchemaError error in errors)
|
||||
{
|
||||
if (error.Severity != EdmSchemaErrorSeverity.Warning)
|
||||
{
|
||||
throw new TerminalErrorException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Event Helpers
|
||||
|
||||
/// <summary>
|
||||
/// Helper method that raises the TypeGenerated event
|
||||
/// </summary>
|
||||
/// <param name="eventArgs">The event arguments passed to the subscriber</param>
|
||||
internal void RaiseTypeGeneratedEvent(TypeGeneratedEventArgs eventArgs)
|
||||
{
|
||||
if (this.OnTypeGenerated != null)
|
||||
{
|
||||
this.OnTypeGenerated(this, eventArgs);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper method that raises the PropertyGenerated event
|
||||
/// </summary>
|
||||
/// <param name="eventArgs">The event arguments passed to the subscriber</param>
|
||||
internal void RaisePropertyGeneratedEvent(PropertyGeneratedEventArgs eventArgs)
|
||||
{
|
||||
if (this.OnPropertyGenerated != null)
|
||||
{
|
||||
this.OnPropertyGenerated(this, eventArgs);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user