001    /**
002     * Copyright 2005-2011 The Kuali Foundation
003     *
004     * Licensed under the Educational Community License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     * http://www.opensource.org/licenses/ecl2.php
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.kuali.rice.krms.framework.engine;
017    
018    import java.util.Map;
019    
020    import org.joda.time.DateTime;
021    import org.kuali.rice.krms.api.engine.Engine;
022    import org.kuali.rice.krms.api.engine.EngineResults;
023    import org.kuali.rice.krms.api.engine.ExecutionEnvironment;
024    import org.kuali.rice.krms.api.engine.ExecutionOptions;
025    import org.kuali.rice.krms.api.engine.Facts;
026    import org.kuali.rice.krms.api.engine.ResultEvent;
027    import org.kuali.rice.krms.api.engine.SelectionCriteria;
028    import org.kuali.rice.krms.api.engine.Term;
029    import org.kuali.rice.krms.framework.engine.result.TimingResult;
030    
031    public class ProviderBasedEngine implements Engine {
032    
033            private static final Term effectiveExecutionTimeTerm = new Term("effectiveExecutionTime", null);
034            
035            private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(ProviderBasedEngine.class);
036            private static final ResultLogger KLog = ResultLogger.getInstance();
037    
038            private ContextProvider contextProvider;
039    
040        @Override
041        public EngineResults execute(SelectionCriteria selectionCriteria, Map<String, Object> facts,
042                ExecutionOptions executionOptions) {
043            return execute(selectionCriteria,
044                    Facts.Builder.create().addFactsByName(facts).build(),
045                    executionOptions);
046        }
047    
048        @Override
049            public EngineResults execute(SelectionCriteria selectionCriteria, Facts facts, ExecutionOptions executionOptions) {
050                    DateTime start, end;
051                    start = new DateTime();
052                    ExecutionEnvironment environment = establishExecutionEnvironment(selectionCriteria, facts.getFactMap(), executionOptions);
053                    
054                    // set execution time
055                    Long effectiveExecutionTime = environment.getSelectionCriteria().getEffectiveExecutionTime();
056                    if (effectiveExecutionTime == null) { effectiveExecutionTime = System.currentTimeMillis(); }
057                    environment.publishFact(effectiveExecutionTimeTerm, effectiveExecutionTime);
058    
059                    Context context = selectContext(selectionCriteria, facts.getFactMap(), executionOptions);
060                    if (context == null) {
061                            LOG.info("Failed to locate a Context for the given qualifiers, skipping rule engine execution: " + selectionCriteria.getContextQualifiers());
062                            return null;
063                    }
064                    context.execute(environment);
065                    end = new DateTime();
066                    if (KLog.isEnabled(environment)){
067                            KLog.logResult(new TimingResult(ResultEvent.TimingEvent, this, environment, start, end));
068                    }
069                    return environment.getEngineResults();
070            }
071            
072            protected ExecutionEnvironment establishExecutionEnvironment(SelectionCriteria selectionCriteria, Map<Term, Object> facts, ExecutionOptions executionOptions) {
073                    return new BasicExecutionEnvironment(selectionCriteria, facts, executionOptions, new TermResolutionEngineImpl());
074            }
075            
076            protected Context selectContext(SelectionCriteria selectionCriteria, Map<Term, Object> facts, ExecutionOptions executionOptions) {
077                    if (contextProvider == null) {
078                            throw new IllegalStateException("No ContextProvider was configured.");
079                    }
080                    return contextProvider.loadContext(selectionCriteria, facts, executionOptions);
081            }
082            
083            
084            public void setContextProvider(ContextProvider contextProvider) {
085                    this.contextProvider = contextProvider;
086            }
087            
088    }