/*
* Copyright 2015 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.drools.core.beliefsystem.simple;
import org.drools.core.beliefsystem.BeliefSet;
import org.drools.core.beliefsystem.BeliefSystem;
import org.drools.core.common.EqualityKey;
import org.drools.core.common.InternalFactHandle;
import org.drools.core.common.InternalWorkingMemoryEntryPoint;
import org.drools.core.common.LogicalDependency;
import org.drools.core.common.NamedEntryPoint;
import org.drools.core.common.ObjectTypeConfigurationRegistry;
import org.drools.core.common.TruthMaintenanceSystem;
import org.drools.core.definitions.rule.impl.RuleImpl;
import org.drools.core.reteoo.ObjectTypeConf;
import org.drools.core.spi.Activation;
import org.drools.core.spi.PropagationContext;
import static org.drools.core.reteoo.PropertySpecificUtil.allSetButTraitBitMask;
/**
* Default implementation emulates classical Drools TMS behaviour.
*
*/
public class SimpleBeliefSystem
implements
BeliefSystem<SimpleMode> {
private InternalWorkingMemoryEntryPoint ep;
private TruthMaintenanceSystem tms;
public SimpleBeliefSystem(InternalWorkingMemoryEntryPoint ep,
TruthMaintenanceSystem tms) {
super();
this.ep = ep;
this.tms = tms;
}
public TruthMaintenanceSystem getTruthMaintenanceSystem() {
return this.tms;
}
@Override
public SimpleMode asMode( Object value ) {
return new SimpleMode();
}
public BeliefSet<SimpleMode> insert(LogicalDependency<SimpleMode> node,
BeliefSet<SimpleMode> beliefSet,
PropagationContext context,
ObjectTypeConf typeConf) {
boolean empty = beliefSet.isEmpty();
beliefSet.add( node.getMode() );
InternalFactHandle bfh = beliefSet.getFactHandle();
if ( empty && bfh.getEqualityKey().getStatus() == EqualityKey.JUSTIFIED ) {
ep.insert( bfh,
bfh.getObject(),
node.getJustifier().getRule(),
node.getJustifier(),
typeConf );
}
return beliefSet;
}
public BeliefSet<SimpleMode> insert( SimpleMode mode,
RuleImpl rule,
Activation activation,
Object payload,
BeliefSet<SimpleMode> beliefSet,
PropagationContext context,
ObjectTypeConf typeConf) {
boolean empty = beliefSet.isEmpty();
beliefSet.add( mode );
InternalFactHandle bfh = beliefSet.getFactHandle();
if ( empty && bfh.getEqualityKey().getStatus() == EqualityKey.JUSTIFIED ) {
ep.insert( bfh,
bfh.getObject(),
rule,
activation,
typeConf );
}
return beliefSet;
}
public void read(LogicalDependency<SimpleMode> node,
BeliefSet<SimpleMode> beliefSet,
PropagationContext context,
ObjectTypeConf typeConf) {
//insert(node, beliefSet, context, typeConf );
beliefSet.add( node.getMode() );
}
public void delete(LogicalDependency<SimpleMode> node,
BeliefSet<SimpleMode> beliefSet,
PropagationContext context) {
delete( node.getMode(), node.getJustifier().getRule(), node.getJustifier(), node.getObject(), beliefSet, context );
}
@Override
public void delete( SimpleMode mode, RuleImpl rule, Activation activation, Object payload, BeliefSet<SimpleMode> beliefSet, PropagationContext context ) {
SimpleBeliefSet sBeliefSet = (SimpleBeliefSet) beliefSet;
beliefSet.remove( mode );
InternalFactHandle bfh = beliefSet.getFactHandle();
if ( beliefSet.isEmpty() && bfh.getEqualityKey() != null && bfh.getEqualityKey().getStatus() == EqualityKey.JUSTIFIED ) {
ep.delete(bfh, bfh.getObject(), getObjectTypeConf(beliefSet), (RuleImpl) context.getRuleOrigin(), (Activation) context.getLeftTupleOrigin() );
} else if ( !beliefSet.isEmpty() && bfh.getObject() == payload && payload != bfh.getObject() ) {
// prime has changed, to update new object
// Equality might have changed on the object, so remove (which uses the handle id) and add back in
((NamedEntryPoint)bfh.getEntryPoint()).getObjectStore().updateHandle(bfh, ((SimpleMode) beliefSet.getFirst()).getObject().getObject());
((NamedEntryPoint) bfh.getEntryPoint() ).update( bfh, bfh.getObject(), allSetButTraitBitMask(), Object.class, null );
}
if ( beliefSet.isEmpty() && bfh.getEqualityKey() != null ) {
// if the beliefSet is empty, we must null the logical handle
EqualityKey key = bfh.getEqualityKey();
key.setLogicalFactHandle( null );
key.setBeliefSet( null );
if ( key.getStatus() == EqualityKey.JUSTIFIED ) {
// if it's stated, there will be other handles, so leave it in the TMS
tms.remove( key );
}
}
}
public void stage(PropagationContext context,
BeliefSet<SimpleMode> beliefSet) {
InternalFactHandle bfh = beliefSet.getFactHandle();
// Remove the FH from the network
ep.delete(bfh, bfh.getObject(), getObjectTypeConf(beliefSet),(RuleImpl) context.getRuleOrigin(), null);
bfh.getEqualityKey().setStatus( EqualityKey.STATED ); // revert to stated
}
public void unstage(PropagationContext context,
BeliefSet<SimpleMode> beliefSet) {
InternalFactHandle bfh = beliefSet.getFactHandle();
bfh.getEqualityKey().setStatus( EqualityKey.JUSTIFIED ); // revert to justified
// Add the FH back into the network
ep.insert(bfh, bfh.getObject(), (RuleImpl) context.getRuleOrigin(), null, getObjectTypeConf(beliefSet) );
}
private ObjectTypeConf getObjectTypeConf(BeliefSet beliefSet) {
InternalFactHandle fh = beliefSet.getFactHandle();
ObjectTypeConfigurationRegistry reg;
ObjectTypeConf typeConf;
reg = ep.getObjectTypeConfigurationRegistry();
typeConf = reg.getObjectTypeConf( ep.getEntryPoint(), fh.getObject() );
return typeConf;
}
public BeliefSet newBeliefSet(InternalFactHandle fh) {
return new SimpleBeliefSet( this, fh );
}
public LogicalDependency newLogicalDependency(Activation activation,
BeliefSet beliefSet,
Object object,
Object value) {
SimpleMode mode = new SimpleMode();
SimpleLogicalDependency dep = new SimpleLogicalDependency( activation, beliefSet, object, mode );
mode.setObject( dep );
return dep;
}
public InternalWorkingMemoryEntryPoint getEp() {
return ep;
}
public void setEp( NamedEntryPoint ep ) {
this.ep = ep;
}
public TruthMaintenanceSystem getTms() {
return tms;
}
public void setTms( TruthMaintenanceSystem tms ) {
this.tms = tms;
}
}