Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorslewis2005-01-12 22:44:16 +0000
committerslewis2005-01-12 22:44:16 +0000
commit81a75dd565634865aae166901c64c03a219e2385 (patch)
treece49c2694559f502981c41c42c56e81d9eb9e2cd
parent49b60c60475f4cb6d941c6c98faa3e8f043e1083 (diff)
downloadorg.eclipse.ecf-81a75dd565634865aae166901c64c03a219e2385.tar.gz
org.eclipse.ecf-81a75dd565634865aae166901c64c03a219e2385.tar.xz
org.eclipse.ecf-81a75dd565634865aae166901c64c03a219e2385.zip
Additions to make the SOContainer abstract class be more robust and extendable. Created methods make* to allow subclasses to override behavior used to create new ISharedObjectConfig, SOWrapper, and ISharedObjectContext instances
-rw-r--r--framework/bundles/org.eclipse.ecf.provider/src/org/eclipse/ecf/provider/generic/SOConfig.java6
-rw-r--r--framework/bundles/org.eclipse.ecf.provider/src/org/eclipse/ecf/provider/generic/SOContainer.java143
-rw-r--r--framework/bundles/org.eclipse.ecf.provider/src/org/eclipse/ecf/provider/generic/SOWrapper.java3
3 files changed, 128 insertions, 24 deletions
diff --git a/framework/bundles/org.eclipse.ecf.provider/src/org/eclipse/ecf/provider/generic/SOConfig.java b/framework/bundles/org.eclipse.ecf.provider/src/org/eclipse/ecf/provider/generic/SOConfig.java
index 298099f0c..141dd6a69 100644
--- a/framework/bundles/org.eclipse.ecf.provider/src/org/eclipse/ecf/provider/generic/SOConfig.java
+++ b/framework/bundles/org.eclipse.ecf.provider/src/org/eclipse/ecf/provider/generic/SOConfig.java
@@ -41,7 +41,11 @@ public class SOConfig implements ISharedObjectConfig {
protected void makeActive(QueueEnqueue queue) {
isActive = true;
- this.context = container.makeNewSharedObjectContext(this,queue);
+ if (container.getID().equals(homeContainerID)) {
+ this.context = container.makeNewSharedObjectContext(this,queue);
+ } else {
+ this.context = container.makeNewRemoteSharedObjectContext(this,queue);
+ }
}
protected void makeInactive() {
diff --git a/framework/bundles/org.eclipse.ecf.provider/src/org/eclipse/ecf/provider/generic/SOContainer.java b/framework/bundles/org.eclipse.ecf.provider/src/org/eclipse/ecf/provider/generic/SOContainer.java
index 33d2ef1bc..1964e1024 100644
--- a/framework/bundles/org.eclipse.ecf.provider/src/org/eclipse/ecf/provider/generic/SOContainer.java
+++ b/framework/bundles/org.eclipse.ecf.provider/src/org/eclipse/ecf/provider/generic/SOContainer.java
@@ -51,8 +51,10 @@ public abstract class SOContainer implements ISharedObjectContainer {
Object credentials;
SharedObjectDescription description;
Thread runner = null;
+ ID fromID = null;
- LoadingSharedObject(SharedObjectDescription sd, Object credentials) {
+ LoadingSharedObject(ID fromID, SharedObjectDescription sd, Object credentials) {
+ this.fromID = fromID;
this.description = sd;
this.credentials = credentials;
}
@@ -91,11 +93,13 @@ public abstract class SOContainer implements ISharedObjectContainer {
throw new InterruptedException(
"Loading interrupted for object "
+ getID().getName());
- // First load given object
+ // First load object
ISharedObject obj = load(description);
+ // Create wrapper object and move from loading to active
+ // list.
+ SOWrapper wrap = makeNewRemoteSharedObjectWrapper(fromID,description,obj);
// Get config info for new object
- SOConfig aConfig = makeNewSharedObjectConfig(
- description, obj);
+ SOConfig aConfig = wrap.getConfig();
// Call init method on new object.
obj.init(aConfig);
// Check to make sure thread has not been
@@ -105,10 +109,8 @@ public abstract class SOContainer implements ISharedObjectContainer {
throw new InterruptedException(
"Loading interrupted for object "
+ getID().getName());
- // Create meta object and move from loading to active
- // list.
- SOContainer.this.moveFromLoadingToActive(new SOWrapper(
- aConfig, obj, SOContainer.this));
+ // Finally, we move from loading to active, and then the object is done
+ SOContainer.this.moveFromLoadingToActive(wrap);
} catch (Exception e) {
dumpStack("Exception loading object ", e);
SOContainer.this.removeFromLoading(getID());
@@ -116,7 +118,7 @@ public abstract class SOContainer implements ISharedObjectContainer {
sendCreateResponse(getHomeID(), getID(), e,
description.getIdentifier());
} catch (Exception e1) {
- dumpStack("Exception sending create response", e1);
+ dumpStack("Exception sending create response from LoadingSharedObject.run", e1);
}
}
}
@@ -297,11 +299,30 @@ public abstract class SOContainer implements ISharedObjectContainer {
return groupManager.addLoadingSharedObject(lso);
}
- protected Object checkCreate(ID fromID, ID toID, long seq,
- SharedObjectDescription desc) {
- debug("checkCreate(" + fromID + "," + toID + "," + seq + "," + desc
+ /**
+ * Check remote creation of shared objects. This method is called by the remote shared object
+ * creation message handler, to verify that the shared object from container 'fromID' to
+ * container 'toID' with description 'desc' is to be allowed to be created within the current
+ * container. If this method throws, a failure (and exception will be sent back to caller
+ * If this method returns null, the create message is ignored. If this method returns a
+ * non-null object, the creation is allowed to proceed. The default implementation is to return
+ * a non-null object
+ *
+ * @param fromID the ID of the container sending us this create request
+ * @param toID the ID (or null) of the container intended to receive this request
+ * @param seq the sequence number associated with the container message
+ * @param desc the SharedObjectDescription that describes the shared object to be created
+ *
+ * @returns Object null if the create message is to be ignored, non-null if the creation
+ * should continue
+ *
+ * @throws Exception may throw any Exception to communicate back (via sendCreateResponse) to
+ * the sender that the creation has failed
+ */
+ protected Object checkRemoteCreate(ID fromID, ID toID, long seq,
+ SharedObjectDescription desc) throws Exception {
+ debug("checkRemoteCreate(" + fromID + "," + toID + "," + seq + "," + desc
+ ")");
- // XXX TODO
return desc;
}
@@ -585,18 +606,36 @@ public abstract class SOContainer implements ISharedObjectContainer {
ID fromID = mess.getFromContainerID();
ID toID = mess.getToContainerID();
long seq = mess.getSequence();
- Object result = checkCreate(fromID, toID, seq, desc);
- if (result != null) {
- LoadingSharedObject lso = new LoadingSharedObject(desc, result);
+ Object checkCreateResult = null;
+ ID sharedObjectID = desc.getID();
+ // Check to make sure that the remote creation is allowed.
+ // If this method throws, a failure (and exception will be sent back to caller
+ // If this method returns null, the create message is ignored. If this method
+ // returns a non-null object, the creation is allowed to proceed
+ try {
+ checkCreateResult = checkRemoteCreate(fromID, toID, seq, desc);
+ } catch (Exception e) {
+ SharedObjectAddException addException = new SharedObjectAddException("shared object "
+ + sharedObjectID + " rejected by container "+getID(),e);
+ dumpStack("Exception in checkRemoteCreate",addException);
+ try {
+ sendCreateResponse(fromID, sharedObjectID,addException, desc.getIdentifier());
+ } catch (IOException except) {
+ logException("Exception from sendCreateResponse in handleCreateResponse", except);
+ }
+ return;
+ }
+ // Then if result from check is non-null, we continue. If null, we ignore
+ if (checkCreateResult != null) {
+ LoadingSharedObject lso = new LoadingSharedObject(fromID,desc, checkCreateResult);
synchronized (getGroupMembershipLock()) {
if (!addToLoading(lso)) {
- ID sharedObjectID = desc.getID();
try {
sendCreateResponse(fromID, sharedObjectID,
new SharedObjectAddException("shared object "
- + sharedObjectID), desc.getIdentifier());
+ + sharedObjectID + " already exists in container "+getID()), desc.getIdentifier());
} catch (IOException e) {
- logException("Exception in handleCreateMessage", e);
+ logException("Exception in handleCreateMessage.sendCreateResponse", e);
}
}
forward(fromID, toID, mess);
@@ -750,17 +789,35 @@ public abstract class SOContainer implements ISharedObjectContainer {
return new SOConfig(sd.getID(), homeID, this, sd.getProperties());
}
+ protected SOConfig makeNewRemoteSharedObjectConfig(ID fromID, SharedObjectDescription sd,
+ ISharedObject obj) {
+ ID homeID = sd.getHomeID();
+ if (homeID == null)
+ homeID = fromID;
+ return new SOConfig(sd.getID(), homeID, this, sd.getProperties());
+ }
+
protected SOContext makeNewSharedObjectContext(SOConfig config,
QueueEnqueue queue) {
return new SOContext(config.getSharedObjectID(), config
.getHomeContainerID(), this, config.getProperties(), queue);
}
+ protected SOContext makeNewRemoteSharedObjectContext(SOConfig config,
+ QueueEnqueue queue) {
+ return new SOContext(config.getSharedObjectID(), config
+ .getHomeContainerID(), this, config.getProperties(), queue);
+ }
protected SOWrapper makeNewSharedObjectWrapper(SharedObjectDescription sd,
ISharedObject s) {
SOConfig newConfig = makeNewSharedObjectConfig(sd, s);
return new SOWrapper(newConfig, s, this);
}
+ protected SOWrapper makeNewRemoteSharedObjectWrapper(ID fromID, SharedObjectDescription sd,
+ ISharedObject s) {
+ SOConfig newConfig = makeNewRemoteSharedObjectConfig(fromID, sd, s);
+ return new SOWrapper(newConfig, s, this);
+ }
protected void memberLeave(ID target, IConnection conn) {
debug("memberLeave:" + target + ":" + conn);
@@ -791,11 +848,51 @@ public abstract class SOContainer implements ISharedObjectContainer {
protected void notifySharedObjectDeactivated(ID sharedObjectID) {
groupManager.notifyOthersDeactivated(sharedObjectID);
}
-
+ protected ContainerMessage validateContainerMessage(Object mess) {
+ // Message must not be null
+ if (mess == null) {
+ debug("Ignoring null ContainerMessage");
+ return null;
+ }
+ if (mess instanceof ContainerMessage) {
+ ContainerMessage contmess = (ContainerMessage) mess;
+ ID fromID = contmess.getFromContainerID();
+ if (fromID == null) {
+ debug("Ignoring ContainerMessage from null sender...ignoring");
+ return null;
+ }
+ ID toID = contmess.getToContainerID();
+ if (toID == null) {
+ return contmess;
+ } else {
+ if (toID.equals(getID())) {
+ return contmess;
+ } else {
+ debug("Ignoring ContainerMessage from "+fromID+" to "+toID);
+ return null;
+ }
+ }
+ // OK
+ } else {
+ debug("Ignoring invalid ContainerMessage:"+mess);
+ return null;
+ }
+
+ }
protected void processAsynch(AsynchConnectionEvent e) {
- debug("processAsynch:" + e);
try {
- ContainerMessage mess = getObjectFromBytes((byte[]) e.getData());
+ Object obj = e.getData();
+ if (obj == null) {
+ debug("Ignoring null data in event "+e);
+ return;
+ }
+ if (!(obj instanceof byte [])) {
+ debug("Ignoring event without valid data "+e);
+ }
+ ContainerMessage mess = validateContainerMessage(getObjectFromBytes((byte[]) obj));
+ if (mess == null) {
+ return;
+ }
Serializable submess = mess.getData();
if (submess != null) {
if (submess instanceof ContainerMessage.CreateMessage) {
@@ -823,7 +920,7 @@ public abstract class SOContainer implements ISharedObjectContainer {
debug("processDisconnect:" + e);
try {
ContainerMessage mess = getObjectFromBytes((byte[]) e.getData());
- } catch (IOException except) {
+ } catch (Exception except) {
logException("Exception in processDisconnect ", except);
}
}
diff --git a/framework/bundles/org.eclipse.ecf.provider/src/org/eclipse/ecf/provider/generic/SOWrapper.java b/framework/bundles/org.eclipse.ecf.provider/src/org/eclipse/ecf/provider/generic/SOWrapper.java
index 90d7105a3..0691bf295 100644
--- a/framework/bundles/org.eclipse.ecf.provider/src/org/eclipse/ecf/provider/generic/SOWrapper.java
+++ b/framework/bundles/org.eclipse.ecf.provider/src/org/eclipse/ecf/provider/generic/SOWrapper.java
@@ -74,6 +74,9 @@ public class SOWrapper {
return sharedObjectConfig.getHomeContainerID();
}
+ protected SOConfig getConfig() {
+ return sharedObjectConfig;
+ }
protected void activated(ID[] ids) {
debug("activated");
sharedObjectConfig.makeActive(new QueueEnqueueImpl(queue));

Back to the top