Improved XmlMarshaller: strings can be dumped as CDATA. Appy objects are marshalled with their history.

This commit is contained in:
Gaetan Delannay 2009-12-07 20:28:41 +01:00
parent c3f5cfc9cd
commit b888f8149b
2 changed files with 29 additions and 5 deletions

View file

@ -295,11 +295,11 @@ class AbstractWrapper:
if toDisk and not at: if toDisk and not at:
at = getOsTempFolder() + '/' + self.o.UID() + '.xml' at = getOsTempFolder() + '/' + self.o.UID() + '.xml'
# Create the XML version of the object # Create the XML version of the object
xml = XmlMarshaller().marshall(self.o, objectType='archetype') xml = XmlMarshaller(cdata=True).marshall(self.o, objectType='appy')
# Produce the desired result # Produce the desired result
if toDisk: if toDisk:
f = file(at, 'w') f = file(at, 'w')
f.write(xml) f.write(xml.encode('utf-8'))
f.close() f.close()
return at return at
else: else:

View file

@ -336,14 +336,25 @@ 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):
'''If p_cdata is True, all string values will be dumped as XML CDATA.'''
self.cdata = cdata
def dumpString(self, res, s): def dumpString(self, res, s):
'''Dumps a string into the result.''' '''Dumps a string into the result.'''
if self.cdata: res.write('<![CDATA[')
# Try to solve encoding problems
try:
s = s.decode('utf-8')
except UnicodeEncodeError:
pass
# Replace special chars by XML entities # Replace special chars by XML entities
for c in s: for c in s:
if self.xmlEntities.has_key(c): if self.xmlEntities.has_key(c):
res.write(self.xmlEntities[c]) res.write(self.xmlEntities[c])
else: else:
res.write(c) res.write(c)
if self.cdata: res.write(']]>')
def dumpFile(self, res, v): def dumpFile(self, res, v):
'''Dumps a file into the result.''' '''Dumps a file into the result.'''
@ -428,10 +439,12 @@ class XmlMarshaller:
'''Returns in a StringIO the XML version of p_instance. If p_instance '''Returns in a StringIO the XML version of p_instance. If p_instance
corresponds to a Plain Old Python Object, specify 'popo' for corresponds to a Plain Old Python Object, specify 'popo' for
p_objectType. If p_instance corresponds to an Archetypes object p_objectType. If p_instance corresponds to an Archetypes object
(Zope/Plone), specify 'archetype' for p_objectType.''' (Zope/Plone), specify 'archetype' for p_objectType. if p_instance is
a Appy object, specify "appy" as p_objectType.'''
res = StringIO() res = StringIO()
# Dump the XML prologue and root element # Dump the XML prologue and root element
if objectType == 'archetype': objectId = instance.UID() # ID in DB if objectType in ('archetype', 'appy'):
objectId = instance.UID() # ID in DB
else: objectId = str(id(instance)) # ID in RAM else: objectId = str(id(instance)) # ID in RAM
res.write(self.xmlPrologue) res.write(self.xmlPrologue)
res.write('<'); res.write(self.rootElementName) res.write('<'); res.write(self.rootElementName)
@ -450,7 +463,7 @@ class XmlMarshaller:
mustDump = True mustDump = True
if mustDump: if mustDump:
self.dumpField(res, fieldName, fieldValue) self.dumpField(res, fieldName, fieldValue)
elif objectType == 'archetype': elif objectType in ('archetype', 'appy'):
fields = instance.schema.fields() fields = instance.schema.fields()
for field in instance.schema.fields(): for field in instance.schema.fields():
# Dump only needed fields # Dump only needed fields
@ -474,6 +487,17 @@ class XmlMarshaller:
fieldType = 'ref' fieldType = 'ref'
self.dumpField(res, field.getName(), field.get(instance), self.dumpField(res, field.getName(), field.get(instance),
fieldType=fieldType) fieldType=fieldType)
if objectType == 'appy':
# Dump the object history.
res.write('<history type="list">')
wfInfo = instance.portal_workflow.getWorkflowsFor(instance)
if wfInfo:
history = instance.workflow_history[wfInfo[0].id]
for event in history:
res.write('<event type="object">')
for k, v in event.iteritems(): self.dumpField(res, k, v)
res.write('</event>')
res.write('</history>')
self.marshallSpecificElements(instance, res) self.marshallSpecificElements(instance, res)
# Return the result # Return the result
res.write('</'); res.write(self.rootElementName); res.write('>') res.write('</'); res.write(self.rootElementName); res.write('>')