diff options
author | Bernard Normier <bernard@zeroc.com> | 2006-10-25 20:59:01 +0000 |
---|---|---|
committer | Bernard Normier <bernard@zeroc.com> | 2006-10-25 20:59:01 +0000 |
commit | b51bbbbdb61ff4e71cd99e2b626e00f701ecb880 (patch) | |
tree | 62de660937598471b96644e9999b0b3e01173b69 | |
parent | update for bug 1500 (diff) | |
download | ice-b51bbbbdb61ff4e71cd99e2b626e00f701ecb880.tar.bz2 ice-b51bbbbdb61ff4e71cd99e2b626e00f701ecb880.tar.xz ice-b51bbbbdb61ff4e71cd99e2b626e00f701ecb880.zip |
Added implicit context implementation
-rw-r--r-- | py/modules/IcePy/Communicator.cpp | 20 | ||||
-rw-r--r-- | py/modules/IcePy/ImplicitContext.cpp | 309 | ||||
-rw-r--r-- | py/modules/IcePy/ImplicitContext.h | 27 | ||||
-rw-r--r-- | py/modules/IcePy/Init.cpp | 5 | ||||
-rw-r--r-- | py/modules/IcePy/Makefile | 1 | ||||
-rwxr-xr-x | py/modules/IcePy/Makefile.mak | 1 | ||||
-rw-r--r-- | py/python/Ice.py | 30 | ||||
-rw-r--r-- | py/test/Ice/operations/Twoways.py | 44 | ||||
-rw-r--r-- | py/test/Ice/operations/TwowaysAMI.py | 51 |
9 files changed, 486 insertions, 2 deletions
diff --git a/py/modules/IcePy/Communicator.cpp b/py/modules/IcePy/Communicator.cpp index 2871800a2a3..caf3d9f2cea 100644 --- a/py/modules/IcePy/Communicator.cpp +++ b/py/modules/IcePy/Communicator.cpp @@ -12,6 +12,7 @@ #endif #include <IceUtil/DisableWarnings.h> #include <Communicator.h> +#include <ImplicitContext.h> #include <Logger.h> #include <ObjectAdapter.h> #include <ObjectFactory.h> @@ -727,6 +728,23 @@ communicatorGetDefaultContext(CommunicatorObject* self) extern "C" #endif static PyObject* +communicatorGetImplicitContext(CommunicatorObject* self) +{ + Ice::ImplicitContextPtr implicitContext = (*self->communicator)->getImplicitContext(); + + if(implicitContext == 0) + { + return 0; + } + + return createImplicitContext(implicitContext); +} + + +#ifdef WIN32 +extern "C" +#endif +static PyObject* communicatorCreateObjectAdapter(CommunicatorObject* self, PyObject* args) { char* name; @@ -1027,6 +1045,8 @@ static PyMethodDef CommunicatorMethods[] = PyDoc_STR(STRCAST("setDefaultContext(ctx) -> None")) }, { STRCAST("getDefaultContext"), (PyCFunction)communicatorGetDefaultContext, METH_NOARGS, PyDoc_STR(STRCAST("getDefaultContext() -> Ice.Context")) }, + { STRCAST("getImplicitContext"), (PyCFunction)communicatorGetImplicitContext, METH_NOARGS, + PyDoc_STR(STRCAST("getImplicitContext() -> Ice.ImplicitContext")) }, { STRCAST("getProperties"), (PyCFunction)communicatorGetProperties, METH_NOARGS, PyDoc_STR(STRCAST("getProperties() -> Ice.Properties")) }, { STRCAST("getLogger"), (PyCFunction)communicatorGetLogger, METH_NOARGS, diff --git a/py/modules/IcePy/ImplicitContext.cpp b/py/modules/IcePy/ImplicitContext.cpp new file mode 100644 index 00000000000..6b8411f816c --- /dev/null +++ b/py/modules/IcePy/ImplicitContext.cpp @@ -0,0 +1,309 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2006 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifdef _WIN32 +# include <IceUtil/Config.h> +#endif +#include <ImplicitContext.h> +#include <ObjectAdapter.h> +#include <Proxy.h> +#include <Util.h> +#include <Ice/ImplicitContext.h> + +using namespace std; +using namespace IcePy; + +namespace IcePy +{ + +extern PyTypeObject ImplicitContextType; + +struct ImplicitContextObject +{ + PyObject_HEAD + Ice::ImplicitContextPtr* implicitContext; +}; + +} + +#ifdef WIN32 +extern "C" +#endif +static ImplicitContextObject* +implicitContextNew(PyObject* /*arg*/) +{ + ImplicitContextObject* self = PyObject_New(ImplicitContextObject, &ImplicitContextType); + if (self == NULL) + { + return NULL; + } + self->implicitContext = 0; + return self; +} + +#ifdef WIN32 +extern "C" +#endif +static void +implicitContextDealloc(ImplicitContextObject* self) +{ + delete self->implicitContext; + PyObject_Del(self); +} + +#ifdef WIN32 +extern "C" +#endif +static int +implicitContextCompare(ImplicitContextObject* c1, ImplicitContextObject* c2) +{ + if(*c1->implicitContext < *c2->implicitContext) + { + return -1; + } + else if(*c1->implicitContext == *c2->implicitContext) + { + return 0; + } + else + { + return 1; + } +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +implicitContextGetContext(ImplicitContextObject* self) +{ + Ice::Context ctx = (*self->implicitContext)->getContext(); + + PyObjectHandle dict = PyDict_New(); + if(dict.get() == NULL) + { + return NULL; + } + + if(!contextToDictionary(ctx, dict.get())) + { + return NULL; + } + + return dict.release(); +} + + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +implicitContextSetContext(ImplicitContextObject* self, PyObject* args) +{ + PyObject* dict; + if(!PyArg_ParseTuple(args, STRCAST("O!"), &PyDict_Type, &dict)) + { + return NULL; + } + + Ice::Context ctx; + if(!dictionaryToContext(dict, ctx)) + { + return NULL; + } + + (*self->implicitContext)->setContext(ctx); + + Py_INCREF(Py_None); + return Py_None; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +implicitContextGet(ImplicitContextObject* self, PyObject* args) +{ + char* key; + if(!PyArg_ParseTuple(args, STRCAST("s"), &key)) + { + return NULL; + } + + string val; + try + { + val = (*self->implicitContext)->get(key); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return NULL; + } + return PyString_FromString(const_cast<char*>(val.c_str())); +} + + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +implicitContextGetWithDefault(ImplicitContextObject* self, PyObject* args) +{ + char* key; + char* dflt; + if(!PyArg_ParseTuple(args, STRCAST("ss"), &key, &dflt)) + { + return NULL; + } + + string val = (*self->implicitContext)->getWithDefault(key, dflt); + return PyString_FromString(const_cast<char*>(val.c_str())); +} + + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +implicitContextSet(ImplicitContextObject* self, PyObject* args) +{ + char* key; + char* val; + if(!PyArg_ParseTuple(args, STRCAST("ss"), &key, &val)) + { + return NULL; + } + + (*self->implicitContext)->set(key, val); + Py_INCREF(Py_None); + return Py_None; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +implicitContextRemove(ImplicitContextObject* self, PyObject* args) +{ + char* key; + if(!PyArg_ParseTuple(args, STRCAST("s"), &key)) + { + return NULL; + } + + try + { + (*self->implicitContext)->remove(key); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return NULL; + } + + Py_INCREF(Py_None); + return Py_None; +} + +static PyMethodDef ImplicitContextMethods[] = +{ + { STRCAST("getContext"), (PyCFunction)implicitContextGetContext, METH_VARARGS, + PyDoc_STR(STRCAST("getContext() -> Ice.Context")) }, + { STRCAST("setContext"), (PyCFunction)implicitContextSetContext, METH_VARARGS, + PyDoc_STR(STRCAST("setContext(ctx) -> None")) }, + { STRCAST("get"), (PyCFunction)implicitContextGet, METH_VARARGS, + PyDoc_STR(STRCAST("get(key) -> string")) }, + { STRCAST("getWithDefault"), (PyCFunction)implicitContextGetWithDefault, METH_VARARGS, + PyDoc_STR(STRCAST("getWithDefault(key, defaultValue) -> string")) }, + { STRCAST("set"), (PyCFunction)implicitContextSet, METH_VARARGS, + PyDoc_STR(STRCAST("set(key, value) -> None")) }, + { STRCAST("remove"), (PyCFunction)implicitContextRemove, METH_VARARGS, + PyDoc_STR(STRCAST("remove(key) -> None")) }, + { NULL, NULL} /* sentinel */ +}; + +namespace IcePy +{ + +PyTypeObject ImplicitContextType = +{ + /* The ob_type field must be initialized in the module init function + * to be portable to Windows without using C++. */ + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + STRCAST("IcePy.ImplicitContext"), /* tp_name */ + sizeof(ImplicitContextObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)implicitContextDealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + (cmpfunc)implicitContextCompare, /* tp_compare */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + ImplicitContextMethods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + (newfunc)implicitContextNew, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ +}; + +} + +bool +IcePy::initImplicitContext(PyObject* module) +{ + if(PyType_Ready(&ImplicitContextType) < 0) + { + return false; + } + if(PyModule_AddObject(module, STRCAST("ImplicitContext"), (PyObject*)&ImplicitContextType) < 0) + { + return false; + } + + return true; +} + +PyObject* +IcePy::createImplicitContext(const Ice::ImplicitContextPtr& implicitContext) +{ + ImplicitContextObject* obj = implicitContextNew(NULL); + if(obj != NULL) + { + obj->implicitContext = new Ice::ImplicitContextPtr(implicitContext); + } + return (PyObject*)obj; +} diff --git a/py/modules/IcePy/ImplicitContext.h b/py/modules/IcePy/ImplicitContext.h new file mode 100644 index 00000000000..12363473128 --- /dev/null +++ b/py/modules/IcePy/ImplicitContext.h @@ -0,0 +1,27 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2006 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICEPY_IMPLICIT_CONTEXT_H +#define ICEPY_IMPLICIT_CONTEXT_H + +#include <Config.h> +#include <Ice/ImplicitContext.h> + +namespace IcePy +{ + +extern PyTypeObject ImplicitContextType; + +bool initImplicitContext(PyObject*); + +PyObject* createImplicitContext(const Ice::ImplicitContextPtr&); + +} + +#endif diff --git a/py/modules/IcePy/Init.cpp b/py/modules/IcePy/Init.cpp index 58eb87d84c4..d70b9d85f02 100644 --- a/py/modules/IcePy/Init.cpp +++ b/py/modules/IcePy/Init.cpp @@ -13,6 +13,7 @@ #include <Communicator.h> #include <Connection.h> #include <Current.h> +#include <ImplicitContext.h> #include <Logger.h> #include <ObjectAdapter.h> #include <Operation.h> @@ -123,4 +124,8 @@ initIcePy(void) { return; } + if(!initImplicitContext(module)) + { + return; + } } diff --git a/py/modules/IcePy/Makefile b/py/modules/IcePy/Makefile index b24c6c63626..53ad6e883a4 100644 --- a/py/modules/IcePy/Makefile +++ b/py/modules/IcePy/Makefile @@ -18,6 +18,7 @@ TARGETS = $(call mklibtargets,$(libdir)/$(LIBFILENAME),$(libdir)/$(SONAME),$(li OBJS = Communicator.o \ Connection.o \ Current.o \ + ImplicitContext.o \ Init.o \ Logger.o \ ObjectAdapter.o \ diff --git a/py/modules/IcePy/Makefile.mak b/py/modules/IcePy/Makefile.mak index 50a3776076c..943e304e357 100755 --- a/py/modules/IcePy/Makefile.mak +++ b/py/modules/IcePy/Makefile.mak @@ -17,6 +17,7 @@ TARGETS = $(LIBNAME) $(DLLNAME) OBJS = Communicator.obj \ Connection.obj \ Current.obj \ + ImplicitContext.obj \ Init.obj \ Logger.obj \ ObjectAdapter.obj \ diff --git a/py/python/Ice.py b/py/python/Ice.py index 608fc52d177..e0e850dab9a 100644 --- a/py/python/Ice.py +++ b/py/python/Ice.py @@ -178,7 +178,6 @@ class InitializationData(object): self.properties = None self.logger = None #self.stats = None # Stats not currently supported in Python. - self.defaultContext = {} self.threadHook = None # @@ -240,6 +239,9 @@ class CommunicatorI(Communicator): def getDefaultContext(self): return self._impl.getDefaultContext() + def getImplicitContext(self): + return ImplicitContextI(self._impl.getImplicitContext()) + def getProperties(self): properties = self._impl.getProperties() return PropertiesI(properties) @@ -476,6 +478,32 @@ def createProperties(args=[], defaults=None): # +# ImplicitContext wrapper +# +class ImplicitContextI(ImplicitContext): + def __init__(self, impl): + self._impl = impl + + def setContext(self, ctx): + self._impl.setContext(ctx) + + def getContext(self): + return self._impl.getContext(); + + def set(self, key, value): + self._impl.set(key, value); + + def remove(self, key): + self._impl.remove(key); + + def get(self, key): + return self._impl.get(key); + + def getWithDefault(self, key, dflt): + return self._impl.getWithDefault(key, dflt); + + +# # The variables below need to be global in order to properly reference a # static method of Application. # diff --git a/py/test/Ice/operations/Twoways.py b/py/test/Ice/operations/Twoways.py index dcf925df4dc..3417182b17e 100644 --- a/py/test/Ice/operations/Twoways.py +++ b/py/test/Ice/operations/Twoways.py @@ -149,7 +149,6 @@ def twoways(communicator, initData, p): # # opByteS (array) # - print "array", bsi1 = array.array('B') bsi1.fromlist([0x01, 0x11, 0x12, 0x22]) bsi2 = array.array('B') @@ -595,3 +594,46 @@ def twoways(communicator, initData, p): test(c5.opContext()['a'] == 'd') communicator.setDefaultContext({}) + + # + # Test implicit context propagation + # + impls = ( 'Shared', 'SharedWithoutLocking', 'PerThread' ) + for i in impls: + initData = Ice.InitializationData() + initData.properties = Ice.createProperties() + initData.properties.setProperty('Ice.ImplicitContext', i) + ic = Ice.initialize(data=initData) + + ctx = {'one': 'ONE', 'two': 'TWO', 'three': 'THREE'} + + p = Test.MyClassPrx.uncheckedCast(ic.stringToProxy("test:default -p 12010 -t 10000")) + + ic.getImplicitContext().setContext(ctx) + test(ic.getImplicitContext().getContext() == ctx) + test(p.opContext() == ctx) + + ic.getImplicitContext().set('zero', 'ZERO') + test(ic.getImplicitContext().get('zero') == 'ZERO') + test(ic.getImplicitContext().getWithDefault('foobar', 'foo') == 'foo') + ic.getImplicitContext().remove('two') + test(ic.getImplicitContext().getWithDefault('two', 'bar') == 'bar') + ctx = ic.getImplicitContext().getContext() + test(p.opContext() == ctx) + + prxContext = {'one': 'UN', 'four': 'QUATRE'} + + combined = ctx + combined.update(prxContext) + test(combined['one'] == 'UN') + + p = Test.MyClassPrx.uncheckedCast(p.ice_context(prxContext)) + ic.getImplicitContext().setContext({}) + test(p.opContext() == prxContext) + + ic.getImplicitContext().setContext(ctx) + test(p.opContext() == combined) + + ic.destroy() + + diff --git a/py/test/Ice/operations/TwowaysAMI.py b/py/test/Ice/operations/TwowaysAMI.py index 4788a03a232..a6ac6db5999 100644 --- a/py/test/Ice/operations/TwowaysAMI.py +++ b/py/test/Ice/operations/TwowaysAMI.py @@ -855,8 +855,59 @@ def twowaysAMI(communicator, initData, p): derived.opDerived_async(cb) test(cb.check()) + # + # Test implicit context propagation + # + impls = ( 'Shared', 'SharedWithoutLocking', 'PerThread' ) + for i in impls: + initData = Ice.InitializationData() + initData.properties = Ice.createProperties() + initData.properties.setProperty('Ice.ImplicitContext', i) + ic = Ice.initialize(data=initData) + + ctx = {'one': 'ONE', 'two': 'TWO', 'three': 'THREE'} + + p = Test.MyClassPrx.uncheckedCast(ic.stringToProxy("test:default -p 12010 -t 10000")) + + ic.getImplicitContext().setContext(ctx) + test(ic.getImplicitContext().getContext() == ctx) + + cb = AMI_MyClass_opContextEqualI(ctx) + p.opContext_async(cb) + test(cb.check()) + + ic.getImplicitContext().set('zero', 'ZERO') + test(ic.getImplicitContext().get('zero') == 'ZERO') + test(ic.getImplicitContext().getWithDefault('foobar', 'foo') == 'foo') + ic.getImplicitContext().remove('two') + test(ic.getImplicitContext().getWithDefault('two', 'bar') == 'bar') + ctx = ic.getImplicitContext().getContext() + + cb = AMI_MyClass_opContextEqualI(ctx) + p.opContext_async(cb) + test(cb.check()) + + prxContext = {'one': 'UN', 'four': 'QUATRE'} + + combined = ctx + combined.update(prxContext) + test(combined['one'] == 'UN') + + p = Test.MyClassPrx.uncheckedCast(p.ice_context(prxContext)) + ic.getImplicitContext().setContext({}) + + cb = AMI_MyClass_opContextEqualI(prxContext) + p.opContext_async(cb) + test(cb.check()) + + ic.getImplicitContext().setContext(ctx) + cb = AMI_MyClass_opContextEqualI(combined) + p.opContext_async(cb) + test(cb.check()) + ic.destroy() + |