001 /** 002 * Copyright 2005-2013 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 /** 032 * An implementation of {@link Engine} 033 * @author Kuali Rice Team (rice.collab@kuali.org) 034 */ 035 public class ProviderBasedEngine implements Engine { 036 037 private static final Term effectiveExecutionTimeTerm = new Term("effectiveExecutionTime", null); 038 039 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(ProviderBasedEngine.class); 040 private static final ResultLogger KLog = ResultLogger.getInstance(); 041 042 private ContextProvider contextProvider; 043 044 @Override 045 public EngineResults execute(SelectionCriteria selectionCriteria, Map<String, Object> facts, 046 ExecutionOptions executionOptions) { 047 return execute(selectionCriteria, 048 Facts.Builder.create().addFactsByName(facts).build(), 049 executionOptions); 050 } 051 052 @Override 053 public EngineResults execute(SelectionCriteria selectionCriteria, Facts facts, ExecutionOptions executionOptions) { 054 DateTime start, end; 055 start = new DateTime(); 056 ExecutionEnvironment environment = establishExecutionEnvironment(selectionCriteria, facts.getFactMap(), executionOptions); 057 058 // set execution time 059 Long effectiveExecutionTime = environment.getSelectionCriteria().getEffectiveExecutionTime(); 060 if (effectiveExecutionTime == null) { effectiveExecutionTime = System.currentTimeMillis(); } 061 environment.publishFact(effectiveExecutionTimeTerm, effectiveExecutionTime); 062 063 Context context = selectContext(selectionCriteria, facts.getFactMap(), executionOptions); 064 if (context == null) { 065 LOG.info("Failed to locate a Context for the given qualifiers, skipping rule engine execution: " + selectionCriteria.getContextQualifiers()); 066 return null; 067 } 068 context.execute(environment); 069 end = new DateTime(); 070 if (KLog.isEnabled(environment)){ 071 KLog.logResult(new TimingResult(ResultEvent.TIMING_EVENT, this, environment, start, end)); 072 } 073 return environment.getEngineResults(); 074 } 075 076 /** 077 * Return a {@link BasicExecutionEnvironment} using the given parameters 078 * @param selectionCriteria {@link SelectionCriteria} 079 * @param facts 080 * @param executionOptions {@link ExecutionOptions} 081 * @return {@link ExecutionEnvironment} created with the given parameters 082 */ 083 protected ExecutionEnvironment establishExecutionEnvironment(SelectionCriteria selectionCriteria, Map<Term, Object> facts, ExecutionOptions executionOptions) { 084 return new BasicExecutionEnvironment(selectionCriteria, facts, executionOptions, new TermResolutionEngineImpl()); 085 } 086 087 /** 088 * Load a Context from the contextProvider using the given parameters 089 * @see ContextProvider loadContext 090 * @param selectionCriteria 091 * @param facts 092 * @param executionOptions 093 * @return {@link Context} 094 * @throws IllegalStateException if the contextProvider is null; 095 */ 096 protected Context selectContext(SelectionCriteria selectionCriteria, Map<Term, Object> facts, ExecutionOptions executionOptions) { 097 if (contextProvider == null) { 098 throw new IllegalStateException("No ContextProvider was configured."); 099 } 100 return contextProvider.loadContext(selectionCriteria, facts, executionOptions); 101 } 102 103 /** 104 * Set the {@link ContextProvider} 105 * @param contextProvider to loadContext from. 106 */ 107 public void setContextProvider(ContextProvider contextProvider) { 108 this.contextProvider = contextProvider; 109 } 110 111 }