All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.drools.core.impl.RuleUnitExecutorSession Maven / Gradle / Ivy

There is a newer version: 9.44.0.Final
Show newest version
/*
 * Copyright 2016 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.
 * 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.core.impl;

import java.util.Collection;
import java.util.concurrent.atomic.AtomicBoolean;

import org.drools.core.SessionConfiguration;
import org.drools.core.SessionConfigurationImpl;
import org.drools.core.common.DynamicEntryPoint;
import org.drools.core.common.InternalAgenda;
import org.drools.core.datasources.CursoredDataSource;
import org.drools.core.datasources.InternalDataSource;
import org.drools.core.event.AgendaEventSupport;
import org.drools.core.event.RuleEventListenerSupport;
import org.drools.core.event.RuleRuntimeEventSupport;
import org.drools.core.rule.EntryPointId;
import org.drools.core.ruleunit.RuleUnitDescr;
import org.drools.core.ruleunit.RuleUnitFactory;
import org.drools.core.ruleunit.RuleUnitGuardSystem;
import org.drools.core.ruleunit.RuleUnitsNodeMemories;
import org.drools.core.spi.Activation;
import org.drools.core.spi.FactHandleFactory;
import org.kie.api.KieBase;
import org.kie.api.runtime.Environment;
import org.kie.api.runtime.Globals;
import org.kie.api.runtime.rule.DataSource;
import org.kie.api.runtime.rule.RuleUnit;
import org.kie.api.runtime.rule.RuleUnitExecutor;

public class RuleUnitExecutorSession implements InternalRuleUnitExecutor {

    private final StatefulKnowledgeSessionImpl session;

    private RuleUnitGuardSystem ruleUnitGuardSystem;

    private RuleUnitFactory ruleUnitFactory;
    private RuleUnit currentRuleUnit;

    private AtomicBoolean suspended = new AtomicBoolean( false );

    public RuleUnitExecutorSession() {
        session = new StatefulKnowledgeSessionImpl();
        initSession(new SessionConfigurationImpl(), EnvironmentFactory.newEnvironment());
        session.agendaEventSupport = new AgendaEventSupport();
        session.ruleRuntimeEventSupport = new RuleRuntimeEventSupport();
        session.ruleEventListenerSupport = new RuleEventListenerSupport();
    }

    public RuleUnitExecutorSession( final long id,
                                    boolean initInitFactHandle,
                                    final SessionConfiguration config,
                                    final Environment environment ) {
        session = new StatefulKnowledgeSessionImpl(id, null, initInitFactHandle, config, environment);
        initSession(config, environment);
    }

    public RuleUnitExecutorSession( final long id,
                                    final FactHandleFactory handleFactory,
                                    final long propagationContext,
                                    final SessionConfiguration config,
                                    final InternalAgenda agenda,
                                    final Environment environment ) {
        session = new StatefulKnowledgeSessionImpl(id, null, handleFactory, propagationContext, config, agenda, environment);
        initSession(config, environment);
    }

    private void initSession(SessionConfiguration config, Environment environment) {
        session.init(config, environment);
        session.ruleUnitExecutor = this;
    }

    @Override
    public RuleUnitExecutor bind( KieBase kiebase ) {
        InternalKnowledgeBase kbase = (InternalKnowledgeBase) kiebase;
        if (!kbase.hasUnits()) {
            throw new IllegalStateException( "Cannot create a RuleUnitExecutor against a KieBase without units" );
        }

        session.handleFactory = kbase.newFactHandleFactory();
        session.bindRuleBase( kbase, null, false, false );
        session.nodeMemories = new RuleUnitsNodeMemories(kbase);

        DynamicEntryPoint defaultEp = new DynamicEntryPoint( EntryPointId.DEFAULT, session );
        session.defaultEntryPoint = defaultEp;
        defaultEp.bindRuleBase( kbase );

        this.ruleUnitGuardSystem = new RuleUnitGuardSystem( this );
        return this;
    }

    @Override
    public  DataSource newDataSource( String name, T... items ) {
        DataSource dataSource = new CursoredDataSource( session );
        for (T item : items) {
            dataSource.insert( item );
        }
        getRuleUnitFactory().bindVariable( name, dataSource );
        return dataSource;
    }

    public int run( Class ruleUnitClass ) {
        return internalRun( getRuleUnitFactory().getOrCreateRuleUnit( this, ruleUnitClass ) );
    }

    public int run( RuleUnit ruleUnit ) {
        return internalRun( getRuleUnitFactory().injectUnitVariables( this, ruleUnit ) );
    }

    private int internalRun( RuleUnit ruleUnit ) {
        return internalExecuteUnit( ruleUnit ) + ruleUnitGuardSystem.fireActiveUnits(ruleUnit);
    }

    public int internalExecuteUnit( RuleUnit ruleUnit ) {
        RuleUnitDescr ruDescr = bindRuleUnit( ruleUnit );
        try {
            return session.fireAllRules();
        } finally {
            unbindRuleUnit(ruDescr);
        }
    }

    public void runUntilHalt( Class ruleUnitClass ) {
        runUntilHalt( getRuleUnitFactory().getOrCreateRuleUnit( this, ruleUnitClass ) );
    }

    public void runUntilHalt( RuleUnit ruleUnit ) {
        bindRuleUnit( ruleUnit );
        session.fireUntilHalt();
    }

    @Override
    public void halt() {
        session.halt();
        unbindRuleUnit(session.kBase.getRuleUnitRegistry().getRuleUnitDescr( currentRuleUnit ));
    }

    @Override
    public RuleUnitDescr switchToRuleUnit( Class ruleUnitClass ) {
        return switchToRuleUnit( getRuleUnitFactory().getOrCreateRuleUnit( this, ruleUnitClass ) );
    }

    @Override
    public RuleUnitDescr switchToRuleUnit( RuleUnit ruleUnit ) {
        if (currentRuleUnit != null) {
            currentRuleUnit.onYield( ruleUnit );
        }
        session.getPropagationList().flush();
        return bindRuleUnit( ruleUnit );
    }

    @Override
    public void guardRuleUnit( Class ruleUnitClass, Activation activation) {
        ruleUnitGuardSystem.registerGuard( getRuleUnitFactory().getOrCreateRuleUnit( this, ruleUnitClass ), activation );
    }

    @Override
    public void guardRuleUnit( RuleUnit ruleUnit, Activation activation ) {
        ruleUnitGuardSystem.registerGuard( getRuleUnitFactory().registerUnit( this, ruleUnit ), activation );
    }

    @Override
    public void cancelActivation( Activation activation ) {
        ruleUnitGuardSystem.removeActivation( activation );
    }

    private RuleUnitDescr bindRuleUnit( RuleUnit ruleUnit ) {
        suspended.set( false );
        currentRuleUnit = ruleUnit;
        currentRuleUnit.onStart();

        getNodeMemories().bindRuleUnit( session, ruleUnit );

        RuleUnitDescr ruDescr = session.kBase.getRuleUnitRegistry().getRuleUnitDescr( ruleUnit );
        ruDescr.bindDataSources( session, ruleUnit );
        ( (Globals) session.getGlobalResolver() ).setDelegate( new RuleUnitGlobals( ruDescr, ruleUnit ) );
        return ruDescr;
    }

    private void unbindRuleUnit( RuleUnitDescr ruDescr ) {
        getNodeMemories().unbindRuleUnit();

        ruDescr.unbindDataSources( session, currentRuleUnit );
        ( (Globals) session.getGlobalResolver() ).setDelegate( null );
        currentRuleUnit.onEnd();
        currentRuleUnit = null;
        suspended.set( true );
    }

    private RuleUnitsNodeMemories getNodeMemories() {
        return ( (RuleUnitsNodeMemories) session.nodeMemories );
    }

    public RuleUnit getCurrentRuleUnit() {
        return currentRuleUnit;
    }

    public RuleUnitFactory getRuleUnitFactory() {
        if (ruleUnitFactory == null) {
            ruleUnitFactory = new RuleUnitFactory();
        }
        return ruleUnitFactory;
    }

    @Override
    public RuleUnitExecutor bindVariable( String name, Object value ) {
        getRuleUnitFactory().bindVariable( name, value );
        if (value instanceof InternalDataSource) {
            bindDataSource( (InternalDataSource) value );
        }
        return this;
    }

    @Override
    public void bindDataSource(InternalDataSource dataSource) {
        dataSource.setWorkingMemory( session );
    }

    @Override
    public void onSuspend() {
        if (!suspended.getAndSet( true )) {
            if ( currentRuleUnit != null ) {
                currentRuleUnit.onSuspend();
            }
        }
    }

    @Override
    public void onResume() {
        if (suspended.getAndSet( false )) {
            if ( currentRuleUnit != null ) {
                currentRuleUnit.onResume();
            }
        }
    }

    @Override
    public void dispose() {
        session.dispose();
        ruleUnitGuardSystem = null;
        ruleUnitFactory = null;
        currentRuleUnit = null;
    }

    public static class RuleUnitGlobals implements Globals {
        private final RuleUnitDescr ruDescr;
        private final RuleUnit ruleUnit;

        private RuleUnitGlobals( RuleUnitDescr ruDescr, RuleUnit ruleUnit ) {
            this.ruDescr = ruDescr;
            this.ruleUnit = ruleUnit;
        }

        @Override
        public Object get( String identifier ) {
            return ruDescr.getValue( ruleUnit, identifier );
        }

        @Override
        public void set( String identifier, Object value ) {
            throw new UnsupportedOperationException();
        }

        @Override
        public void setDelegate( Globals delegate ) {
            throw new UnsupportedOperationException();
        }

        @Override
        public Collection getGlobalKeys() {
            throw new UnsupportedOperationException();
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy