diff options
Diffstat (limited to 'py/modules/IcePy/ObjectFactory.cpp')
-rw-r--r-- | py/modules/IcePy/ObjectFactory.cpp | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/py/modules/IcePy/ObjectFactory.cpp b/py/modules/IcePy/ObjectFactory.cpp new file mode 100644 index 00000000000..fd461295c12 --- /dev/null +++ b/py/modules/IcePy/ObjectFactory.cpp @@ -0,0 +1,157 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2004 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. +// +// ********************************************************************** + +#include <ObjectFactory.h> +#include <Types.h> +#include <Util.h> +#include <Ice/LocalException.h> + +using namespace std; +using namespace IcePy; + +IcePy::ObjectFactory::ObjectFactory() +{ +} + +IcePy::ObjectFactory::~ObjectFactory() +{ + assert(_factoryMap.empty()); +} + +Ice::ObjectPtr +IcePy::ObjectFactory::create(const string& id) +{ + Lock sync(*this); + + // + // Get the type information. + // + ClassInfoPtr info = ClassInfoPtr::dynamicCast(getTypeInfo(id)); + if(!info) + { + return 0; + } + + // + // Check if the application has registered a factory for this id. + // + FactoryMap::iterator p = _factoryMap.find(id); + if(p != _factoryMap.end()) + { + // + // Invoke the create method on the Python factory object. + // + PyObjectHandle obj = PyObject_CallMethod(p->second, "create", "s", id.c_str()); + if(obj.get() == NULL) + { + throw AbortMarshaling(); + } + if(obj.get() == Py_None) + { + return 0; + } + return new ObjectReader(obj.get(), info); + } + + // + // Check if the requested type is a concrete class. If so, we can instantiate it directly. + // + if(info->isInterface || (info->id != Ice::Object::ice_staticId() && info->hasOperations())) + { + return 0; + } + + // + // Instantiate the object. + // + PyTypeObject* type = (PyTypeObject*)info->pythonType.get(); + PyObjectHandle args = PyTuple_New(0); + PyObjectHandle obj = type->tp_new(type, args.get(), NULL); + if(obj.get() == NULL) + { + throw AbortMarshaling(); + } + + return new ObjectReader(obj.get(), info); +} + +void +IcePy::ObjectFactory::destroy() +{ + Lock sync(*this); + + for(FactoryMap::iterator p = _factoryMap.begin(); p != _factoryMap.end(); ++p) + { + // + // Invoke the destroy method on each registered Python factory. + // + PyObjectHandle obj = PyObject_CallMethod(p->second, "destroy", NULL); + PyErr_Clear(); + Py_DECREF(p->second); + } + _factoryMap.clear(); +} + +bool +IcePy::ObjectFactory::add(PyObject* factory, const string& id) +{ + Lock sync(*this); + + FactoryMap::iterator p = _factoryMap.find(id); + if(p != _factoryMap.end()) + { + Ice::AlreadyRegisteredException ex(__FILE__, __LINE__); + ex.kindOfObject = "object factory"; + ex.id = id; + setPythonException(ex); + return false; + } + + _factoryMap.insert(FactoryMap::value_type(id, factory)); + Py_INCREF(factory); + + return true; +} + +bool +IcePy::ObjectFactory::remove(const string& id) +{ + Lock sync(*this); + + FactoryMap::iterator p = _factoryMap.find(id); + if(p == _factoryMap.end()) + { + Ice::NotRegisteredException ex(__FILE__, __LINE__); + ex.kindOfObject = "object factory"; + ex.id = id; + setPythonException(ex); + return false; + } + + Py_DECREF(p->second); + _factoryMap.erase(p); + + return true; +} + +PyObject* +IcePy::ObjectFactory::find(const string& id) +{ + Lock sync(*this); + + FactoryMap::iterator p = _factoryMap.find(id); + if(p == _factoryMap.end()) + { + Py_INCREF(Py_None); + return Py_None; + } + + Py_INCREF(p->second); + return p->second; +} |