clockwerk-opensim-stable – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 vero 1 /*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27  
28 using System;
29 using System.Collections;
30 using System.Collections.Generic;
31 using System.IO;
32 using System.Reflection;
33 using System.Text;
34 using System.Xml;
35 using System.Xml.Schema;
36 using System.Xml.Serialization;
37 using log4net;
38 using OpenMetaverse;
39 using OpenMetaverse.StructuredData;
40  
41 namespace OpenSim.Framework
42 {
43 /// <summary>
44 /// This class stores and retrieves dynamic attributes.
45 /// </summary>
46 /// <remarks>
47 /// Modules that want to use dynamic attributes need to do so in a private data store
48 /// which is accessed using a unique name. DAMap provides access to the data stores,
49 /// each of which is an OSDMap. Modules are free to store any type of data they want
50 /// within their data store. However, avoid storing large amounts of data because that
51 /// would slow down database access.
52 /// </remarks>
53 public class DAMap : IXmlSerializable
54 {
55 // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
56  
57 private static readonly int MIN_NAMESPACE_LENGTH = 4;
58  
59 private OSDMap m_map = new OSDMap();
60  
61 // WARNING: this is temporary for experimentation only, it will be removed!!!!
62 public OSDMap TopLevelMap
63 {
64 get { return m_map; }
65 set { m_map = value; }
66 }
67  
68 public XmlSchema GetSchema() { return null; }
69  
70 public static DAMap FromXml(string rawXml)
71 {
72 DAMap map = new DAMap();
73 map.ReadXml(rawXml);
74 return map;
75 }
76  
77 public void ReadXml(XmlReader reader)
78 {
79 ReadXml(reader.ReadInnerXml());
80 }
81  
82 public void ReadXml(string rawXml)
83 {
84 // System.Console.WriteLine("Trying to deserialize [{0}]", rawXml);
85  
86 lock (this)
87 {
88 m_map = (OSDMap)OSDParser.DeserializeLLSDXml(rawXml);
89 SanitiseMap(this);
90 }
91 }
92  
93 public void WriteXml(XmlWriter writer)
94 {
95 writer.WriteRaw(ToXml());
96 }
97  
98 public string ToXml()
99 {
100 lock (this)
101 return OSDParser.SerializeLLSDXmlString(m_map);
102 }
103  
104 public void CopyFrom(DAMap other)
105 {
106 // Deep copy
107  
108 string data = null;
109 lock (other)
110 {
111 if (other.CountNamespaces > 0)
112 {
113 data = OSDParser.SerializeLLSDXmlString(other.m_map);
114 }
115 }
116  
117 lock (this)
118 {
119 if (data == null)
120 Clear();
121 else
122 m_map = (OSDMap)OSDParser.DeserializeLLSDXml(data);
123 }
124 }
125  
126 /// <summary>
127 /// Sanitise the map to remove any namespaces or stores that are not OSDMap.
128 /// </summary>
129 /// <param name='map'>
130 /// </param>
131 public static void SanitiseMap(DAMap daMap)
132 {
133 List<string> keysToRemove = null;
134  
135 OSDMap namespacesMap = daMap.m_map;
136  
137 foreach (string key in namespacesMap.Keys)
138 {
139 // Console.WriteLine("Processing ns {0}", key);
140 if (!(namespacesMap[key] is OSDMap))
141 {
142 if (keysToRemove == null)
143 keysToRemove = new List<string>();
144  
145 keysToRemove.Add(key);
146 }
147 }
148  
149 if (keysToRemove != null)
150 {
151 foreach (string key in keysToRemove)
152 {
153 // Console.WriteLine ("Removing bad ns {0}", key);
154 namespacesMap.Remove(key);
155 }
156 }
157  
158 foreach (OSD nsOsd in namespacesMap.Values)
159 {
160 OSDMap nsOsdMap = (OSDMap)nsOsd;
161 keysToRemove = null;
162  
163 foreach (string key in nsOsdMap.Keys)
164 {
165 if (!(nsOsdMap[key] is OSDMap))
166 {
167 if (keysToRemove == null)
168 keysToRemove = new List<string>();
169  
170 keysToRemove.Add(key);
171 }
172 }
173  
174 if (keysToRemove != null)
175 foreach (string key in keysToRemove)
176 nsOsdMap.Remove(key);
177 }
178 }
179  
180 /// <summary>
181 /// Get the number of namespaces
182 /// </summary>
183 public int CountNamespaces { get { lock (this) { return m_map.Count; } } }
184  
185 /// <summary>
186 /// Get the number of stores.
187 /// </summary>
188 public int CountStores
189 {
190 get
191 {
192 int count = 0;
193  
194 lock (this)
195 {
196 foreach (OSD osdNamespace in m_map)
197 {
198 count += ((OSDMap)osdNamespace).Count;
199 }
200 }
201  
202 return count;
203 }
204 }
205  
206 /// <summary>
207 /// Retrieve a Dynamic Attribute store
208 /// </summary>
209 /// <param name="ns">namespace for the store - use "OpenSim" for in-core modules</param>
210 /// <param name="storeName">name of the store within the namespace</param>
211 /// <returns>an OSDMap representing the stored data, or null if not found</returns>
212 public OSDMap GetStore(string ns, string storeName)
213 {
214 OSD namespaceOsd;
215  
216 lock (this)
217 {
218 if (m_map.TryGetValue(ns, out namespaceOsd))
219 {
220 OSD store;
221  
222 if (((OSDMap)namespaceOsd).TryGetValue(storeName, out store))
223 return (OSDMap)store;
224 }
225 }
226  
227 return null;
228 }
229  
230 /// <summary>
231 /// Saves a Dynamic attribute store
232 /// </summary>
233 /// <param name="ns">namespace for the store - use "OpenSim" for in-core modules</param>
234 /// <param name="storeName">name of the store within the namespace</param>
235 /// <param name="store">an OSDMap representing the data to store</param>
236 public void SetStore(string ns, string storeName, OSDMap store)
237 {
238 ValidateNamespace(ns);
239 OSDMap nsMap;
240  
241 lock (this)
242 {
243 if (!m_map.ContainsKey(ns))
244 {
245 nsMap = new OSDMap();
246 m_map[ns] = nsMap;
247 }
248  
249 nsMap = (OSDMap)m_map[ns];
250  
251 // m_log.DebugFormat("[DA MAP]: Setting store to {0}:{1}", ns, storeName);
252 nsMap[storeName] = store;
253 }
254 }
255  
256 /// <summary>
257 /// Validate the key used for storing separate data stores.
258 /// </summary>
259 /// <param name='key'></param>
260 public static void ValidateNamespace(string ns)
261 {
262 if (ns.Length < MIN_NAMESPACE_LENGTH)
263 throw new Exception("Minimum namespace length is " + MIN_NAMESPACE_LENGTH);
264 }
265  
266 public bool ContainsStore(string ns, string storeName)
267 {
268 OSD namespaceOsd;
269  
270 lock (this)
271 {
272 if (m_map.TryGetValue(ns, out namespaceOsd))
273 {
274 return ((OSDMap)namespaceOsd).ContainsKey(storeName);
275 }
276 }
277  
278 return false;
279 }
280  
281 public bool TryGetStore(string ns, string storeName, out OSDMap store)
282 {
283 OSD namespaceOsd;
284  
285 lock (this)
286 {
287 if (m_map.TryGetValue(ns, out namespaceOsd))
288 {
289 OSD storeOsd;
290  
291 bool result = ((OSDMap)namespaceOsd).TryGetValue(storeName, out storeOsd);
292 store = (OSDMap)storeOsd;
293  
294 return result;
295 }
296 }
297  
298 store = null;
299 return false;
300 }
301  
302 public void Clear()
303 {
304 lock (this)
305 m_map.Clear();
306 }
307  
308 public bool RemoveStore(string ns, string storeName)
309 {
310 OSD namespaceOsd;
311  
312 lock (this)
313 {
314 if (m_map.TryGetValue(ns, out namespaceOsd))
315 {
316 OSDMap namespaceOsdMap = (OSDMap)namespaceOsd;
317 namespaceOsdMap.Remove(storeName);
318  
319 // Don't keep empty namespaces around
320 if (namespaceOsdMap.Count <= 0)
321 m_map.Remove(ns);
322 }
323 }
324  
325 return false;
326 }
327 }
328 }