}
try {
this.wm.startOperation();
ObjectTypeConf typeConf = this.typeConfReg.getObjectTypeConf( this.entryPoint,
object );
if ( logical && !typeConf.isTMSEnabled()) {
enableTMS(object, typeConf);
}
InternalFactHandle handle = null;
if ( this.wm.isSequential() ) {
handle = createHandle( object,
typeConf );
insert( handle,
object,
rule,
activation,
typeConf );
return handle;
}
try {
this.ruleBase.readLock();
this.lock.lock();
// check if the object already exists in the WM
handle = this.objectStore.getHandleForObject( object );
if ( typeConf.isTMSEnabled() ) {
EqualityKey key;
TruthMaintenanceSystem tms = wm.getTruthMaintenanceSystem();
if ( handle == null ) {
// lets see if the object is already logical asserted
key = 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 );
tms.removeLogicalDependencies( handle );
} else {
// this was object is already justified, so just add new logical dependency
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 = createEqualityKey(handle);
tms.put( key );
if ( !logical ) {
key.setStatus( EqualityKey.STATED );
} else {
key.setStatus( EqualityKey.JUSTIFIED );
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();
tms.removeLogicalDependencies( justifiedHandle );
if ( this.wm.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 );
}
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
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( handle, dynamic );
}
insert( handle,
object,