Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataEntity / System / Data / EntityModel / SchemaObjectModel / SchemaManager.cs / 1305376 / SchemaManager.cs
//----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// @owner [....]
// @backupOwner [....]
//---------------------------------------------------------------------
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Data.Metadata.Edm;
using System.Data.Common.Utils;
using System.Xml;
using System.Data.Common;
using System.Data.Entity;
using System.Linq;
namespace System.Data.EntityModel.SchemaObjectModel
{
internal delegate void AttributeValueNotification(string token, Action addError);
internal delegate DbProviderManifest ProviderManifestNeeded(Action addError);
///
/// Class responsible for parsing,validating a collection of schema
///
[System.Diagnostics.DebuggerDisplay("DataModel={DataModel}")]
internal class SchemaManager
{
#region Instance Fields
// This keeps track of all the possible namespaces encountered till now. This helps in displaying the error to the
// user - if the particular type is not found, we can report whether the namespace was invalid or the type with the
// given name was not found in the given namespace. This also helps in validating the namespace in the using elements
private readonly HashSet _namespaceLookUpTable = new HashSet(StringComparer.Ordinal);
// List of all the schema types across all the schemas. This is to ensure that there is no duplicate type encountered
// across schemas
private readonly SchemaElementLookUpTable _schemaTypes = new SchemaElementLookUpTable();
// We want to stop parsing/resolving/validation after the first 100 errors
private const int MaxErrorCount = 100;
// delay loaded
private DbProviderManifest _providerManifest;
private PrimitiveSchema _primitiveSchema;
private readonly SchemaDataModelOption _dataModel;
private readonly ProviderManifestNeeded _providerManifestNeeded;
private readonly AttributeValueNotification _providerNotification;
private readonly AttributeValueNotification _providerManifestTokenNotification;
#endregion
#region Constructor
private SchemaManager(SchemaDataModelOption dataModel, AttributeValueNotification providerNotification, AttributeValueNotification providerManifestTokenNotification, ProviderManifestNeeded providerManifestNeeded)
{
_dataModel = dataModel;
_providerNotification = providerNotification;
_providerManifestTokenNotification = providerManifestTokenNotification;
_providerManifestNeeded = providerManifestNeeded;
}
#endregion
#region Public Methods
public static IList LoadProviderManifest(XmlReader xmlReader, string location,
bool checkForSystemNamespace, out Schema schema)
{
IList schemaCollection = new List(1);
DbProviderManifest providerManifest = checkForSystemNamespace ? EdmProviderManifest.Instance : null;
IList errors = ParseAndValidate(new XmlReader[] { xmlReader },
new string[] { location }, SchemaDataModelOption.ProviderManifestModel,
providerManifest, out schemaCollection);
// In case of errors, there are no schema in the schema collection
if (schemaCollection.Count != 0)
{
schema = schemaCollection[0];
}
else
{
Debug.Assert(errors.Count != 0, "There must be some error encountered");
schema = null;
}
return errors;
}
public static void NoOpAttributeValueNotification(string attributeValue, Action addError) { }
public static IList ParseAndValidate(IEnumerable xmlReaders,
IEnumerable sourceFilePaths, SchemaDataModelOption dataModel,
DbProviderManifest providerManifest,
out IList schemaCollection)
{
return ParseAndValidate(xmlReaders,
sourceFilePaths,
dataModel,
NoOpAttributeValueNotification,
NoOpAttributeValueNotification,
delegate(Action addError) { return providerManifest == null ? MetadataItem.EdmProviderManifest : providerManifest; },
out schemaCollection);
}
public static IList ParseAndValidate(IEnumerable xmlReaders,
IEnumerable sourceFilePaths, SchemaDataModelOption dataModel,
AttributeValueNotification providerNotification,
AttributeValueNotification providerManifestTokenNotification,
ProviderManifestNeeded providerManifestNeeded,
out IList schemaCollection)
{
SchemaManager schemaManager = new SchemaManager(dataModel, providerNotification, providerManifestTokenNotification, providerManifestNeeded);
var errorCollection = new List();
schemaCollection = new List();
bool errorEncountered = false;
List filePathList;
if (sourceFilePaths != null)
{
filePathList = new List(sourceFilePaths);
}
else
{
filePathList = new List();
}
int index = 0;
foreach (XmlReader xmlReader in xmlReaders)
{
string location = null;
if (filePathList.Count <= index)
{
TryGetBaseUri(xmlReader, out location);
}
else
{
location = filePathList[index];
}
Schema schema;
schema = new Schema(schemaManager);
var errorsForCurrentSchema = schema.Parse(xmlReader, location);
CheckIsSameVersion(schema, schemaCollection, errorCollection);
// If the number of errors exceeded the max error count, then return
if (UpdateErrorCollectionAndCheckForMaxErrors(errorCollection, errorsForCurrentSchema, ref errorEncountered))
{
return errorCollection;
}
// Add the schema to the collection if there are no errors. There are errors in which schema do not have any namespace.
// Also if there is an error encountered in one of the schema, we do not need to add the remaining schemas since
// we will never go to the resolve phase.
if (!errorEncountered)
{
schemaCollection.Add(schema);
schemaManager.AddSchema(schema);
var currentSchemaVersion = schema.SchemaVersion;
Debug.Assert(schemaCollection.All(s => s.SchemaVersion == currentSchemaVersion || s.SchemaVersion != XmlConstants.UndefinedVersion));
}
index++;
}
// If there are no errors encountered in the parsing stage, we can proceed to the
// parsing and validating phase
if (!errorEncountered)
{
foreach (Schema schema in schemaCollection)
{
if (UpdateErrorCollectionAndCheckForMaxErrors(errorCollection, schema.Resolve(), ref errorEncountered))
{
return errorCollection;
}
}
// If there are no errors encountered in the parsing stage, we can proceed to the
// parsing and validating phase
if (!errorEncountered)
{
foreach (Schema schema in schemaCollection)
{
if (UpdateErrorCollectionAndCheckForMaxErrors(errorCollection, schema.ValidateSchema(), ref errorEncountered))
{
return errorCollection;
}
}
}
}
return errorCollection;
}
private static bool CheckIsSameVersion(Schema schemaToBeAdded, IEnumerable schemaCollection, List errorCollection)
{
if (schemaToBeAdded.SchemaVersion != XmlConstants.UndefinedVersion && schemaCollection.Count() > 0)
{
if (schemaCollection.Any(s => s.SchemaVersion != XmlConstants.UndefinedVersion && s.SchemaVersion != schemaToBeAdded.SchemaVersion))
{
errorCollection.Add(
new EdmSchemaError(
Strings.CannotLoadDifferentVersionOfSchemaInTheSameItemCollection,
(int)ErrorCode.CannotLoadDifferentVersionOfSchemaInTheSameItemCollection,
EdmSchemaErrorSeverity.Error));
}
}
return true;
}
///
/// Add the namespace of the given schema to the namespace lookup table
///
public void AddSchema(Schema schema)
{
Debug.Assert(schema.DataModel == _dataModel, "DataModel must match");
if (_namespaceLookUpTable.Count == 0 && schema.DataModel != SchemaDataModelOption.ProviderManifestModel)
{
// Add the primitive type namespace to the namespace look up table
if (this.PrimitiveSchema.Namespace != null)
{
_namespaceLookUpTable.Add(this.PrimitiveSchema.Namespace);
}
}
// Add the namespace to the namespaceLookUpTable.
// Its okay to have multiple schemas with the same namespace
_namespaceLookUpTable.Add(schema.Namespace);
}
///
/// Resolve the type - if the type is not found, return appropriate error
///
///
public bool TryResolveType(string namespaceName, string typeName, out SchemaType schemaType)
{
// For resolving entity container names, namespace can be null
string fullyQualifiedName = String.IsNullOrEmpty(namespaceName) ? typeName : namespaceName + "." + typeName;
schemaType = SchemaTypes.LookUpEquivalentKey(fullyQualifiedName);
if (schemaType != null)
{
return true;
}
return false;
}
///
/// Returns true if this is a valid namespace name or else returns false
///
public bool IsValidNamespaceName(string namespaceName)
{
return _namespaceLookUpTable.Contains(namespaceName);
}
#endregion // Public Methods
#region Private Methods
///
/// Checks if the xml reader has base uri. If it doesn't have, it adds error, other
/// returns the location from the base uri
///
///
internal static bool TryGetBaseUri(XmlReader xmlReader, out string location)
{
string baseUri = xmlReader.BaseURI;
Uri uri = null;
if (!string.IsNullOrEmpty(baseUri) &&
Uri.TryCreate(baseUri, UriKind.Absolute, out uri) &&
uri.Scheme == "file")
{
location = Helper.GetFileNameFromUri(uri);
return true;
}
else
{
location = null;
return false;
}
}
///
/// Add the given list of newErrors to the error collection. If there is a error in the new errors,
/// it sets the errorEncountered to true. Returns true if the number of errors encountered is more
/// than max errors
///
///
private static bool UpdateErrorCollectionAndCheckForMaxErrors(List errorCollection,
IList newErrors, ref bool errorEncountered)
{
// If we have encountered error already in one of the schemas, then we don't need to check for errors in the remaining schemas.
// Just keep aggregating the errors and throw them at the end.
if (!errorEncountered)
{
if (!MetadataHelper.CheckIfAllErrorsAreWarnings(newErrors))
{
errorEncountered = true;
}
}
// Add the new errors to the error collection
errorCollection.AddRange(newErrors);
if (errorEncountered &&
errorCollection.Where(e => e.Severity == EdmSchemaErrorSeverity.Error).Count() > MaxErrorCount)
{
return true;
}
return false;
}
#endregion
#region Internal Properties
internal SchemaElementLookUpTable SchemaTypes
{
get
{
return _schemaTypes;
}
}
internal DbProviderManifest GetProviderManifest(Action addError)
{
if (_providerManifest == null)
{
_providerManifest = _providerManifestNeeded(addError);
}
return _providerManifest;
}
internal SchemaDataModelOption DataModel { get { return _dataModel; } }
internal void EnsurePrimitiveSchemaIsLoaded()
{
if (_primitiveSchema == null)
{
_primitiveSchema = new PrimitiveSchema(this);
}
}
internal PrimitiveSchema PrimitiveSchema
{
get
{
return _primitiveSchema;
}
}
internal AttributeValueNotification ProviderNotification
{
get
{
return _providerNotification;
}
}
internal AttributeValueNotification ProviderManifestTokenNotification
{
get
{
return _providerManifestTokenNotification;
}
}
#endregion
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- PagedDataSource.cs
- CollectionConverter.cs
- ObjectDataSource.cs
- AsyncDataRequest.cs
- Image.cs
- EncryptedPackage.cs
- EventDescriptor.cs
- ContentElement.cs
- TCEAdapterGenerator.cs
- OdbcFactory.cs
- BinaryParser.cs
- EntityContainerAssociationSet.cs
- Input.cs
- BlurEffect.cs
- SoapInteropTypes.cs
- Native.cs
- IIS7UserPrincipal.cs
- CodeCompiler.cs
- ZipIOExtraFieldZip64Element.cs
- MethodBuilderInstantiation.cs
- BamlRecords.cs
- XmlSchemaCollection.cs
- BasicViewGenerator.cs
- DataList.cs
- TextParaLineResult.cs
- GridViewEditEventArgs.cs
- SqlDataSourceFilteringEventArgs.cs
- TemplateBindingExpressionConverter.cs
- IndicShape.cs
- XmlNodeChangedEventArgs.cs
- TableRowCollection.cs
- ColorConvertedBitmapExtension.cs
- MessageSecurityOverHttp.cs
- TemplateInstanceAttribute.cs
- ScriptManagerProxy.cs
- ResolveNameEventArgs.cs
- VirtualPath.cs
- TextAdaptor.cs
- CodeLabeledStatement.cs
- UnauthorizedWebPart.cs
- Buffer.cs
- Activity.cs
- TextEditorContextMenu.cs
- ResourceSetExpression.cs
- PerformanceCountersElement.cs
- LineVisual.cs
- XmlArrayItemAttribute.cs
- SingleSelectRootGridEntry.cs
- OleDbWrapper.cs
- DynamicRendererThreadManager.cs
- CodeMemberProperty.cs
- DesignerSelectionListAdapter.cs
- Utils.cs
- TransformGroup.cs
- DynamicFilter.cs
- ConfigXmlReader.cs
- DataGridViewButtonColumn.cs
- CqlParserHelpers.cs
- XmlDataSourceView.cs
- RunWorkerCompletedEventArgs.cs
- SerializerWriterEventHandlers.cs
- BitStream.cs
- Win32NamedPipes.cs
- DoubleUtil.cs
- PointHitTestParameters.cs
- HttpConfigurationContext.cs
- Parser.cs
- RoutedEventArgs.cs
- SaveFileDialogDesigner.cs
- DomainConstraint.cs
- XmlSchemaComplexContentExtension.cs
- SmtpReplyReaderFactory.cs
- InternalEnumValidatorAttribute.cs
- ProxyGenerationError.cs
- Line.cs
- BindingListCollectionView.cs
- StreamWriter.cs
- ExplicitDiscriminatorMap.cs
- CTreeGenerator.cs
- HttpStreamXmlDictionaryReader.cs
- InputScope.cs
- HtmlEncodedRawTextWriter.cs
- SqlInternalConnectionTds.cs
- AsyncDataRequest.cs
- Visual3D.cs
- DataRelationCollection.cs
- HttpCookieCollection.cs
- PointLightBase.cs
- WmiEventSink.cs
- StartUpEventArgs.cs
- SqlErrorCollection.cs
- TypeDescriptionProviderAttribute.cs
- StaticTextPointer.cs
- HttpWriter.cs
- PlatformCulture.cs
- WrapPanel.cs
- WebPartUserCapability.cs
- HttpRuntime.cs
- BatchServiceHost.cs
- WebPermission.cs