Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / NetFx40 / XamlBuildTask / Microsoft / Build / Tasks / Xaml / XamlValidatingReader.cs / 1305376 / XamlValidatingReader.cs
//------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------- namespace Microsoft.Build.Tasks.Xaml { using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Linq; using System.Text; using System.Xaml; using System.Xaml.Schema; using System.Reflection; using System.Runtime; using System.Globalization; using System.Diagnostics.CodeAnalysis; using System.IO; internal class XamlValidatingReader : XamlWrappingReader { XamlStackWriter _stack = new XamlStackWriter(); Assembly assembly; Type definedType; string rootNamespace; string localAssemblyName; string realAssemblyName; public event EventHandlerOnValidationError; public XamlValidatingReader(XamlReader underlyingReader, Assembly assembly, string rootNamespace, string realAssemblyName) : base(underlyingReader) { this.assembly = assembly; this.definedType = null; this.rootNamespace = rootNamespace; this.localAssemblyName = assembly != null ? assembly.GetName().Name : null; this.realAssemblyName = realAssemblyName; } [SuppressMessage(FxCop.Category.Design, FxCop.Rule.DoNotCatchGeneralExceptionTypes, Justification = "Need to catch and log the exception here so that all the errors, including the exception thrown, are surfaced.")] public override bool Read() { if (!base.Read()) { return false; } try { if (_stack.Depth == 0) { State_AtRoot(); } else if (_stack.TopFrame.FrameType == XamlStackFrameType.Member) { if (_stack.TopFrame.IsSet() && !AllowsMultiple(_stack.TopFrame.Member)) { State_ExpectEndMember(); } else { State_InsideMember(); } } else { if (_stack.TopFrame.FrameType != XamlStackFrameType.Object && _stack.TopFrame.FrameType != XamlStackFrameType.GetObject) { ValidationError(SR.UnexpectedXaml); } State_InsideObject(); } } catch (FileLoadException e) { if (Fx.IsFatal(e)) { throw; } ValidationError(SR.AssemblyCannotBeResolved(XamlBuildTaskServices.FileNotLoaded)); } catch (Exception e) { if (Fx.IsFatal(e)) { throw; } ValidationError(e.Message); } return true; } protected virtual void ValidationError(string message, params object[] args) { EventHandler handler = OnValidationError; if (handler != null) { string formattedMessage = (args == null || args.Length == 0) ? message : string.Format(CultureInfo.InvariantCulture, message, args); handler(this, new ValidationEventArgs(formattedMessage, LineNumber, LinePosition)); } } private void State_AtRoot() { switch (NodeType) { case XamlNodeType.NamespaceDeclaration: return; case XamlNodeType.StartObject: ValidateUnknown(Type); break; default: ValidationError(SR.UnexpectedXaml); break; } _stack.WriteNode(this); } private void State_InsideObject() { switch (NodeType) { case XamlNodeType.NamespaceDeclaration: return; case XamlNodeType.StartMember: if (_stack.TopFrame.IsSet(Member)) { ValidationError(SR.UnexpectedXaml); } if (_stack.TopFrame.FrameType == XamlStackFrameType.GetObject) { ValidateMemberOnGetObject(Member); } else { ValidateUnknown(Member); ValidateMemberOnType(Member, _stack.TopFrame.Type); } break; case XamlNodeType.EndObject: break; default: ValidationError(SR.UnexpectedXamlDupMember); break; } _stack.WriteNode(this); } private void State_InsideMember() { switch (NodeType) { case XamlNodeType.NamespaceDeclaration: return; case XamlNodeType.StartObject: ValidateUnknown(Type); ValidateTypeToMemberOnStack(Type); break; case XamlNodeType.GetObject: ValidateGetObjectOnMember(_stack.TopFrame.Member); break; case XamlNodeType.Value: ValidateValueToMemberOnStack(Value); break; case XamlNodeType.EndMember: break; default: ValidationError(SR.UnexpectedXaml); break; } _stack.WriteNode(this); } private void State_ExpectEndMember() { if (NodeType != XamlNodeType.EndMember) { ValidationError(SR.UnexpectedXaml); } _stack.WriteNode(this); } private void ValidateGetObjectOnMember(XamlMember member) { if (member == XamlLanguage.Items || member == XamlLanguage.PositionalParameters) { ValidationError(SR.UnexpectedXaml); } else if (!member.IsUnknown && member != XamlLanguage.UnknownContent && !member.Type.IsCollection && !member.Type.IsDictionary) { ValidationError(SR.UnexpectedXaml); } } private void ValidateMemberOnGetObject(XamlMember member) { if (member != XamlLanguage.Items) { ValidationError(SR.UnexpectedXaml); } } private void ValidateMemberOnType(XamlMember member, XamlType type) { if (member.IsUnknown || type.IsUnknown) { return; } if (member.IsDirective) { if (member == XamlLanguage.Items) { if (!type.IsCollection && !type.IsDictionary) { ValidationError(SR.UnexpectedXamlDictionary(member.Name, GetXamlTypeName(_stack.TopFrame.Type))); } } if (member == XamlLanguage.Class && _stack.Depth > 1) { ValidationError(SR.UnexpectedXamlClass); } } else if (member.IsAttachable) { if (!type.CanAssignTo(member.TargetType)) { ValidationError(SR.UnexpectedXamlAttachableMember(member.Name, GetXamlTypeName(member.TargetType))); } } else if (!member.IsDirective && !type.CanAssignTo(member.DeclaringType)) { ValidationError(SR.UnexpectedXamlMemberNotAssignable(member.Name, GetXamlTypeName(type))); } } private void ValidateTypeToMemberOnStack(XamlType type) { if (type.IsUnknown) { return; } if (type == XamlLanguage.Null) { ValidateValueToMemberOnStack(null); } XamlMember member = _stack.TopFrame.Member; if (member == XamlLanguage.PositionalParameters || type.IsMarkupExtension || member.IsUnknown) { return; } if (member == XamlLanguage.Items) { XamlType collectionType = GetCollectionTypeOnStack(); if (collectionType == null || collectionType.IsUnknown || collectionType.AllowedContentTypes == null) { return; } if (!collectionType.AllowedContentTypes.Any(contentType => type.CanAssignTo(contentType))) { ValidationError(SR.UnassignableCollection(GetXamlTypeName(type), GetXamlTypeName(collectionType.ItemType), GetXamlTypeName(collectionType))); } } else if (member.IsDirective && (member.Type.IsCollection || member.Type.IsDictionary)) { XamlType collectionType = member.Type; if (collectionType == null || collectionType.IsUnknown || collectionType.AllowedContentTypes == null) { return; } if (!collectionType.AllowedContentTypes.Any(contentType => type.CanAssignTo(contentType))) { ValidationError(SR.UnassignableCollection(GetXamlTypeName(type), GetXamlTypeName(collectionType.ItemType), GetXamlTypeName(collectionType))); } } else if (!type.CanAssignTo(member.Type)) { if (member.DeferringLoader != null) { return; } if (NodeType == XamlNodeType.Value) { ValidationError(SR.UnassignableTypes(GetXamlTypeName(type), GetXamlTypeName(member.Type), member.Name)); } else { ValidationError(SR.UnassignableTypesObject(GetXamlTypeName(type), GetXamlTypeName(member.Type), member.Name)); } } } private void ValidateValueToMemberOnStack(object value) { XamlMember member = _stack.TopFrame.Member; if (member.IsUnknown) { return; } if (value != null) { if (member.IsEvent) { if (this.definedType != null && this.definedType.GetMethod(value as string, BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public) == null) { ValidationError(SR.UnexpectedXamlEventHandlerNotFound(value, definedType.FullName)); } return; } else if (member == XamlLanguage.Class) { string className = value as string; Fx.Assert(!string.IsNullOrEmpty(className), "ClassName cannot be null"); if (!string.IsNullOrEmpty(this.rootNamespace)) { className = this.rootNamespace + "." + className; } if (this.assembly != null) { this.definedType = this.assembly.GetType(className); } return; } else if (member.TypeConverter != null) { return; } XamlType typeOfValue = SchemaContext.GetXamlType(value.GetType()); ValidateTypeToMemberOnStack(typeOfValue); } else { if (member == XamlLanguage.PositionalParameters) { return; } if (member == XamlLanguage.Items) { XamlType collectionType = GetCollectionTypeOnStack(); if (collectionType == null || collectionType.IsUnknown || collectionType.AllowedContentTypes == null) { return; } if (!collectionType.AllowedContentTypes.Any(contentType => contentType.IsNullable)) { ValidationError(SR.UnassignableCollection("(null)", GetXamlTypeName(collectionType.ItemType), GetXamlTypeName(collectionType))); } } else { if (!member.Type.IsNullable) { ValidationError(SR.UnassignableTypes("(null)", GetXamlTypeName(member.Type), member.Name)); } } } } private bool AllowsMultiple(XamlMember member) { return member == XamlLanguage.Items || member == XamlLanguage.PositionalParameters || member == XamlLanguage.UnknownContent; } private XamlType GetCollectionTypeOnStack() { Fx.Assert(_stack.TopFrame.Member == XamlLanguage.Items, "CollectionType should have _Items member"); XamlType result; if (_stack.FrameAtDepth(_stack.Depth - 1).FrameType == XamlStackFrameType.GetObject) { XamlMember member = _stack.FrameAtDepth(_stack.Depth - 2).Member; if (member.IsUnknown) { return null; } result = member.Type; } else { result = _stack.FrameAtDepth(_stack.Depth - 1).Type; } Fx.Assert(result.IsUnknown || result.IsCollection || result.IsDictionary, "Incorrect Collection Type Encountered"); return result; } private void ValidateUnknown(XamlMember member) { if (member == XamlLanguage.UnknownContent) { ValidationError(SR.MemberUnknownContect(GetXamlTypeName(_stack.TopFrame.Type))); } else if (member.IsUnknown) { bool retryAttachable = false; XamlType declaringType = member.DeclaringType; if (_stack.Depth == 1 && declaringType.IsUnknown && !string.IsNullOrEmpty(this.rootNamespace) && this.definedType != null && declaringType.Name == this.definedType.Name) { // Need to handle the case where the namespace of a member on the document root // is missing the project root namespace string clrNs; if (XamlBuildTaskServices.TryExtractClrNs(declaringType.PreferredXamlNamespace, out clrNs)) { clrNs = string.IsNullOrEmpty(clrNs) ? this.rootNamespace : this.rootNamespace + "." + clrNs; if (clrNs == this.definedType.Namespace) { declaringType = SchemaContext.GetXamlType(this.definedType); retryAttachable = true; } } } XamlMember typeMember = declaringType.GetMember(member.Name); if (typeMember == null && retryAttachable) { typeMember = declaringType.GetAttachableMember(member.Name); } if (typeMember == null || typeMember.IsUnknown) { if (member.IsAttachable) { ValidationError(SR.UnresolvedAttachableMember(GetXamlTypeName(member.DeclaringType) + "." + member.Name)); } else if (member.IsDirective) { ValidationError(SR.UnresolvedDirective(member.PreferredXamlNamespace + ":" + member.Name)); } else { // Skip if declaring type is unknown as the member unknown error messages become redundant. if (declaringType != null && !declaringType.IsUnknown) { ValidationError(SR.UnresolvedMember(member.Name, GetXamlTypeName(declaringType))); } } } } } private void ValidateUnknown(XamlType type) { if (type.IsUnknown) { if (type.IsGeneric) { ThrowGenericTypeValidationError(type); } else { ThrowTypeValidationError(type); } } } private void ThrowGenericTypeValidationError(XamlType type) { IList unresolvedLeafTypeList = new List (); XamlBuildTaskServices.GetUnresolvedLeafTypeArg(type, ref unresolvedLeafTypeList); if (unresolvedLeafTypeList.Count > 1 || !unresolvedLeafTypeList.Contains(type)) { string fullTypeName = GetXamlTypeName(type); ValidationError(SR.UnresolvedGenericType(fullTypeName)); foreach (XamlType xamlType in unresolvedLeafTypeList) { ThrowTypeValidationError(xamlType); } } else { ThrowTypeValidationError(type); } } private void ThrowTypeValidationError(XamlType type) { string typeName, assemblyName, ns; if (XamlBuildTaskServices.GetTypeNameInAssemblyOrNamespace(type, this.localAssemblyName, this.realAssemblyName, out typeName, out assemblyName, out ns)) { ValidationError(SR.UnresolvedTypeWithAssemblyName(ns + "." + typeName, assemblyName)); } else { ValidationError(SR.UnresolvedTypeWithNamespace(typeName, ns)); } } private string GetXamlTypeName(XamlType type) { return XamlBuildTaskServices.GetTypeName(type, this.localAssemblyName, this.realAssemblyName); } } } // 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
- SafeEventLogWriteHandle.cs
- WizardSideBarListControlItemEventArgs.cs
- LocalizableAttribute.cs
- IntPtr.cs
- UnsafeNativeMethods.cs
- ScaleTransform3D.cs
- WindowsScroll.cs
- LicenseException.cs
- ComponentDispatcher.cs
- AppSecurityManager.cs
- Registry.cs
- WebBrowserHelper.cs
- shaperfactoryquerycachekey.cs
- EntityDataSourceWrapperCollection.cs
- SocketPermission.cs
- WorkflowNamespace.cs
- ScrollItemPattern.cs
- EventLogger.cs
- Connector.cs
- ByteStorage.cs
- LayoutTableCell.cs
- SemaphoreSecurity.cs
- PropertyGridView.cs
- StreamGeometry.cs
- Exceptions.cs
- RTLAwareMessageBox.cs
- KeyTime.cs
- InteropTrackingRecord.cs
- NamespaceExpr.cs
- SqlReferenceCollection.cs
- AuthorizationSection.cs
- XmlSerializerVersionAttribute.cs
- BamlRecordReader.cs
- OleCmdHelper.cs
- BaseCAMarshaler.cs
- RemotingConfiguration.cs
- CancelEventArgs.cs
- DataServiceQuery.cs
- EventSetter.cs
- DetailsViewModeEventArgs.cs
- UTF7Encoding.cs
- DurableServiceAttribute.cs
- PageContent.cs
- NotifyInputEventArgs.cs
- SqlUserDefinedAggregateAttribute.cs
- OutOfMemoryException.cs
- HandledMouseEvent.cs
- ApplicationCommands.cs
- ClipboardData.cs
- TabControlAutomationPeer.cs
- XPathSelfQuery.cs
- ViewRendering.cs
- CompoundFileStreamReference.cs
- GridViewDeletedEventArgs.cs
- Adorner.cs
- TableHeaderCell.cs
- ProcessHostMapPath.cs
- ErrorTableItemStyle.cs
- SymbolEqualComparer.cs
- CacheSection.cs
- ErrorFormatter.cs
- OdbcParameterCollection.cs
- CultureInfoConverter.cs
- SeverityFilter.cs
- TextServicesHost.cs
- ProfilePropertySettings.cs
- BasicKeyConstraint.cs
- NegotiateStream.cs
- DynamicILGenerator.cs
- DataGridViewCellLinkedList.cs
- ObjectDataSourceStatusEventArgs.cs
- IItemContainerGenerator.cs
- PathSegment.cs
- BaseCAMarshaler.cs
- DesignerInterfaces.cs
- LinkedResourceCollection.cs
- EntitySqlException.cs
- FontCollection.cs
- DataTableCollection.cs
- TextServicesContext.cs
- ProfileManager.cs
- InnerItemCollectionView.cs
- DetailsViewInsertEventArgs.cs
- JulianCalendar.cs
- XmlSchemaSimpleContentExtension.cs
- BufferedGenericXmlSecurityToken.cs
- InstanceDataCollection.cs
- AvTraceFormat.cs
- HtmlInputText.cs
- CompositeTypefaceMetrics.cs
- StreamDocument.cs
- ControlValuePropertyAttribute.cs
- LabelEditEvent.cs
- ValidationError.cs
- IERequestCache.cs
- IISMapPath.cs
- DocumentManager.cs
- KeyValueSerializer.cs
- EntityDataSourceContainerNameItem.cs
- TextCompositionManager.cs