source: products/quintagroup.transmogrifier/trunk/quintagroup/transmogrifier/adapters/exporting.py @ 1589

Last change on this file since 1589 was 1446, checked in by piv, 14 years ago

merge from plone 2.1 branch: r2465-2483

File size: 2.9 KB
Line 
1from xml.dom import minidom
2
3from zope.interface import implements
4from zope.component import adapts
5
6from Products.Archetypes import atapi
7from Products.Archetypes.interfaces import IBaseObject
8from Products.ATContentTypes.interface import IATTopicCriterion
9from Products.Marshall.registry import getComponent
10from Products.Archetypes import config as atcfg
11
12from collective.transmogrifier.interfaces import ITransmogrifier
13
14from quintagroup.transmogrifier.interfaces import IExportDataCorrector
15
16class ReferenceExporter(object):
17    """ Add reference fields to XML, generated by Marshall product.
18    """
19    implements(IExportDataCorrector)
20    adapts(IBaseObject, ITransmogrifier)
21
22    def __init__(self, context, transmogrifier):
23        self.context = context
24        self.transmogrifier = transmogrifier
25
26    def __call__(self, data):
27        data['data'] = self.exportReferences(data['data'])
28        return data
29
30    def exportReferences(self, xml):
31        """ Marshall 1.0.0 doesn't export references, do it manually.
32        """
33        doc = minidom.parseString(xml)
34        root = doc.documentElement
35        for fname in self.context.Schema().keys():
36            if not isinstance(self.context.Schema()[fname], atapi.ReferenceField):
37                continue
38            values = self.context[fname]
39            if not values:
40                continue
41            elem = doc.createElement("field")
42            attr = doc.createAttribute("name")
43            attr.value = fname
44            elem.setAttributeNode(attr)
45            if type(values) not in (tuple, list):
46                values = [values,]
47            for value in values:
48                ref = doc.createElement('reference')
49                uid = doc.createElement('uid')
50                value = doc.createTextNode(str(value))
51                uid.appendChild(value)
52                ref.appendChild(uid)
53                elem.appendChild(ref)
54            root.appendChild(elem)
55        return doc.toxml('utf-8')
56
57class CriterionExporter(ReferenceExporter):
58    """ Special marshalling adapter for topic criterias.
59    """
60
61    implements(IExportDataCorrector)
62    adapts(IATTopicCriterion, ITransmogrifier)
63
64    def __init__(self, context, transmogrifier):
65        self.context = context
66        self.transmogrifier = transmogrifier
67        self.marshaller = getComponent('atxml')
68
69    def __call__(self, data):
70        if data['data'] is not None:
71            return super(CriterionExporter, self).__call__(data)
72        # Marshall fails when object has UID that is equal to None
73        # fix it here by setting it to empty string and after marshalling setting back to old value
74        old_uid_attr = getattr(self.context, atcfg.UUID_ATTR)
75        setattr(self.context, atcfg.UUID_ATTR, "")
76
77        ct, length, xml = self.marshaller.marshall(self.context)
78        xml = self.exportReferences(xml)
79        data['data'] = xml
80
81        setattr(self.context, atcfg.UUID_ATTR, old_uid_attr)
82        return data
Note: See TracBrowser for help on using the repository browser.