aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/DAMap.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Framework/DAMap.cs328
1 files changed, 328 insertions, 0 deletions
diff --git a/OpenSim/Framework/DAMap.cs b/OpenSim/Framework/DAMap.cs
new file mode 100644
index 0000000..4995a92
--- /dev/null
+++ b/OpenSim/Framework/DAMap.cs
@@ -0,0 +1,328 @@
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
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.IO;
32using System.Reflection;
33using System.Text;
34using System.Xml;
35using System.Xml.Schema;
36using System.Xml.Serialization;
37using log4net;
38using OpenMetaverse;
39using OpenMetaverse.StructuredData;
40
41namespace 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} \ No newline at end of file