source: products/quintagroup.transmogrifier/branches/dictionary/quintagroup/transmogrifier/namespaces/atns.py @ 2721

Last change on this file since 2721 was 2721, checked in by mylan, 14 years ago

Fix wrong processing of BaseUnit? field value

File size: 5.5 KB
Line 
1"""
2    Archetypes Marshall namespace but which can safely handle
3    Control Characters for you
4"""
5
6from Products.Archetypes.interfaces.base import IBaseUnit
7
8from Products.Marshall import config
9from Products.Marshall.handlers.atxml import XmlNamespace
10from Products.Marshall.handlers.atxml import SchemaAttribute
11from Products.Marshall.handlers.atxml import getRegisteredNamespaces
12from Products.Marshall.exceptions import MarshallingException
13from Products.Marshall import utils
14
15from Products.Marshall.namespaces import atns as base
16
17from quintagroup.transmogrifier.namespaces.util import has_ctrlchars
18
19_marker = ()
20
21class ATAttribute(base.ATAttribute):
22
23    def serialize(self, dom, parent_node, instance, options={}):
24
25        def getPreparedValue(value):
26            if isinstance(value, unicode):
27                value = value.encode('utf-8')
28            elif IBaseUnit.isImplementedBy(value):
29                value = value.getRaw(encoding='utf-8')
30            else:
31                value = str(value)
32            return value
33
34
35        def addNode(node, value, nspref):
36            if is_ref:
37                if config.HANDLE_REFS:
38                    ref_node = dom.createElementNS(nspref, 'reference')
39                    uid_node = dom.createElementNS(nspref, 'uid')
40                    value = response.createTextNode(value)
41                    uid_node.append(value)
42                    ref_node.append(uid_node)
43                    node.append(ref_node)
44
45            elif isinstance(value, str) and has_ctrlchars(value):
46                value = value.encode('base64')
47                attr = dom.createAttributeNS(nspref, 'transfer_encoding')
48                attr.value = 'base64'
49                node.setAttributeNode(attr)
50                value_node = dom.createCDATASection(value)
51                node.appendChild(value_node)
52            else:
53                value_node = dom.createTextNode(value)
54                node.appendChild(value_node)
55
56        values = self.get(instance)
57        if not values:
58            return
59
60        is_ref = self.isReference(instance)
61        for value in values:
62            node = dom.createElementNS(self.namespace.xmlns, "field")
63            name_attr = dom.createAttribute("name")
64            name_attr.value = self.name
65            node.setAttributeNode(name_attr)
66            # map and not map fields
67            # take-off aquisition
68            if hasattr(value, 'aq_base'):
69                chck_val = value.aq_base
70            else:
71                chck_val = value
72            items = getattr(chck_val, 'items', _marker)
73            if items is not _marker and callable(items):
74                # Map field
75                # set type attribute for the field
76                type_attr = dom.createAttribute("type")
77                type_attr.value = "dict"
78                node.setAttributeNode(type_attr)
79                for k, v in items():
80                    # create item node with key attribute
81                    good_key = getPreparedValue(k)
82                    item_node = dom.createElementNS(self.namespace.xmlns, "item")
83                    key_attr = dom.createAttribute("key")
84                    key_attr.value = good_key
85                    item_node.setAttributeNode(key_attr)
86                    # prepare value for the item
87                    good_value = getPreparedValue(v)
88                    addNode(item_node, good_value, self.namespace.xmlns)
89                    item_node.normalize()
90                    node.appendChild(item_node)
91            else:
92                # Common field
93                value = getPreparedValue(value)
94                addNode(node, value, self.namespace.xmlns)
95       
96            node.normalize()
97            parent_node.appendChild(node)
98
99        return True
100
101    def processXmlValue(self, context, value):
102        def getValue(node, value):
103            if value is None:
104                return
105            value = value.strip()
106            if not value:
107                return
108            # decode node value if needed
109            te = node.get('transfer_encoding', None)
110            if te is not None:
111                value = value.decode(te)
112            return value
113           
114        # Get value type
115        vtype = context.node.attrib.get('type', None)
116        if vtype=='dict':
117            # process dictionary type
118            d = {}
119            for item in context.node:
120                k = item.get("key", None)
121                v = getValue(item, item.text)
122                if k and v:
123                    d[k] = v
124            value = d
125        else:
126            # Common field
127            value = getValue(context.node, value)
128
129        if not value:
130            return
131
132        data = context.getDataFor(self.namespace.xmlns)
133        if data.has_key(self.name):
134            svalues = data[self.name]
135            if not isinstance(svalues, list):
136                data[self.name] = svalues = [svalues]
137            svalues.append(value)
138            return
139        else:
140            data[self.name] = value
141
142class Archetypes(base.Archetypes):
143
144    def getAttributeByName(self, schema_name, context=None):
145        if context is not None and schema_name not in self.at_fields:
146            if not context.instance.Schema().has_key(schema_name):
147                return
148                raise AssertionError, \
149                      "invalid attribute %s"%(schema_name)
150       
151        if schema_name in self.at_fields:
152            return self.at_fields[schema_name]
153
154        attribute = ATAttribute(schema_name)
155        attribute.setNamespace(self)
156       
157        return attribute
Note: See TracBrowser for help on using the repository browser.