if ( object == null ) {
// you cannot assert a null object
return null;
}
ObjectTypeConf typeConf = this.typeConfReg.getObjectTypeConf( this.entryPoint,
object );
InternalFactHandle handle = null;
if ( isSequential() ) {
handle = createHandle( object,
typeConf );
insert( handle,
object,
rule,
activation,
typeConf );
return handle;
}
try {
this.lock.lock();
// check if the object already exists in the WM
handle = (InternalFactHandle) this.objectStore.getHandleForObject( object );
if ( this.maintainTms ) {
EqualityKey key = null;
if ( handle == null ) {
// lets see if the object is already logical asserted
key = this.tms.get( object );
} else {
// Object is already asserted, so check and possibly correct
// its
// status and then return the handle
key = handle.getEqualityKey();
if ( key.getStatus() == EqualityKey.STATED ) {
// return null as you cannot justify a stated object.
return handle;
}
if ( !logical ) {
// this object was previously justified, so we have to
// override it to stated
key.setStatus( EqualityKey.STATED );
this.tms.removeLogicalDependencies( handle );
} else {
// this was object is already justified, so just add new
// logical dependency
this.tms.addLogicalDependency( handle,
activation,
activation.getPropagationContext(),
rule );
}
return handle;
}
// At this point we know the handle is null
if ( key == null ) {
handle = createHandle( object,
typeConf );
key = new EqualityKey( handle );
handle.setEqualityKey( key );
this.tms.put( key );
if ( !logical ) {
key.setStatus( EqualityKey.STATED );
} else {
key.setStatus( EqualityKey.JUSTIFIED );
this.tms.addLogicalDependency( handle,
activation,
activation.getPropagationContext(),
rule );
}
} else if ( !logical ) {
if ( key.getStatus() == EqualityKey.JUSTIFIED ) {
// Its previous justified, so switch to stated and
// remove
// logical dependencies
final InternalFactHandle justifiedHandle = key.getFactHandle();
this.tms.removeLogicalDependencies( justifiedHandle );
if ( this.discardOnLogicalOverride ) {
// override, setting to new instance, and return
// existing handle
key.setStatus( EqualityKey.STATED );
handle = key.getFactHandle();
if ( AssertBehaviour.IDENTITY.equals( this.ruleBase.getConfiguration().getAssertBehaviour() ) ) {
// as assertMap may be using an "identity"
// equality comparator,
// we need to remove the handle from the map,
// before replacing the object
// and then re-add the handle. Otherwise we may
// end up with a leak.
this.objectStore.updateHandle( handle,
object );
} else {
Object oldObject = handle.getObject();
}
return handle;
} else {
// override, then instantiate new handle for
// assertion
key.setStatus( EqualityKey.STATED );
handle = createHandle( object,
typeConf );
handle.setEqualityKey( key );
key.addFactHandle( handle );
}
} else {
handle = createHandle( object,
typeConf );
key.addFactHandle( handle );
handle.setEqualityKey( key );
}
} else {
if ( key.getStatus() == EqualityKey.JUSTIFIED ) {
// only add as logical dependency if this wasn't
// previously
// stated
this.tms.addLogicalDependency( key.getFactHandle(),
activation,
activation.getPropagationContext(),
rule );
return key.getFactHandle();
} else {
// You cannot justify a previously stated equality equal
// object, so return null
return null;
}
}
} else {
if ( handle != null ) {
return handle;
}
handle = createHandle( object,
typeConf );
}
// if the dynamic parameter is true or if the
// user declared the fact type with the meta tag:
// @propertyChangeSupport
if ( dynamic || typeConf.isDynamic() ) {
addPropertyChangeListener( object );
}
insert( handle,
object,