Package org.drools.agent.impl

Source Code of org.drools.agent.impl.BinaryResourceDiffProducerImpl$DummyConsequence

/**
* Copyright 2010 JBoss Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      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.agent.impl;

import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.HashSet;
import java.util.Set;
import org.drools.SystemEventListener;
import org.drools.SystemEventListenerFactory;
import org.drools.WorkingMemory;
import org.drools.core.util.ReflectiveVisitor;
import org.drools.definition.KnowledgeDefinition;
import org.drools.definitions.impl.KnowledgePackageImp;
import org.drools.agent.ResourceDiffProducer;
import org.drools.rule.Function;
import org.drools.rule.Query;
import org.drools.rule.Rule;
import org.drools.spi.Consequence;
import org.drools.spi.KnowledgeHelper;

/**
*
* @author esteban.aliverti@gmail.com
*/
public class BinaryResourceDiffProducerImpl extends ReflectiveVisitor implements ResourceDiffProducer {



    private KnowledgePackageImp newPkg;
    private KnowledgePackageImp currentPkg;
    private Set<KnowledgeDefinition> unmodifiedDefinitions = new HashSet<KnowledgeDefinition>();
    private Set<KnowledgeDefinition> removedDefinitions = new HashSet<KnowledgeDefinition>();

    private SystemEventListener listener;

    //attributes used during rules comparison
    private Calendar now = new GregorianCalendar();
    private Consequence dummyConsequence = new DummyConsequence();

    public ResourceDiffResult diff(Set<KnowledgeDefinition> originalDefinitions, KnowledgePackageImp newPkg, KnowledgePackageImp currentPkg ) {

        this.listener = SystemEventListenerFactory.getSystemEventListener();

        this.newPkg = newPkg;
        this.currentPkg = currentPkg;

        for (KnowledgeDefinition knowledgeDefinition : originalDefinitions) {
            this.visit(knowledgeDefinition);
        }



        //return the whole new package as new
        return new ResourceDiffResult(this.newPkg, this.unmodifiedDefinitions, this.removedDefinitions);
    }

   
    public void visitRule(final Rule oldRule){

      

        //ok, so I get an old rule: is it modified in the new pkg? is it even present on it?
        org.drools.definition.rule.Rule newRule = newPkg.getRule(oldRule.getName());

        if (newRule == null){
            //the old rule is not present on the new package. Add it to
            //removed rules list.
            listener.debug("BinaryResourceDiffProducerImpl: "+oldRule+" is not present anymore. Adding to removed list.");
            this.removedDefinitions.add(oldRule);
            return;
        }

        //it is possible that the old rule doesn't exist anymore in the current
        //pkg. This is because maybe some other resouce updated its definition
        //and after that the same resource removed it. If that is the case,
        //this resource (the one we are processing) still contain a reference
        //to the rule, but it is no present on kbase anymore. If this is the
        //case, we wan't to skip this rule. Because remember that someone
        //modified it and removed it before this resource. We don't even
        //add it to removedDefinitions, because it is no present on kbase. What
        //we have to do is remove it from the new pkg so it won't reapears.
        if (currentPkg.getRule(oldRule.getName()) == null){
            listener.debug("BinaryResourceDiffProducerImpl: "+oldRule+" is not present on current PKG. Removing from new package.");
            newPkg.removeRule(oldRule);
            return;
        }

        //I hate to do this. But if it is not instance of
        //org.drools.rule.Rule I can't get his LHS.
        if (!(newRule instanceof org.drools.rule.Rule)){
            listener.warning("BinaryResourceDiffProducerImpl: Rules must be subclasses of org.drools.rule.Rule.");
            return;
        }

        //Queries are not supported yet.
        if (newRule instanceof Query){
            listener.debug("BinaryResourceDiffProducerImpl: Query diff is not supported yet.");
            return;
        }

        //is newRule equal to oldRule?
        if (this.compareRules((Rule)newRule,oldRule)){
            //if so, we don't need the rule in the new Package.
            listener.debug("BinaryResourceDiffProducerImpl: "+oldRule+" didn't change. Removing from diff package and adding it to unmodified list.");
            newPkg.removeRule((org.drools.rule.Rule)newRule);
            this.unmodifiedDefinitions.add(oldRule);
        }

    }

    public void visitFunction(final Function oldFunction){
        //ok, so I get an old function: is it modified in the new pkg? is it even present on it?
        Function newFunction = newPkg.getFunction(oldFunction.getName());

        if (newFunction == null){
            //the old function is not present on the new package. Add it to
            //removed rules list.
            listener.debug("BinaryResourceDiffProducerImpl: "+oldFunction+" is not present anymore. Adding to removed list.");
            this.removedDefinitions.add(oldFunction);
            return;
        }

        //it is possible that the old function doesn't exist anymore in the current
        //pkg. This is because maybe some other resouce updated its definition
        //and after that the same resource removed it. If that is the case,
        //this resource (the one we are processing) still contain a reference
        //to the function, but it is no present on kbase anymore. If this is the
        //case, we wan't to skip this function. Remember that someone
        //modified it and removed it before this resource. We don't even
        //add it to removedDefinitions, because it is no present on kbase. What
        //we have to do is remove it from the new pkg so it won't reapears.
        if (currentPkg.getFunction(oldFunction.getName()) == null){
            listener.debug("BinaryResourceDiffProducerImpl: "+oldFunction+" is not present on current PKG. Removing from new package.");
            newPkg.removeFunction(oldFunction.getName());
            return;
        }

        //is newFunction equal to oldFunction?
        if (newFunction.equals(oldFunction)){
            //if so, we don't need the function in the new Package.
            listener.debug("BinaryResourceDiffProducerImpl: "+oldFunction+" didn't change. Removing from diff package and adding it to unmodified list.");
            newPkg.removeFunction(newFunction.getName());
            this.unmodifiedDefinitions.add(oldFunction);
        }else{
            //it seems that the kbase doesn't overrides function's definitions.
            //that's why we need to mark this function as removed, but don't
            //remove it from the new pkg.
            listener.debug("BinaryResourceDiffProducerImpl: "+oldFunction+" did change. Marking as removed so it new version could be added later.");
            this.removedDefinitions.add(oldFunction);
        }


    }


    public void visitKnowledgeDefinition(final KnowledgeDefinition oldDefinition){
        listener.debug("BinaryResourceDiffProducerImpl: Couldn't handle "+oldDefinition+". We must leave it in the new Package.");
    }



    private boolean compareRules(Rule r1, Rule r2){
        listener.debug("BinaryResourceDiffProducerImpl: Comparing "+r1+" against "+r2);
       
       

        //compares the salinces
        String v1 = r1.getSalience()== null?"":r1.getSalience().toString();
        String v2 = r2.getSalience()== null?"":r2.getSalience().toString();
       
        if (!v1.equals(v2)){
            listener.debug("BinaryResourceDiffProducerImpl: The rules have different saliences: r1= "+v1+", r2= "+v2);
            return false;
        }

        //compares the activation groups
        v1 = r1.getActivationGroup()== null?"":r1.getActivationGroup();
        v2 = r2.getActivationGroup()== null?"":r2.getActivationGroup();
        if (!v1.equals(v2)){
            listener.debug("BinaryResourceDiffProducerImpl: The rules have different activation groups: r1= "+v1+", r2= "+v2);
            return false;
        }

        //compares no-loop attribute
        if (r1.isNoLoop() != r2.isNoLoop()){
            listener.debug("BinaryResourceDiffProducerImpl: The rules have different values for no-loop attribure: r1= "+r1.isNoLoop()+", r2= "+r2.isNoLoop());
            return false;
        }

        //compares lock-on-active attribute
        if (r1.isLockOnActive() != r2.isLockOnActive()){
            listener.debug("BinaryResourceDiffProducerImpl: The rules have different values for lock-on-active attribure: r1= "+r1.isLockOnActive()+", r2= "+r2.isLockOnActive());
            return false;
        }

        //compares agenda-group attribute
        v1 = r1.getAgendaGroup()== null?"":r1.getAgendaGroup();
        v2 = r2.getAgendaGroup()== null?"":r2.getAgendaGroup();
        if (!v1.equals(v2)){
            listener.debug("BinaryResourceDiffProducerImpl: The rules have different agenda groups: r1= "+v1+", r2= "+v2);
            return false;
        }

        //compares auto-focus attribute
        if (r1.getAutoFocus() != r2.getAutoFocus()){
            listener.debug("BinaryResourceDiffProducerImpl: The rules have different values for auto-focus attribure: r1= "+r1.getAutoFocus()+", r2= "+r2.getAutoFocus());
            return false;
        }

        //compares ruleflow-group attribute
        v1 = r1.getRuleFlowGroup()== null?"":r1.getRuleFlowGroup();
        v2 = r2.getRuleFlowGroup()== null?"":r2.getRuleFlowGroup();
        if (!v1.equals(v2)){
            listener.debug("BinaryResourceDiffProducerImpl: The rules have different ruleflow-group attribute: r1= "+v1+", r2= "+v2);
            return false;
        }

        //compares dialect attribute
        v1 = r1.getDialect()== null?"":r1.getDialect();
        v2 = r2.getDialect()== null?"":r2.getDialect();
        if (!v1.equals(v2)){
            listener.debug("BinaryResourceDiffProducerImpl: The rules have different dialect attribute: r1= "+v1+", r2= "+v2);
            return false;
        }

        //compares date-effective attribute
        Calendar c1 = r1.getDateEffective()== null?now:r1.getDateEffective();
        Calendar c2 = r2.getDateEffective()== null?now:r2.getDateEffective();
        if (!c1.equals(c2)){
            listener.debug("BinaryResourceDiffProducerImpl: The rules have different date-effective attribute: r1= "+c1+", r2= "+c2);
            return false;
        }

        //compares date-expires attribute
        c1 = r1.getDateExpires()== null?now:r1.getDateExpires();
        c2 = r2.getDateExpires()== null?now:r2.getDateExpires();
        if (!c1.equals(c2)){
            listener.debug("BinaryResourceDiffProducerImpl: The rules have different date-expires attribute: r1= "+c1+", r2= "+c2);
            return false;
        }

        //compares the rules' LHS
        if (!r1.getLhs().equals(r2.getLhs())){
            listener.debug("BinaryResourceDiffProducerImpl: The rules have different LHS");
            return false;
        }

        //compares the rules consequences
        Consequence consequence1 = r1.getConsequence()== null?dummyConsequence:r1.getConsequence();
        Consequence consequence2 = r2.getConsequence()== null?dummyConsequence:r2.getConsequence();
        if (!consequence1.equals(consequence2)){
            listener.debug("BinaryResourceDiffProducerImpl: The rules have different Consequences: r1= "+consequence1+", r2= "+consequence2);
            return false;
        }

        return true;
    }

    //Dummy implementation of Consequnce used for rules comparison.
    private class DummyConsequence implements Consequence{

        public void evaluate(KnowledgeHelper knowledgeHelper, WorkingMemory workingMemory) throws Exception {
            throw new UnsupportedOperationException("You should never call this method!!");
        }

        public String getName() {
            return "default";
        }       
    }

}
TOP

Related Classes of org.drools.agent.impl.BinaryResourceDiffProducerImpl$DummyConsequence

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.