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 }