source: products/vendor/Products.CacheSetup/current/Products/CacheSetup/exportimport/atcontent.py @ 3296

Last change on this file since 3296 was 3296, checked in by fenix, 13 years ago

Load Products.CacheSetup?-1.2.1 into vendor/Products.CacheSetup?/current.

  • Property svn:eol-style set to native
File size: 6.0 KB
Line 
1from zope.component import queryMultiAdapter
2from Products.GenericSetup.interfaces import INode
3from Products.GenericSetup import utils as gsutils
4from ZPublisher.HTTPRequest import default_encoding
5
6import logging
7logger = logging.getLogger('GS adapter')
8
9
10class ATContentAdapterBase(gsutils.XMLAdapterBase,
11                           gsutils.ObjectManagerHelpers):
12
13    _LOGGER_ID = "CacheSetup"
14    _encoding = default_encoding
15    _fields = None
16
17
18    def _getObjectNode(self, name, i18n=True):
19        """Override NodeAdapterBase._getObjectNode to use portal_type."""
20        node = self._doc.createElement(name)
21        node.setAttribute("name", self.context.getId())
22        node.setAttribute("portal_type", self.context.portal_type)
23        i18n_domain = getattr(self.context, "i18n_domain", None)
24        if i18n and i18n_domain:
25            node.setAttributeNS(gsutils.I18NURI, "i18n:domain", i18n_domain)
26            self._i18n_props = ("title", "description")
27        return node
28
29
30    def _exportNode(self):
31        """Export the object as a DOM node.
32        """
33        node = self._getObjectNode("object")
34        node.appendChild(self._extractFields())
35        node.appendChild(self._extractObjects())
36        return node
37
38
39    def _convertValueToString(self, value):
40        if isinstance(value, bool):
41            value = unicode(bool(value))
42        elif isinstance(value, str):
43            value = value.decode(self._encoding)
44        elif not isinstance(value, basestring) and value is not None:
45            value = unicode(value)
46        return value
47
48
49    def _extractFields(self):
50        fragment = self._doc.createDocumentFragment()
51        schema = self.context.Schema()
52        for fieldname in self._fields:
53            field = schema[fieldname]
54            accessor = field.getEditAccessor(self.context)
55            if accessor is not None:
56                value = accessor()
57            else:
58                value = field.get(self.context)
59
60            node = self._doc.createElement("property")
61            node.setAttribute("name", fieldname)
62
63            if isinstance(value, (tuple,list)):
64                for v in value:
65                    if isinstance(v, str):
66                        v = v.decode(self._encoding)
67                    child = self._doc.createElement("element")
68                    child.setAttribute("value", v)
69                    node.appendChild(child)
70            else:
71                value = self._convertValueToString(value)
72                if value is None:
73                    continue
74                child = self._doc.createTextNode(value)
75                node.appendChild(child)
76
77            if fieldname in getattr(self, "_i18n_props", []):
78                node.setAttribute("i18n:translate", "")
79
80            fragment.appendChild(node)
81
82        return fragment
83
84
85    def _purgeFields(self):
86        schema = self.context.Schema()
87        for fieldname in self._fields:
88            field = schema[fieldname]
89            field.getMutator(self.context)(field.getDefault(self.context))
90
91
92    def _initFields(self, node):
93        schema = self.context.Schema()
94
95        for child in node.childNodes:
96            if child.nodeName != "property":
97                continue
98
99            fieldname = str(child.getAttribute("name"))
100            if fieldname not in schema.keys():
101                continue
102
103            field = schema[fieldname]
104            accessor = field.getEditAccessor(self.context)
105            if accessor is not None:
106                current_value = accessor()
107            else:
108                current_value = field.get(self.context)
109
110            if isinstance(current_value, (list,tuple)):
111                if not self._convertToBoolean(child.getAttribute("purge") or "True"):
112                    value = current_value
113                else:
114                    value = []
115                for sub in child.childNodes:
116                    if sub.nodeName != "element":
117                        continue
118                    value.append(sub.getAttribute("value").encode(self._encoding))
119
120                if isinstance(current_value, tuple):
121                    value = tuple(value)
122            else:
123                value = self._getNodeText(child)
124                if value == "None":
125                    value = None
126                elif isinstance(current_value, bool):
127                    value = self._convertToBoolean(value)
128                elif isinstance(current_value, int):
129                    if "Boolean" in field.getType():
130                        # Archetypes releases before 1.5.8 had BooleanFields
131                        # which could return integers.
132                        value = self._convertToBoolean(value)
133                    else:
134                        value = int(value)
135
136            field.getMutator(self.context)(value)
137
138
139    def _initObjects(self, node):
140        """Import objects. This is a much simpler version of
141        ObjectManagerHelpers._init_objects which does not support ordering
142        and uses portal_types.
143        """
144
145        for child in node.childNodes:
146            if child.nodeName != "object":
147                continue
148
149            parent = self.context
150            obj_id = str(child.getAttribute("name"))
151            if child.hasAttribute("remove"):
152                if obj_id in parent.objectIds():
153                    parent.manage_delObjects([obj_id])
154                continue
155
156            if obj_id not in parent.objectIds():
157                portal_type = str(child.getAttribute("portal_type"))
158                self.context.invokeFactory(portal_type, obj_id)
159
160            obj = getattr(self.context, obj_id)
161
162            importer = queryMultiAdapter((obj, self.environ), INode)
163            if importer:
164                importer.node = child
165
166
167    def _importNode(self, node):
168        """Import the object from the DOM node.
169        """
170
171        if self.environ.shouldPurge():
172            self._purgeFields()
173            self._purgeObjects()
174                   
175        self._initObjects(node)
176        self._initFields(node)
177        self.context.indexObject()
178
179    node = property(_exportNode, _importNode)
180
Note: See TracBrowser for help on using the repository browser.