1
2
3
4
5
6 using System;
7 using System.Text;
8 using System.IO;
9
10 namespace System.Xml.Serialization
11 {
12 public enum XmlBundleKind : int
13 {
14 shallow = 0, deep = 1
15 }
16
17 public class XmlBundle : XmlContainer
18 {
19 public nothrow XmlBundle() : base(), owning(false)
20 {
21 }
22 public ~XmlBundle()
23 {
24 if (owning)
25 {
26 DestroyNonownedObjects();
27 }
28 }
29 public nothrow bool IsOwning() const
30 {
31 return owning;
32 }
33 public nothrow void SetOwning()
34 {
35 owning = true;
36 }
37 public nothrow void ResetOwning()
38 {
39 owning = false;
40 }
41 public nothrow void DestroyNonownedObjects()
42 {
43 List<XmlSerializableProxy*> proxies = GetProxies();
44 List<XmlSerializableProxy*> toBeDestroyed;
45 for (XmlSerializableProxy* proxy : proxies)
46 {
47 if (!proxy->IsOwned())
48 {
49 toBeDestroyed.Add(proxy);
50 }
51 }
52 for (XmlSerializableProxy* d : toBeDestroyed)
53 {
54 d->DestroyObject();
55 }
56 Clear();
57 }
58 public nothrow const Uuid& RootObjectId() const
59 {
60 return rootObjectId;
61 }
62 public override nothrow void SetRootObjectId(const Uuid& rootObjectId_)
63 {
64 rootObjectId = rootObjectId_;
65 }
66 public nothrow XmlSerializableProxy* Root() const
67 {
68 if (rootObjectId != Uuid())
69 {
70 return Get(rootObjectId);
71 }
72 else
73 {
74 return null;
75 }
76 }
77 public UniquePtr<System.Dom.Document> ToXmlDocument()
78 {
79 UniquePtr<System.Dom.Element> rootElement(new System.Dom.Element(u"xmlBundle"));
80 rootElement->SetAttribute(u"rootObjectId", ToUtf32(ToString(rootObjectId)));
81 List<XmlSerializableProxy*> proxies = GetProxies();
82 for (XmlSerializableProxy* proxy : proxies)
83 {
84 if (proxy->Object() != null)
85 {
86 UniquePtr<System.Dom.Element> serializableElement = proxy->ToXml("object");
87 rootElement->AppendChild(UniquePtr<System.Dom.Node>(serializableElement.Release()));
88 }
89 }
90 UniquePtr<System.Dom.Document> document(new System.Dom.Document());
91 document->AppendChild(UniquePtr<System.Dom.Node>(rootElement.Release()));
92 return document;
93 }
94 public string ToXmlString() const
95 {
96 return ToXmlString(1);
97 }
98 public string ToXmlString(int indent) const
99 {
100 UniquePtr<System.Dom.Document> document = ToXmlDocument();
101 StringWriter stringWriter;
102 CodeFormatter formatter(stringWriter);
103 formatter.SetIndentSize(indent);
104 document->Write(formatter);
105 return stringWriter.GetString();
106 }
107 public void ResolveXmlPtrs()
108 {
109 List<XmlSerializableProxy*> proxies = GetProxies();
110 for (XmlSerializableProxy* proxy : proxies)
111 {
112 List<XmlPtrBase*> ptrs = proxy->GetPtrs();
113 for (XmlPtrBase* ptr : ptrs)
114 {
115 ptr->Resolve(this);
116 }
117 }
118 }
119 private Uuid rootObjectId;
120 private bool owning;
121 }
122
123 public UniquePtr<XmlBundle> ToXmlBundle(const string& xmlStr, const string& systemId)
124 {
125 return ToXmlBundle(xmlStr, systemId, true);
126 }
127
128 public UniquePtr<XmlBundle> ToXmlBundle(const string& xmlStr, const string& systemId, bool createOwningBundle)
129 {
130 UniquePtr<XmlBundle> bundle(new XmlBundle());
131 if (createOwningBundle)
132 {
133 bundle->SetOwning();
134 }
135 ustring content = ToUtf32(xmlStr);
136 UniquePtr<System.Dom.Document> document = System.Dom.ParseDocument(content, systemId);
137 UniquePtr<System.XPath.XPathObject> bundleObject = System.XPath.Evaluate(u"xmlBundle", document.Get());
138 if (!bundleObject.IsNull())
139 {
140 if (bundleObject.Get() is System.XPath.XPathNodeSet*)
141 {
142 System.XPath.XPathNodeSet* nodeSet = cast<System.XPath.XPathNodeSet*>(bundleObject.Get());
143 int length = nodeSet->Length();
144 if (length == 1)
145 {
146 System.Dom.Node* node = (*nodeSet)[0];
147 if (node is System.Dom.Element*)
148 {
149 System.Dom.Element* rootElement = cast<System.Dom.Element*>(node);
150 ustring rootObjectIdAttr = rootElement->GetAttribute(u"rootObjectId");
151 if (!rootObjectIdAttr.IsEmpty())
152 {
153 Uuid rootObjectId = ParseUuid(ToUtf8(rootObjectIdAttr));
154 bundle->SetRootObjectId(rootObjectId);
155 }
156 }
157 UniquePtr<System.XPath.XPathObject> object = System.XPath.Evaluate(u"xmlBundle/object", document.Get());
158 if (!object.IsNull())
159 {
160 if (object.Get() is System.XPath.XPathNodeSet*)
161 {
162 System.XPath.XPathNodeSet* nodeSet = cast<System.XPath.XPathNodeSet*>(object.Get());
163 int n = nodeSet->Length();
164 for (int i = 0; i < n; ++i;)
165 {
166 System.Dom.Node* node = (*nodeSet)[i];
167 if (node is System.Dom.Element*)
168 {
169 System.Dom.Element* element = cast<System.Dom.Element*>(node);
170 ustring classIdAttr = element->GetAttribute(u"classId");
171 if (!classIdAttr.IsEmpty())
172 {
173 int classId = ParseInt(ToUtf8(classIdAttr));
174 XmlSerializable xmlSerializable = XmlClassRegistry.Instance().CreateXmlSerializable(classId);
175 xmlSerializable.FromXml(element);
176 bundle->Add(xmlSerializable);
177 }
178 }
179 }
180 }
181 }
182 bundle->ResolveXmlPtrs();
183 }
184 else
185 {
186 throw XmlSerializationException("single 'xmlBundle' element expected");
187 }
188 }
189 }
190 return bundle;
191 }
192 }
193