/* * 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.defeasible; import org.drools.core.beliefsystem.BeliefSystem; import org.drools.core.beliefsystem.jtms.JTMSMode; import org.drools.core.common.LogicalDependency; import org.drools.core.spi.Activation; import org.drools.core.util.LinkedListEntry; import org.kie.internal.runtime.beliefs.Mode; import java.util.Arrays; public class DefeasibleMode<M extends DefeasibleMode<M>> extends JTMSMode<M> { //extends LinkedListEntry<Activation> implements Mode { private static final String[] EMPTY_DEFEATS = new String[0]; public static final String DEFEATS = Defeats.class.getSimpleName(); public static final String DEFEATER = Defeater.class.getSimpleName(); private DefeasibilityStatus status; private String[] defeats; private M rootDefeated; private M tailDefeated; // private int attacks; private DefeasibleMode<M> defeatedBy; private boolean isDefeater; private BeliefSystem<M> beliefSystem; private Mode nextMode; @Override public Object getBeliefSystem() { return beliefSystem; } public DefeasibleMode(String value, BeliefSystem beliefSystem) { super(value, beliefSystem); this.beliefSystem = beliefSystem; } public DefeasibleMode(String value, BeliefSystem beliefSystem, Mode nextMode) { super(value, beliefSystem); this.beliefSystem = beliefSystem; this.nextMode = nextMode; } public void initDefeats() { Object o = getLogicalDependency().getJustifier().getRule().getMetaData().get(DEFEATER); if ( o != null && ((Boolean)o).booleanValue() ) { isDefeater = true; } o = getLogicalDependency().getJustifier().getRule().getMetaData().get(DEFEATS); if ( o != null ) { // this must be sorted, so superiority is a quick search. if (o instanceof String) { defeats = new String[]{(String) o}; Arrays.sort(defeats); } else if (o instanceof Object[]) { defeats = Arrays.copyOf( (Object[]) o, ( (Object[]) o ).length, String[].class ); Arrays.sort(defeats); } } else { defeats = EMPTY_DEFEATS; } } public void addDefeated( M defeated ) { defeated.setDefeatedBy( this ); if (rootDefeated == null) { rootDefeated = defeated; } else { tailDefeated.setNext( defeated ); defeated.setPrevious( tailDefeated ); } tailDefeated = defeated; } public void removeDefeated( DefeasibleMode<M> defeated ) { defeated.setDefeatedBy( null ); if (this.rootDefeated == defeated) { removeFirst(); } else if (this.tailDefeated == defeated) { removeLast(); } else { DefeasibleMode<M> entry = this.rootDefeated; while ( entry != defeated ) { entry = entry.getNext(); } entry.getPrevious().setNext( entry.getNext() ); entry.getNext().setPrevious( entry.getPrevious() ); entry.nullPrevNext(); } } public DefeasibleMode<M> removeFirst() { if (this.rootDefeated == null) { return null; } final DefeasibleMode<M> node = this.rootDefeated; this.rootDefeated = node.getNext(); node.setNext(null); if (this.rootDefeated != null) { this.rootDefeated.setPrevious(null); } else { this.tailDefeated = null; } return node; } public DefeasibleMode<M> removeLast() { if (this.tailDefeated == null) { return null; } final DefeasibleMode<M> node = this.tailDefeated; this.tailDefeated = node.getPrevious(); node.setPrevious(null); if (this.tailDefeated != null) { this.tailDefeated.setNext(null); } else { this.rootDefeated = this.tailDefeated; } return node; } public M getRootDefeated() { return this.rootDefeated; } public M getTailDefeated() { return this.tailDefeated; } public String[] getDefeats() { return this.defeats; } public DefeasibleMode<M> getDefeatedBy() { return defeatedBy; } public void setDefeatedBy(DefeasibleMode<M> defeatedBy) { this.defeatedBy = defeatedBy; } // public int getAttacks() { // return attacks; // } // // public void incAttacks() { // attacks++; // } // // public void decAttacks() { // attacks--; // } public DefeasibilityStatus getStatus() { return status; } public void setStatus(DefeasibilityStatus status) { this.status = status; } public boolean isDefeater() { return isDefeater; } public void setDefeater(boolean defeater) { isDefeater = defeater; } public void clearDefeated() { this.rootDefeated = null; this.tailDefeated = null; } @Override public Mode getNextMode() { return nextMode; } @Override public String toString() { return "DefeasibleMode{" + "status=" + status + " Object=" + getLogicalDependency().getObject() + "} "; } }