The ServantLocator Interface
module Ice {
local interface ServantLocator {
["UserException"]
Object locate(Current curr, out LocalObject cookie);
["UserException"]
void finished(Current curr, Object servant, LocalObject cookie);
void deactivate(string category);
};
};
Servant Locator Registration
module Ice {
local interface ObjectAdapter {
// ...
void addServantLocator(ServantLocator locator, string category);
ServantLocator removeServantLocator(string category);
ServantLocator findServantLocator(string category);
// ...
};
};
Servant Locator Example
struct Details {
// Lots of details about the entry here...
};
interface PhoneEntry {
idempotent Details getDetails();
idempotent void updateDetails(Details d);
// ...
};
struct SearchCriteria {
// Fields to permit searching...
};
interface PhoneBook {
idempotent PhoneEntry* search(SearchCriteria c);
// ...
};
class MyServantLocator : public virtual Ice::ServantLocator {
public:
virtual Ice::ObjectPtr locate(const Ice::Current& c, Ice::LocalObjectPtr& cookie);
virtual void finished(const Ice::Current& c, const Ice::ObjectPtr& servant,
const Ice::LocalObjectPtr& cookie);
virtual void deactivate(const std::string& category);
};
Ice::ObjectPtr
MyServantLocator::locate(const Ice::Current& c, Ice::LocalObjectPtr& cookie)
{
// Get the object identity. (We use the name member
// as the database key.)
//
std::string name = c.id.name;
// Use the identity to retrieve the state from the database.
//
ServantDetails d;
try {
d = DB_lookup(name);
} catch (const DB_error&)
return 0;
}
// We have the state, instantiate a servant and return it.
//
return new PhoneEntryI(d);
}
Using Identity Categories with Servant Locators
Ice::ObjectPtr
MyServantLocator::locate(const Ice::Current& c, Ice::LocalObjectPtr& cookie)
{
// Get the object identity. (We use the name member
// as the database key.)
//
std::string name = c.id.name;
std::string realId = c.id.name.substr(1);
try {
if (name[0] == 'd') {
// The request is for a directory.
//
DirectoryDetails d = DB_lookup(realId);
return new DirectoryI(d);
} else {
// The request is for a file.
//
FileDetails d = DB_lookup(realId);
return new FileI(d);
}
} catch (DatabaseNotFoundException&) {
return 0;
}
}
class DirectoryLocator : public virtual Ice::ServantLocator {
public:
virtual Ice::ObjectPtr locate(const Ice::Current& c, Ice::LocalObjectPtr& cookie)
{
// Code to locate and instantiate a directory here...
}
virtual void finished(const Ice::Current& c, const Ice::ObjectPtr& servant,
const Ice::LocalObjectPtr& cookie)
{
}
virtual void deactivate(const std::string& category)
{
}
};
class FileLocator : public virtual Ice::ServantLocator {
public:
virtual Ice::ObjectPtr locate(const Ice::Current& c, Ice::LocalObjectPtr& cookie)
{
// Code to locate and instantiate a file here...
}
virtual void finished(const Ice::Current& c, const Ice::ObjectPtr& servant,
const Ice::LocalObjectPtr& cookie)
{
}
virtual void deactivate(const std::string& category)
{
}
};
// ...
// Register two locators, one for directories and
// one for files.
//
adapter->addServantLocator(new DirectoryLocator(), "d");
adapter->addServantLocator(new FileLocator(), "f");