[shared] Improvements to the XmlMarshaller and bugfix: Mixin.xml returns appy.Object instances correctly marshalled.

This commit is contained in:
Gaetan Delannay 2014-12-09 11:40:30 +01:00
parent 12836a40dc
commit b39c5553ea
3 changed files with 30 additions and 38 deletions

View file

@ -484,7 +484,7 @@ class Pod(Field):
obj = obj.appy() obj = obj.appy()
template = template or self.template[0] template = template or self.template[0]
format = format or 'odt' format = format or 'odt'
# Security check. # Security check
if not noSecurity and not queryData: if not noSecurity and not queryData:
if self.showTemplate and not self.showTemplate(obj, template): if self.showTemplate and not self.showTemplate(obj, template):
raise Exception(self.UNAUTHORIZED) raise Exception(self.UNAUTHORIZED)
@ -495,7 +495,7 @@ class Pod(Field):
if frozen: if frozen:
fileName = self.getDownloadName(obj, template, format, False) fileName = self.getDownloadName(obj, template, format, False)
return FileInfo(frozen, inDb=False, uploadName=fileName) return FileInfo(frozen, inDb=False, uploadName=fileName)
# We must call pod to compute a pod document from "template". # We must call pod to compute a pod document from "template"
tool = obj.tool tool = obj.tool
diskFolder = tool.getDiskFolder() diskFolder = tool.getDiskFolder()
# Get the path to the pod template. # Get the path to the pod template.

View file

@ -527,7 +527,9 @@ class BaseMixin:
methodRes.startswith('<?xml'): # Already XML methodRes.startswith('<?xml'): # Already XML
return methodRes return methodRes
else: else:
res = XmlMarshaller().marshall(methodRes, objectType='appy') marshaller = XmlMarshaller()
oType = isinstance(methodRes, Object) and 'popo' or 'appy'
res = marshaller.marshall(methodRes, objectType=oType)
except Exception, e: except Exception, e:
tb = sutils.Traceback.get() tb = sutils.Traceback.get()
res = XmlMarshaller(rootTag='exception').marshall(tb) res = XmlMarshaller(rootTag='exception').marshall(tb)

View file

@ -508,7 +508,12 @@ class XmlMarshaller:
trueFalse = {True: 'True', False: 'False'} trueFalse = {True: 'True', False: 'False'}
fieldsToMarshall = 'all' fieldsToMarshall = 'all'
fieldsToExclude = [] fieldsToExclude = []
atFiles = ('image', 'file') # Types of archetypes fields that contain files. atFiles = ('image', 'file') # Types of archetypes fields that contain files
typesMap = {'list': 'list', 'PersistentList': 'list', 'LazyMap': 'list',
'UserList': 'list', 'dict': 'dict', 'PersistentMapping': 'dict',
'UserDict': 'dict', 'FileInfo': 'file', 'bool': 'bool',
'int': 'int', 'float': 'float', 'long': 'long',
'tuple': 'tuple', 'DateTime': 'DateTime'}
def __init__(self, cdata=False, dumpUnicode=False, conversionFunctions={}, def __init__(self, cdata=False, dumpUnicode=False, conversionFunctions={},
dumpXmlPrologue=True, rootTag='xmlPythonData', namespaces={}, dumpXmlPrologue=True, rootTag='xmlPythonData', namespaces={},
@ -557,7 +562,7 @@ class XmlMarshaller:
def isAnObject(self, instance): def isAnObject(self, instance):
'''Returns True if p_instance is a class instance, False if it is a '''Returns True if p_instance is a class instance, False if it is a
basic type, or tuple, sequence, etc.''' basic type, or tuple, sequence, etc.'''
if instance.__class__.__name__ == 'LazyMap': return False if instance.__class__.__name__ == 'LazyMap': return
iType = type(instance) iType = type(instance)
if iType == types.InstanceType: if iType == types.InstanceType:
return True return True
@ -566,15 +571,6 @@ class XmlMarshaller:
return True return True
elif iType.__class__.__name__ == 'ExtensionClass': elif iType.__class__.__name__ == 'ExtensionClass':
return True return True
return False
def isAList(self, value):
'''Is p_value a list?'''
return value.__class__.__name__ in ('list', 'PersistentList', 'LazyMap')
def isADict(self, value):
'''Is p_value a dict?'''
return value.__class__.__name__ in ('dict', 'PersistentMapping')
def dumpRootTag(self, res, instance): def dumpRootTag(self, res, instance):
'''Dumps the root tag.''' '''Dumps the root tag.'''
@ -634,7 +630,10 @@ class XmlMarshaller:
w('</%s>' % partTag) w('</%s>' % partTag)
elif hasattr(v, 'uploadName'): elif hasattr(v, 'uploadName'):
# The file is a Appy FileInfo instance. Read the file from disk. # The file is a Appy FileInfo instance. Read the file from disk.
filePath = v.getFilePath(self.instance) if hasattr(self, 'instance'):
filePath = v.getFilePath(self.instance)
else:
filePath = v.fsPath
f = file(filePath, 'rb') f = file(filePath, 'rb')
partNb = 1 partNb = 1
while True: while True:
@ -707,29 +706,22 @@ class XmlMarshaller:
if fieldName == '_any': if fieldName == '_any':
res.write(value) res.write(value)
return return
# Now, dump "normal" fields. # Now, dump "normal" fields
fieldTag = self.getTagName(fieldName) fieldTag = self.getTagName(fieldName)
res.write('<'); res.write(fieldTag) res.write('<'); res.write(fieldTag)
# Dump the type of the field as an XML attribute # Dump the type of the field as an XML attribute
fType = None # No type will mean "unicode". fType = None # No type will mean "unicode"
if fieldType == 'file': fType = 'file' className = fieldValue.__class__.__name__
elif fieldType == 'ref': fType = 'list' if fieldType == 'file': fType = 'file'
elif isinstance(fieldValue, bool): fType = 'bool' elif fieldType == 'ref': fType = 'list'
elif isinstance(fieldValue, int): fType = 'int' elif className in self.typesMap: fType = self.typesMap[className]
elif isinstance(fieldValue, float): fType = 'float' elif self.isAnObject(fieldValue): fType = 'object'
elif isinstance(fieldValue, long): fType = 'long' if fType: res.write(' type="%s"' % fType)
elif isinstance(fieldValue, tuple): fType = 'tuple' # Dump other attributes if needed
elif self.isAList(fieldValue): fType = 'list' if fType in ('list', 'tuple'):
elif self.isADict(fieldValue): fType = 'dict' length = 0
elif fieldValue.__class__.__name__ == 'DateTime': fType = 'DateTime' if fieldValue: length = len(fieldValue)
elif self.isAnObject(fieldValue): fType = 'object' res.write(' count="%d"' % length)
if self.objectType != 'popo':
if fType: res.write(' type="%s"' % fType)
# Dump other attributes if needed
if fType in ('list', 'tuple'):
length = 0
if fieldValue: length = len(fieldValue)
res.write(' count="%d"' % length)
if fType == 'file': if fType == 'file':
# Get the MIME type # Get the MIME type
mimeType = None mimeType = None
@ -823,11 +815,9 @@ class XmlMarshaller:
if field.name in self.fieldsToExclude: continue if field.name in self.fieldsToExclude: continue
if (type(self.fieldsToMarshall) in sequenceTypes) \ if (type(self.fieldsToMarshall) in sequenceTypes) \
and (field.name not in self.fieldsToMarshall): continue and (field.name not in self.fieldsToMarshall): continue
# Determine field type and value
fieldType = (field.type == 'File') and 'file' or 'basic'
v = field.getXmlValue(instance.appy(), v = field.getXmlValue(instance.appy(),
field.getValue(instance)) field.getValue(instance))
self.dumpField(res, field.name, v, fieldType=fieldType) self.dumpField(res, field.name, v)
# Dump the object history # Dump the object history
if hasattr(instance.aq_base, 'workflow_history'): if hasattr(instance.aq_base, 'workflow_history'):
histTag = self.getTagName('history') histTag = self.getTagName('history')