summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES9
-rwxr-xr-xcpp/allTests.py1
-rw-r--r--cpp/src/Ice/ObjectAdapterI.cpp30
-rw-r--r--cpp/src/Ice/ObjectAdapterI.h4
-rw-r--r--cpp/src/Ice/ServantManager.cpp82
-rw-r--r--cpp/src/Ice/ServantManager.h6
-rw-r--r--cpp/test/Ice/Makefile3
-rw-r--r--cpp/test/Ice/Makefile.mak3
-rw-r--r--cpp/test/Ice/defaultServant/.depend3
-rw-r--r--cpp/test/Ice/defaultServant/.gitignore6
-rw-r--r--cpp/test/Ice/defaultServant/AllTests.cpp158
-rw-r--r--cpp/test/Ice/defaultServant/Client.cpp57
-rw-r--r--cpp/test/Ice/defaultServant/Makefile33
-rw-r--r--cpp/test/Ice/defaultServant/Makefile.mak39
-rw-r--r--cpp/test/Ice/defaultServant/Test.ice23
-rw-r--r--cpp/test/Ice/defaultServant/TestI.cpp45
-rw-r--r--cpp/test/Ice/defaultServant/TestI.h23
-rwxr-xr-xcpp/test/Ice/defaultServant/run.py25
-rwxr-xr-xcs/allTests.py1
-rw-r--r--cs/src/Ice/ObjectAdapterI.cs30
-rw-r--r--cs/src/Ice/ServantManager.cs63
-rw-r--r--cs/test/Ice/Makefile3
-rw-r--r--cs/test/Ice/Makefile.mak3
-rw-r--r--cs/test/Ice/defaultServant/.depend1
-rw-r--r--cs/test/Ice/defaultServant/AllTests.cs167
-rw-r--r--cs/test/Ice/defaultServant/Client.cs66
-rw-r--r--cs/test/Ice/defaultServant/Makefile32
-rw-r--r--cs/test/Ice/defaultServant/Makefile.mak32
-rw-r--r--cs/test/Ice/defaultServant/MyObjectI.cs44
-rw-r--r--cs/test/Ice/defaultServant/Test.ice23
-rwxr-xr-xcs/test/Ice/defaultServant/run.py30
-rwxr-xr-xjava/allTests.py1
-rw-r--r--java/build.xml3
-rw-r--r--java/src/Ice/ObjectAdapterI.java24
-rw-r--r--java/src/IceInternal/ServantManager.java54
-rw-r--r--java/test/Ice/defaultServant/AllTests.java171
-rw-r--r--java/test/Ice/defaultServant/Client.java29
-rw-r--r--java/test/Ice/defaultServant/MyObjectI.java46
-rw-r--r--java/test/Ice/defaultServant/Test.ice24
-rwxr-xr-xjava/test/Ice/defaultServant/run.py28
-rwxr-xr-xpy/allTests.py1
-rw-r--r--py/modules/IcePy/ObjectAdapter.cpp129
-rw-r--r--py/python/Ice.py9
-rw-r--r--py/test/Ice/defaultServant/AllTests.py124
-rwxr-xr-xpy/test/Ice/defaultServant/Client.py36
-rw-r--r--py/test/Ice/defaultServant/MyObjectI.py29
-rw-r--r--py/test/Ice/defaultServant/Test.ice23
-rwxr-xr-xpy/test/Ice/defaultServant/run.py28
-rw-r--r--slice/Ice/ObjectAdapter.ice50
49 files changed, 1847 insertions, 7 deletions
diff --git a/CHANGES b/CHANGES
index 6a42383d584..cb0d9c51c20 100644
--- a/CHANGES
+++ b/CHANGES
@@ -32,6 +32,15 @@ General Changes
These entries apply to all relevant language mappings unless otherwise
noted.
+- Added the following operations to the ObjectAdapter API:
+
+ - addDefaultServant
+ - removeDefaultServant
+ - findDefaultServant
+
+These methods allow you to use default servants with Ice. Please refer
+to the manual file for more information.
+
- Using the --depend option with Slice compilers that support it no
longer outputs dependency info even if the Slice file itself
contains errors.
diff --git a/cpp/allTests.py b/cpp/allTests.py
index 257a63c9da1..005db4d6f32 100755
--- a/cpp/allTests.py
+++ b/cpp/allTests.py
@@ -56,6 +56,7 @@ tests = [
("Ice/interceptor", ["core"]),
("Ice/stringConverter", ["core"]),
("Ice/udp", ["core"]),
+ ("Ice/defaultServant", ["core"]),
("IceSSL/configuration", ["once", "novalgrind"]), # valgrind doesn't work well with openssl
("IceBox/configuration", ["core", "noipv6"]),
("Freeze/dbmap", ["once"]),
diff --git a/cpp/src/Ice/ObjectAdapterI.cpp b/cpp/src/Ice/ObjectAdapterI.cpp
index 897ef753181..22832b15ac0 100644
--- a/cpp/src/Ice/ObjectAdapterI.cpp
+++ b/cpp/src/Ice/ObjectAdapterI.cpp
@@ -407,6 +407,16 @@ Ice::ObjectAdapterI::addFacetWithUUID(const ObjectPtr& object, const string& fac
return addFacet(object, ident, facet);
}
+void
+Ice::ObjectAdapterI::addDefaultServant(const ObjectPtr& servant, const string& category)
+{
+ IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
+
+ checkForDeactivation();
+
+ _servantManager->addDefaultServant(servant, category);
+}
+
ObjectPtr
Ice::ObjectAdapterI::remove(const Identity& ident)
{
@@ -436,6 +446,16 @@ Ice::ObjectAdapterI::removeAllFacets(const Identity& ident)
}
ObjectPtr
+Ice::ObjectAdapterI::removeDefaultServant(const string& category)
+{
+ IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
+
+ checkForDeactivation();
+
+ return _servantManager->removeDefaultServant(category);
+}
+
+ObjectPtr
Ice::ObjectAdapterI::find(const Identity& ident) const
{
return findFacet(ident, "");
@@ -474,6 +494,16 @@ Ice::ObjectAdapterI::findByProxy(const ObjectPrx& proxy) const
return findFacet(ref->getIdentity(), ref->getFacet());
}
+ObjectPtr
+Ice::ObjectAdapterI::findDefaultServant(const string& category) const
+{
+ IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
+
+ checkForDeactivation();
+
+ return _servantManager->findDefaultServant(category);
+}
+
void
Ice::ObjectAdapterI::addServantLocator(const ServantLocatorPtr& locator, const string& prefix)
{
diff --git a/cpp/src/Ice/ObjectAdapterI.h b/cpp/src/Ice/ObjectAdapterI.h
index 58b2830e13f..5985dac062a 100644
--- a/cpp/src/Ice/ObjectAdapterI.h
+++ b/cpp/src/Ice/ObjectAdapterI.h
@@ -56,13 +56,17 @@ public:
virtual ObjectPrx addFacet(const ObjectPtr&, const Identity&, const std::string&);
virtual ObjectPrx addWithUUID(const ObjectPtr&);
virtual ObjectPrx addFacetWithUUID(const ObjectPtr&, const std::string&);
+ virtual void addDefaultServant(const ObjectPtr&, const std::string&);
virtual ObjectPtr remove(const Identity&);
virtual ObjectPtr removeFacet(const Identity&, const std::string&);
virtual FacetMap removeAllFacets(const Identity&);
+ virtual ObjectPtr removeDefaultServant(const std::string&);
virtual ObjectPtr find(const Identity&) const;
virtual ObjectPtr findFacet(const Identity&, const std::string&) const;
virtual FacetMap findAllFacets(const Identity&) const;
virtual ObjectPtr findByProxy(const ObjectPrx&) const;
+ virtual ObjectPtr findDefaultServant(const std::string&) const;
+
virtual void addServantLocator(const ServantLocatorPtr&, const std::string&);
virtual ServantLocatorPtr findServantLocator(const std::string&) const;
diff --git a/cpp/src/Ice/ServantManager.cpp b/cpp/src/Ice/ServantManager.cpp
index 743f0bdb6b9..6562896ae0a 100644
--- a/cpp/src/Ice/ServantManager.cpp
+++ b/cpp/src/Ice/ServantManager.cpp
@@ -58,6 +58,25 @@ IceInternal::ServantManager::addServant(const ObjectPtr& object, const Identity&
p->second.insert(pair<const string, ObjectPtr>(facet, object));
}
+void
+IceInternal::ServantManager::addDefaultServant(const ObjectPtr& object, const string& category)
+{
+ IceUtil::Mutex::Lock sync(*this);
+
+ assert(_instance); // Must not be called after destruction.
+
+ DefaultServantMap::iterator p = _defaultServantMap.find(category);
+ if(p != _defaultServantMap.end())
+ {
+ AlreadyRegisteredException ex(__FILE__, __LINE__);
+ ex.kindOfObject = "default servant";
+ ex.id = category;
+ throw ex;
+ }
+
+ _defaultServantMap.insert(pair<const string, ObjectPtr>(category, object));
+}
+
ObjectPtr
IceInternal::ServantManager::removeServant(const Identity& ident, const string& facet)
{
@@ -110,6 +129,35 @@ IceInternal::ServantManager::removeServant(const Identity& ident, const string&
return servant;
}
+ObjectPtr
+IceInternal::ServantManager::removeDefaultServant(const string& category)
+{
+ //
+ // We return the removed servant to avoid releasing the last reference count
+ // with *this locked. We don't want to run user code, such as the servant
+ // destructor, with an internal Ice mutex locked.
+ //
+ ObjectPtr servant = 0;
+
+ IceUtil::Mutex::Lock sync(*this);
+
+ assert(_instance); // Must not be called after destruction.
+
+ DefaultServantMap::iterator p = _defaultServantMap.find(category);
+ if(p == _defaultServantMap.end())
+ {
+ NotRegisteredException ex(__FILE__, __LINE__);
+ ex.kindOfObject = "default servant";
+ ex.id = category;
+ throw ex;
+ }
+
+ servant = p->second;
+ _defaultServantMap.erase(p);
+
+ return servant;
+}
+
FacetMap
IceInternal::ServantManager::removeAllFacets(const Identity& ident)
{
@@ -172,7 +220,23 @@ IceInternal::ServantManager::findServant(const Identity& ident, const string& fa
if(p == servantMapMap.end() || (q = p->second.find(facet)) == p->second.end())
{
- return 0;
+ DefaultServantMap::const_iterator p = _defaultServantMap.find(ident.category);
+ if(p == _defaultServantMap.end())
+ {
+ p = _defaultServantMap.find("");
+ if(p == _defaultServantMap.end())
+ {
+ return 0;
+ }
+ else
+ {
+ return p->second;
+ }
+ }
+ else
+ {
+ return p->second;
+ }
}
else
{
@@ -181,6 +245,22 @@ IceInternal::ServantManager::findServant(const Identity& ident, const string& fa
}
}
+ObjectPtr
+IceInternal::ServantManager::findDefaultServant(const string& category) const
+{
+ IceUtil::Mutex::Lock sync(*this);
+
+ DefaultServantMap::const_iterator p = _defaultServantMap.find(category);
+ if(p == _defaultServantMap.end())
+ {
+ return 0;
+ }
+ else
+ {
+ return p->second;
+ }
+}
+
FacetMap
IceInternal::ServantManager::findAllFacets(const Identity& ident) const
{
diff --git a/cpp/src/Ice/ServantManager.h b/cpp/src/Ice/ServantManager.h
index a06d050fa71..2cb1134e2e9 100644
--- a/cpp/src/Ice/ServantManager.h
+++ b/cpp/src/Ice/ServantManager.h
@@ -33,9 +33,12 @@ class ServantManager : public IceUtil::Shared, public IceUtil::Mutex
public:
void addServant(const Ice::ObjectPtr&, const Ice::Identity&, const std::string&);
+ void addDefaultServant(const Ice::ObjectPtr&, const std::string&);
Ice::ObjectPtr removeServant(const Ice::Identity&, const std::string&);
+ Ice::ObjectPtr removeDefaultServant(const std::string&);
Ice::FacetMap removeAllFacets(const Ice::Identity&);
Ice::ObjectPtr findServant(const Ice::Identity&, const std::string&) const;
+ Ice::ObjectPtr findDefaultServant(const std::string&) const;
Ice::FacetMap findAllFacets(const Ice::Identity&) const;
bool hasServant(const Ice::Identity&) const;
@@ -54,10 +57,13 @@ private:
const std::string _adapterName;
typedef std::map<Ice::Identity, Ice::FacetMap> ServantMapMap;
+ typedef std::map<std::string, Ice::ObjectPtr> DefaultServantMap;
ServantMapMap _servantMapMap;
mutable ServantMapMap::iterator _servantMapMapHint;
+ DefaultServantMap _defaultServantMap;
+
std::map<std::string, Ice::ServantLocatorPtr> _locatorMap;
mutable std::map<std::string, Ice::ServantLocatorPtr>::iterator _locatorMapHint;
};
diff --git a/cpp/test/Ice/Makefile b/cpp/test/Ice/Makefile
index f344aa259de..9eb14928c79 100644
--- a/cpp/test/Ice/Makefile
+++ b/cpp/test/Ice/Makefile
@@ -33,7 +33,8 @@ SUBDIRS = proxy \
interceptor \
stringConverter \
background \
- udp
+ udp \
+ defaultServant
$(EVERYTHING)::
@for subdir in $(SUBDIRS); \
diff --git a/cpp/test/Ice/Makefile.mak b/cpp/test/Ice/Makefile.mak
index 58f3c8aabac..728a96f3873 100644
--- a/cpp/test/Ice/Makefile.mak
+++ b/cpp/test/Ice/Makefile.mak
@@ -33,7 +33,8 @@ SUBDIRS = proxy \
interceptor \
stringConverter \
background \
- udp
+ udp \
+ defaultServant
$(EVERYTHING)::
@for %i in ( $(SUBDIRS) ) do \
diff --git a/cpp/test/Ice/defaultServant/.depend b/cpp/test/Ice/defaultServant/.depend
new file mode 100644
index 00000000000..e2f6cf95eff
--- /dev/null
+++ b/cpp/test/Ice/defaultServant/.depend
@@ -0,0 +1,3 @@
+Test$(OBJEXT): Test.cpp ./Test.h $(includedir)/Ice/LocalObjectF.h $(includedir)/IceUtil/Shared.h $(includedir)/IceUtil/Config.h $(includedir)/Ice/Handle.h $(includedir)/IceUtil/Handle.h $(includedir)/IceUtil/Exception.h $(includedir)/Ice/Config.h $(includedir)/Ice/ProxyHandle.h $(includedir)/Ice/ProxyF.h $(includedir)/Ice/ObjectF.h $(includedir)/Ice/GCCountMap.h $(includedir)/Ice/GCShared.h $(includedir)/Ice/Exception.h $(includedir)/Ice/LocalObject.h $(includedir)/Ice/Proxy.h $(includedir)/IceUtil/Mutex.h $(includedir)/IceUtil/Lock.h $(includedir)/IceUtil/ThreadException.h $(includedir)/IceUtil/Time.h $(includedir)/Ice/ProxyFactoryF.h $(includedir)/Ice/ConnectionIF.h $(includedir)/Ice/RequestHandlerF.h $(includedir)/Ice/EndpointIF.h $(includedir)/Ice/Endpoint.h $(includedir)/Ice/UndefSysMacros.h $(includedir)/Ice/ObjectAdapterF.h $(includedir)/Ice/ReferenceF.h $(includedir)/Ice/OutgoingAsyncF.h $(includedir)/Ice/Current.h $(includedir)/Ice/ConnectionF.h $(includedir)/Ice/Identity.h $(includedir)/Ice/StreamF.h $(includedir)/Ice/CommunicatorF.h $(includedir)/Ice/Object.h $(includedir)/Ice/IncomingAsyncF.h $(includedir)/Ice/Outgoing.h $(includedir)/IceUtil/Monitor.h $(includedir)/IceUtil/Cond.h $(includedir)/Ice/InstanceF.h $(includedir)/Ice/BasicStream.h $(includedir)/Ice/ObjectFactoryF.h $(includedir)/Ice/Buffer.h $(includedir)/Ice/Protocol.h $(includedir)/Ice/StringConverter.h $(includedir)/Ice/Plugin.h $(includedir)/Ice/LoggerF.h $(includedir)/IceUtil/Unicode.h $(includedir)/Ice/Incoming.h $(includedir)/Ice/ServantLocatorF.h $(includedir)/Ice/ServantManagerF.h $(includedir)/Ice/Direct.h $(includedir)/Ice/LocalException.h $(includedir)/Ice/BuiltinSequences.h $(includedir)/Ice/ObjectFactory.h $(includedir)/IceUtil/Iterator.h $(includedir)/IceUtil/ScopedArray.h
+Test.cpp: Test.ice
+Test.ice: $(SLICE2CPP) $(SLICEPARSERLIB)
diff --git a/cpp/test/Ice/defaultServant/.gitignore b/cpp/test/Ice/defaultServant/.gitignore
new file mode 100644
index 00000000000..505a9066685
--- /dev/null
+++ b/cpp/test/Ice/defaultServant/.gitignore
@@ -0,0 +1,6 @@
+// Generated by makegitignore.py
+
+// IMPORTANT: Do not edit this file -- any edits made here will be lost!
+client
+Test.cpp
+Test.h
diff --git a/cpp/test/Ice/defaultServant/AllTests.cpp b/cpp/test/Ice/defaultServant/AllTests.cpp
new file mode 100644
index 00000000000..0ff1da9a5a8
--- /dev/null
+++ b/cpp/test/Ice/defaultServant/AllTests.cpp
@@ -0,0 +1,158 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 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 <Ice/Ice.h>
+#include <TestCommon.h>
+#include <TestI.h>
+
+using namespace std;
+using namespace Test;
+
+void
+allTests(const Ice::CommunicatorPtr& communicator)
+{
+ Ice::ObjectAdapterPtr oa = communicator->createObjectAdapterWithEndpoints("MyOA", "tcp -h localhost");
+ oa->activate();
+
+ Ice::ObjectPtr servant = new MyObjectI();
+
+ //
+ // Register default servant with category "foo"
+ //
+ oa->addDefaultServant(servant, "foo");
+
+ //
+ // Start test
+ //
+ cout << "testing single category... " << flush;
+
+ Ice::ObjectPtr r = oa->findDefaultServant("foo");
+ test(r == servant);
+
+ r = oa->findDefaultServant("bar");
+ test(r == 0);
+
+ Ice::Identity identity;
+ identity.category = "foo";
+
+ string names[] = { "foo", "bar", "x", "y", "abcdefg" };
+
+ for(int idx = 0; idx < 5; ++idx)
+ {
+ identity.name = names[idx];
+ MyObjectPrx prx = MyObjectPrx::uncheckedCast(oa->createProxy(identity));
+ prx->ice_ping();
+ test(prx->getName() == names[idx]);
+ }
+
+ identity.name = "ObjectNotExist";
+ MyObjectPrx prx = MyObjectPrx::uncheckedCast(oa->createProxy(identity));
+ try
+ {
+ prx->ice_ping();
+ test(false);
+ }
+ catch(const Ice::ObjectNotExistException&)
+ {
+ // Expected
+ }
+
+ try
+ {
+ prx->getName();
+ test(false);
+ }
+ catch(const Ice::ObjectNotExistException&)
+ {
+ // Expected
+ }
+
+ identity.name = "FacetNotExist";
+ prx = MyObjectPrx::uncheckedCast(oa->createProxy(identity));
+ try
+ {
+ prx->ice_ping();
+ test(false);
+ }
+ catch(const Ice::FacetNotExistException&)
+ {
+ // Expected
+ }
+
+ try
+ {
+ prx->getName();
+ test(false);
+ }
+ catch(const Ice::FacetNotExistException&)
+ {
+ // Expected
+ }
+
+ identity.category = "bar";
+ for(int idx = 0; idx < 5; idx++)
+ {
+ identity.name = names[idx];
+ prx = MyObjectPrx::uncheckedCast(oa->createProxy(identity));
+
+ try
+ {
+ prx->ice_ping();
+ test(false);
+ }
+ catch(const Ice::ObjectNotExistException&)
+ {
+ // Expected
+ }
+
+ try
+ {
+ prx->getName();
+ test(false);
+ }
+ catch(const Ice::ObjectNotExistException&)
+ {
+ // Expected
+ }
+ }
+
+ oa->removeDefaultServant("foo");
+ identity.category = "foo";
+ prx = MyObjectPrx::uncheckedCast(oa->createProxy(identity));
+ try
+ {
+ prx->ice_ping();
+ }
+ catch(const Ice::ObjectNotExistException&)
+ {
+ // Expected
+ }
+
+ cout << "ok" << endl;
+
+ cout << "testing default category... " << flush;
+
+ oa->addDefaultServant(servant, "");
+
+ r = oa->findDefaultServant("bar");
+ test(r == 0);
+
+ r = oa->findDefaultServant("");
+ test(r == servant);
+
+ for(int idx = 0; idx < 5; ++idx)
+ {
+ identity.name = names[idx];
+ prx = MyObjectPrx::uncheckedCast(oa->createProxy(identity));
+ prx->ice_ping();
+ test(prx->getName() == names[idx]);
+ }
+
+ cout << "ok" << endl;
+}
diff --git a/cpp/test/Ice/defaultServant/Client.cpp b/cpp/test/Ice/defaultServant/Client.cpp
new file mode 100644
index 00000000000..0b5ffe9cca6
--- /dev/null
+++ b/cpp/test/Ice/defaultServant/Client.cpp
@@ -0,0 +1,57 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 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 <Ice/Ice.h>
+#include <TestCommon.h>
+#include <Test.h>
+
+using namespace std;
+using namespace Test;
+
+int
+run(int argc, char* argv[], const Ice::CommunicatorPtr& communicator)
+{
+ void allTests(const Ice::CommunicatorPtr&);
+ allTests(communicator);
+
+ return EXIT_SUCCESS;
+}
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ Ice::CommunicatorPtr communicator;
+
+ try
+ {
+ communicator = Ice::initialize(argc, argv);
+ status = run(argc, argv, communicator);
+ }
+ catch(const Ice::Exception& ex)
+ {
+ cerr << ex << endl;
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ try
+ {
+ communicator->destroy();
+ }
+ catch(const Ice::Exception& ex)
+ {
+ cerr << ex << endl;
+ status = EXIT_FAILURE;
+ }
+ }
+
+ return status;
+}
diff --git a/cpp/test/Ice/defaultServant/Makefile b/cpp/test/Ice/defaultServant/Makefile
new file mode 100644
index 00000000000..928ecf67c5d
--- /dev/null
+++ b/cpp/test/Ice/defaultServant/Makefile
@@ -0,0 +1,33 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 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.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+CLIENT = client
+
+TARGETS = $(CLIENT)
+
+OBJS = Test.o \
+ TestI.o \
+ Client.o \
+ AllTests.o
+
+SRCS = $(OBJS:.o=.cpp)
+
+SLICE_SRCS = Test.ice
+
+include $(top_srcdir)/config/Make.rules
+
+CPPFLAGS := -I. -I../../include $(CPPFLAGS)
+
+$(CLIENT): $(OBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
+
+include .depend
diff --git a/cpp/test/Ice/defaultServant/Makefile.mak b/cpp/test/Ice/defaultServant/Makefile.mak
new file mode 100644
index 00000000000..65486d149cc
--- /dev/null
+++ b/cpp/test/Ice/defaultServant/Makefile.mak
@@ -0,0 +1,39 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 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.
+#
+# **********************************************************************
+
+top_srcdir = ..\..\..
+
+CLIENT = client.exe
+
+TARGETS = $(CLIENT)
+
+COBJS = Test.obj \
+ TestI.obj \
+ Client.obj \
+ AllTests.obj
+
+SRCS = $(COBJS:.obj=.cpp)
+
+!include $(top_srcdir)/config/Make.rules.mak
+
+CPPFLAGS = -I. -I../../include $(CPPFLAGS) -DWIN32_LEAN_AND_MEAN
+
+!if "$(GENERATE_PDB)" == "yes"
+PDBFLAGS = /pdb:$(CLIENT:.exe=.pdb)
+!endif
+
+$(CLIENT): $(COBJS)
+ $(LINK) $(LD_EXEFLAGS) $(PDBFLAGS) $(SETARGV) $(COBJS) $(PREOUT)$@ $(PRELIBS)$(LIBS)
+ @if exist $@.manifest echo ^ ^ ^ Embedding manifest using $(MT) && \
+ $(MT) -nologo -manifest $@.manifest -outputresource:$@;#1 && del /q $@.manifest
+
+clean::
+ del /q Test.cpp Test.h
+
+!include .depend
diff --git a/cpp/test/Ice/defaultServant/Test.ice b/cpp/test/Ice/defaultServant/Test.ice
new file mode 100644
index 00000000000..46398613058
--- /dev/null
+++ b/cpp/test/Ice/defaultServant/Test.ice
@@ -0,0 +1,23 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 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 TEST_ICE
+#define TEST_ICE
+
+module Test
+{
+
+interface MyObject
+{
+ string getName();
+};
+
+};
+
+#endif
diff --git a/cpp/test/Ice/defaultServant/TestI.cpp b/cpp/test/Ice/defaultServant/TestI.cpp
new file mode 100644
index 00000000000..50d2f49fc1f
--- /dev/null
+++ b/cpp/test/Ice/defaultServant/TestI.cpp
@@ -0,0 +1,45 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 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 <Ice/Ice.h>
+#include <TestI.h>
+
+using namespace std;
+
+void
+MyObjectI::ice_ping(const Ice::Current& current) const
+{
+ string name = current.id.name;
+
+ if(name == "ObjectNotExist")
+ {
+ throw Ice::ObjectNotExistException(__FILE__, __LINE__);
+ }
+ else if(name == "FacetNotExist")
+ {
+ throw Ice::FacetNotExistException(__FILE__, __LINE__);
+ }
+}
+
+std::string
+MyObjectI::getName(const Ice::Current& current)
+{
+ string name = current.id.name;
+
+ if(name == "ObjectNotExist")
+ {
+ throw Ice::ObjectNotExistException(__FILE__, __LINE__);
+ }
+ else if(name == "FacetNotExist")
+ {
+ throw Ice::FacetNotExistException(__FILE__, __LINE__);
+ }
+
+ return name;
+}
diff --git a/cpp/test/Ice/defaultServant/TestI.h b/cpp/test/Ice/defaultServant/TestI.h
new file mode 100644
index 00000000000..7731e95be90
--- /dev/null
+++ b/cpp/test/Ice/defaultServant/TestI.h
@@ -0,0 +1,23 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 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 TEST_I_H
+#define TEST_I_H
+
+#include <Test.h>
+
+class MyObjectI : virtual public Test::MyObject
+{
+public:
+
+ virtual void ice_ping(const Ice::Current&) const;
+ virtual std::string getName(const Ice::Current&);
+};
+
+#endif
diff --git a/cpp/test/Ice/defaultServant/run.py b/cpp/test/Ice/defaultServant/run.py
new file mode 100755
index 00000000000..e2a84c8cd83
--- /dev/null
+++ b/cpp/test/Ice/defaultServant/run.py
@@ -0,0 +1,25 @@
+#!/usr/bin/env python
+# **********************************************************************
+#
+# Copyright (c) 2003-2008 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice-E is licensed to you under the terms described in the
+# ICEE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+import os, sys
+
+path = [ ".", "..", "../..", "../../..", "../../../.." ]
+head = os.path.dirname(sys.argv[0])
+if len(head) > 0:
+ path = [os.path.join(head, p) for p in path]
+path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "scripts", "TestUtil.py")) ]
+if len(path) == 0:
+ raise "can't find toplevel directory!"
+sys.path.append(os.path.join(path[0]))
+from scripts import *
+
+client = os.path.join(os.getcwd(), "client")
+
+TestUtil.simpleTest(client)
diff --git a/cs/allTests.py b/cs/allTests.py
index df497955cae..40a6c445d36 100755
--- a/cs/allTests.py
+++ b/cs/allTests.py
@@ -49,6 +49,7 @@ tests = [
("Ice/seqMapping", ["core"]),
("Ice/background", ["core"]),
("Ice/udp", ["core"]),
+ ("Ice/defaultServant", ["core"]),
("IceBox/configuration", ["core", "noipv6"]),
("Glacier2/router", ["service"]),
("IceGrid/simple", ["service"]),
diff --git a/cs/src/Ice/ObjectAdapterI.cs b/cs/src/Ice/ObjectAdapterI.cs
index 8ad2efeb684..b3480b5568b 100644
--- a/cs/src/Ice/ObjectAdapterI.cs
+++ b/cs/src/Ice/ObjectAdapterI.cs
@@ -400,6 +400,16 @@ namespace Ice
return addFacet(obj, ident, facet);
}
+
+ public void addDefaultServant(Ice.Object servant, string category)
+ {
+ lock(this)
+ {
+ checkForDeactivation();
+
+ _servantManager.addDefaultServant(servant, category);
+ }
+ }
public Ice.Object remove(Identity ident)
{
@@ -428,6 +438,16 @@ namespace Ice
}
}
+ public Ice.Object removeDefaultServant(string category)
+ {
+ lock(this)
+ {
+ checkForDeactivation();
+
+ return _servantManager.removeDefaultServant(category);
+ }
+ }
+
public Ice.Object find(Identity ident)
{
return findFacet(ident, "");
@@ -466,6 +486,16 @@ namespace Ice
}
}
+ public Ice.Object findDefaultServant(string category)
+ {
+ lock(this)
+ {
+ checkForDeactivation();
+
+ return _servantManager.findDefaultServant(category);
+ }
+ }
+
public void addServantLocator(ServantLocator locator, string prefix)
{
lock(this)
diff --git a/cs/src/Ice/ServantManager.cs b/cs/src/Ice/ServantManager.cs
index 9ae77ccb174..15539b195ea 100644
--- a/cs/src/Ice/ServantManager.cs
+++ b/cs/src/Ice/ServantManager.cs
@@ -50,6 +50,25 @@ public sealed class ServantManager
m[facet] = servant;
}
}
+
+ public void addDefaultServant(Ice.Object servant, string category)
+ {
+ lock(this)
+ {
+ Debug.Assert(instance_ != null); // Must not be called after destruction.
+ Ice.Object obj = null;
+ _defaultServantMap.TryGetValue(category, out obj);
+ if(obj != null)
+ {
+ Ice.AlreadyRegisteredException ex = new Ice.AlreadyRegisteredException();
+ ex.kindOfObject = "default servant";
+ ex.id = category;
+ throw ex;
+ }
+
+ _defaultServantMap[category] = servant;
+ }
+ }
public Ice.Object removeServant(Ice.Identity ident, string facet)
{
@@ -86,6 +105,27 @@ public sealed class ServantManager
return obj;
}
}
+
+ public Ice.Object removeDefaultServant(string category)
+ {
+ lock(this)
+ {
+ Debug.Assert(instance_ != null); // Must not be called after destruction.
+
+ Ice.Object obj = null;
+ _defaultServantMap.TryGetValue(category, out obj);
+ if(obj == null)
+ {
+ Ice.NotRegisteredException ex = new Ice.NotRegisteredException();
+ ex.kindOfObject = "default servant";
+ ex.id = category;
+ throw ex;
+ }
+
+ _defaultServantMap.Remove(category);
+ return obj;
+ }
+ }
public Dictionary<string, Ice.Object> removeAllFacets(Ice.Identity ident)
{
@@ -128,7 +168,15 @@ public sealed class ServantManager
Dictionary<string, Ice.Object> m;
_servantMapMap.TryGetValue(ident, out m);
Ice.Object obj = null;
- if(m != null)
+ if(m == null)
+ {
+ _defaultServantMap.TryGetValue(ident.category, out obj);
+ if(obj == null)
+ {
+ _defaultServantMap.TryGetValue("", out obj);
+ }
+ }
+ else
{
m.TryGetValue(facet, out obj);
}
@@ -137,6 +185,18 @@ public sealed class ServantManager
}
}
+ public Ice.Object findDefaultServant(string category)
+ {
+ lock(this)
+ {
+ Debug.Assert(instance_ != null); // Must not be called after destruction.
+
+ Ice.Object obj = null;
+ _defaultServantMap.TryGetValue(category, out obj);
+ return obj;
+ }
+ }
+
public Dictionary<string, Ice.Object> findAllFacets(Ice.Identity ident)
{
lock(this)
@@ -279,6 +339,7 @@ public sealed class ServantManager
private readonly string _adapterName;
private Dictionary <Ice.Identity, Dictionary<string, Ice.Object>> _servantMapMap
= new Dictionary<Ice.Identity, Dictionary<string, Ice.Object>>();
+ private Dictionary <string, Ice.Object> _defaultServantMap = new Dictionary<string, Ice.Object>();
private Dictionary<string, Ice.ServantLocator> _locatorMap = new Dictionary<string, Ice.ServantLocator>();
}
diff --git a/cs/test/Ice/Makefile b/cs/test/Ice/Makefile
index 8d18f8d2e83..fa130830c16 100644
--- a/cs/test/Ice/Makefile
+++ b/cs/test/Ice/Makefile
@@ -33,7 +33,8 @@ SUBDIRS = application \
dictMapping \
seqMapping \
background \
- udp
+ udp \
+ defaultServant
$(EVERYTHING)::
@for subdir in $(SUBDIRS); \
diff --git a/cs/test/Ice/Makefile.mak b/cs/test/Ice/Makefile.mak
index 3632757730a..e205b1f5f67 100644
--- a/cs/test/Ice/Makefile.mak
+++ b/cs/test/Ice/Makefile.mak
@@ -33,7 +33,8 @@ SUBDIRS = application \
dictMapping \
seqMapping \
background \
- udp
+ udp \
+ defaultServant
$(EVERYTHING)::
@for %i in ( $(SUBDIRS) ) do \
diff --git a/cs/test/Ice/defaultServant/.depend b/cs/test/Ice/defaultServant/.depend
new file mode 100644
index 00000000000..d07cfb3711e
--- /dev/null
+++ b/cs/test/Ice/defaultServant/.depend
@@ -0,0 +1 @@
+Test.cs: ./Test.ice
diff --git a/cs/test/Ice/defaultServant/AllTests.cs b/cs/test/Ice/defaultServant/AllTests.cs
new file mode 100644
index 00000000000..2cb7727304b
--- /dev/null
+++ b/cs/test/Ice/defaultServant/AllTests.cs
@@ -0,0 +1,167 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 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.
+//
+// **********************************************************************
+
+using System;
+
+public class AllTests
+{
+ private static void test(bool b)
+ {
+ if(!b)
+ {
+ throw new System.Exception();
+ }
+ }
+
+ public static void
+ allTests(Ice.Communicator communicator)
+ {
+ Ice.ObjectAdapter oa = communicator.createObjectAdapterWithEndpoints("MyOA", "tcp -h localhost");
+ oa.activate();
+
+ Ice.Object servant = new MyObjectI();
+
+ //
+ // Register default servant with category "foo"
+ //
+ oa.addDefaultServant(servant, "foo");
+
+ //
+ // Start test
+ //
+ Console.Out.Write("testing single category... ");
+ Console.Out.Flush();
+
+ Ice.Object r = oa.findDefaultServant("foo");
+ test(r == servant);
+
+ r = oa.findDefaultServant("bar");
+ test(r == null);
+
+ Ice.Identity identity = new Ice.Identity();
+ identity.category = "foo";
+
+ string[] names = new string[] { "foo", "bar", "x", "y", "abcdefg" };
+
+ Test.MyObjectPrx prx = null;
+ for(int idx = 0; idx < 5; ++idx)
+ {
+ identity.name = names[idx];
+ prx = Test.MyObjectPrxHelper.uncheckedCast(oa.createProxy(identity));
+ prx.ice_ping();
+ test(prx.getName() == names[idx]);
+ }
+
+ identity.name = "ObjectNotExist";
+ prx = Test.MyObjectPrxHelper.uncheckedCast(oa.createProxy(identity));
+ try
+ {
+ prx.ice_ping();
+ test(false);
+ }
+ catch(Ice.ObjectNotExistException)
+ {
+ // Expected
+ }
+
+ try
+ {
+ prx.getName();
+ test(false);
+ }
+ catch(Ice.ObjectNotExistException)
+ {
+ // Expected
+ }
+
+ identity.name = "FacetNotExist";
+ prx = Test.MyObjectPrxHelper.uncheckedCast(oa.createProxy(identity));
+ try
+ {
+ prx.ice_ping();
+ test(false);
+ }
+ catch(Ice.FacetNotExistException)
+ {
+ // Expected
+ }
+
+ try
+ {
+ prx.getName();
+ test(false);
+ }
+ catch(Ice.FacetNotExistException)
+ {
+ // Expected
+ }
+
+ identity.category = "bar";
+ for(int idx = 0; idx < 5; idx++)
+ {
+ identity.name = names[idx];
+ prx = Test.MyObjectPrxHelper.uncheckedCast(oa.createProxy(identity));
+
+ try
+ {
+ prx.ice_ping();
+ test(false);
+ }
+ catch(Ice.ObjectNotExistException)
+ {
+ // Expected
+ }
+
+ try
+ {
+ prx.getName();
+ test(false);
+ }
+ catch(Ice.ObjectNotExistException)
+ {
+ // Expected
+ }
+ }
+
+ oa.removeDefaultServant("foo");
+ identity.category = "foo";
+ prx = Test.MyObjectPrxHelper.uncheckedCast(oa.createProxy(identity));
+ try
+ {
+ prx.ice_ping();
+ }
+ catch(Ice.ObjectNotExistException)
+ {
+ // Expected
+ }
+
+ Console.Out.WriteLine("ok");
+
+ Console.Out.Write("testing default category... ");
+ Console.Out.Flush();
+
+ oa.addDefaultServant(servant, "");
+
+ r = oa.findDefaultServant("bar");
+ test(r == null);
+
+ r = oa.findDefaultServant("");
+ test(r == servant);
+
+ for(int idx = 0; idx < 5; ++idx)
+ {
+ identity.name = names[idx];
+ prx = Test.MyObjectPrxHelper.uncheckedCast(oa.createProxy(identity));
+ prx.ice_ping();
+ test(prx.getName() == names[idx]);
+ }
+
+ Console.Out.WriteLine("ok");
+ }
+}
diff --git a/cs/test/Ice/defaultServant/Client.cs b/cs/test/Ice/defaultServant/Client.cs
new file mode 100644
index 00000000000..da7f9a9b55b
--- /dev/null
+++ b/cs/test/Ice/defaultServant/Client.cs
@@ -0,0 +1,66 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 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.
+//
+// **********************************************************************
+
+using System;
+using System.Diagnostics;
+using System.Reflection;
+
+[assembly: CLSCompliant(true)]
+
+[assembly: AssemblyTitle("IceTest")]
+[assembly: AssemblyDescription("Ice test")]
+[assembly: AssemblyCompany("ZeroC, Inc.")]
+
+public class Client
+{
+ private static int run(string[] args, Ice.Communicator communicator)
+ {
+ AllTests.allTests(communicator);
+
+ return 0;
+ }
+
+ public static void Main(string[] args)
+ {
+ int status = 0;
+ Ice.Communicator communicator = null;
+
+ Debug.Listeners.Add(new ConsoleTraceListener());
+
+ try
+ {
+ communicator = Ice.Util.initialize(ref args);
+ status = run(args, communicator);
+ }
+ catch(System.Exception ex)
+ {
+ Console.Error.WriteLine(ex);
+ status = 1;
+ }
+
+ if(communicator != null)
+ {
+ try
+ {
+ communicator.destroy();
+ }
+ catch(Ice.LocalException ex)
+ {
+ Console.Error.WriteLine(ex);
+ status = 1;
+ }
+ }
+
+ if(status != 0)
+ {
+ System.Environment.Exit(status);
+ }
+ }
+}
+
diff --git a/cs/test/Ice/defaultServant/Makefile b/cs/test/Ice/defaultServant/Makefile
new file mode 100644
index 00000000000..2b5422bc2d0
--- /dev/null
+++ b/cs/test/Ice/defaultServant/Makefile
@@ -0,0 +1,32 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 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.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+TARGETS = client.exe
+
+C_SRCS = Client.cs \
+ AllTests.cs \
+ MyObjectI.cs
+
+SLICE_SRCS = $(SDIR)/Test.ice
+
+SDIR = .
+
+GDIR = generated
+
+include $(top_srcdir)/config/Make.rules.cs
+
+MCSFLAGS := $(MCSFLAGS) -target:exe
+
+
+client.exe: $(C_SRCS) $(GEN_SRCS)
+ $(MCS) $(MCSFLAGS) -out:$@ $(call ref,Ice) $(subst /,$(DSEP),$^)
+
+include .depend
diff --git a/cs/test/Ice/defaultServant/Makefile.mak b/cs/test/Ice/defaultServant/Makefile.mak
new file mode 100644
index 00000000000..6d47f42df66
--- /dev/null
+++ b/cs/test/Ice/defaultServant/Makefile.mak
@@ -0,0 +1,32 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 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.
+#
+# **********************************************************************
+
+top_srcdir = ..\..\..
+
+TARGETS = client.exe
+TARGETS_CONFIG = $(TARGETS:.exe=.exe.config)
+
+C_SRCS = Client.cs \
+ AllTests.cs \
+ MyObjectI.cs
+
+GEN_SRCS = $(GDIR)\Test.cs
+
+SDIR = .
+
+GDIR = generated
+
+!include $(top_srcdir)\config\Make.rules.mak.cs
+
+MCSFLAGS = $(MCSFLAGS) -target:exe
+
+client.exe: $(C_SRCS) $(GEN_SRCS)
+ $(MCS) $(MCSFLAGS) -out:$@ -r:$(refdir)\Ice.dll $(C_SRCS) $(GEN_SRCS)
+
+!include .depend
diff --git a/cs/test/Ice/defaultServant/MyObjectI.cs b/cs/test/Ice/defaultServant/MyObjectI.cs
new file mode 100644
index 00000000000..15ae0818935
--- /dev/null
+++ b/cs/test/Ice/defaultServant/MyObjectI.cs
@@ -0,0 +1,44 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 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.
+//
+// **********************************************************************
+
+
+public sealed class MyObjectI : Test.MyObjectDisp_
+{
+ public override void
+ ice_ping(Ice.Current current)
+ {
+ string name = current.id.name;
+
+ if(name == "ObjectNotExist")
+ {
+ throw new Ice.ObjectNotExistException();
+ }
+ else if(name == "FacetNotExist")
+ {
+ throw new Ice.FacetNotExistException();
+ }
+ }
+
+ public override string
+ getName(Ice.Current current)
+ {
+ string name = current.id.name;
+
+ if(name == "ObjectNotExist")
+ {
+ throw new Ice.ObjectNotExistException();
+ }
+ else if(name == "FacetNotExist")
+ {
+ throw new Ice.FacetNotExistException();
+ }
+
+ return name;
+ }
+}
diff --git a/cs/test/Ice/defaultServant/Test.ice b/cs/test/Ice/defaultServant/Test.ice
new file mode 100644
index 00000000000..46398613058
--- /dev/null
+++ b/cs/test/Ice/defaultServant/Test.ice
@@ -0,0 +1,23 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 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 TEST_ICE
+#define TEST_ICE
+
+module Test
+{
+
+interface MyObject
+{
+ string getName();
+};
+
+};
+
+#endif
diff --git a/cs/test/Ice/defaultServant/run.py b/cs/test/Ice/defaultServant/run.py
new file mode 100755
index 00000000000..c37cd7dd820
--- /dev/null
+++ b/cs/test/Ice/defaultServant/run.py
@@ -0,0 +1,30 @@
+#!/usr/bin/env python
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 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.
+#
+# **********************************************************************
+
+import os, sys, getopt
+
+path = [ ".", "..", "../..", "../../..", "../../../.." ]
+head = os.path.dirname(sys.argv[0])
+if len(head) > 0:
+ path = [os.path.join(head, p) for p in path]
+path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "scripts", "TestUtil.py")) ]
+if len(path) == 0:
+ raise "can't find toplevel directory!"
+sys.path.append(os.path.join(path[0]))
+from scripts import *
+
+client = os.path.join(os.getcwd(), "client")
+
+print "starting client...",
+clientProc = TestUtil.startClient(client, " --Ice.Warn.Dispatch=0", startReader = False)
+print "ok"
+clientProc.startReader()
+
+clientProc.waitTestSuccess()
diff --git a/java/allTests.py b/java/allTests.py
index 8c8825008fb..5db47603281 100755
--- a/java/allTests.py
+++ b/java/allTests.py
@@ -57,6 +57,7 @@ tests = [
("Ice/interceptor", ["core"]),
("Ice/udp", ["core"]),
("Ice/serialize", ["core"]),
+ ("Ice/defaultServant", ["core"]),
("IceBox/configuration", ["core", "noipv6"]),
("Freeze/dbmap", ["once"]),
("Freeze/complex", ["once"]),
diff --git a/java/build.xml b/java/build.xml
index ab0474daa5c..b3b46f597ae 100644
--- a/java/build.xml
+++ b/java/build.xml
@@ -220,6 +220,9 @@
<fileset dir="test/Ice/binding">
<include name="Test.ice" />
</fileset>
+ <fileset dir="test/Ice/defaultServant">
+ <include name="Test.ice" />
+ </fileset>
<fileset dir="test/Ice/exceptions">
<include name="Test.ice" />
<include name="TestAMD.ice" />
diff --git a/java/src/Ice/ObjectAdapterI.java b/java/src/Ice/ObjectAdapterI.java
index 49f78794cc7..ba25b1b1173 100644
--- a/java/src/Ice/ObjectAdapterI.java
+++ b/java/src/Ice/ObjectAdapterI.java
@@ -423,6 +423,14 @@ public final class ObjectAdapterI implements ObjectAdapter
return addFacet(object, ident, facet);
}
+ public synchronized void
+ addDefaultServant(Ice.Object servant, String category)
+ {
+ checkForDeactivation();
+
+ _servantManager.addDefaultServant(servant, category);
+ }
+
public Ice.Object
remove(Identity ident)
{
@@ -447,6 +455,14 @@ public final class ObjectAdapterI implements ObjectAdapter
return _servantManager.removeAllFacets(ident);
}
+ public synchronized Ice.Object
+ removeDefaultServant(String category)
+ {
+ checkForDeactivation();
+
+ return _servantManager.removeDefaultServant(category);
+ }
+
public Ice.Object
find(Identity ident)
{
@@ -480,6 +496,14 @@ public final class ObjectAdapterI implements ObjectAdapter
return findFacet(ref.getIdentity(), ref.getFacet());
}
+ public synchronized Ice.Object
+ findDefaultServant(String category)
+ {
+ checkForDeactivation();
+
+ return _servantManager.findDefaultServant(category);
+ }
+
public synchronized void
addServantLocator(ServantLocator locator, String prefix)
{
diff --git a/java/src/IceInternal/ServantManager.java b/java/src/IceInternal/ServantManager.java
index 83652e87882..7fe206c0d14 100644
--- a/java/src/IceInternal/ServantManager.java
+++ b/java/src/IceInternal/ServantManager.java
@@ -45,6 +45,23 @@ public final class ServantManager
m.put(facet, servant);
}
+ public synchronized void
+ addDefaultServant(Ice.Object servant, String category)
+ {
+ assert(_instance != null); // Must not be called after destruction
+
+ Ice.Object obj = _defaultServantMap.get(category);
+ if(obj != null)
+ {
+ Ice.AlreadyRegisteredException ex = new Ice.AlreadyRegisteredException();
+ ex.kindOfObject = "default servant";
+ ex.id = category;
+ throw ex;
+ }
+
+ _defaultServantMap.put(category, servant);
+ }
+
public synchronized Ice.Object
removeServant(Ice.Identity ident, String facet)
{
@@ -76,6 +93,24 @@ public final class ServantManager
return obj;
}
+ public synchronized Ice.Object
+ removeDefaultServant(String category)
+ {
+ assert(_instance != null); // Must not be called after destruction.
+
+ Ice.Object obj = _defaultServantMap.get(category);
+ if(obj == null)
+ {
+ Ice.NotRegisteredException ex = new Ice.NotRegisteredException();
+ ex.kindOfObject = "default servant";
+ ex.id = category;
+ throw ex;
+ }
+
+ _defaultServantMap.remove(category);
+ return obj;
+ }
+
public synchronized java.util.Map<String, Ice.Object>
removeAllFacets(Ice.Identity ident)
{
@@ -113,7 +148,15 @@ public final class ServantManager
java.util.Map<String, Ice.Object> m = _servantMapMap.get(ident);
Ice.Object obj = null;
- if(m != null)
+ if(m == null)
+ {
+ obj = _defaultServantMap.get(ident.category);
+ if(obj == null)
+ {
+ obj = _defaultServantMap.get("");
+ }
+ }
+ else
{
obj = m.get(facet);
}
@@ -121,6 +164,14 @@ public final class ServantManager
return obj;
}
+ public synchronized Ice.Object
+ findDefaultServant(String category)
+ {
+ assert(_instance != null); // Must not be called after destruction.
+
+ return _defaultServantMap.get(category);
+ }
+
public synchronized java.util.Map<String, Ice.Object>
findAllFacets(Ice.Identity ident)
{
@@ -253,5 +304,6 @@ public final class ServantManager
final private String _adapterName;
private java.util.Map<Ice.Identity, java.util.Map<String, Ice.Object> > _servantMapMap =
new java.util.HashMap<Ice.Identity, java.util.Map<String, Ice.Object> >();
+ private java.util.Map<String, Ice.Object> _defaultServantMap = new java.util.HashMap<String, Ice.Object>();
private java.util.Map<String, Ice.ServantLocator> _locatorMap = new java.util.HashMap<String, Ice.ServantLocator>();
}
diff --git a/java/test/Ice/defaultServant/AllTests.java b/java/test/Ice/defaultServant/AllTests.java
new file mode 100644
index 00000000000..efc0a105d07
--- /dev/null
+++ b/java/test/Ice/defaultServant/AllTests.java
@@ -0,0 +1,171 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 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.
+//
+// **********************************************************************
+
+package test.Ice.defaultServant;
+import java.io.PrintWriter;
+import test.Ice.defaultServant.Test.MyObjectPrx;
+import test.Ice.defaultServant.Test.MyObjectPrxHelper;
+
+public class AllTests
+{
+ private static void
+ test(boolean b)
+ {
+ if(!b)
+ {
+ throw new RuntimeException();
+ }
+ }
+
+ public static void
+ allTests(test.Util.Application app, PrintWriter out)
+ {
+ Ice.Communicator communicator = app.communicator();
+ Ice.ObjectAdapter oa = communicator.createObjectAdapterWithEndpoints("MyOA", "tcp -h localhost");
+ oa.activate();
+
+ Ice.Object servant = (Ice.Object)new MyObjectI();
+
+ //
+ // Register default servant with category "foo"
+ //
+ oa.addDefaultServant(servant, "foo");
+
+ //
+ // Start test
+ //
+ out.print("testing single category... ");
+ out.flush();
+
+ Ice.Object r = oa.findDefaultServant("foo");
+ test(r == servant);
+
+ r = oa.findDefaultServant("bar");
+ test(r == null);
+
+ Ice.Identity identity = new Ice.Identity();
+ identity.category = "foo";
+
+ String names[] = { "foo", "bar", "x", "y", "abcdefg" };
+
+ for(int idx = 0; idx < 5; ++idx)
+ {
+ identity.name = names[idx];
+ MyObjectPrx prx = MyObjectPrxHelper.uncheckedCast(oa.createProxy(identity));
+ prx.ice_ping();
+ test(prx.getName() == names[idx]);
+ }
+
+ identity.name = "ObjectNotExist";
+ MyObjectPrx prx = MyObjectPrxHelper.uncheckedCast(oa.createProxy(identity));
+ try
+ {
+ prx.ice_ping();
+ test(false);
+ }
+ catch(Ice.ObjectNotExistException ex)
+ {
+ // Expected
+ }
+
+ try
+ {
+ prx.getName();
+ test(false);
+ }
+ catch(Ice.ObjectNotExistException ex)
+ {
+ // Expected
+ }
+
+ identity.name = "FacetNotExist";
+ prx = MyObjectPrxHelper.uncheckedCast(oa.createProxy(identity));
+ try
+ {
+ prx.ice_ping();
+ test(false);
+ }
+ catch(Ice.FacetNotExistException ex)
+ {
+ // Expected
+ }
+
+ try
+ {
+ prx.getName();
+ test(false);
+ }
+ catch(Ice.FacetNotExistException ex)
+ {
+ // Expected
+ }
+
+ identity.category = "bar";
+ for(int idx = 0; idx < 5; idx++)
+ {
+ identity.name = names[idx];
+ prx = MyObjectPrxHelper.uncheckedCast(oa.createProxy(identity));
+
+ try
+ {
+ prx.ice_ping();
+ test(false);
+ }
+ catch(Ice.ObjectNotExistException ex)
+ {
+ // Expected
+ }
+
+ try
+ {
+ prx.getName();
+ test(false);
+ }
+ catch(Ice.ObjectNotExistException ex)
+ {
+ // Expected
+ }
+ }
+
+ oa.removeDefaultServant("foo");
+ identity.category = "foo";
+ prx = MyObjectPrxHelper.uncheckedCast(oa.createProxy(identity));
+ try
+ {
+ prx.ice_ping();
+ }
+ catch(Ice.ObjectNotExistException ex)
+ {
+ // Expected
+ }
+
+ out.println("ok");
+
+ out.print("testing default category... ");
+ out.flush();
+
+ oa.addDefaultServant(servant, "");
+
+ r = oa.findDefaultServant("bar");
+ test(r == null);
+
+ r = oa.findDefaultServant("");
+ test(r == servant);
+
+ for(int idx = 0; idx < 5; ++idx)
+ {
+ identity.name = names[idx];
+ prx = MyObjectPrxHelper.uncheckedCast(oa.createProxy(identity));
+ prx.ice_ping();
+ test(prx.getName() == names[idx]);
+ }
+
+ out.println("ok");
+ }
+}
diff --git a/java/test/Ice/defaultServant/Client.java b/java/test/Ice/defaultServant/Client.java
new file mode 100644
index 00000000000..51ccdabf237
--- /dev/null
+++ b/java/test/Ice/defaultServant/Client.java
@@ -0,0 +1,29 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 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.
+//
+// **********************************************************************
+
+package test.Ice.defaultServant;
+
+public class Client extends test.Util.Application
+{
+ public int run(String[] args)
+ {
+ AllTests.allTests(this, getWriter());
+
+ return 0;
+ }
+
+ public static void main(String[] args)
+ {
+ Client c = new Client();
+ int status = c.main("Client", args);
+
+ System.gc();
+ System.exit(status);
+ }
+}
diff --git a/java/test/Ice/defaultServant/MyObjectI.java b/java/test/Ice/defaultServant/MyObjectI.java
new file mode 100644
index 00000000000..553db4ad3e2
--- /dev/null
+++ b/java/test/Ice/defaultServant/MyObjectI.java
@@ -0,0 +1,46 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 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.
+//
+// **********************************************************************
+
+package test.Ice.defaultServant;
+import test.Ice.defaultServant.Test.*;
+
+public final class MyObjectI extends _MyObjectDisp
+{
+ public void
+ ice_ping(Ice.Current current)
+ {
+ String name = current.id.name;
+
+ if(name == "ObjectNotExist")
+ {
+ throw new Ice.ObjectNotExistException();
+ }
+ else if(name == "FacetNotExist")
+ {
+ throw new Ice.FacetNotExistException();
+ }
+ }
+
+ public String
+ getName(Ice.Current current)
+ {
+ String name = current.id.name;
+
+ if(name == "ObjectNotExist")
+ {
+ throw new Ice.ObjectNotExistException();
+ }
+ else if(name == "FacetNotExist")
+ {
+ throw new Ice.FacetNotExistException();
+ }
+
+ return name;
+ }
+}
diff --git a/java/test/Ice/defaultServant/Test.ice b/java/test/Ice/defaultServant/Test.ice
new file mode 100644
index 00000000000..6020b9639b6
--- /dev/null
+++ b/java/test/Ice/defaultServant/Test.ice
@@ -0,0 +1,24 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 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 TEST_ICE
+#define TEST_ICE
+
+[["java:package:test.Ice.defaultServant"]]
+module Test
+{
+
+interface MyObject
+{
+ string getName();
+};
+
+};
+
+#endif
diff --git a/java/test/Ice/defaultServant/run.py b/java/test/Ice/defaultServant/run.py
new file mode 100755
index 00000000000..5053bafec30
--- /dev/null
+++ b/java/test/Ice/defaultServant/run.py
@@ -0,0 +1,28 @@
+#!/usr/bin/env python
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 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.
+#
+# **********************************************************************
+
+import os, sys
+
+path = [ ".", "..", "../..", "../../..", "../../../.." ]
+head = os.path.dirname(sys.argv[0])
+if len(head) > 0:
+ path = [os.path.join(head, p) for p in path]
+path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "scripts", "TestUtil.py")) ]
+if len(path) == 0:
+ raise "can't find toplevel directory!"
+sys.path.append(os.path.join(path[0]))
+from scripts import *
+
+print "starting client...",
+clientProc = TestUtil.startClient("test.Ice.defaultServant.Client", "--Ice.Warn.Dispatch=0",startReader=False)
+print "ok"
+clientProc.startReader()
+
+clientProc.waitTestSuccess()
diff --git a/py/allTests.py b/py/allTests.py
index d7c78b41dd7..459dd846e59 100755
--- a/py/allTests.py
+++ b/py/allTests.py
@@ -43,6 +43,7 @@ tests = [
("Ice/timeout", ["core"]),
("Ice/servantLocator", ["core"]),
("Ice/blobject", ["core"])
+ ("Ice/defaultServant", ["core"])
]
if __name__ == "__main__":
diff --git a/py/modules/IcePy/ObjectAdapter.cpp b/py/modules/IcePy/ObjectAdapter.cpp
index efd8b2164b2..8a27457b428 100644
--- a/py/modules/IcePy/ObjectAdapter.cpp
+++ b/py/modules/IcePy/ObjectAdapter.cpp
@@ -790,6 +790,47 @@ adapterAddFacetWithUUID(ObjectAdapterObject* self, PyObject* args)
extern "C"
#endif
static PyObject*
+adapterAddDefaultServant(ObjectAdapterObject* self, PyObject* args)
+{
+ PyObject* objectType = lookupType("Ice.Object");
+ PyObject* servant;
+ PyObject* categoryObj;
+ if(!PyArg_ParseTuple(args, STRCAST("O!O"), objectType, &servant, &categoryObj))
+ {
+ return 0;
+ }
+
+ ServantWrapperPtr wrapper= createServantWrapper(servant);
+ if(PyErr_Occurred())
+ {
+ return 0;
+ }
+
+ string category;
+ if(!getStringArg(categoryObj, "category", category))
+ {
+ return 0;
+ }
+
+ assert(self->adapter);
+ try
+ {
+ (*self->adapter)->addDefaultServant(wrapper, category);
+ }
+ catch(const Ice::Exception& ex)
+ {
+ setPythonException(ex);
+ return 0;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+#ifdef WIN32
+extern "C"
+#endif
+static PyObject*
adapterRemove(ObjectAdapterObject* self, PyObject* args)
{
PyObject* identityType = lookupType("Ice.Identity");
@@ -932,6 +973,47 @@ adapterRemoveAllFacets(ObjectAdapterObject* self, PyObject* args)
extern "C"
#endif
static PyObject*
+adapterRemoveDefaultServant(ObjectAdapterObject* self, PyObject* args)
+{
+ PyObject* categoryObj;
+ if(!PyArg_ParseTuple(args, STRCAST("O"), &categoryObj))
+ {
+ return 0;
+ }
+
+ string category;
+ if(!getStringArg(categoryObj, "category", category))
+ {
+ return 0;
+ }
+
+ assert(self->adapter);
+ Ice::ObjectPtr obj;
+ try
+ {
+ obj = (*self->adapter)->removeDefaultServant(category);
+ }
+ catch(const Ice::Exception& ex)
+ {
+ setPythonException(ex);
+ return 0;
+ }
+
+ if(!obj)
+ {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+
+ ServantWrapperPtr wrapper = ServantWrapperPtr::dynamicCast(obj);
+ assert(wrapper);
+ return wrapper->getObject();
+}
+
+#ifdef WIN32
+extern "C"
+#endif
+static PyObject*
adapterFind(ObjectAdapterObject* self, PyObject* args)
{
PyObject* identityType = lookupType("Ice.Identity");
@@ -1112,6 +1194,47 @@ adapterFindByProxy(ObjectAdapterObject* self, PyObject* args)
extern "C"
#endif
static PyObject*
+adapterFindDefaultServant(ObjectAdapterObject* self, PyObject* args)
+{
+ PyObject* categoryObj;
+ if(!PyArg_ParseTuple(args, STRCAST("O"), &categoryObj))
+ {
+ return 0;
+ }
+
+ string category;
+ if(!getStringArg(categoryObj, "category", category))
+ {
+ return 0;
+ }
+
+ assert(self->adapter);
+ Ice::ObjectPtr obj;
+ try
+ {
+ obj = (*self->adapter)->findDefaultServant(category);
+ }
+ catch(const Ice::Exception& ex)
+ {
+ setPythonException(ex);
+ return 0;
+ }
+
+ if(!obj)
+ {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+
+ ServantWrapperPtr wrapper = ServantWrapperPtr::dynamicCast(obj);
+ assert(wrapper);
+ return wrapper->getObject();
+}
+
+#ifdef WIN32
+extern "C"
+#endif
+static PyObject*
adapterAddServantLocator(ObjectAdapterObject* self, PyObject* args)
{
PyObject* locatorType = lookupType("Ice.ServantLocator");
@@ -1369,12 +1492,16 @@ static PyMethodDef AdapterMethods[] =
PyDoc_STR(STRCAST("addWithUUID(servant) -> Ice.ObjectPrx")) },
{ STRCAST("addFacetWithUUID"), reinterpret_cast<PyCFunction>(adapterAddFacetWithUUID), METH_VARARGS,
PyDoc_STR(STRCAST("addFacetWithUUID(servant, facet) -> Ice.ObjectPrx")) },
+ { STRCAST("addDefaultServant"), reinterpret_cast<PyCFunction>(adapterAddDefaultServant), METH_VARARGS,
+ PyDoc_STR(STRCAST("addDefaultServant(servant, category) -> None")) },
{ STRCAST("remove"), reinterpret_cast<PyCFunction>(adapterRemove), METH_VARARGS,
PyDoc_STR(STRCAST("remove(identity) -> Ice.Object")) },
{ STRCAST("removeFacet"), reinterpret_cast<PyCFunction>(adapterRemoveFacet), METH_VARARGS,
PyDoc_STR(STRCAST("removeFacet(identity, facet) -> Ice.Object")) },
{ STRCAST("removeAllFacets"), reinterpret_cast<PyCFunction>(adapterRemoveAllFacets), METH_VARARGS,
PyDoc_STR(STRCAST("removeAllFacets(identity) -> dictionary")) },
+ { STRCAST("removeDefaultServant"), reinterpret_cast<PyCFunction>(adapterRemoveDefaultServant), METH_VARARGS,
+ PyDoc_STR(STRCAST("removeDefaultServant(category) -> Ice.Object")) },
{ STRCAST("find"), reinterpret_cast<PyCFunction>(adapterFind), METH_VARARGS,
PyDoc_STR(STRCAST("find(identity) -> Ice.Object")) },
{ STRCAST("findFacet"), reinterpret_cast<PyCFunction>(adapterFindFacet), METH_VARARGS,
@@ -1383,6 +1510,8 @@ static PyMethodDef AdapterMethods[] =
PyDoc_STR(STRCAST("findAllFacets(identity) -> dictionary")) },
{ STRCAST("findByProxy"), reinterpret_cast<PyCFunction>(adapterFindByProxy), METH_VARARGS,
PyDoc_STR(STRCAST("findByProxy(Ice.ObjectPrx) -> Ice.Object")) },
+ { STRCAST("findDefaultServant"), reinterpret_cast<PyCFunction>(adapterFindDefaultServant), METH_VARARGS,
+ PyDoc_STR(STRCAST("findDefaultServant(category) -> Ice.Object")) },
{ STRCAST("addServantLocator"), reinterpret_cast<PyCFunction>(adapterAddServantLocator), METH_VARARGS,
PyDoc_STR(STRCAST("addServantLocator(Ice.ServantLocator, category) -> None")) },
{ STRCAST("findServantLocator"), reinterpret_cast<PyCFunction>(adapterFindServantLocator), METH_VARARGS,
diff --git a/py/python/Ice.py b/py/python/Ice.py
index 9689dbabc88..3ebee8efd6e 100644
--- a/py/python/Ice.py
+++ b/py/python/Ice.py
@@ -399,6 +399,9 @@ class ObjectAdapterI(ObjectAdapter):
def addFacetWithUUID(self, servant, facet):
return self._impl.addFacetWIthUUID(servant, facet)
+ def addDefaultServant(self, servant, category):
+ self._impl.addDefaultServant(servant, category)
+
def remove(self, id):
return self._impl.remove(id)
@@ -408,6 +411,9 @@ class ObjectAdapterI(ObjectAdapter):
def removeAllFacets(self, id):
return self._impl.removeAllFacets(id)
+ def removeDefaultServant(self, category):
+ return self._impl.removeDefaultServant(category)
+
def find(self, id):
return self._impl.find(id)
@@ -420,6 +426,9 @@ class ObjectAdapterI(ObjectAdapter):
def findByProxy(self, proxy):
return self._impl.findByProxy(proxy)
+ def findDefaultServant(self, category):
+ return self._impl.findDefaultServant(category)
+
def addServantLocator(self, locator, category):
self._impl.addServantLocator(locator, category)
diff --git a/py/test/Ice/defaultServant/AllTests.py b/py/test/Ice/defaultServant/AllTests.py
new file mode 100644
index 00000000000..421e3397e97
--- /dev/null
+++ b/py/test/Ice/defaultServant/AllTests.py
@@ -0,0 +1,124 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 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.
+#
+# **********************************************************************
+
+import Ice, Test, MyObjectI
+
+def test(b):
+ if not b:
+ raise RuntimeError('test assertion failed')
+
+def allTests(communicator):
+
+ oa = communicator.createObjectAdapterWithEndpoints("MyOA", "tcp -h localhost")
+ oa.activate()
+
+ servant = MyObjectI.MyObjectI()
+
+ # Register default servant with category "foo"
+ oa.addDefaultServant(servant, "foo")
+
+ # Start test
+ print "testing single category... ",
+
+ r = oa.findDefaultServant("foo")
+ test(r == servant)
+
+ r = oa.findDefaultServant("bar")
+ test(r == None)
+
+ identity = Ice.Identity()
+ identity.category = "foo"
+
+ names = ( "foo", "bar", "x", "y", "abcdefg" )
+
+ for idx in range(0, 5):
+ identity.name = names[idx]
+ prx = Test.MyObjectPrx.uncheckedCast(oa.createProxy(identity))
+ prx.ice_ping()
+ test(prx.getName() == names[idx])
+
+ identity.name = "ObjectNotExist"
+ prx = Test.MyObjectPrx.uncheckedCast(oa.createProxy(identity))
+ try:
+ prx.ice_ping()
+ test(false)
+ except Ice.ObjectNotExistException:
+ # Expected
+ pass
+
+ try:
+ prx.getName()
+ test(false)
+ except Ice.ObjectNotExistException:
+ # Expected
+ pass
+
+ identity.name = "FacetNotExist"
+ prx = Test.MyObjectPrx.uncheckedCast(oa.createProxy(identity))
+ try:
+ prx.ice_ping()
+ test(false)
+ except Ice.FacetNotExistException:
+ # Expected
+ pass
+
+ try:
+ prx.getName()
+ test(false)
+ except Ice.FacetNotExistException:
+ # Expected
+ pass
+
+ identity.category = "bar"
+ for idx in range(0, 5):
+ identity.name = names[idx]
+ prx = Test.MyObjectPrx.uncheckedCast(oa.createProxy(identity))
+
+ try:
+ prx.ice_ping()
+ test(false)
+ except Ice.ObjectNotExistException:
+ # Expected
+ pass
+
+ try:
+ prx.getName()
+ test(false)
+ except Ice.ObjectNotExistException:
+ # Expected
+ pass
+
+ oa.removeDefaultServant("foo")
+ identity.category = "foo"
+ prx = Test.MyObjectPrx.uncheckedCast(oa.createProxy(identity))
+ try:
+ prx.ice_ping()
+ except Ice.ObjectNotExistException:
+ # Expected
+ pass
+
+ print "ok"
+
+ print "testing default category... ",
+
+ oa.addDefaultServant(servant, "")
+
+ r = oa.findDefaultServant("bar")
+ test(r == None)
+
+ r = oa.findDefaultServant("")
+ test(r == servant)
+
+ for idx in range(0, 5):
+ identity.name = names[idx]
+ prx = Test.MyObjectPrx.uncheckedCast(oa.createProxy(identity))
+ prx.ice_ping()
+ test(prx.getName() == names[idx])
+
+ print "ok"
diff --git a/py/test/Ice/defaultServant/Client.py b/py/test/Ice/defaultServant/Client.py
new file mode 100755
index 00000000000..b806752c0ea
--- /dev/null
+++ b/py/test/Ice/defaultServant/Client.py
@@ -0,0 +1,36 @@
+#!/usr/bin/env python
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 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.
+#
+# **********************************************************************
+
+import os, sys, traceback
+
+import Ice
+
+Ice.loadSlice('Test.ice')
+import AllTests
+
+def run(args, communicator):
+ AllTests.allTests(communicator)
+ return True
+
+try:
+ communicator = Ice.initialize(sys.argv)
+ status = run(sys.argv, communicator)
+except:
+ traceback.print_exc()
+ status = False
+
+if communicator:
+ try:
+ communicator.destroy()
+ except:
+ traceback.print_exc()
+ status = False
+
+sys.exit(not status)
diff --git a/py/test/Ice/defaultServant/MyObjectI.py b/py/test/Ice/defaultServant/MyObjectI.py
new file mode 100644
index 00000000000..fcc6adb10b3
--- /dev/null
+++ b/py/test/Ice/defaultServant/MyObjectI.py
@@ -0,0 +1,29 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 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.
+#
+# **********************************************************************
+
+import Ice, Test
+
+class MyObjectI(Test.MyObject):
+ def ice_ping(self, current=None):
+ name = current.id.name
+
+ if name == "ObjectNotExist":
+ raise Ice.ObjectNotExistException()
+ elif name == "FacetNotExist":
+ raise Ice.FacetNotExistException()
+
+ def getName(self, current=None):
+ name = current.id.name
+
+ if name == "ObjectNotExist":
+ raise Ice.ObjectNotExistException()
+ elif name == "FacetNotExist":
+ raise Ice.FacetNotExistException()
+
+ return name
diff --git a/py/test/Ice/defaultServant/Test.ice b/py/test/Ice/defaultServant/Test.ice
new file mode 100644
index 00000000000..46398613058
--- /dev/null
+++ b/py/test/Ice/defaultServant/Test.ice
@@ -0,0 +1,23 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 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 TEST_ICE
+#define TEST_ICE
+
+module Test
+{
+
+interface MyObject
+{
+ string getName();
+};
+
+};
+
+#endif
diff --git a/py/test/Ice/defaultServant/run.py b/py/test/Ice/defaultServant/run.py
new file mode 100755
index 00000000000..4bafa789a82
--- /dev/null
+++ b/py/test/Ice/defaultServant/run.py
@@ -0,0 +1,28 @@
+#!/usr/bin/env python
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 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.
+#
+# **********************************************************************
+
+import os, sys
+
+path = [ ".", "..", "../..", "../../..", "../../../.." ]
+head = os.path.dirname(sys.argv[0])
+if len(head) > 0:
+ path = [os.path.join(head, p) for p in path]
+path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "scripts", "TestUtil.py")) ]
+if len(path) == 0:
+ raise "can't find toplevel directory!"
+sys.path.append(os.path.join(path[0]))
+from scripts import *
+
+print "starting client...",
+clientProc = TestUtil.startClient("Client.py", startReader = False)
+print "ok"
+clientProc.startReader()
+
+clientProc.waitTestSuccess()
diff --git a/slice/Ice/ObjectAdapter.ice b/slice/Ice/ObjectAdapter.ice
index c1d48a151e2..6dd095851a5 100644
--- a/slice/Ice/ObjectAdapter.ice
+++ b/slice/Ice/ObjectAdapter.ice
@@ -264,6 +264,25 @@ local interface ObjectAdapter
/**
*
+ * Add a default servant to handle requests for specific
+ * category. Adding a default servant for a category for
+ * which a default servant locator is already registered
+ * throws [AlreadyRegisteredException].
+ *
+ * @param servant The default servant.
+ *
+ * @param category The category for which the default
+ * servant is registered. An empty category means it will
+ * handle all categories.
+ *
+ * @see removeDefaultServant
+ * @see findDefaultServant
+ *
+ **/
+ void addDefaultServant(Object servant, string category);
+
+ /**
+ *
* Remove a servant (that is, the default facet) from the
* object adapter's Active Servant Map.
*
@@ -323,6 +342,22 @@ local interface ObjectAdapter
/**
*
+ * Remove the default servant for a specific category. Attempting
+ * to remove a default servant for a category that is not
+ * registered throws [NotRegisteredException].
+ *
+ * @param category The category of the default servant to remove.
+ *
+ * @return The default servant.
+ *
+ * @see addDefaultServant
+ * @see findDefaultServant
+ *
+ **/
+ Object removeDefaultServant(string category);
+
+ /**
+ *
* Look up a servant in this object adapter's Active Servant Map
* by the identity of the Ice object it implements.
*
@@ -474,6 +509,21 @@ local interface ObjectAdapter
/**
*
+ * Find the default servant for a specific category.
+ *
+ * @param category The category of the default servant to find.
+ *
+ * @return The default servant or null if no default servant was
+ * registered for the category.
+ *
+ * @see addDefaultServant
+ * @see removeDefaultServant
+ *
+ **/
+ ["cpp:const"] Object findDefaultServant(string category);
+
+ /**
+ *
* Create a proxy for the object with the given identity. If this
* object adapter is configured with an adapter id, the return
* value is an indirect proxy that refers to the adapter id. If