// -*- Mode: C++; -*-
// Package : omniORBpy
// pyInterceptors.cc Created on: 2003/05/27
// Author : Duncan Grisby (dgrisby)
//
// Copyright (C) 2003 Apasphere Ltd.
//
// This file is part of the omniORBpy library
//
// The omniORBpy library is free software; you can redistribute it
// and/or modify it under the terms of the GNU Lesser General
// Public License as published by the Free Software Foundation;
// either version 2.1 of the License, or (at your option) any later
// version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free
// Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
// MA 02111-1307, USA
//
// Description:
// Python request interceptors
// $Id: pyInterceptors.cc,v 1.1.4.3 2006/06/05 11:51:00 dgrisby Exp $
// $Log: pyInterceptors.cc,v $
// Revision 1.1.4.3 2006/06/05 11:51:00 dgrisby
// Track ORB core interceptor change.
//
// Revision 1.1.4.2 2005/07/22 17:41:08 dgrisby
// Update from omnipy2_develop.
//
// Revision 1.1.4.1 2005/01/07 00:22:32 dgrisby
// Big merge from omnipy2_develop.
//
// Revision 1.1.2.2 2003/07/26 23:17:43 dgrisby
// Avoid spurious warning about lack of return value.
//
// Revision 1.1.2.1 2003/05/28 10:13:01 dgrisby
// Preliminary interceptor support. General clean-up.
//
#include <omnipy.h>
#include <pyThreadCache.h>
#include <omniORB4/omniInterceptors.h>
#include <giopStream.h>
#include <giopStrand.h>
#include <giopRope.h>
#include <GIOP_S.h>
#include <GIOP_C.h>
OMNI_USING_NAMESPACE(omni)
// Python lists of interceptor functions
static PyObject* clientSendRequestFns = 0;
static PyObject* clientReceiveReplyFns = 0;
static PyObject* serverReceiveRequestFns = 0;
static PyObject* serverSendReplyFns = 0;
static PyObject* serverSendExceptionFns = 0;
static inline
CORBA::ULong
pyNumberToULong(PyObject* obj, CORBA::CompletionStatus completion)
{
if (PyInt_Check(obj)) {
long r = PyInt_AS_LONG(obj);
if (r >= 0)
return r;
}
if (PyLong_Check(obj)) {
CORBA::ULong r = PyLong_AsUnsignedLong(obj);
if (r == (CORBA::ULong)-1 && PyErr_Occurred())
PyErr_Clear();
else
return r;
}
OMNIORB_THROW(BAD_PARAM, BAD_PARAM_WrongPythonType, completion);
return 0;
}
static
void
callInterceptorsAndSetContexts(PyObject* fnlist,
const char* opname,
const char* exrepoid,
IOP::ServiceContextList& service_contexts,
CORBA::CompletionStatus completion)
{
PyObject* argtuple;
if (exrepoid)
argtuple = PyTuple_New(3);
else
argtuple = PyTuple_New(2);
PyObject* ctxtlist = PyList_New(0);
PyTuple_SetItem(argtuple, 0, PyString_FromString(opname));
PyTuple_SetItem(argtuple, 1, ctxtlist);
if (exrepoid)
PyTuple_SetItem(argtuple, 2, PyString_FromString(exrepoid));
CORBA::ULong sclen = service_contexts.length();
CORBA::ULong sci = sclen;
try {
for (int i=0; i < PyList_GET_SIZE(fnlist); i++) {
PyObject* interceptor = PyList_GET_ITEM(fnlist, i);
PyObject* result = PyObject_CallObject(interceptor, argtuple);
if (!result) {
omniPy::handlePythonException();
}
if (result != Py_None) {
Py_DECREF(result);
OMNIORB_THROW(BAD_PARAM, BAD_PARAM_WrongPythonType, completion);
}
Py_DECREF(result);
if (PyList_GET_SIZE(ctxtlist) > 0) {
sclen += PyList_GET_SIZE(ctxtlist);
service_contexts.length(sclen);
for (int j=0; j < PyList_GET_SIZE(ctxtlist); j++, sci++) {
PyObject* sc = PyList_GET_ITEM(ctxtlist, j);
if (!PyTuple_Check(sc) || PyTuple_GET_SIZE(sc) != 2) {
OMNIORB_THROW(BAD_PARAM, BAD_PARAM_WrongPythonType, completion);
}
service_contexts[sci].context_id =
pyNumberToULong(PyTuple_GET_ITEM(sc, 0), completion);
PyObject* data = PyTuple_GET_ITEM(sc, 1);
if (!PyString_Check(data))
OMNIORB_THROW(BAD_PARAM, BAD_PARAM_WrongPythonType, completion);
service_contexts[sci].context_data.length(PyString_GET_SIZE(data));
memcpy(service_contexts[sci].context_data.NP_data(),
PyString_AS_STRING(data),
PyString_GET_SIZE(data));
}
PyList_SetSlice(ctxtlist, 0, PyList_GET_SIZE(ctxtlist), 0);
}
}
}
catch (...) {
Py_DECREF(argtuple);
throw;
}
Py_DECREF(argtuple);
}
static
void
getContextsAndCallInterceptors(PyObject* fnlist,
const char* opname,
IOP::ServiceContextList& service_contexts,
CORBA::CompletionStatus completion)
{
int i;
int sclen = service_contexts.length();
PyObject* argtuple = PyTuple_New(2);
PyObject* sctuple = PyTuple_New(sclen);
PyTuple_SET_ITEM(argtuple, 0, PyString_FromString(opname));
PyTuple_SET_ITEM(argtuple, 1, sctuple);
for (i=0; i < sclen; i++) {
PyObject* sc = PyTuple_New(2);
PyTuple_SET_ITEM(sc, 0,
PyLong_FromUnsignedLong(service_contexts[i].context_id));
const char* data = (const char*)service_contexts[i].context_data.NP_data();
int len = service_contexts[i].context_data.length();
PyTuple_SET_ITEM(sc, 1, PyString_FromStringAndSize(data, len));
PyTuple_SET_ITEM(sctuple, i, sc);
}
try {
for (i=0; i < PyList_GET_SIZE(fnlist); i++) {
PyObject* interceptor = PyList_GET_ITEM(fnlist, i);
PyObject* result = PyObject_CallObject(interceptor, argtuple);
if (!result) {
omniPy::handlePythonException();
}
if (result != Py_None) {
Py_DECREF(result);
OMNIORB_THROW(BAD_PARAM, BAD_PARAM_WrongPythonType, completion);
}
Py_DECREF(result);
}
}
catch (...) {
Py_DECREF(argtuple);
throw;
}
Py_DECREF(argtuple);
}
static
CORBA::Boolean
pyClientSendRequestFn(omniInterceptors::clientSendRequest_T::info_T& info)
{
OMNIORB_ASSERT(clientSendRequestFns);
omnipyThreadCache::lock _t;
callInterceptorsAndSetContexts(clientSendRequestFns,
info.giop_c.operation(),
0,
info.service_contexts,
CORBA::COMPLETED_NO);
return 1;
}
static
CORBA::Boolean
pyClientReceiveReplyFn(omniInterceptors::clientReceiveReply_T::info_T& info)
{
OMNIORB_ASSERT(clientReceiveReplyFns);
omnipyThreadCache::lock _t;
getContextsAndCallInterceptors(clientReceiveReplyFns,
info.giop_c.operation(),
info.service_contexts,
(CORBA::CompletionStatus)
info.giop_c.completion());
return 1;
}
static
CORBA::Boolean
pyServerReceiveRequestFn(omniInterceptors::
serverReceiveRequest_T::info_T& info)
{
OMNIORB_ASSERT(serverReceiveRequestFns);
omnipyThreadCache::lock _t;
getContextsAndCallInterceptors(serverReceiveRequestFns,
info.giop_s.operation(),
info.giop_s.service_contexts(),
(CORBA::CompletionStatus)
info.giop_s.completion());
return 1;
}
static
CORBA::Boolean
pyServerSendReplyFn(omniInterceptors::serverSendReply_T::info_T& info)
{
OMNIORB_ASSERT(serverSendReplyFns);
omnipyThreadCache::lock _t;
callInterceptorsAndSetContexts(serverSendReplyFns,
info.giop_s.operation(), 0,
info.giop_s.service_contexts(),
(CORBA::CompletionStatus)
info.giop_s.completion());
return 1;
}
static
CORBA::Boolean
pyServerSendExceptionFn(omniInterceptors::serverSendException_T::info_T& info)
{
OMNIORB_ASSERT(serverSendExceptionFns);
omnipyThreadCache::lock _t;
callInterceptorsAndSetContexts(serverSendExceptionFns,
info.giop_s.operation(),
info.exception->_rep_id(),
info.giop_s.service_contexts(),
(CORBA::CompletionStatus)
info.giop_s.completion());
return 1;
}
void
omniPy::
registerInterceptors()
{
omniInterceptors* interceptors = omniORB::getInterceptors();
if (clientSendRequestFns)
interceptors->clientSendRequest.add(pyClientSendRequestFn);
if (clientReceiveReplyFns)
interceptors->clientReceiveReply.add(pyClientReceiveReplyFn);
if (serverReceiveRequestFns)
interceptors->serverReceiveRequest.add(pyServerReceiveRequestFn);
if (serverSendReplyFns)
interceptors->serverSendReply.add(pyServerSendReplyFn);
if (serverSendExceptionFns)
interceptors->serverSendException.add(pyServerSendExceptionFn);
}
#define CHECK_ORB_NOT_INITIALISED() \
do { \
if (omniPy::orb) { \
CORBA::BAD_INV_ORDER _ex(BAD_INV_ORDER_InvalidPortableInterceptorCall, \
CORBA::COMPLETED_NO); \
return omniPy::handleSystemException(_ex); \
} \
} while(0)
extern "C" {
static char addClientSendRequest_doc [] =
"addClientSendRequest(interceptor) -> None\n"
"\n"
"Install an interceptor for when clients send requests.\n";
static PyObject* pyInterceptor_addClientSendRequest(PyObject* self,
PyObject* args)
{
PyObject* interceptor;
if (!PyArg_ParseTuple(args, (char*)"O", &interceptor))
return 0;
RAISE_PY_BAD_PARAM_IF(!PyCallable_Check(interceptor),
BAD_PARAM_WrongPythonType);
CHECK_ORB_NOT_INITIALISED();
if (!clientSendRequestFns)
clientSendRequestFns = PyList_New(0);
PyList_Append(clientSendRequestFns, interceptor);
Py_INCREF(Py_None);
return Py_None;
}
static char addClientReceiveReply_doc [] =
"addClientReceiveReply(interceptor) -> None\n"
"\n"
"Install an interceptor for when clients receive replies.\n";
static PyObject* pyInterceptor_addClientReceiveReply(PyObject* self,
PyObject* args)
{
PyObject* interceptor;
if (!PyArg_ParseTuple(args, (char*)"O", &interceptor))
return 0;
RAISE_PY_BAD_PARAM_IF(!PyCallable_Check(interceptor),
BAD_PARAM_WrongPythonType);
CHECK_ORB_NOT_INITIALISED();
if (!clientReceiveReplyFns)
clientReceiveReplyFns = PyList_New(0);
PyList_Append(clientReceiveReplyFns, interceptor);
Py_INCREF(Py_None);
return Py_None;
}
static char addServerReceiveRequest_doc [] =
"addServerReceiveRequest(interceptor) -> None\n"
"\n"
"Install an interceptor for when servers receive requests.\n";
static PyObject* pyInterceptor_addServerReceiveRequest(PyObject* self,
PyObject* args)
{
PyObject* interceptor;
if (!PyArg_ParseTuple(args, (char*)"O", &interceptor))
return 0;
RAISE_PY_BAD_PARAM_IF(!PyCallable_Check(interceptor),
BAD_PARAM_WrongPythonType);
CHECK_ORB_NOT_INITIALISED();
if (!serverReceiveRequestFns)
serverReceiveRequestFns = PyList_New(0);
PyList_Append(serverReceiveRequestFns, interceptor);
Py_INCREF(Py_None);
return Py_None;
}
static char addServerSendReply_doc [] =
"addServerSendReply(interceptor) -> None\n"
"\n"
"Install an interceptor for when servers send replies.\n";
static PyObject* pyInterceptor_addServerSendReply(PyObject* self,
PyObject* args)
{
PyObject* interceptor;
if (!PyArg_ParseTuple(args, (char*)"O", &interceptor))
return 0;
RAISE_PY_BAD_PARAM_IF(!PyCallable_Check(interceptor),
BAD_PARAM_WrongPythonType);
CHECK_ORB_NOT_INITIALISED();
if (!serverSendReplyFns)
serverSendReplyFns = PyList_New(0);
PyList_Append(serverSendReplyFns, interceptor);
Py_INCREF(Py_None);
return Py_None;
}
static char addServerSendException_doc [] =
"addServerSendException(interceptor) -> None\n"
"\n"
"Install an interceptor for when servers send exceptions.\n";
static PyObject* pyInterceptor_addServerSendException(PyObject* self,
PyObject* args)
{
PyObject* interceptor;
if (!PyArg_ParseTuple(args, (char*)"O", &interceptor))
return 0;
RAISE_PY_BAD_PARAM_IF(!PyCallable_Check(interceptor),
BAD_PARAM_WrongPythonType);
CHECK_ORB_NOT_INITIALISED();
if (!serverSendExceptionFns)
serverSendExceptionFns = PyList_New(0);
PyList_Append(serverSendExceptionFns, interceptor);
Py_INCREF(Py_None);
return Py_None;
}
static PyMethodDef pyInterceptor_methods[] = {
{(char*)"addClientSendRequest",
pyInterceptor_addClientSendRequest,
METH_VARARGS,
addClientSendRequest_doc},
{(char*)"addClientReceiveReply",
pyInterceptor_addClientReceiveReply,
METH_VARARGS,
addClientReceiveReply_doc},
{(char*)"addServerReceiveRequest",
pyInterceptor_addServerReceiveRequest,
METH_VARARGS,
addServerReceiveRequest_doc},
{(char*)"addServerSendReply",
pyInterceptor_addServerSendReply,
METH_VARARGS,
addServerSendReply_doc},
{(char*)"addServerSendException",
pyInterceptor_addServerSendException,
METH_VARARGS,
addServerSendException_doc},
{NULL,NULL}
};
}
void
omniPy::initInterceptorFunc(PyObject* d)
{
PyObject* m = Py_InitModule((char*)"_omnipy.interceptor_func",
pyInterceptor_methods);
PyDict_SetItemString(d, (char*)"interceptor_func", m);
}
syntax highlighted by Code2HTML, v. 0.9.1