aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/Serialization/External/ExternalRepresentationUtils.cs
diff options
context:
space:
mode:
authorDavid Walter Seikel2016-11-03 21:44:39 +1000
committerDavid Walter Seikel2016-11-03 21:44:39 +1000
commit134f86e8d5c414409631b25b8c6f0ee45fbd8631 (patch)
tree216b89d3fb89acfb81be1e440c25c41ab09fa96d /OpenSim/Framework/Serialization/External/ExternalRepresentationUtils.cs
parentMore changing to production grid. Double oops. (diff)
downloadopensim-SC_OLD-134f86e8d5c414409631b25b8c6f0ee45fbd8631.zip
opensim-SC_OLD-134f86e8d5c414409631b25b8c6f0ee45fbd8631.tar.gz
opensim-SC_OLD-134f86e8d5c414409631b25b8c6f0ee45fbd8631.tar.bz2
opensim-SC_OLD-134f86e8d5c414409631b25b8c6f0ee45fbd8631.tar.xz
Initial update to OpenSim 0.8.2.1 source code.
Diffstat (limited to 'OpenSim/Framework/Serialization/External/ExternalRepresentationUtils.cs')
-rw-r--r--OpenSim/Framework/Serialization/External/ExternalRepresentationUtils.cs267
1 files changed, 251 insertions, 16 deletions
diff --git a/OpenSim/Framework/Serialization/External/ExternalRepresentationUtils.cs b/OpenSim/Framework/Serialization/External/ExternalRepresentationUtils.cs
index c56f213..55640ac 100644
--- a/OpenSim/Framework/Serialization/External/ExternalRepresentationUtils.cs
+++ b/OpenSim/Framework/Serialization/External/ExternalRepresentationUtils.cs
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Diagnostics;
30using System.IO; 31using System.IO;
31using System.Reflection; 32using System.Reflection;
32using System.Xml; 33using System.Xml;
@@ -47,20 +48,20 @@ namespace OpenSim.Framework.Serialization.External
47 /// Populate a node with data read from xml using a dictinoary of processors 48 /// Populate a node with data read from xml using a dictinoary of processors
48 /// </summary> 49 /// </summary>
49 /// <param name="nodeToFill"></param> 50 /// <param name="nodeToFill"></param>
50 /// <param name="processors">/param> 51 /// <param name="processors"></param>
51 /// <param name="xtr"></param> 52 /// <param name="xtr"></param>
52 /// <returns>true on successful, false if there were any processing failures</returns> 53 /// <returns>true on successful, false if there were any processing failures</returns>
53 public static bool ExecuteReadProcessors<NodeType>( 54 public static bool ExecuteReadProcessors<NodeType>(
54 NodeType nodeToFill, Dictionary<string, Action<NodeType, XmlTextReader>> processors, XmlTextReader xtr) 55 NodeType nodeToFill, Dictionary<string, Action<NodeType, XmlReader>> processors, XmlReader xtr)
55 { 56 {
56 return ExecuteReadProcessors( 57 return ExecuteReadProcessors(
57 nodeToFill, 58 nodeToFill,
58 processors, 59 processors,
59 xtr, 60 xtr,
60 (o, name, e) 61 (o, nodeName, e) => {
61 => m_log.DebugFormat( 62 m_log.Debug(string.Format("[ExternalRepresentationUtils]: Error while parsing element {0} ",
62 "[ExternalRepresentationUtils]: Exception while parsing element {0}, continuing. Exception {1}{2}", 63 nodeName), e);
63 name, e.Message, e.StackTrace)); 64 });
64 } 65 }
65 66
66 /// <summary> 67 /// <summary>
@@ -75,23 +76,27 @@ namespace OpenSim.Framework.Serialization.External
75 /// <returns>true on successful, false if there were any processing failures</returns> 76 /// <returns>true on successful, false if there were any processing failures</returns>
76 public static bool ExecuteReadProcessors<NodeType>( 77 public static bool ExecuteReadProcessors<NodeType>(
77 NodeType nodeToFill, 78 NodeType nodeToFill,
78 Dictionary<string, Action<NodeType, XmlTextReader>> processors, 79 Dictionary<string, Action<NodeType, XmlReader>> processors,
79 XmlTextReader xtr, 80 XmlReader xtr,
80 Action<NodeType, string, Exception> parseExceptionAction) 81 Action<NodeType, string, Exception> parseExceptionAction)
81 { 82 {
82 bool errors = false; 83 bool errors = false;
84 int numErrors = 0;
85
86 Stopwatch timer = new Stopwatch();
87 timer.Start();
83 88
84 string nodeName = string.Empty; 89 string nodeName = string.Empty;
85 while (xtr.NodeType != XmlNodeType.EndElement) 90 while (xtr.NodeType != XmlNodeType.EndElement)
86 { 91 {
87 nodeName = xtr.Name; 92 nodeName = xtr.Name;
88 93
89// m_log.DebugFormat("[ExternalRepresentationUtils]: Processing: {0}", nodeName); 94 // m_log.DebugFormat("[ExternalRepresentationUtils]: Processing node: {0}", nodeName);
90 95
91 Action<NodeType, XmlTextReader> p = null; 96 Action<NodeType, XmlReader> p = null;
92 if (processors.TryGetValue(xtr.Name, out p)) 97 if (processors.TryGetValue(xtr.Name, out p))
93 { 98 {
94// m_log.DebugFormat("[ExternalRepresentationUtils]: Found {0} processor, nodeName); 99 // m_log.DebugFormat("[ExternalRepresentationUtils]: Found processor for {0}", nodeName);
95 100
96 try 101 try
97 { 102 {
@@ -101,6 +106,18 @@ namespace OpenSim.Framework.Serialization.External
101 { 106 {
102 errors = true; 107 errors = true;
103 parseExceptionAction(nodeToFill, nodeName, e); 108 parseExceptionAction(nodeToFill, nodeName, e);
109
110 if (xtr.EOF)
111 {
112 m_log.Debug("[ExternalRepresentationUtils]: Aborting ExecuteReadProcessors due to unexpected end of XML");
113 break;
114 }
115
116 if (++numErrors == 10)
117 {
118 m_log.Debug("[ExternalRepresentationUtils]: Aborting ExecuteReadProcessors due to too many parsing errors");
119 break;
120 }
104 121
105 if (xtr.NodeType == XmlNodeType.EndElement) 122 if (xtr.NodeType == XmlNodeType.EndElement)
106 xtr.Read(); 123 xtr.Read();
@@ -108,9 +125,16 @@ namespace OpenSim.Framework.Serialization.External
108 } 125 }
109 else 126 else
110 { 127 {
111 // m_log.DebugFormat("[LandDataSerializer]: caught unknown element {0}", nodeName); 128 // m_log.DebugFormat("[ExternalRepresentationUtils]: found unknown element \"{0}\"", nodeName);
112 xtr.ReadOuterXml(); // ignore 129 xtr.ReadOuterXml(); // ignore
113 } 130 }
131
132 if (timer.Elapsed.TotalSeconds >= 60)
133 {
134 m_log.Debug("[ExternalRepresentationUtils]: Aborting ExecuteReadProcessors due to timeout");
135 errors = true;
136 break;
137 }
114 } 138 }
115 139
116 return errors; 140 return errors;
@@ -125,7 +149,8 @@ namespace OpenSim.Framework.Serialization.External
125 /// <param name="userService">The service for retrieving user account information</param> 149 /// <param name="userService">The service for retrieving user account information</param>
126 /// <param name="scopeID">The scope of the user account information (Grid ID)</param> 150 /// <param name="scopeID">The scope of the user account information (Grid ID)</param>
127 /// <returns>The SceneObjectPart represented in XML2</returns> 151 /// <returns>The SceneObjectPart represented in XML2</returns>
128 public static string RewriteSOP(string xml, string homeURL, IUserAccountService userService, UUID scopeID) 152 [Obsolete("This method is deprecated. Use RewriteSOP instead.")]
153 public static string RewriteSOP_Old(string xml, string homeURL, IUserAccountService userService, UUID scopeID)
129 { 154 {
130 if (xml == string.Empty || homeURL == string.Empty || userService == null) 155 if (xml == string.Empty || homeURL == string.Empty || userService == null)
131 return xml; 156 return xml;
@@ -161,7 +186,7 @@ namespace OpenSim.Framework.Serialization.External
161 if (!hasCreatorData && creator != null) 186 if (!hasCreatorData && creator != null)
162 { 187 {
163 XmlElement creatorData = doc.CreateElement("CreatorData"); 188 XmlElement creatorData = doc.CreateElement("CreatorData");
164 creatorData.InnerText = homeURL + ";" + creator.FirstName + " " + creator.LastName; 189 creatorData.InnerText = CalcCreatorData(homeURL, creator.FirstName + " " + creator.LastName);
165 sop.AppendChild(creatorData); 190 sop.AppendChild(creatorData);
166 } 191 }
167 } 192 }
@@ -172,5 +197,215 @@ namespace OpenSim.Framework.Serialization.External
172 return wr.ToString(); 197 return wr.ToString();
173 } 198 }
174 } 199 }
200
201 /// <summary>
202 /// Takes a XML representation of a SceneObjectPart and returns another XML representation
203 /// with creator data added to it.
204 /// </summary>
205 /// <param name="xml">The SceneObjectPart represented in XML2</param>
206 /// <param name="sceneName">An identifier for the component that's calling this function</param>
207 /// <param name="homeURL">The URL of the user agents service (home) for the creator</param>
208 /// <param name="userService">The service for retrieving user account information</param>
209 /// <param name="scopeID">The scope of the user account information (Grid ID)</param>
210 /// <returns>The SceneObjectPart represented in XML2</returns>
211 public static string RewriteSOP(string xmlData, string sceneName, string homeURL, IUserAccountService userService, UUID scopeID)
212 {
213 // Console.WriteLine("Input XML [{0}]", xmlData);
214 if (xmlData == string.Empty || homeURL == string.Empty || userService == null)
215 return xmlData;
216
217 // Deal with bug
218 xmlData = ExternalRepresentationUtils.SanitizeXml(xmlData);
219
220 using (StringWriter sw = new StringWriter())
221 using (XmlTextWriter writer = new XmlTextWriter(sw))
222 using (XmlTextReader wrappedReader = new XmlTextReader(xmlData, XmlNodeType.Element, null))
223 using (XmlReader reader = XmlReader.Create(wrappedReader, new XmlReaderSettings() { IgnoreWhitespace = true, ConformanceLevel = ConformanceLevel.Fragment }))
224 {
225 TransformXml(reader, writer, sceneName, homeURL, userService, scopeID);
226
227 // Console.WriteLine("Output: [{0}]", sw.ToString());
228
229 return sw.ToString();
230 }
231 }
232
233 protected static void TransformXml(XmlReader reader, XmlWriter writer, string sceneName, string homeURI, IUserAccountService userAccountService, UUID scopeID)
234 {
235 // m_log.DebugFormat("[HG ASSET MAPPER]: Transforming XML");
236
237 int sopDepth = -1;
238 UserAccount creator = null;
239 bool hasCreatorData = false;
240
241 while (reader.Read())
242 {
243 // Console.WriteLine("Depth: {0}, name {1}", reader.Depth, reader.Name);
244
245 switch (reader.NodeType)
246 {
247 case XmlNodeType.Attribute:
248 // Console.WriteLine("FOUND ATTRIBUTE {0}", reader.Name);
249 writer.WriteAttributeString(reader.Name, reader.Value);
250 break;
251
252 case XmlNodeType.CDATA:
253 writer.WriteCData(reader.Value);
254 break;
255
256 case XmlNodeType.Comment:
257 writer.WriteComment(reader.Value);
258 break;
259
260 case XmlNodeType.DocumentType:
261 writer.WriteDocType(reader.Name, reader.Value, null, null);
262 break;
263
264 case XmlNodeType.Element:
265 // m_log.DebugFormat("Depth {0} at element {1}", reader.Depth, reader.Name);
266
267 writer.WriteStartElement(reader.Prefix, reader.LocalName, reader.NamespaceURI);
268
269 if (reader.HasAttributes)
270 {
271 while (reader.MoveToNextAttribute())
272 writer.WriteAttributeString(reader.Name, reader.Value);
273
274 reader.MoveToElement();
275 }
276
277 if (reader.LocalName == "SceneObjectPart")
278 {
279 if (sopDepth < 0)
280 {
281 sopDepth = reader.Depth;
282 // m_log.DebugFormat("[HG ASSET MAPPER]: Set sopDepth to {0}", sopDepth);
283 }
284 }
285 else
286 {
287 if (sopDepth >= 0 && reader.Depth == sopDepth + 1)
288 {
289 if (reader.Name == "CreatorID")
290 {
291 reader.Read();
292 if (reader.NodeType == XmlNodeType.Element && reader.Name == "Guid" || reader.Name == "UUID")
293 {
294 reader.Read();
295
296 if (reader.NodeType == XmlNodeType.Text)
297 {
298 UUID uuid = UUID.Zero;
299 UUID.TryParse(reader.Value, out uuid);
300 creator = userAccountService.GetUserAccount(scopeID, uuid);
301 writer.WriteElementString("UUID", reader.Value);
302 reader.Read();
303 }
304 else
305 {
306 // If we unexpected run across mixed content in this node, still carry on
307 // transforming the subtree (this replicates earlier behaviour).
308 TransformXml(reader, writer, sceneName, homeURI, userAccountService, scopeID);
309 }
310 }
311 else
312 {
313 // If we unexpected run across mixed content in this node, still carry on
314 // transforming the subtree (this replicates earlier behaviour).
315 TransformXml(reader, writer, sceneName, homeURI, userAccountService, scopeID);
316 }
317 }
318 else if (reader.Name == "CreatorData")
319 {
320 reader.Read();
321 if (reader.NodeType == XmlNodeType.Text)
322 {
323 hasCreatorData = true;
324 writer.WriteString(reader.Value);
325 }
326 else
327 {
328 // If we unexpected run across mixed content in this node, still carry on
329 // transforming the subtree (this replicates earlier behaviour).
330 TransformXml(reader, writer, sceneName, homeURI, userAccountService, scopeID);
331 }
332 }
333 }
334 }
335
336 if (reader.IsEmptyElement)
337 {
338 // m_log.DebugFormat("[HG ASSET MAPPER]: Writing end for empty element {0}", reader.Name);
339 writer.WriteEndElement();
340 }
341
342 break;
343
344 case XmlNodeType.EndElement:
345 // m_log.DebugFormat("Depth {0} at EndElement", reader.Depth);
346 if (sopDepth == reader.Depth)
347 {
348 if (!hasCreatorData && creator != null)
349 writer.WriteElementString(reader.Prefix, "CreatorData", reader.NamespaceURI, string.Format("{0};{1} {2}", homeURI, creator.FirstName, creator.LastName));
350
351 // m_log.DebugFormat("[HG ASSET MAPPER]: Reset sopDepth");
352 sopDepth = -1;
353 creator = null;
354 hasCreatorData = false;
355 }
356 writer.WriteEndElement();
357 break;
358
359 case XmlNodeType.EntityReference:
360 writer.WriteEntityRef(reader.Name);
361 break;
362
363 case XmlNodeType.ProcessingInstruction:
364 writer.WriteProcessingInstruction(reader.Name, reader.Value);
365 break;
366
367 case XmlNodeType.Text:
368 writer.WriteString(reader.Value);
369 break;
370
371 case XmlNodeType.XmlDeclaration:
372 // For various reasons, not all serializations have xml declarations (or consistent ones)
373 // and as it's embedded inside a byte stream we don't need it anyway, so ignore.
374 break;
375
376 default:
377 m_log.WarnFormat(
378 "[HG ASSET MAPPER]: Unrecognized node {0} in asset XML transform in {1}",
379 reader.NodeType, sceneName);
380 break;
381 }
382 }
383 }
384
385 public static string CalcCreatorData(string homeURL, string name)
386 {
387 return homeURL + ";" + name;
388 }
389
390 internal static string CalcCreatorData(string homeURL, UUID uuid, string name)
391 {
392 return homeURL + "/" + uuid + ";" + name;
393 }
394
395 /// <summary>
396 /// Sanitation for bug introduced in Oct. 20 (1eb3e6cc43e2a7b4053bc1185c7c88e22356c5e8)
397 /// </summary>
398 /// <param name="xmlData"></param>
399 /// <returns></returns>
400 public static string SanitizeXml(string xmlData)
401 {
402 string fixedData = xmlData;
403 if (fixedData != null)
404 // Loop, because it may contain multiple
405 while (fixedData.Contains("xmlns:xmlns:"))
406 fixedData = fixedData.Replace("xmlns:xmlns:", "xmlns:");
407 return fixedData;
408 }
409
175 } 410 }
176} \ No newline at end of file 411}