Changeset 115
- Timestamp:
- 04/21/02 13:47:10 (6 years ago)
- Files:
-
- trunk/RBFoundation/RBFoundation/Composite.py (deleted)
- trunk/RBFoundation/RBFoundation/XMLBuilder.py (modified) (2 diffs)
- trunk/RBFoundation/RBFoundation/XMLClassBuilder.py (modified) (1 diff)
- trunk/RBFoundation/RBFoundation/XMLObjectify.py (modified) (11 diffs)
- trunk/RBJabber/RBJabber/Client.py (modified) (1 diff)
- trunk/RBJabber/RBJabber/JabberConnection.py (modified) (3 diffs)
- trunk/RBSkinning/RBSkinning/SkinObject.py (modified) (2 diffs)
- trunk/RBSkinning/RBSkinning/XMLSkinner.py (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/RBFoundation/RBFoundation/XMLBuilder.py
r94 r115 58 58 pass 59 59 60 def _xmlChildFactory(self, owner, parent, namespace, node, attributes): 61 return None 62 60 63 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 61 64 … … 68 71 69 72 def _GetElementFactory(self, owner, element, namespace, node, attributes): 70 raise self.e_no_class_registered, '%s %s' % (namespace, node)73 raise KeyError, '%s: %s %s' % (self.e_no_class_registered, namespace, node) 71 74 72 75 def _GetOwner(self): trunk/RBFoundation/RBFoundation/XMLClassBuilder.py
r98 r115 42 42 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 43 43 44 class XMLClassBuilder(XMLBuilder.XMLBuilder): 44 class ModuleByNamespaceMixin(object): 45 def _GetModuleClass(self, namespace, node): 46 # Simple construction to convert an XML namespace and node to a python import 47 return ('%s.%s' % (namespace, node), node) 48 49 ## Another plausable import scheme would be. However, I don't care for the 50 ## directory structure that this creates; but, since this is an arbitrary 51 ## opinion... You can do whatever you please. =) 52 ## return (namespace, node) 53 54 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 55 56 class ModuleByDictionaryMixin(object): 57 ModuleNamespaces = {} 58 59 def AddModuleNamespaces(self, dictModuleNamespaces): 60 # Did they send us a real change? 61 if dictModuleNamespaces: 62 # Are we working on the class dictionary? 63 if self.ModuleNamespaces is ModuleByDictionaryMixin.ModuleNamespaces: 64 # If so, lets get an instance copy 65 self.ModuleNamespaces = self.ModuleNamespaces.copy() 66 # And now update with what they gave us 67 self.ModuleNamespaces.update(dictModuleNamespaces) 68 69 def _GetModuleClass(self, namespace, node): 70 try: 71 # Try returning the entry in the dictionary 72 return '%s.%s' % (self.ModuleNamespaces[namespace], node), node 73 except KeyError: 74 try: 75 # Try asking the "next" class in line via super 76 self.__super._GetModuleClass 77 except AttributeError: 78 # Oops... there didnt seem to be a next class in line 79 raise KeyError, 'Could not find class for %r' % ((namespace, node),) 80 else: 81 # Ok, there is a next class in line, and their errors are their own 82 return self.__super._GetModuleClass(namespace, node) 83 84 ModuleByDictionaryMixin._ModuleByDictionaryMixin__super = super(ModuleByDictionaryMixin) 85 86 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 87 88 class XMLClassBuilderMixin(XMLBuilder.XMLBuilder): 45 89 seperator = '.' 46 Build = XMLBuilder.XMLBuilder.Parse 47 BuildFile = XMLBuilder.XMLBuilder.ParseFile 48 49 def _GetModuleClass(self, namespace, node): 50 return ('%s.%s' % (namespace, node), node) 90 _CachedElementFactories = {} 51 91 52 92 def _GetElementFactory(self, owner, parent, namespace, node, attributes): 53 93 result = None 54 55 94 if self._elements: 56 95 # Try to get a factory from the parent 57 factory = getattr(self._elements[-1], '_xmlChildFactory', None) 58 result = factory and factory(owner, parent, namespace, node, attributes) 59 96 result = self._elements[-1]._xmlChildFactory(owner, parent, namespace, node, attributes) 60 97 if not result: 61 strModule, strClass = self._GetModuleClass(namespace, node) 62 module = __import__(strModule, globals(), {}, [strClass]) 63 result = getattr(module, strClass) 64 98 # Otherwise, try to load it from the disk 99 result = self._LoadModule(self._GetModuleClass(namespace, node)) 100 elif isinstance(result, tuple): 101 # Instead of returning a factory, they returned a way to find the factory 102 # So, lets find it 103 result = self._LoadModule(result) 65 104 return result 66 105 106 def _LoadModule(self, tupleModuleClass): 107 result = self._CachedElementFactories.get(tupleModuleClass, None) 108 if not result: 109 # Import the module 110 module = __import__(tupleModuleClass[0], globals(), {}, [tupleModuleClass[1]]) 111 # Get the class factory 112 result = getattr(module, tupleModuleClass[1]) 113 # Cache this class factory 114 self._CachedElementFactories[tupleModuleClass] = result 115 return result 116 117 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 118 119 class XMLClassBuilderByNamespace(ModuleByNamespaceMixin, XMLClassBuilderMixin): 120 Build = XMLClassBuilderMixin.Parse 121 BuildFile = XMLClassBuilderMixin.ParseFile 122 123 class XMLClassBuilderByDictionary(ModuleByDictionaryMixin, XMLClassBuilderMixin): 124 Build = XMLClassBuilderMixin.Parse 125 BuildFile = XMLClassBuilderMixin.ParseFile 126 127 class XMLClassBuilderByBoth(ModuleByDictionaryMixin, ModuleByNamespaceMixin, XMLClassBuilderMixin): 128 Build = XMLClassBuilderMixin.Parse 129 BuildFile = XMLClassBuilderMixin.ParseFile 130 131 XMLClassBuilder = XMLClassBuilderByBoth 132 trunk/RBFoundation/RBFoundation/XMLObjectify.py
r112 r115 31 31 ##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 32 32 33 """Builds a Python object tree from an XML stream. 34 35 History 36 37 XMLObjectify found its conceptual roots in a similar tool created by David Mertz <mertz@gnosis.cx> 38 named objectify.py, which is still extremely useful and can still be found at http://gnosis.cx . 39 Futher history of his module can be found there. Now I say conceptual roots can be found there, 40 because the present state of XMLObjectify represents a 2nd rewrite of that code to serve the new 41 requirements. 42 43 One new requirement is the ability to "build" a python object tree by instantiating python classes 44 from modules found on disk, and subsequently raising an exception if a suitable module is not found. 45 (Raising that exception is one of the essential reasons for the 2nd rewrite, as I did not factor it 46 in the 1st.) This requirement provides the Foundation of the Skinning framework found in the 47 RuneBlade distribution, as well as XMLClassBuilder module 48 """ 49 33 50 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 34 51 #~ Imports … … 42 59 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 43 60 44 class _Objectified(object):61 class ObjectifiedXML(XMLBuilder.XMLBuilderObjectBase): 45 62 _default_attributes = {} 46 63 … … 62 79 if result: 63 80 return result 64 return object.__getattribute__(self, name)81 return XMLBuilder.XMLBuilderObjectBase.__getattribute__(self, name) 65 82 66 83 def __setattr__(self, name, value): … … 70 87 self._attributes[xmlName] = value 71 88 else: 72 return object.__setattr__(self, name, value)89 return XMLBuilder.XMLBuilderObjectBase.__setattr__(self, name, value) 73 90 74 91 def __delattr__(self, name): … … 79 96 del self._attributes[xmlName] 80 97 return 81 object.__delattr__(self, name)98 XMLBuilder.XMLBuilderObjectBase.__delattr__(self, name) 82 99 return 83 100 … … 104 121 105 122 def __repr__(self): 106 result = object.__repr__(self)123 result = XMLBuilder.XMLBuilderObjectBase.__repr__(self) 107 124 return '<%s %r %r>' % (result[1:-1], self.__namespace__, self.__node__) 108 125 … … 111 128 return self._elements[-1] 112 129 113 def _addObjectifiedElement(self, obj ect):114 return self._addElement(obj ect.__namespace__, object.__node__, object)130 def _addObjectifiedElement(self, obj): 131 return self._addElement(obj.__namespace__, obj.__node__, object) 115 132 116 133 def _addNewElement(self, namespace, node, **attributes): 117 134 namespace = namespace or self.__namespace__ 118 return self._addElement(namespace, node, _Objectified(self, self, namespace, node, attributes))135 return self._addElement(namespace, node, ObjectifiedXML(self, self, namespace, node, attributes)) 119 136 120 137 def _addData(self, data): … … 151 168 _childrenToPrettyXML = _childrenToXML 152 169 153 def _xmlInitStarted(self):154 pass #print '%r started' % self155 156 def _xmlInitComplete(self):157 pass #print '%r complete' % self158 159 170 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 160 171 161 172 class Objectifier(XMLBuilder.XMLBuilder): 162 objectified_class = _Objectified173 objectified_class = ObjectifiedXML 163 174 Objectify = XMLBuilder.XMLBuilder.Parse 164 175 ObjectifyFile = XMLBuilder.XMLBuilder.ParseFile … … 167 178 return self.objectified_class 168 179 180 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 181 #~ Functional Definitions 169 182 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 170 183 … … 173 186 ObjectifyFile = _defaultObjectifier.ObjectifyFile 174 187 175 if __name__ == '__main__': 188 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 189 #~ Testing 190 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 191 192 def _Test_XMLObjectify(): 176 193 from pprint import pprint 177 194 xml = open('test_objectify.xml', 'r') … … 181 198 print ' ~ ' * 20 182 199 pprint (obj._toXML()) 200 201 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 202 203 if __name__=='__main__': 204 print "Testing..." 205 _Test_XMLObjectify() 206 print "Test complete." 207 208 trunk/RBJabber/RBJabber/Client.py
r110 r115 45 45 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 46 46 47 class JabberNode(XMLObjectify. _Objectified):47 class JabberNode(XMLObjectify.ObjectifiedXML): 48 48 def __init__(self, client, parent, namespace, node, attributes): 49 49 self._client = weakref.proxy(client) 50 XMLObjectify. _Objectified.__init__(self, client, parent, namespace, node, attributes)50 XMLObjectify.ObjectifiedXML.__init__(self, client, parent, namespace, node, attributes) 51 51 52 52 def Content(self): trunk/RBJabber/RBJabber/JabberConnection.py
r102 r115 117 117 118 118 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 119 #~ Private Methods119 #~ XMLBuilding Private Methods 120 120 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 121 121 … … 128 128 129 129 def _GetElementFactory(self, owner, parent, namespace, node, attributes): 130 result = self.JabberNodeMap.get((namespace, node), self.DefaultJabberNode) 130 result = None 131 132 if self._elements: 133 # Try to get a factory from the parent 134 result = self._elements[-1]._xmlChildFactory(owner, parent, namespace, node, attributes) 135 136 if not result: 137 # Otherwise, try to load it from the disk 138 result = self.JabberNodeMap.get((namespace, node), self.DefaultJabberNode) 139 131 140 return result 141 142 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 143 #~ Smart Select Private Methods 144 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 132 145 133 146 def _NeedsRead(self): return self._socket and 1 … … 143 156 self._sendData = self._sendData[nSent:] 144 157 158 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 159 #~ Other Private Methods 160 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 161 145 162 def _SendXMLImmediate(self, xmlData): 146 163 self._sendData += xmlData trunk/RBSkinning/RBSkinning/SkinObject.py
r66 r115 35 35 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 36 36 37 from Foundation.XMLBuilder import XMLBuilderObjectBase 37 38 import SkinContext 38 39 import weakref … … 46 47 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 47 48 48 class SkinObject( object):49 class SkinObject(XMLBuilderObjectBase): 49 50 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 50 51 #~ Constants / Variables / Etc. trunk/RBSkinning/RBSkinning/XMLSkinner.py
r113 r115 36 36 37 37 from xml.parsers.expat import ParserCreate, ExpatError 38 from Foundation.XML Builder import XMLBuilder38 from Foundation.XMLClassBuilder import XMLClassBuilderByDictionary 39 39 from Foundation.WeakBind import BindCallable 40 40 import SkinContext … … 47 47 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 48 48 49 class XMLSkinner(XMLBuilder): 50 DefaultSkinNamespaces = { 49 class XMLSkinner(XMLClassBuilderByDictionary): 50 51 ModuleNamespaces = XMLClassBuilderByDictionary.ModuleNamespaces.copy() 52 ModuleNamespaces.update({ 53 ## Long names 51 54 'http://namespaces.runeblade.com/skin': 'Foundation.Skinning.skin', 52 55 'http://namespaces.runeblade.com/wxPythonSkin': 'Foundation.Skinning.wxPythonSkin', 53 56 'http://namespaces.runeblade.com/xmlPython': 'Foundation.Skinning.xmlPython', 54 57 'http://namespaces.runeblade.com/wxogl': 'Foundation.Skinning.wxOGLSkin', 55 } 56 _CachedElementFactories = {} 58 59 ## Short names 60 'skin': 'Foundation.Skinning.skin', 61 'wxPythonSkin': 'Foundation.Skinning.wxPythonSkin', 62 'xmlPython': 'Foundation.Skinning.xmlPython', 63 'wxogl': 'Foundation.Skinning.wxOGLSkin', 64 }) 57 65 58 66 def __init__(self, mapSupportedSkinNamespaces={}, rootPath=''): 59 67 self.rootPath = rootPath 60 XMLBuilder.__init__(self) 61 self.SkinNamespaces = self.DefaultSkinNamespaces.copy() 62 self.SkinNamespaces.update(mapSupportedSkinNamespaces) 68 XMLClassBuilderByDictionary.__init__(self) 69 self.AddModuleNamespaces(mapSupportedSkinNamespaces) 63 70 64 def _GetModuleClass(self, namespace, node): 65 try: 66 return '%s.%s' % (self.SkinNamespaces[namespace], node), node 67 except KeyError: 68 raise KeyError, 'Could not find class for %r' % ((namespace, node),) 71 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 69 72 70 def _GetElementFactory(self, owner, parent, namespace, node, attributes):71 strModule, strClass = self._GetModuleClass(namespace, node)72 result = self._CachedElementFactories.get((strModule, strClass), None)73 if not result:74 module = __import__(strModule, globals(), {}, [strClass])75 result = getattr(module, strClass)76 self._CachedElementFactories[(strModule, strClass)] = result77 return result78 79 73 def _PreParse(self): 80 74 parser = ParserCreate('ASCII', self._seperator)
