throws gov.cca.CCAException {
// Retrieve information for this component
if (!componentMap.containsKey(componentName))
throw new NonstandardException("Unknown component: " + componentName);
ComponentInfo cInfo = (ComponentInfo) componentMap.get(componentName);
// create empty connection list if entry for this component doesn't exist
if (!connectionMap.containsKey(componentName)) {
Vector connIDs = new Vector();
connectionMap.put(componentName, connIDs);
}
// Get a list of connections for this component
Vector connIDs = (Vector) connectionMap.get(componentName);
// Send migration requests to all connected components
int numConns = connIDs.size();
logger.finest("found " + numConns + " connection " +
"for component " + componentName);
// create an entry into the migrationMap
MigrationInfo mInfo = new MigrationInfo(numConns);
migrationMap.put(componentName, mInfo);
for (int i = 0; i < numConns; i++) {
XCATConnectionID connID = (XCATConnectionID) connIDs.get(i);
MobileComponentID userID = (MobileComponentID) connID.getUser();
userID.requestMigration(componentName,
connID.getUserPortName(),
getGSH());
}
// Wait till all users are OK with migration
synchronized(mInfo) {
if (mInfo.getApprovedUsers() < numConns) {
try {
mInfo.wait();
} catch (InterruptedException ie) {
logger.severe("Exception when waiting for uses sides to approve migration",
ie);
throw new NonstandardException("Exception when waiting for migration approval",
ie);
}
}
}
// check if the above call was successful
if (mInfo.getMigrationStatus() == AppCoordinatorCallback.EXCEPTION)
throw new NonstandardException("Remote side did not approve migration");
// Confirm to all users that provider is migrating
for (int i = 0; i < numConns; i++) {
XCATConnectionID connID = (XCATConnectionID) connIDs.get(i);
MobileComponentID userID = (MobileComponentID) connID.getUser();
userID.confirmMigration(connID.getUserPortName());
}
// Freeze the execution of the component
MobileComponentID cid =
new MobileComponentIDClientImpl(cInfo.getInstanceName(),
cInfo.getInstanceHandle());
cid.freezeComponent(getGSH());
// Wait till the component sends back a notification that it is frozen
synchronized(mInfo) {
if (!mInfo.getIsFrozen()) {
try {
mInfo.wait();
} catch (InterruptedException ie) {
logger.severe("Exception when waiting for migration to complete",
ie);
throw new NonstandardException("Exception when waiting for migration to complete",
ie);
}
}
}
// decrement number of outstanding frozen components
synchronized(this) {
outstandingFrozenComps--;
}
// check if the above call was successful
if (mInfo.getMigrationStatus() == AppCoordinatorCallback.EXCEPTION)
throw new NonstandardException("Remote component threw exception while being frozen");
// Store the individual component state into persistent storage
MasterStorageService mss = (MasterStorageService)
URLToReference.createReference(masterStorageServiceURL,
MasterStorageService.class.getName());
String individualStorageServiceURL = mss.getIndividualStorageServiceLocation();
String storageID = cid.storeIndividualComponentState(individualStorageServiceURL);
// destroy the remote component
try {
cid.destroy();
} catch (Exception e) {
logger.severe("Caught exception while trying to destroy component",
e);
throw new NonstandardException("Caught exception while trying to destroy component",
e);
}
// create a new instance of the component at the specified location
cInfo.setInstanceLocation(targetLocation);
createComponentInstance(cInfo);
// retrieve the state for the migrated component
cid.loadComponentState(individualStorageServiceURL, storageID);