1 //Copyright 2010 Microsoft Corporation 2 // 3 //Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. 4 //You may obtain a copy of the License at 5 // 6 //http://www.apache.org/licenses/LICENSE-2.0 7 // 8 //Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an 9 //"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 //See the License for the specific language governing permissions and limitations under the License. 11 12 13 namespace System.Data.Services.Common 14 { 15 using System.Collections.Generic; 16 using System.Diagnostics; 17 using System.Data.Services.Client; 18 using System.Xml; 19 20 internal sealed class EpmCustomContentSerializer : EpmContentSerializerBase, IDisposable 21 { 22 private bool disposed; 23 24 private Dictionary<EpmTargetPathSegment, EpmCustomContentWriterNodeData> visitorContent; 25 EpmCustomContentSerializer(EpmTargetTree targetTree, object element, XmlWriter target)26 internal EpmCustomContentSerializer(EpmTargetTree targetTree, object element, XmlWriter target) 27 : base(targetTree, false, element, target) 28 { 29 this.InitializeVisitorContent(); 30 } 31 Dispose()32 public void Dispose() 33 { 34 if (!this.disposed) 35 { 36 foreach (EpmTargetPathSegment subSegmentOfRoot in this.Root.SubSegments) 37 { 38 EpmCustomContentWriterNodeData c = this.visitorContent[subSegmentOfRoot]; 39 Debug.Assert(c != null, "Must have custom data for all the children of root"); 40 if (this.Success) 41 { 42 c.AddContentToTarget(this.Target); 43 } 44 45 c.Dispose(); 46 } 47 48 this.disposed = true; 49 } 50 } 51 Serialize(EpmTargetPathSegment targetSegment, EpmSerializationKind kind)52 protected override void Serialize(EpmTargetPathSegment targetSegment, EpmSerializationKind kind) 53 { 54 if (targetSegment.IsAttribute) 55 { 56 this.WriteAttribute(targetSegment); 57 } 58 else 59 { 60 this.WriteElement(targetSegment); 61 } 62 } 63 WriteAttribute(EpmTargetPathSegment targetSegment)64 private void WriteAttribute(EpmTargetPathSegment targetSegment) 65 { 66 Debug.Assert(targetSegment.HasContent, "Must have content for attributes"); 67 68 EpmCustomContentWriterNodeData currentContent = this.visitorContent[targetSegment]; 69 currentContent.XmlContentWriter.WriteAttributeString( 70 targetSegment.SegmentNamespacePrefix, 71 targetSegment.SegmentName.Substring(1), 72 targetSegment.SegmentNamespaceUri, 73 currentContent.Data); 74 } 75 WriteElement(EpmTargetPathSegment targetSegment)76 private void WriteElement(EpmTargetPathSegment targetSegment) 77 { 78 EpmCustomContentWriterNodeData currentContent = this.visitorContent[targetSegment]; 79 80 currentContent.XmlContentWriter.WriteStartElement( 81 targetSegment.SegmentNamespacePrefix, 82 targetSegment.SegmentName, 83 targetSegment.SegmentNamespaceUri); 84 85 base.Serialize(targetSegment, EpmSerializationKind.Attributes); 86 87 if (targetSegment.HasContent) 88 { 89 Debug.Assert(currentContent.Data != null, "Must always have non-null data content value"); 90 currentContent.XmlContentWriter.WriteString(currentContent.Data); 91 } 92 93 base.Serialize(targetSegment, EpmSerializationKind.Elements); 94 95 currentContent.XmlContentWriter.WriteEndElement(); 96 } 97 98 InitializeVisitorContent()99 private void InitializeVisitorContent() 100 { 101 this.visitorContent = new Dictionary<EpmTargetPathSegment, EpmCustomContentWriterNodeData>(ReferenceEqualityComparer<EpmTargetPathSegment>.Instance); 102 103 foreach (EpmTargetPathSegment subSegmentOfRoot in this.Root.SubSegments) 104 { 105 this.visitorContent.Add(subSegmentOfRoot, new EpmCustomContentWriterNodeData(subSegmentOfRoot, this.Element)); 106 this.InitializeSubSegmentVisitorContent(subSegmentOfRoot); 107 } 108 } 109 InitializeSubSegmentVisitorContent(EpmTargetPathSegment subSegment)110 private void InitializeSubSegmentVisitorContent(EpmTargetPathSegment subSegment) 111 { 112 foreach (EpmTargetPathSegment segment in subSegment.SubSegments) 113 { 114 this.visitorContent.Add(segment, new EpmCustomContentWriterNodeData(this.visitorContent[subSegment], segment, this.Element)); 115 this.InitializeSubSegmentVisitorContent(segment); 116 } 117 } 118 119 } 120 }