From f7d09b898ad6df32b3f07cb64657623980178c2f Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 27 Jun 2013 23:14:28 +0100 Subject: Make the concept of namespaces explicit in dynamic attributes This is in order to reduce the likelihood of naming clashes, make it easier to filter in/out attributes, ensure uniformity, etc. All dynattrs in the opensim distro itself or likely future ones should be in the "OpenSim" namespace. This does alter the underlying dynattrs data structure. All data in previous structures may not be available, though old structures should not cause errors. This is done without notice since this feature has been explicitly labelled as experimental, subject to change and has not been in a release. However, existing materials data is being preserved by moving it to the "Materials" store in the "OpenSim" namespace. --- OpenSim/Framework/DAMap.cs | 300 +++++++++++++++++++++++++++------------------ OpenSim/Framework/DOMap.cs | 8 +- 2 files changed, 182 insertions(+), 126 deletions(-) (limited to 'OpenSim/Framework') diff --git a/OpenSim/Framework/DAMap.cs b/OpenSim/Framework/DAMap.cs index df4a6bc..a57393b 100644 --- a/OpenSim/Framework/DAMap.cs +++ b/OpenSim/Framework/DAMap.cs @@ -29,10 +29,12 @@ using System; using System.Collections; using System.Collections.Generic; using System.IO; +using System.Reflection; using System.Text; using System.Xml; using System.Xml.Schema; using System.Xml.Serialization; +using log4net; using OpenMetaverse; using OpenMetaverse.StructuredData; @@ -48,13 +50,20 @@ namespace OpenSim.Framework /// within their data store. However, avoid storing large amounts of data because that /// would slow down database access. /// - public class DAMap : IDictionary, IXmlSerializable + public class DAMap : IXmlSerializable { - private static readonly int MIN_STORE_NAME_LENGTH = 4; +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - protected OSDMap m_map; - - public DAMap() { m_map = new OSDMap(); } + private static readonly int MIN_NAMESPACE_LENGTH = 4; + + private OSDMap m_map = new OSDMap(); + + // WARNING: this is temporary for experimentation only, it will be removed!!!! + public OSDMap TopLevelMap + { + get { return m_map; } + set { m_map = value; } + } public XmlSchema GetSchema() { return null; } @@ -64,39 +73,34 @@ namespace OpenSim.Framework map.ReadXml(rawXml); return map; } - + + public void ReadXml(XmlReader reader) + { + ReadXml(reader.ReadInnerXml()); + } + public void ReadXml(string rawXml) { // System.Console.WriteLine("Trying to deserialize [{0}]", rawXml); lock (this) + { m_map = (OSDMap)OSDParser.DeserializeLLSDXml(rawXml); + SanitiseMap(this); + } } - - // WARNING: this is temporary for experimentation only, it will be removed!!!! - public OSDMap TopLevelMap + + public void WriteXml(XmlWriter writer) { - get { return m_map; } - set { m_map = value; } + writer.WriteRaw(ToXml()); } - - public void ReadXml(XmlReader reader) - { - ReadXml(reader.ReadInnerXml()); - } - public string ToXml() { lock (this) return OSDParser.SerializeLLSDXmlString(m_map); } - public void WriteXml(XmlWriter writer) - { - writer.WriteRaw(ToXml()); - } - public void CopyFrom(DAMap other) { // Deep copy @@ -104,7 +108,7 @@ namespace OpenSim.Framework string data = null; lock (other) { - if (other.Count > 0) + if (other.CountNamespaces > 0) { data = OSDParser.SerializeLLSDXmlString(other.m_map); } @@ -120,59 +124,133 @@ namespace OpenSim.Framework } /// - /// Returns the number of data stores. + /// Sanitise the map to remove any namespaces or stores that are not OSDMap. /// - public int Count { get { lock (this) { return m_map.Count; } } } - - public bool IsReadOnly { get { return false; } } - + /// + /// + public static void SanitiseMap(DAMap daMap) + { + List keysToRemove = null; + + // Hard-coded special case that needs to be removed in the future. Normally, modules themselves should + // handle reading data from old locations + bool osMaterialsMigrationRequired = false; + + OSDMap namespacesMap = daMap.m_map; + + foreach (string key in namespacesMap.Keys) + { +// Console.WriteLine("Processing ns {0}", key); + if (!(namespacesMap[key] is OSDMap)) + { + if (keysToRemove == null) + keysToRemove = new List(); + + keysToRemove.Add(key); + } + else if (key == "OS:Materials") + { + osMaterialsMigrationRequired = true; + } + } + + if (keysToRemove != null) + { + foreach (string key in keysToRemove) + { +// Console.WriteLine ("Removing bad ns {0}", key); + namespacesMap.Remove(key); + } + } + + // Hard-coded special case that needs to be removed in the future. Normally, modules themselves should + // handle reading data from old locations + if (osMaterialsMigrationRequired) + daMap.SetStore("OpenSim", "Materials", (OSDMap)namespacesMap["OS:Materials"]); + + foreach (OSD nsOsd in namespacesMap.Values) + { + OSDMap nsOsdMap = (OSDMap)nsOsd; + keysToRemove = null; + + foreach (string key in nsOsdMap.Keys) + { + if (!(nsOsdMap[key] is OSDMap)) + { + if (keysToRemove == null) + keysToRemove = new List(); + + keysToRemove.Add(key); + } + } + + if (keysToRemove != null) + foreach (string key in keysToRemove) + nsOsdMap.Remove(key); + } + } + /// - /// Returns the names of the data stores. + /// Get the number of namespaces /// - public ICollection Keys { get { lock (this) { return m_map.Keys; } } } + public int CountNamespaces { get { lock (this) { return m_map.Count; } } } /// - /// Returns all the data stores. + /// Get the number of stores. /// - public ICollection Values + public int CountStores { - get + get { + int count = 0; + lock (this) { - List stores = new List(m_map.Count); - foreach (OSD llsd in m_map.Values) - stores.Add((OSDMap)llsd); - return stores; + foreach (OSD osdNamespace in m_map) + { + count += ((OSDMap)osdNamespace).Count; + } } + + return count; } } - - /// - /// Gets or sets one data store. - /// - /// Store name - /// - public OSDMap this[string key] - { - get - { - OSD llsd; - - lock (this) + + public OSDMap GetStore(string ns, string storeName) + { + OSD namespaceOsd; + + lock (this) + { + if (m_map.TryGetValue(ns, out namespaceOsd)) { - if (m_map.TryGetValue(key, out llsd)) - return (OSDMap)llsd; - else - return null; + OSD store; + + if (((OSDMap)namespaceOsd).TryGetValue(storeName, out store)) + return (OSDMap)store; } - } - - set + } + + return null; + } + + public void SetStore(string ns, string storeName, OSDMap store) + { + ValidateNamespace(ns); + OSDMap nsMap; + + lock (this) { - ValidateKey(key); - lock (this) - m_map[key] = value; + if (!m_map.ContainsKey(ns)) + { + nsMap = new OSDMap(); + m_map[ns] = nsMap; + } + + nsMap = (OSDMap)m_map[ns]; + +// m_log.DebugFormat("[DA MAP]: Setting store to {0}:{1}", ns, storeName); + nsMap[storeName] = store; } } @@ -180,54 +258,46 @@ namespace OpenSim.Framework /// Validate the key used for storing separate data stores. /// /// - public static void ValidateKey(string key) + public static void ValidateNamespace(string ns) { - if (key.Length < MIN_STORE_NAME_LENGTH) - throw new Exception("Minimum store name length is " + MIN_STORE_NAME_LENGTH); + if (ns.Length < MIN_NAMESPACE_LENGTH) + throw new Exception("Minimum namespace length is " + MIN_NAMESPACE_LENGTH); } - public bool ContainsKey(string key) + public bool ContainsStore(string ns, string storeName) { - lock (this) - return m_map.ContainsKey(key); - } - - public void Add(string key, OSDMap store) - { - ValidateKey(key); - lock (this) - m_map.Add(key, store); - } + OSD namespaceOsd; - public void Add(KeyValuePair kvp) - { - ValidateKey(kvp.Key); lock (this) - m_map.Add(kvp.Key, kvp.Value); - } + { + if (m_map.TryGetValue(ns, out namespaceOsd)) + { + return ((OSDMap)namespaceOsd).ContainsKey(storeName); + } + } - public bool Remove(string key) - { - lock (this) - return m_map.Remove(key); - } + return false; + } - public bool TryGetValue(string key, out OSDMap store) + public bool TryGetStore(string ns, string storeName, out OSDMap store) { + OSD namespaceOsd; + lock (this) { - OSD llsd; - if (m_map.TryGetValue(key, out llsd)) - { - store = (OSDMap)llsd; - return true; - } - else + if (m_map.TryGetValue(ns, out namespaceOsd)) { - store = null; - return false; + OSD storeOsd; + + bool result = ((OSDMap)namespaceOsd).TryGetValue(storeName, out storeOsd); + store = (OSDMap)storeOsd; + + return result; } } + + store = null; + return false; } public void Clear() @@ -235,39 +305,25 @@ namespace OpenSim.Framework lock (this) m_map.Clear(); } - - public bool Contains(KeyValuePair kvp) - { - lock (this) - return m_map.ContainsKey(kvp.Key); - } - public void CopyTo(KeyValuePair[] array, int index) + public bool RemoveStore(string ns, string storeName) { - throw new NotImplementedException(); - } + OSD namespaceOsd; - public bool Remove(KeyValuePair kvp) - { - lock (this) - return m_map.Remove(kvp.Key); - } - - public System.Collections.IDictionaryEnumerator GetEnumerator() - { lock (this) - return m_map.GetEnumerator(); - } + { + if (m_map.TryGetValue(ns, out namespaceOsd)) + { + OSDMap namespaceOsdMap = (OSDMap)namespaceOsd; + namespaceOsdMap.Remove(storeName); - IEnumerator> IEnumerable>.GetEnumerator() - { - return null; - } + // Don't keep empty namespaces around + if (namespaceOsdMap.Count <= 0) + m_map.Remove(ns); + } + } - IEnumerator IEnumerable.GetEnumerator() - { - lock (this) - return m_map.GetEnumerator(); - } + return false; + } } } \ No newline at end of file diff --git a/OpenSim/Framework/DOMap.cs b/OpenSim/Framework/DOMap.cs index 755e129..f5b650b 100644 --- a/OpenSim/Framework/DOMap.cs +++ b/OpenSim/Framework/DOMap.cs @@ -42,22 +42,22 @@ namespace OpenSim.Framework /// This class stores and retrieves dynamic objects. /// /// - /// Experimental - DO NOT USE. + /// Experimental - DO NOT USE. Does not yet have namespace support. /// public class DOMap { private IDictionary m_map; - public void Add(string key, object dynObj) + public void Add(string ns, string objName, object dynObj) { - DAMap.ValidateKey(key); + DAMap.ValidateNamespace(ns); lock (this) { if (m_map == null) m_map = new Dictionary(); - m_map.Add(key, dynObj); + m_map.Add(objName, dynObj); } } -- cgit v1.1