XmlMarshaller may be given custom functions for marshalling in a specific way some Python values or instances.

This commit is contained in:
Gaetan Delannay 2010-02-24 10:27:41 +01:00
parent 15ef6f334d
commit 97494592d5

View file

@ -336,10 +336,20 @@ class XmlMarshaller:
fieldsToExclude = [] fieldsToExclude = []
atFiles = ('image', 'file') # Types of archetypes fields that contain files. atFiles = ('image', 'file') # Types of archetypes fields that contain files.
def __init__(self, cdata=False, dumpUnicode=False): def __init__(self, cdata=False, dumpUnicode=False, conversionFunctions={}):
'''If p_cdata is True, all string values will be dumped as XML CDATA.''' '''If p_cdata is True, all string values will be dumped as XML CDATA.'''
self.cdata = cdata self.cdata = cdata
self.dumpUnicode = dumpUnicode self.dumpUnicode = dumpUnicode
# The following dict stores specific conversion (=Python to XML)
# functions. A specific conversion function is useful when you are not
# happy with the way built-in converters work, or if you want to
# specify a specific way to represent, in XML, some particular Python
# object or value. In this dict, every key represents a given type
# (class names must be full-path class names); every value is a function
# accepting 2 args: first one is the UnicodeBuffer where the result is
# being dumped, while the second one is the Python object or value to
# dump.
self.conversionFunctions = conversionFunctions
def dumpString(self, res, s): def dumpString(self, res, s):
'''Dumps a string into the result.''' '''Dumps a string into the result.'''
@ -383,6 +393,12 @@ class XmlMarshaller:
def dumpValue(self, res, value, fieldType): def dumpValue(self, res, value, fieldType):
'''Dumps the XML version of p_value to p_res.''' '''Dumps the XML version of p_value to p_res.'''
# Use a custom function if one is defined for this type of value.
fType = value.__class__.__name__
if fType in self.conversionFunctions:
self.conversionFunctions[fType](res, value)
return
# Use a standard conversion else.
if fieldType == 'file': if fieldType == 'file':
self.dumpFile(res, value) self.dumpFile(res, value)
elif fieldType == 'ref': elif fieldType == 'ref':
@ -394,7 +410,7 @@ class XmlMarshaller:
self.dumpField(res, 'url', value.absolute_url()) self.dumpField(res, 'url', value.absolute_url())
elif type(value) in self.sequenceTypes: elif type(value) in self.sequenceTypes:
# The previous condition must be checked before this one because # The previous condition must be checked before this one because
# Referred objects may be stored in lists or tuples, too. # referred objects may be stored in lists or tuples, too.
for elem in value: for elem in value:
self.dumpField(res, 'e', elem) self.dumpField(res, 'e', elem)
elif isinstance(value, basestring): elif isinstance(value, basestring):
@ -452,9 +468,11 @@ class XmlMarshaller:
elif iType.__name__ == 'ImplicitAcquirerWrapper': elif iType.__name__ == 'ImplicitAcquirerWrapper':
# This is the case with Archetype instances # This is the case with Archetype instances
return True return True
elif iType.__class__.__name__ == 'ExtensionClass':
return True
return False return False
def marshall(self, instance, objectType='popo'): def marshall(self, instance, objectType='popo', conversionFunctions={}):
'''Returns in a UnicodeBuffer the XML version of p_instance. If '''Returns in a UnicodeBuffer the XML version of p_instance. If
p_instance corresponds to a Plain Old Python Object, specify 'popo' p_instance corresponds to a Plain Old Python Object, specify 'popo'
for p_objectType. If p_instance corresponds to an Archetypes object for p_objectType. If p_instance corresponds to an Archetypes object
@ -465,6 +483,8 @@ class XmlMarshaller:
# Call the XmlMarshaller constructor if it hasn't been called yet. # Call the XmlMarshaller constructor if it hasn't been called yet.
if not hasattr(self, 'cdata'): if not hasattr(self, 'cdata'):
XmlMarshaller.__init__(self) XmlMarshaller.__init__(self)
if conversionFunctions:
self.conversionFunctions.update(conversionFunctions)
# Create the buffer where the XML result will be dumped. # Create the buffer where the XML result will be dumped.
res = UnicodeBuffer() res = UnicodeBuffer()
# Dump the XML prologue # Dump the XML prologue
@ -541,7 +561,7 @@ class XmlMarshaller:
'''You can use this marshaller as a base class for creating your own. '''You can use this marshaller as a base class for creating your own.
In this case, this method will be called by the marshall method In this case, this method will be called by the marshall method
for allowing your concrete marshaller to insert more things in the for allowing your concrete marshaller to insert more things in the
result. p_res is the StringIO buffer where the result of the result. p_res is the UnicodeBuffer buffer where the result of the
marshalling process is currently dumped; p_instance is the instance marshalling process is currently dumped; p_instance is the instance
currently marshalled.''' currently marshalled.'''