[gen] Extended the HTTP-XML system to be able to call a method via a HTTP POST containing XML data (SOAP or REST-like).
This commit is contained in:
parent
91e0bd2240
commit
6a83285e64
|
@ -46,7 +46,7 @@ class Phase:
|
|||
<img src=":url('edit')" title=":_('object_edit')"/></a>
|
||||
<a if="editable and locked">
|
||||
<img style="cursor: help"
|
||||
var="lockDate=tool.formatDate(locked[1]);
|
||||
var="lockDate=ztool.formatDate(locked[1]);
|
||||
lockMap={'user':ztool.getUserName(locked[0]), \
|
||||
'date':lockDate};
|
||||
lockMsg=_('page_locked', mapping=lockMap)"
|
||||
|
|
|
@ -286,6 +286,13 @@ class ZopeInstaller:
|
|||
if role not in roles: roles.append(role)
|
||||
self.app.__ac_roles__ = tuple(roles)
|
||||
|
||||
def patchZope(self):
|
||||
'''Patches some arts of Zope.'''
|
||||
# Disables XMLRPC. This way, Zope can transmit HTTP POSTs containing
|
||||
# XML to Appy without trying to recognize it himself as XMLRPC requests.
|
||||
import ZPublisher.HTTPRequest
|
||||
ZPublisher.HTTPRequest.xmlrpc = FakeXmlrpc()
|
||||
|
||||
def installDependencies(self):
|
||||
'''Zope products are installed in alphabetical order. But here, we need
|
||||
ZCTextIndex to be installed before our Appy application. So, we cheat
|
||||
|
@ -297,6 +304,7 @@ class ZopeInstaller:
|
|||
def install(self):
|
||||
self.logger.info('is being installed...')
|
||||
self.installDependencies()
|
||||
self.patchZope()
|
||||
self.installRoles()
|
||||
self.installAppyTypes()
|
||||
self.installZopeClasses()
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
# ------------------------------------------------------------------------------
|
||||
import os, os.path, sys, types, urllib, cgi
|
||||
from appy import Object
|
||||
from appy.px import Px
|
||||
from appy.fields.workflow import UiTransition
|
||||
import appy.gen as gen
|
||||
from appy.gen.utils import *
|
||||
|
@ -479,7 +480,7 @@ class BaseMixin:
|
|||
def xml(self, action=None):
|
||||
'''If no p_action is defined, this method returns the XML version of
|
||||
this object. Else, it calls method named p_action on the
|
||||
corresponding Appy wrapper and returns, as XML, the its result.'''
|
||||
corresponding Appy wrapper and returns, as XML, its result.'''
|
||||
self.REQUEST.RESPONSE.setHeader('Content-Type','text/xml;charset=utf-8')
|
||||
# Check if the user is allowed to consult this object
|
||||
if not self.allows('read'):
|
||||
|
@ -492,7 +493,13 @@ class BaseMixin:
|
|||
appyObj = self.appy()
|
||||
try:
|
||||
methodRes = getattr(appyObj, action)()
|
||||
res = XmlMarshaller().marshall(methodRes, objectType='appy')
|
||||
if isinstance(methodRes, Px):
|
||||
res = methodRes({'self': self.appy()})
|
||||
elif isinstance(methodRes, file):
|
||||
res = methodRes.read()
|
||||
methodRes.close()
|
||||
else:
|
||||
res = XmlMarshaller().marshall(methodRes, objectType='appy')
|
||||
except Exception, e:
|
||||
tb = Traceback.get()
|
||||
res = XmlMarshaller().marshall(tb, objectType='appy')
|
||||
|
@ -1378,9 +1385,24 @@ class BaseMixin:
|
|||
return res
|
||||
|
||||
def index_html(self):
|
||||
'''Redirects to /view.'''
|
||||
'''Base method called when hitting this object.
|
||||
- The standard behaviour is to redirect to /view.
|
||||
- If a parameter named "do" is present in the request, it is supposed
|
||||
to contain the name of a method to call on this object. In this
|
||||
case, we call this method and return its result as XML.
|
||||
- If method is POST, we consider the request to be XML data, that we
|
||||
marshall to Python, and we call the method in param "do" with, as
|
||||
arg, this marshalled Python object. While this could sound strange
|
||||
to expect a query string containing a param "do" in a HTTP POST,
|
||||
the HTTP spec does not prevent to do it.'''
|
||||
rq = self.REQUEST
|
||||
if rq.has_key('do'):
|
||||
if (rq.REQUEST_METHOD == 'POST') and rq.QUERY_STRING:
|
||||
# A POST method containing XML data.
|
||||
rq.args = XmlUnmarshaller().parse(rq.stdin.getvalue())
|
||||
# Find the name of the method to call.
|
||||
methodName = rq.QUERY_STRING.split('=')[1]
|
||||
return self.xml(action=methodName)
|
||||
elif rq.has_key('do'):
|
||||
# The user wants to call a method on this object and get its result
|
||||
# as XML.
|
||||
return self.xml(action=rq['do'])
|
||||
|
|
|
@ -476,8 +476,9 @@ class AbstractWrapper(object):
|
|||
<!-- Locked -->
|
||||
<a if="editable and locked">
|
||||
<img style="cursor: help"
|
||||
var="lockDate=tool.formatDate(locked[1]);
|
||||
lockMap={'user':tool.getUserName(locked[0]),'date':lockDate};
|
||||
var="lockDate=ztool.formatDate(locked[1]);
|
||||
lockMap={'user':ztool.getUserName(locked[0]), \
|
||||
'date':lockDate};
|
||||
lockMsg=_('page_locked', mapping=lockMap)"
|
||||
src=":url('lockedBig')" title=":lockMsg"/></a>
|
||||
</td>
|
||||
|
|
Loading…
Reference in a new issue