Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataWeb / Design / system / Data / EntityModel / Emitters / AttributeEmitter.cs / 1305376 / AttributeEmitter.cs
//---------------------------------------------------------------------- //// Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner [....] // @backupOwner [....] //--------------------------------------------------------------------- using System.CodeDom; using System.Collections.Generic; using System.Data.Metadata.Edm; using System.Data.Services.Common; using System.Data.Services.Design; using System.Diagnostics; using System.Globalization; using System.Linq; namespace System.Data.EntityModel.Emitters { ////// Summary description for AttributeEmitter. /// internal sealed partial class AttributeEmitter { private const string _generatorVersion = "1.0.0"; private const string _generatorName = "System.Data.Services.Design"; private static readonly CodeAttributeDeclaration _generatedCodeAttribute = new CodeAttributeDeclaration( new CodeTypeReference(typeof(System.CodeDom.Compiler.GeneratedCodeAttribute)), new CodeAttributeArgument(new CodePrimitiveExpression(_generatorName)), new CodeAttributeArgument(new CodePrimitiveExpression(_generatorVersion))); TypeReference _typeReference; internal TypeReference TypeReference { get { return _typeReference; } } internal AttributeEmitter(TypeReference typeReference) { _typeReference = typeReference; } ////// The method to be called to create the type level attributes for the ItemTypeEmitter /// /// The strongly typed emitter /// The type declaration to add the attribues to. public void EmitTypeAttributes(EntityTypeEmitter emitter, CodeTypeDeclaration typeDecl) { Debug.Assert(emitter != null, "emitter should not be null"); Debug.Assert(typeDecl != null, "typeDecl should not be null"); if (emitter.Generator.Version != DataServiceCodeVersion.V1) { EmitEpmAttributesForEntityType(emitter.Generator.EdmItemCollection, emitter.Item, typeDecl); EmitStreamAttributesForEntityType(emitter.Item, typeDecl); } object[] keys = emitter.Item.KeyMembers.Select(km => (object) km.Name).ToArray(); typeDecl.CustomAttributes.Add(EmitSimpleAttribute(Utils.WebFrameworkCommonNamespace + "." + "DataServiceKeyAttribute", keys)); } ////// The method to be called to create the type level attributes for the StructuredTypeEmitter /// /// The strongly typed emitter /// The type declaration to add the attribues to. public void EmitTypeAttributes(StructuredTypeEmitter emitter, CodeTypeDeclaration typeDecl) { Debug.Assert(emitter != null, "emitter should not be null"); Debug.Assert(typeDecl != null, "typeDecl should not be null"); // nothing to do here yet } ////// The method to be called to create the type level attributes for the SchemaTypeEmitter /// /// The strongly typed emitter /// The type declaration to add the attribues to. public void EmitTypeAttributes(SchemaTypeEmitter emitter, CodeTypeDeclaration typeDecl) { Debug.Assert(emitter != null, "emitter should not be null"); Debug.Assert(typeDecl != null, "typeDecl should not be null"); } ////// The method to be called to create the property level attributes for the PropertyEmitter /// /// The strongly typed emitter /// The type declaration to add the attribues to. /// Additional attributes to emit public void EmitPropertyAttributes(PropertyEmitter emitter, CodeMemberProperty propertyDecl, ListadditionalAttributes) { if (additionalAttributes != null && additionalAttributes.Count > 0) { try { propertyDecl.CustomAttributes.AddRange(additionalAttributes.ToArray()); } catch (ArgumentNullException e) { emitter.Generator.AddError(Strings.InvalidAttributeSuppliedForProperty(emitter.Item.Name), ModelBuilderErrorCode.InvalidAttributeSuppliedForProperty, EdmSchemaErrorSeverity.Error, e); } } } /// /// The method to be called to create the type level attributes for the NestedTypeEmitter /// /// The strongly typed emitter /// The type declaration to add the attribues to. public void EmitTypeAttributes(ComplexTypeEmitter emitter, CodeTypeDeclaration typeDecl) { Debug.Assert(emitter != null, "emitter should not be null"); Debug.Assert(typeDecl != null, "typeDecl should not be null"); // not emitting System.Runtime.Serializaton.DataContractAttribute // not emitting System.Serializable } #region Static Methods ////// /// /// /// ///public CodeAttributeDeclaration EmitSimpleAttribute(string attributeType, params object[] arguments) { CodeAttributeDeclaration attribute = new CodeAttributeDeclaration(TypeReference.FromString(attributeType, true)); AddAttributeArguments(attribute, arguments); return attribute; } /// /// /// /// /// public static void AddAttributeArguments(CodeAttributeDeclaration attribute, object[] arguments) { foreach (object argument in arguments) { CodeExpression expression = argument as CodeExpression; if (expression == null) expression = new CodePrimitiveExpression(argument); attribute.Arguments.Add(new CodeAttributeArgument(expression)); } } ////// Adds an XmlIgnore attribute to the given property declaration. This is /// used to explicitly skip certain properties during XML serialization. /// /// the property to mark with XmlIgnore public void AddIgnoreAttributes(CodeMemberProperty propertyDecl) { // not emitting System.Xml.Serialization.XmlIgnoreAttribute // not emitting System.Xml.Serialization.SoapIgnoreAttribute } ////// Adds an Browsable(false) attribute to the given property declaration. /// This is used to explicitly avoid display property in the PropertyGrid. /// /// the property to mark with XmlIgnore public void AddBrowsableAttribute(CodeMemberProperty propertyDecl) { // not emitting System.ComponentModel.BrowsableAttribute } #endregion ////// Add the GeneratedCode attribute to the code type member /// /// the code type member public static void AddGeneratedCodeAttribute(CodeTypeMember ctm) { ctm.CustomAttributes.Add(_generatedCodeAttribute); } ///Given a type detects if it is an open type or not /// Input type ///true if it is an open type, false otherwise private static bool IsOpenType(StructuralType entityType) { MetadataProperty isOpenTypeProperty = entityType.MetadataProperties.FirstOrDefault(x => x.Name == System.Data.Services.XmlConstants.EdmV1dot2Namespace + ":" + System.Data.Services.XmlConstants.DataWebOpenTypeAttributeName); if (isOpenTypeProperty != null) { bool isOpenType; if (!Boolean.TryParse(Convert.ToString(isOpenTypeProperty.Value, CultureInfo.InvariantCulture), out isOpenType)) { throw new InvalidOperationException(Strings.ObjectContext_OpenTypePropertyValueIsNotCorrect(System.Data.Services.XmlConstants.DataWebOpenTypeAttributeName, entityType.Name)); } return isOpenType; } else { return false; } } ////// Checks if the given path corresponds to some open property on the /// Type to check the path for /// Input property path ////// true if there is some open property corresponding to the path, false otherwise bool IsOpenPropertyOnPath(StructuralType baseEntityType, String sourcePath) { Debug.Assert(baseEntityType != null, "Expecting non-null entity type"); if (String.IsNullOrEmpty(sourcePath)) { return false; } String[] propertyPath = sourcePath.Split('/'); EdmMember entityProperty = baseEntityType.Members.SingleOrDefault(p => p.Name == propertyPath[0]); if (entityProperty == null) { if (baseEntityType.BaseType != null) { return IsOpenPropertyOnPath(baseEntityType.BaseType as StructuralType, sourcePath); } else { return IsOpenType(baseEntityType); } } else { StructuralType entityPropertyType = entityProperty.TypeUsage.EdmType as StructuralType; if (entityPropertyType != null) { return IsOpenPropertyOnPath(entityPropertyType, String.Join("/", propertyPath, 1, propertyPath.Length - 1)); } else { return false; } } } ////// Obtains the entity property corresponding to a given sourcePath /// /// Entity type in which to look for property /// Source Path ///EdmMember object corresponding to the property given through source path private static EdmMember GetEntityPropertyFromEpmPath(StructuralType baseEntityType, String sourcePath) { Debug.Assert(baseEntityType != null, "Expecting non-null entity type"); String[] propertyPath = sourcePath.Split('/'); if (!baseEntityType.Members.Any(p => p.Name == propertyPath[0])) { return baseEntityType.BaseType != null ? GetEntityPropertyFromEpmPath(baseEntityType.BaseType as StructuralType, sourcePath) : null; } else { EdmMember entityProperty = null; foreach (var pathSegment in propertyPath) { if (baseEntityType == null) { return null; } entityProperty = baseEntityType.Members.SingleOrDefault(p => p.Name == pathSegment); if (entityProperty == null) { return null; } baseEntityType = entityProperty.TypeUsage.EdmType as StructuralType; } return entityProperty; } } ////// Returns a sequence of attributes corresponding to a complex type with recursion /// /// Complex typed property /// Source path /// Target path /// Namespace prefix /// Namespace Uri /// KeepInContent setting ///Sequence of entity property mapping information for complex type properties private static IEnumerableGetEpmAttrsFromComplexProperty( EdmMember complexProperty, String epmSourcePath, String epmTargetPath, String epmNsPrefix, String epmNsUri, bool epmKeepContent) { Debug.Assert(complexProperty != null, "Expecting non-null complex property"); ComplexType complexType = complexProperty.TypeUsage.EdmType as ComplexType; if (complexType == null) { throw new ArgumentException(Strings.ExpectingComplexTypeForMember(complexProperty.Name, complexProperty.DeclaringType.Name)); } foreach (EdmMember subProperty in complexType.Properties) { String sourcePath = epmSourcePath + "/" + subProperty.Name; String targetPath = epmTargetPath + "/" + subProperty.Name; if (subProperty.TypeUsage.EdmType.BuiltInTypeKind == BuiltInTypeKind.ComplexType) { foreach (EntityPropertyMappingAttribute epmAttr in GetEpmAttrsFromComplexProperty(subProperty, sourcePath, targetPath, epmNsPrefix, epmNsUri, epmKeepContent)) { yield return epmAttr; } } else { yield return new EntityPropertyMappingAttribute( sourcePath, targetPath, epmNsPrefix, epmNsUri, epmKeepContent); } } } /// /// Given a resource type, builds the EntityPropertyMappingInfo for each EntityPropertyMappingAttribute on it /// /// EFx metadata item collection that has been loaded /// Entity type for which EntityPropertyMappingAttribute discovery is happening /// Type declaration to add the attributes to private void EmitEpmAttributesForEntityType(EdmItemCollection itemCollection, EntityType entityType, CodeTypeDeclaration typeDecl) { // Get epm information provided at the entity type declaration level IEnumerableextendedProperties = entityType.MetadataProperties.Where(mp => mp.PropertyKind == PropertyKind.Extended); foreach (EpmPropertyInformation propertyInformation in GetEpmPropertyInformation(extendedProperties, entityType.Name, null)) { EdmMember redefinedProperty = GetEntityPropertyFromEpmPath(entityType, propertyInformation.SourcePath); if (redefinedProperty == null) { if (IsOpenPropertyOnPath(entityType, propertyInformation.SourcePath)) { EmitEpmAttributeForEntityProperty( propertyInformation, new EdmInfo { IsComplex = false, Member = null }, typeDecl); } else { throw new InvalidOperationException(Strings.ObjectContext_UnknownPropertyNameInEpmAttributesType(propertyInformation.SourcePath, entityType.Name)); } } else { EmitEpmAttributeForEntityProperty( propertyInformation, new EdmInfo { IsComplex = redefinedProperty.TypeUsage.EdmType.BuiltInTypeKind == BuiltInTypeKind.ComplexType, Member = redefinedProperty }, typeDecl); } } // Get epm information provided at the entity type property level foreach (EdmMember member in entityType.Members.Where(m => m.DeclaringType == entityType)) { EdmMember entityProperty = entityType.Properties.SingleOrDefault(p => p.DeclaringType == entityType && p.Name == member.Name); IEnumerable extendedMemberProperties = member.MetadataProperties.Where(mdp => mdp.PropertyKind == PropertyKind.Extended); foreach (EpmPropertyInformation propertyInformation in GetEpmPropertyInformation(extendedMemberProperties, entityType.Name, member.Name)) { EdmMember entityPropertyCurrent = entityProperty; if (entityProperty.TypeUsage.EdmType.BuiltInTypeKind == BuiltInTypeKind.ComplexType && propertyInformation.PathGiven) { String originalPath = propertyInformation.SourcePath; propertyInformation.SourcePath = entityProperty.Name + "/" + propertyInformation.SourcePath; entityPropertyCurrent = GetEntityPropertyFromEpmPath(entityType, propertyInformation.SourcePath); if (entityPropertyCurrent == null) { if (IsOpenPropertyOnPath(entityProperty.TypeUsage.EdmType as StructuralType, originalPath)) { EmitEpmAttributeForEntityProperty( propertyInformation, new EdmInfo { IsComplex = false, Member = null }, typeDecl); continue; } else { throw new InvalidOperationException(Strings.ObjectContext_UnknownPropertyNameInEpmAttributesMember(originalPath, member.Name, entityType.Name)); } } } EmitEpmAttributeForEntityProperty( propertyInformation, new EdmInfo { IsComplex = entityPropertyCurrent.TypeUsage.EdmType.BuiltInTypeKind == BuiltInTypeKind.ComplexType, Member = entityPropertyCurrent }, typeDecl); } } } /// /// Given a resource type and its resource proeperty builds the EntityPropertyMappingInfo for the EntityPropertyMappingAttribute on it /// /// EPM information for current property /// Property for which to get the information /// Type declaration to add the attributes to private void EmitEpmAttributeForEntityProperty( EpmPropertyInformation propertyInformation, EdmInfo entityProperty, CodeTypeDeclaration typeDecl) { if (propertyInformation.IsAtom) { if (entityProperty.IsComplex) { throw new InvalidOperationException(Strings.ObjectContext_SyndicationMappingForComplexPropertiesNotAllowed); } else { EntityPropertyMappingAttribute epmAttr = new EntityPropertyMappingAttribute( propertyInformation.SourcePath, propertyInformation.SyndicationItem, propertyInformation.ContentKind, propertyInformation.KeepInContent); this.AddEpmAttributeToTypeDeclaration(epmAttr, typeDecl); } } else { if (entityProperty.IsComplex) { foreach (EntityPropertyMappingAttribute epmAttr in GetEpmAttrsFromComplexProperty( entityProperty.Member, propertyInformation.SourcePath, propertyInformation.TargetPath, propertyInformation.NsPrefix, propertyInformation.NsUri, propertyInformation.KeepInContent)) { this.AddEpmAttributeToTypeDeclaration(epmAttr, typeDecl); } } else { EntityPropertyMappingAttribute epmAttr = new EntityPropertyMappingAttribute( propertyInformation.SourcePath, propertyInformation.TargetPath, propertyInformation.NsPrefix, propertyInformation.NsUri, propertyInformation.KeepInContent); this.AddEpmAttributeToTypeDeclaration(epmAttr, typeDecl); } } } ///Creates an EntityPropertyMappingAttribute and adds it to the /// Attribute to add /// Type declaration for which the attribute is generated private void AddEpmAttributeToTypeDeclaration(EntityPropertyMappingAttribute epmAttr, CodeTypeDeclaration typeDecl) { if (epmAttr.TargetSyndicationItem != SyndicationItemProperty.CustomProperty) { var syndicationItem = new CodeFieldReferenceExpression( new CodeTypeReferenceExpression(typeof(SyndicationItemProperty)), epmAttr.TargetSyndicationItem.ToString()); var contentKind = new CodeFieldReferenceExpression( new CodeTypeReferenceExpression(typeof(SyndicationTextContentKind)), epmAttr.TargetTextContentKind.ToString()); CodeAttributeDeclaration attribute = new CodeAttributeDeclaration( TypeReference.FromString( Utils.WebFrameworkCommonNamespace + "." + "EntityPropertyMappingAttribute", true)); AddAttributeArguments(attribute, new object[] { epmAttr.SourcePath, syndicationItem, contentKind, epmAttr.KeepInContent }); typeDecl.CustomAttributes.Add(attribute); } else { CodeAttributeDeclaration attribute = new CodeAttributeDeclaration( TypeReference.FromString( Utils.WebFrameworkCommonNamespace + "." + "EntityPropertyMappingAttribute", true)); AddAttributeArguments(attribute, new object[] { epmAttr.SourcePath, epmAttr.TargetPath, epmAttr.TargetNamespacePrefix, epmAttr.TargetNamespaceUri, epmAttr.KeepInContent }); typeDecl.CustomAttributes.Add(attribute); } } ////// Given a resource type, generates the HasStreamAttribute for it /// /// Entity type for which HasStreamAttribute discovery is happening /// Type declaration to add the attributes to private void EmitStreamAttributesForEntityType(EntityType entityType, CodeTypeDeclaration typeDecl) { IEnumerablehasStreamMetadataProperties = entityType.MetadataProperties.Where(mp => mp.PropertyKind == PropertyKind.Extended && mp.Name == System.Data.Services.XmlConstants.DataWebMetadataNamespace + ":" + System.Data.Services.XmlConstants.DataWebAccessHasStreamAttribute); MetadataProperty hasStreamMetadataProperty = null; foreach (MetadataProperty p in hasStreamMetadataProperties) { if (hasStreamMetadataProperty != null) { throw new InvalidOperationException( Strings.ObjectContext_MultipleValuesForSameExtendedAttributeType( System.Data.Services.XmlConstants.DataWebAccessHasStreamAttribute, entityType.Name)); } hasStreamMetadataProperty = p; } if (hasStreamMetadataProperty == null) { return; } if (!String.Equals(Convert.ToString(hasStreamMetadataProperty.Value, CultureInfo.InvariantCulture), System.Data.Services.XmlConstants.DataWebAccessDefaultStreamPropertyValue, StringComparison.Ordinal)) { return; } CodeAttributeDeclaration attribute = new CodeAttributeDeclaration( TypeReference.FromString( Utils.WebFrameworkCommonNamespace + "." + "HasStreamAttribute", true)); typeDecl.CustomAttributes.Add(attribute); } /// Edm Member information used for generating attribute, necessary for supporting /// open types which can potentioall not have any member so EdmMember property can be null /// private sealed class EdmInfo { ///Is the given type a complex type public bool IsComplex { get; set; } ///Corresponding EdmMember public EdmMember Member { get; set; } } } } // 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
- ManipulationVelocities.cs
- SectionXmlInfo.cs
- PointHitTestParameters.cs
- UnhandledExceptionEventArgs.cs
- IPCCacheManager.cs
- ListBox.cs
- XmlSchemaDatatype.cs
- SafeRightsManagementQueryHandle.cs
- FeatureSupport.cs
- Token.cs
- shaperfactoryquerycachekey.cs
- HttpCachePolicy.cs
- SocketException.cs
- SelectionRange.cs
- HttpWebRequest.cs
- WebPartHeaderCloseVerb.cs
- ProcessModuleCollection.cs
- ObjectResult.cs
- DataGridViewColumnConverter.cs
- FloatSumAggregationOperator.cs
- PropertyPanel.cs
- TriggerAction.cs
- FamilyMap.cs
- DataListItemCollection.cs
- ImageDrawing.cs
- AddingNewEventArgs.cs
- XamlInt32CollectionSerializer.cs
- CellQuery.cs
- ErrorFormatter.cs
- ConfigurationException.cs
- SqlCacheDependencySection.cs
- Crypto.cs
- GenericTypeParameterConverter.cs
- SchemaNotation.cs
- BuilderPropertyEntry.cs
- Choices.cs
- KnownBoxes.cs
- ComponentDispatcher.cs
- TextParagraph.cs
- SinglePhaseEnlistment.cs
- AsymmetricSignatureDeformatter.cs
- XmlSchemaInfo.cs
- ImageFormatConverter.cs
- ToolStripItemDesigner.cs
- SystemResources.cs
- FullTrustAssembly.cs
- LookupBindingPropertiesAttribute.cs
- DataGridViewToolTip.cs
- DbModificationCommandTree.cs
- BlockCollection.cs
- XmlSchemaExternal.cs
- RadioButton.cs
- SettingsSection.cs
- RestClientProxyHandler.cs
- Panel.cs
- WeakHashtable.cs
- StringKeyFrameCollection.cs
- MessageFilterTable.cs
- SqlClientFactory.cs
- ZoneButton.cs
- SqlFactory.cs
- HMACSHA256.cs
- CrossAppDomainChannel.cs
- GeneralTransformCollection.cs
- DbConnectionStringBuilder.cs
- ClientCredentialsSecurityTokenManager.cs
- KeyEvent.cs
- followingquery.cs
- HwndSourceParameters.cs
- RequestCachePolicy.cs
- StrokeDescriptor.cs
- Dispatcher.cs
- DiagnosticsConfigurationHandler.cs
- CommandValueSerializer.cs
- ServiceBehaviorElementCollection.cs
- DbConnectionFactory.cs
- WebBrowserContainer.cs
- XmlParser.cs
- BitmapEffectInput.cs
- WSTrust.cs
- JournalEntry.cs
- DataTemplateSelector.cs
- WorkflowFileItem.cs
- AspCompat.cs
- AnchoredBlock.cs
- HiddenField.cs
- EventLogWatcher.cs
- ApplicationFileParser.cs
- ActivitiesCollection.cs
- FlowDocumentView.cs
- Transform.cs
- ListViewTableCell.cs
- StringToken.cs
- ModelFunctionTypeElement.cs
- MonikerSyntaxException.cs
- DiscoveryDocumentReference.cs
- EventLog.cs
- FilterElement.cs
- PropertyFilterAttribute.cs
- RoutedCommand.cs