diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Framework/DAMap.cs | 328 |
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 | |||
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 | } \ No newline at end of file | ||