1   
  2   
  3   
  4   
  5   
  6   
  7   
  8   
  9   
 10   
 11   
 12   
 13   
 14   
 15   
 16   
 17   
 18   
 19  """General base classes for PyXMPP objects.""" 
 20   
 21  __revision__="$Id: objects.py 647 2006-08-26 18:27:39Z jajcus $" 
 22  __docformat__="restructuredtext en" 
 23   
 24  import libxml2 
 25  from pyxmpp.xmlextra import common_doc 
 26   
 28      """Base class for objects that may be used as XMPP stanza payload and don't keep 
 29      internal XML representation, only parsed values. 
 30   
 31      Provides `as_xml` method. Derived classes must override `xml_element_name` and 
 32      `xml_element_namespace` class attributes and the `complete_xml_element` method. 
 33   
 34      Please note that not all classes derived from `StanzaPayloadObject` should be 
 35      used directly as stanza payload. Some of them are parts of higher level objects. 
 36   
 37      :Cvariables: 
 38          - `xml_element_name`: name for the XML element provided by the class. 
 39          - `xml_element_namespace`: namespace URI for the XML element provided 
 40            by the class. 
 41      :Types: 
 42          - `xml_element_name`: `unicode` 
 43          - `xml_element_namespace`: `unicode` 
 44      """ 
 45      xml_element_name = None 
 46      xml_element_namespace = None 
 47   
 48 -    def as_xml(self, parent = None, doc = None): 
  49          """Get the XML representation of `self`. 
 50   
 51          New document will be created if no `parent` and no `doc` is given. 
 52   
 53          :Parameters: 
 54              - `parent`: the parent for the XML element. 
 55              - `doc`: the document where the element should be created. If not 
 56                given and `parent` is provided then autodetection is attempted. 
 57                If that fails, then `common_doc` is used. 
 58          :Types: 
 59              - `parent`: `libxml2.xmlNode` 
 60              - `doc`: `libxml2.xmlDoc` 
 61          :return: the new XML element or document created. 
 62          :returntype: `libxml2.xmlNode` or `libxml2.xmlDoc`""" 
 63          if parent: 
 64              if not doc: 
 65                  n = parent 
 66                  while n: 
 67                      if n.type == "xml_document": 
 68                          doc = n 
 69                          break 
 70                      n = n.parent 
 71                  if not doc: 
 72                      doc = common_doc 
 73              try: 
 74                  ns = parent.searchNsByHref(doc, self.xml_element_namespace) 
 75              except libxml2.treeError: 
 76                  ns = None 
 77              xmlnode = parent.newChild(ns,self.xml_element_name,None) 
 78              if not ns: 
 79                  ns = xmlnode.newNs(self.xml_element_namespace,None) 
 80                  xmlnode.setNs(ns) 
 81              doc1 = doc 
 82          else: 
 83              if doc: 
 84                  doc1 = doc 
 85              else: 
 86                  doc1 = libxml2.newDoc("1.0") 
 87              xmlnode = doc1.newChild(None,self.xml_element_name, None) 
 88              ns = xmlnode.newNs(self.xml_element_namespace, None) 
 89              xmlnode.setNs(ns) 
 90   
 91          self.complete_xml_element(xmlnode, doc1) 
 92   
 93          if doc or parent: 
 94              return xmlnode 
 95          doc1.setRootElement(xmlnode) 
 96          return doc1 
  97   
 99          """Complete the XML node with `self` content. 
100   
101          Should be overriden in classes derived from `StanzaPayloadObject`. 
102   
103          :Parameters: 
104              - `xmlnode`: XML node with the element being built. It has already 
105                right name and namespace, but no attributes or content. 
106              - `doc`: document to which the element belongs. 
107          :Types: 
108              - `xmlnode`: `libxml2.xmlNode` 
109              - `doc`: `libxml2.xmlDoc`""" 
110          pass 
  111   
113      """Base class for objects that may be used as XMPP stanza payload and maintain 
114      an internal XML representation of self. 
115   
116      Provides `as_xml` method. Objects of derived classes must have the `xmlnode` attribute. 
117   
118      Please note that not all classes derived from `StanzaPayloadWrapperObject` should be 
119      used directly as stanza payload. Some of them are parts of higher level objects. 
120   
121      :Ivariables: 
122          - `xmlnode`: XML node of the object. 
123      :Types: 
124          - `xmlnode`: `libxml2.xmlNode` 
125      """ 
126   
127 -    def as_xml(self, parent = None, doc = None): 
 128          """Get the XML representation of `self`. 
129   
130          New document will be created if no `parent` and no `doc` is given. 
131   
132          :Parameters: 
133              - `parent`: the parent for the XML element. 
134              - `doc`: the document where the element should be created. If not 
135                given and `parent` is provided then autodetection is attempted. 
136                If that fails, then `common_doc` is used. 
137          :Types: 
138              - `parent`: `libxml2.xmlNode` 
139              - `doc`: `libxml2.xmlDoc` 
140   
141          :return: the new XML element (copy of `self.xmlnode`) or document 
142              created (containg the copy as the root element). 
143          :returntype: `libxml2.xmlNode` or `libxml2.xmlDoc`""" 
144          if parent: 
145              if not doc: 
146                  n = parent 
147                  while n: 
148                      if n.type == "xml_document": 
149                          doc = n 
150                          break 
151                      n = n.parent 
152                  if not doc: 
153                      doc = common_doc 
154              copy=self.xmlnode.docCopyNode(doc,True) 
155              parent.addChild(copy) 
156              return copy 
157          else: 
158              if not doc: 
159                  doc1=libxml2.newDoc("1.0") 
160              else: 
161                  doc1=doc 
162              xmlnode=doc1.addChild(self.xmlnode.docCopyNode(doc,True)) 
163              doc1.setRootElement(xmlnode) 
164              if doc: 
165                  return xmlnode 
166              return doc1 
  167   
168   
169