Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Framework / System / Windows / Markup / XamlTypeMapperSchemaContext.cs / 1305600 / XamlTypeMapperSchemaContext.cs
using System; using System.Collections; using System.Collections.Generic; using System.Reflection; using System.Threading; using System.Windows.Baml2006; using System.Xaml; using MS.Internal; using MS.Utility; namespace System.Windows.Markup { public partial class XamlTypeMapper { internal class XamlTypeMapperSchemaContext : XamlSchemaContext { // Initialized in constructor Dictionary> _nsDefinitions; XamlTypeMapper _typeMapper; WpfSharedXamlSchemaContext _sharedSchemaContext; // Lock on syncObject object syncObject = new object(); Dictionary _piNamespaces; IEnumerable _allXamlNamespaces; Dictionary _allowedInternalTypes; HashSet _clrNamespaces; internal XamlTypeMapperSchemaContext(XamlTypeMapper typeMapper) : base() { _typeMapper = typeMapper; _sharedSchemaContext = (WpfSharedXamlSchemaContext)XamlReader.GetWpfSchemaContext(); // Copy all the NamespaceMapEntrys from our parent into _nsDefinitions if (typeMapper._namespaceMaps != null) { _nsDefinitions = new Dictionary >(); foreach (NamespaceMapEntry mapEntry in _typeMapper._namespaceMaps) { FrugalObjectList clrNsList; if (!_nsDefinitions.TryGetValue(mapEntry.XmlNamespace, out clrNsList)) { clrNsList = new FrugalObjectList (1); _nsDefinitions.Add(mapEntry.XmlNamespace, clrNsList); } string clrNs = GetClrNsUri(mapEntry.ClrNamespace, mapEntry.AssemblyName); clrNsList.Add(clrNs); } } // Copy all the PIs from our parent into _piNamespaces if (typeMapper.PITable.Count > 0) { _piNamespaces = new Dictionary (typeMapper.PITable.Count); foreach (DictionaryEntry entry in typeMapper.PITable) { ClrNamespaceAssemblyPair pair = (ClrNamespaceAssemblyPair)entry.Value; string clrNs = GetClrNsUri(pair.ClrNamespace, pair.AssemblyName); _piNamespaces.Add((string)entry.Key, clrNs); } } _clrNamespaces = new HashSet (); } // Return all the namespaces gathered via reflection, plus any additional ones from user mappings public override IEnumerable GetAllXamlNamespaces() { IEnumerable result = _allXamlNamespaces; if (result == null) { lock (syncObject) { if (_nsDefinitions != null || _piNamespaces != null) { // Use shared schema context, to avoid redundant reflection List resultList = new List (_sharedSchemaContext.GetAllXamlNamespaces()); AddKnownNamespaces(resultList); result = resultList.AsReadOnly(); } else { result = _sharedSchemaContext.GetAllXamlNamespaces(); } _allXamlNamespaces = result; } } return result; } public override XamlType GetXamlType(Type type) { if (ReflectionHelper.IsPublicType(type)) { return _sharedSchemaContext.GetXamlType(type); } return GetInternalType(type, null); } public override bool TryGetCompatibleXamlNamespace(string xamlNamespace, out string compatibleNamespace) { // XmlnsCompat mappings only come from reflection, so get them from the shared SchemaContext if (_sharedSchemaContext.TryGetCompatibleXamlNamespace(xamlNamespace, out compatibleNamespace)) { return true; } // Otherwise, if we have a map or a PI for the namespace, then treat it as known if (_nsDefinitions != null && _nsDefinitions.ContainsKey(xamlNamespace) || _piNamespaces != null && SyncContainsKey(_piNamespaces, xamlNamespace)) { compatibleNamespace = xamlNamespace; return true; } return false; } // Returns a Hashtable of ns -> NamespaceMapEntry[] containing all mappings that are // different from what would be returned by the shared context. // We don't use _typeMapper.NamespaceMapHashList because we don't want to duplicate all // the reflection done by the shared SchemaContext. // Thread safety: we assume this is called on the parser thread, and so it's safe to // iterate the _typeMapper's data structures. internal Hashtable GetNamespaceMapHashList() { // Copy the ctor-provided namespace mappings into the result Hashtable result = new Hashtable(); if (_typeMapper._namespaceMaps != null) { foreach (NamespaceMapEntry mapEntry in _typeMapper._namespaceMaps) { NamespaceMapEntry clone = new NamespaceMapEntry { XmlNamespace = mapEntry.XmlNamespace, ClrNamespace = mapEntry.ClrNamespace, AssemblyName = mapEntry.AssemblyName, AssemblyPath = mapEntry.AssemblyPath }; AddToMultiHashtable(result, mapEntry.XmlNamespace, clone); } } // Copy the Mapping PIs into the result foreach (DictionaryEntry piEntry in _typeMapper.PITable) { ClrNamespaceAssemblyPair mapping = (ClrNamespaceAssemblyPair)piEntry.Value; NamespaceMapEntry mapEntry = new NamespaceMapEntry { XmlNamespace = (string)piEntry.Key, ClrNamespace = mapping.ClrNamespace, AssemblyName = mapping.AssemblyName, AssemblyPath = _typeMapper.AssemblyPathFor(mapping.AssemblyName) }; AddToMultiHashtable(result, mapEntry.XmlNamespace, mapEntry); } // Add any clr-namespaces that were resolved using custom assembly paths lock (syncObject) { foreach (string clrNs in _clrNamespaces) { string clrNamespace, assembly; SplitClrNsUri(clrNs, out clrNamespace, out assembly); if (!string.IsNullOrEmpty(assembly)) { string assemblyPath = _typeMapper.AssemblyPathFor(assembly); if (!string.IsNullOrEmpty(assemblyPath)) { NamespaceMapEntry mapEntry = new NamespaceMapEntry { XmlNamespace = clrNs, ClrNamespace = clrNamespace, AssemblyName = assembly, AssemblyPath = assemblyPath }; AddToMultiHashtable(result, mapEntry.XmlNamespace, mapEntry); } } } } // Convert all the lists to arrays object[] keys = new object[result.Count]; result.Keys.CopyTo(keys, 0); foreach (object key in keys) { List list = (List )result[key]; result[key] = list.ToArray(); } return result; } internal void SetMappingProcessingInstruction(string xamlNamespace, ClrNamespaceAssemblyPair pair) { string clrNs = GetClrNsUri(pair.ClrNamespace, pair.AssemblyName); lock (syncObject) { if (_piNamespaces == null) { _piNamespaces = new Dictionary (); } _piNamespaces[xamlNamespace] = clrNs; // We potentially have a new namespace, so invalidate the cached list of namespaces _allXamlNamespaces = null; } } protected override XamlType GetXamlType(string xamlNamespace, string name, params XamlType[] typeArguments) { try { return LookupXamlType(xamlNamespace, name, typeArguments); } catch (Exception e) { if (CriticalExceptions.IsCriticalException(e)) { throw; } if (_typeMapper.LoadReferenceAssemblies()) { // If new reference assemblies were loaded, retry the type load return LookupXamlType(xamlNamespace, name, typeArguments); } else { throw; } } } // Load assembly using the user-provided path, if available protected override Assembly OnAssemblyResolve(string assemblyName) { string assemblyPath = _typeMapper.AssemblyPathFor(assemblyName); if (!string.IsNullOrEmpty(assemblyPath)) { return ReflectionHelper.LoadAssembly(assemblyName, assemblyPath); } return base.OnAssemblyResolve(assemblyName); } private static string GetClrNsUri(string clrNamespace, string assembly) { return XamlReaderHelper.MappingProtocol + clrNamespace + XamlReaderHelper.MappingAssembly + assembly; } private static void SplitClrNsUri(string xmlNamespace, out string clrNamespace, out string assembly) { clrNamespace = null; assembly = null; int clrNsIndex = xmlNamespace.IndexOf(XamlReaderHelper.MappingProtocol, StringComparison.Ordinal); if (clrNsIndex < 0) { return; } clrNsIndex += XamlReaderHelper.MappingProtocol.Length; if (clrNsIndex <= xmlNamespace.Length) { return; } int assemblyIndex = xmlNamespace.IndexOf(XamlReaderHelper.MappingAssembly, StringComparison.Ordinal); if (assemblyIndex < clrNsIndex) { clrNamespace = xmlNamespace.Substring(clrNsIndex); return; } clrNamespace = xmlNamespace.Substring(clrNsIndex, assemblyIndex - clrNsIndex); assemblyIndex += XamlReaderHelper.MappingAssembly.Length; if (assemblyIndex <= xmlNamespace.Length) { return; } assembly = xmlNamespace.Substring(assemblyIndex); } // Should be called within lock (syncObject) private void AddKnownNamespaces(List nsList) { if (_nsDefinitions != null) { foreach (string ns in _nsDefinitions.Keys) { if (!nsList.Contains(ns)) { nsList.Add(ns); } } } if (_piNamespaces != null) { foreach (string ns in _piNamespaces.Keys) { if (!nsList.Contains(ns)) { nsList.Add(ns); } } } } private XamlType GetInternalType(Type type, XamlType sharedSchemaXamlType) { lock (syncObject) { if (_allowedInternalTypes == null) { _allowedInternalTypes = new Dictionary (); } XamlType result; if (!_allowedInternalTypes.TryGetValue(type, out result)) { WpfSharedXamlSchemaContext.RequireRuntimeType(type); if (_typeMapper.IsInternalTypeAllowedInFullTrust(type)) { // Return a type that claims to be public, so that XXR doesn't filter it out. result = new VisibilityMaskingXamlType(type, _sharedSchemaContext); } else { result = sharedSchemaXamlType ?? _sharedSchemaContext.GetXamlType(type); } _allowedInternalTypes.Add(type, result); } return result; } } // Tries to use the user-provided mappings to resolve a type. Note that the returned type // won't include the mapping in its list of namespaces; that is not necessary for v3 compat. // // Note that for anything other than reflected mappings, we don't use the shared SchemaContext, // because we want to make sure that our OnAssemblyResolve handler is called. private XamlType LookupXamlType(string xamlNamespace, string name, XamlType[] typeArguments) { // First look through the user-provided namespace mappings XamlType result; FrugalObjectList clrNsList; if (_nsDefinitions != null && _nsDefinitions.TryGetValue(xamlNamespace, out clrNsList)) { for (int i = 0; i < clrNsList.Count; i++) { result = base.GetXamlType(clrNsList[i], name, typeArguments); if (result != null) { return result; } } } // Then look for a PI string piMappingClrNs; if (_piNamespaces != null && SyncTryGetValue(_piNamespaces, xamlNamespace, out piMappingClrNs)) { return base.GetXamlType(piMappingClrNs, name, typeArguments); } // Then see if it's a CLR namespace if (xamlNamespace.StartsWith(XamlReaderHelper.MappingProtocol, StringComparison.Ordinal)) { lock (syncObject) { if (!_clrNamespaces.Contains(xamlNamespace)) { _clrNamespaces.Add(xamlNamespace); } } return base.GetXamlType(xamlNamespace, name, typeArguments); } // Finally, use the reflected xmlnsdefs (get them from the shared SchemaContext, to avoid redundant reflection) result = _sharedSchemaContext.GetXamlTypeInternal(xamlNamespace, name, typeArguments); // Apply visibility filtering, because the shared SchemaContext can't do that. return result == null || result.IsPublic ? result : GetInternalType(result.UnderlyingType, result); } private bool SyncContainsKey (IDictionary dict, K key) { lock (syncObject) { return dict.ContainsKey(key); } } private bool SyncTryGetValue(IDictionary dict, string key, out string value) { lock (syncObject) { return dict.TryGetValue(key, out value); } } private static void AddToMultiHashtable (Hashtable hashtable, K key, V value) { List list = (List )hashtable[key]; if (list == null) { list = new List (); hashtable.Add(key, list); } list.Add(value); } } // This XamlType claims to be public, so that XXR won't filter out internals that are // allowed by XamlTypeMapper.AllowInternalType private class VisibilityMaskingXamlType : XamlType { public VisibilityMaskingXamlType(Type underlyingType, XamlSchemaContext schemaContext) : base(underlyingType, schemaContext) { } protected override bool LookupIsPublic() { return true; } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- DecimalStorage.cs
- AlphabeticalEnumConverter.cs
- SqlComparer.cs
- ExternalFile.cs
- HtmlSelect.cs
- XPathPatternParser.cs
- CheckoutException.cs
- MouseEvent.cs
- Brush.cs
- ApplicationServiceManager.cs
- ClientOptions.cs
- SmtpFailedRecipientsException.cs
- TypedReference.cs
- DataColumnChangeEvent.cs
- Int32Converter.cs
- DrawingState.cs
- StrongNamePublicKeyBlob.cs
- RequestStatusBarUpdateEventArgs.cs
- AuthorizationPolicyTypeElementCollection.cs
- PageSetupDialog.cs
- StylusPointDescription.cs
- RelationshipDetailsCollection.cs
- EncoderFallback.cs
- WindowsToolbarItemAsMenuItem.cs
- WebPartZoneCollection.cs
- RemoteWebConfigurationHostServer.cs
- SchemaMerger.cs
- StaticContext.cs
- SystemInfo.cs
- TypeBuilderInstantiation.cs
- LogConverter.cs
- Baml2006ReaderContext.cs
- MDIClient.cs
- PeerResolverBindingElement.cs
- GeometryValueSerializer.cs
- GPPOINT.cs
- ExpressionBinding.cs
- SqlNotificationRequest.cs
- TextDecorationCollection.cs
- TokenBasedSet.cs
- JsonObjectDataContract.cs
- TypedElement.cs
- MtomMessageEncodingBindingElement.cs
- FlowDocumentScrollViewer.cs
- XamlTypeMapper.cs
- UnmanagedBitmapWrapper.cs
- MethodImplAttribute.cs
- SolidColorBrush.cs
- EntityDataSourceUtil.cs
- NonClientArea.cs
- CompilationSection.cs
- ApplicationTrust.cs
- DictionaryEntry.cs
- CodeDirectionExpression.cs
- FirstMatchCodeGroup.cs
- Peer.cs
- SafeSecurityHandles.cs
- XmlSchemaObject.cs
- PaintEvent.cs
- TrackingProfileDeserializationException.cs
- StylusPointProperties.cs
- ComponentRenameEvent.cs
- TypeUsageBuilder.cs
- XmlFormatExtensionPointAttribute.cs
- ResXBuildProvider.cs
- FlowDocumentReader.cs
- FormatSettings.cs
- WorkflowMarkupSerializationProvider.cs
- CLSCompliantAttribute.cs
- NotSupportedException.cs
- BinaryObjectReader.cs
- ProgressBar.cs
- TextLine.cs
- FontFamilyIdentifier.cs
- TableCellCollection.cs
- TypedReference.cs
- DBConcurrencyException.cs
- ExecutionPropertyManager.cs
- documentation.cs
- PropertyPathWorker.cs
- QualificationDataItem.cs
- CryptoStream.cs
- PointConverter.cs
- UserControlFileEditor.cs
- InstanceDataCollection.cs
- BlobPersonalizationState.cs
- ZipQueryOperator.cs
- RegexRunner.cs
- TextEvent.cs
- MatrixIndependentAnimationStorage.cs
- XamlToRtfParser.cs
- AttachmentService.cs
- ChangeTracker.cs
- ToolStripDropDownButton.cs
- graph.cs
- HtmlHead.cs
- XmlEntity.cs
- ConstrainedDataObject.cs
- BulletedListEventArgs.cs
- SimpleHandlerBuildProvider.cs