Modified event helper mechanism to allow helpers to abort the event
dispatch. Added code to abort object added events that are trying to add a non-existent object to an oid list. Wrote test driver for this and duplicate object add request handling. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@196 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: PresentsDObjectMgr.java,v 1.12 2001/08/08 00:28:49 mdb Exp $
|
// $Id: PresentsDObjectMgr.java,v 1.13 2001/08/08 21:56:47 mdb Exp $
|
||||||
|
|
||||||
package com.threerings.cocktail.cher.server;
|
package com.threerings.cocktail.cher.server;
|
||||||
|
|
||||||
@@ -126,16 +126,22 @@ public class CherDObjectMgr implements DObjectManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// everything's good so far, apply the event to the object
|
|
||||||
boolean notify = event.applyToObject(target);
|
|
||||||
|
|
||||||
// do any internal management necessary based on this
|
// do any internal management necessary based on this
|
||||||
// event
|
// event
|
||||||
Method helper = (Method)_helpers.get(event.getClass());
|
Method helper = (Method)_helpers.get(event.getClass());
|
||||||
if (helper != null) {
|
if (helper != null) {
|
||||||
helper.invoke(this, new Object[] { event, target });
|
// invoke the helper method
|
||||||
|
Object rv =
|
||||||
|
helper.invoke(this, new Object[] { event, target });
|
||||||
|
// if helper returns false, we abort event processing
|
||||||
|
if (!((Boolean)rv).booleanValue()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// everything's good so far, apply the event to the object
|
||||||
|
boolean notify = event.applyToObject(target);
|
||||||
|
|
||||||
// if the event returns false from applyToObject, this
|
// if the event returns false from applyToObject, this
|
||||||
// means it's a silent event and we shouldn't notify the
|
// means it's a silent event and we shouldn't notify the
|
||||||
// subscribers
|
// subscribers
|
||||||
@@ -169,8 +175,11 @@ public class CherDObjectMgr implements DObjectManager
|
|||||||
/**
|
/**
|
||||||
* Called as a helper for <code>ObjectDestroyedEvent</code> events. It
|
* Called as a helper for <code>ObjectDestroyedEvent</code> events. It
|
||||||
* removes the object from the object table.
|
* removes the object from the object table.
|
||||||
|
*
|
||||||
|
* @return true if the event should be dispatched, false if it should
|
||||||
|
* be aborted.
|
||||||
*/
|
*/
|
||||||
public void objectDestroyed (DEvent event, DObject target)
|
public boolean objectDestroyed (DEvent event, DObject target)
|
||||||
{
|
{
|
||||||
int oid = target.getOid();
|
int oid = target.getOid();
|
||||||
|
|
||||||
@@ -240,6 +249,8 @@ public class CherDObjectMgr implements DObjectManager
|
|||||||
"[target=" + target + ", field=" + field + "].");
|
"[target=" + target + ", field=" + field + "].");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -278,12 +289,22 @@ public class CherDObjectMgr implements DObjectManager
|
|||||||
/**
|
/**
|
||||||
* Called as a helper for <code>ObjectAddedEvent</code> events. It
|
* Called as a helper for <code>ObjectAddedEvent</code> events. It
|
||||||
* updates the object/oid list tracking structures.
|
* updates the object/oid list tracking structures.
|
||||||
|
*
|
||||||
|
* @return true if the event should be dispatched, false if it should
|
||||||
|
* be aborted.
|
||||||
*/
|
*/
|
||||||
public void objectAdded (DEvent event, DObject target)
|
public boolean objectAdded (DEvent event, DObject target)
|
||||||
{
|
{
|
||||||
ObjectAddedEvent oae = (ObjectAddedEvent)event;
|
ObjectAddedEvent oae = (ObjectAddedEvent)event;
|
||||||
int oid = oae.getOid();
|
int oid = oae.getOid();
|
||||||
Reference ref = new Reference(target.getOid(), oae.getName(), oid);
|
|
||||||
|
// ensure that the target object exists
|
||||||
|
if (!_objects.contains(oid)) {
|
||||||
|
Log.info("Rejecting object added event of non-existent object " +
|
||||||
|
"[refferOid=" + target.getOid() +
|
||||||
|
", reffedOid=" + oid + "].");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// get the reference vector for the referenced object. we use bare
|
// get the reference vector for the referenced object. we use bare
|
||||||
// arrays rather than something like an array list to conserve
|
// arrays rather than something like an array list to conserve
|
||||||
@@ -295,12 +316,13 @@ public class CherDObjectMgr implements DObjectManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
// determine where to add the reference
|
// determine where to add the reference
|
||||||
|
Reference ref = new Reference(target.getOid(), oae.getName(), oid);
|
||||||
int rpos = -1;
|
int rpos = -1;
|
||||||
for (int i = 0; i < refs.length; i++) {
|
for (int i = 0; i < refs.length; i++) {
|
||||||
if (ref.equals(refs[i])) {
|
if (ref.equals(refs[i])) {
|
||||||
Log.warning("Ignoring request to track existing " +
|
Log.warning("Ignoring request to track existing " +
|
||||||
"reference " + ref + ".");
|
"reference " + ref + ".");
|
||||||
return;
|
return true;
|
||||||
} else if (refs[i] == null && rpos == -1) {
|
} else if (refs[i] == null && rpos == -1) {
|
||||||
rpos = i;
|
rpos = i;
|
||||||
}
|
}
|
||||||
@@ -318,13 +340,17 @@ public class CherDObjectMgr implements DObjectManager
|
|||||||
refs[rpos] = ref;
|
refs[rpos] = ref;
|
||||||
|
|
||||||
// Log.info("Tracked reference " + ref + ".");
|
// Log.info("Tracked reference " + ref + ".");
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called as a helper for <code>ObjectRemovedEvent</code> events. It
|
* Called as a helper for <code>ObjectRemovedEvent</code> events. It
|
||||||
* updates the object/oid list tracking structures.
|
* updates the object/oid list tracking structures.
|
||||||
|
*
|
||||||
|
* @return true if the event should be dispatched, false if it should
|
||||||
|
* be aborted.
|
||||||
*/
|
*/
|
||||||
public void objectRemoved (DEvent event, DObject target)
|
public boolean objectRemoved (DEvent event, DObject target)
|
||||||
{
|
{
|
||||||
ObjectRemovedEvent ore = (ObjectRemovedEvent)event;
|
ObjectRemovedEvent ore = (ObjectRemovedEvent)event;
|
||||||
String field = ore.getName();
|
String field = ore.getName();
|
||||||
@@ -342,7 +368,7 @@ public class CherDObjectMgr implements DObjectManager
|
|||||||
// Log.warning("Object removed without reference to track it " +
|
// Log.warning("Object removed without reference to track it " +
|
||||||
// "[toid=" + toid + ", field=" + field +
|
// "[toid=" + toid + ", field=" + field +
|
||||||
// ", oid=" + oid + "].");
|
// ", oid=" + oid + "].");
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// look for the matching reference
|
// look for the matching reference
|
||||||
@@ -350,13 +376,14 @@ public class CherDObjectMgr implements DObjectManager
|
|||||||
if (refs[i].equals(toid, field)) {
|
if (refs[i].equals(toid, field)) {
|
||||||
// Log.info("Removed reference " + refs[i] + ".");
|
// Log.info("Removed reference " + refs[i] + ".");
|
||||||
refs[i] = null;
|
refs[i] = null;
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.warning("Unable to locate reference for removal " +
|
Log.warning("Unable to locate reference for removal " +
|
||||||
"[reffingOid=" + toid + ", field=" + field +
|
"[reffingOid=" + toid + ", field=" + field +
|
||||||
", reffedOid=" + oid + "].");
|
", reffedOid=" + oid + "].");
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected synchronized boolean isRunning ()
|
protected synchronized boolean isRunning ()
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
//
|
||||||
|
// $Id: DestroyedRefTest.java,v 1.1 2001/08/08 21:56:48 mdb Exp $
|
||||||
|
|
||||||
|
package com.threerings.cocktail.cher.server.test;
|
||||||
|
|
||||||
|
import com.threerings.cocktail.cher.Log;
|
||||||
|
import com.threerings.cocktail.cher.dobj.*;
|
||||||
|
import com.threerings.cocktail.cher.server.CherServer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests that the dobjmgr will not allow a destroyed object to be added to
|
||||||
|
* an oid list.
|
||||||
|
*/
|
||||||
|
public class DestroyedRefTest
|
||||||
|
implements Runnable, Subscriber
|
||||||
|
{
|
||||||
|
public void run ()
|
||||||
|
{
|
||||||
|
// create two test objects
|
||||||
|
CherServer.omgr.createObject(TestObject.class, this, true);
|
||||||
|
CherServer.omgr.createObject(TestObject.class, this, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void objectAvailable (DObject object)
|
||||||
|
{
|
||||||
|
// keep references to our test objects
|
||||||
|
if (_objone == null) {
|
||||||
|
_objone = (TestObject)object;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
_objtwo = (TestObject)object;
|
||||||
|
|
||||||
|
// add object one to object two twice in a row to make sure
|
||||||
|
// repeated adds don't result in the object being listed twice
|
||||||
|
_objtwo.addToList(_objone.getOid());
|
||||||
|
_objtwo.addToList(_objone.getOid());
|
||||||
|
|
||||||
|
// now that we have both objects, try to set up the reference.
|
||||||
|
// first we queue up a destroy event for object two, then we
|
||||||
|
// try to reference it on object one's oid list
|
||||||
|
_objtwo.destroy();
|
||||||
|
_objone.addToList(_objtwo.getOid());
|
||||||
|
|
||||||
|
// finally dispatch an event on which we can trigger our exit
|
||||||
|
_objone.setFoo(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void requestFailed (int oid, ObjectAccessException cause)
|
||||||
|
{
|
||||||
|
Log.warning("Ack. Unable to create object [cause=" + cause + "].");
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean handleEvent (DEvent event, DObject target)
|
||||||
|
{
|
||||||
|
// when we get the attribute change, we can exit
|
||||||
|
if (event instanceof ObjectDestroyedEvent) {
|
||||||
|
Log.info("The upcoming object added event should be rejected.");
|
||||||
|
|
||||||
|
} else if (event instanceof ObjectAddedEvent &&
|
||||||
|
target == _objtwo) {
|
||||||
|
Log.info("list should contain only one oid: " + _objtwo.list);
|
||||||
|
|
||||||
|
} else if (event instanceof AttributeChangedEvent) {
|
||||||
|
// go bye bye
|
||||||
|
CherServer.shutdown();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Log.info("Got unexpected event: " + event);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected TestObject _objone;
|
||||||
|
protected TestObject _objtwo;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user