package com.sctrcd.buspassws; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.kie.api.runtime.KieContainer; import org.kie.api.runtime.KieSession; import org.kie.api.runtime.ObjectFilter; import org.kie.api.runtime.rule.FactHandle; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.sctrcd.buspassws.facts.BusPass; import com.sctrcd.buspassws.facts.Person; @Service public class BusPassService { private static Logger log = LoggerFactory.getLogger(BusPassService.class); private final KieContainer kieContainer; @Autowired public BusPassService(KieContainer kieContainer) { log.info("Initialising a new bus pass session."); this.kieContainer = kieContainer; } /** * Create a new session, insert a person's details and fire rules to * determine what kind of bus pass is to be issued. */ public BusPass getBusPass(Person person) { KieSession kieSession = kieContainer.newKieSession("BusPassSession"); kieSession.insert(person); kieSession.fireAllRules(); BusPass busPass = findBusPass(kieSession); kieSession.dispose(); return busPass; } /** * Search the {@link KieSession} for bus passes. */ private BusPass findBusPass(KieSession kieSession) { // Find all BusPass facts and 1st generation child classes of BusPass. ObjectFilter busPassFilter = new ObjectFilter() { @Override public boolean accept(Object object) { if (BusPass.class.equals(object.getClass())) return true; if (BusPass.class.equals(object.getClass().getSuperclass())) return true; return false; } }; // printFactsMessage(kieSession); List<BusPass> facts = new ArrayList<BusPass>(); for (FactHandle handle : kieSession.getFactHandles(busPassFilter)) { facts.add((BusPass) kieSession.getObject(handle)); } if (facts.size() == 0) { return null; } // Assumes that the rules will always be generating a single bus pass. return facts.get(0); } /** * Print out details of all facts in working memory. * Handy for debugging. */ @SuppressWarnings("unused") private void printFactsMessage(KieSession kieSession) { Collection<FactHandle> allHandles = kieSession.getFactHandles(); String msg = "\nAll facts:\n"; for (FactHandle handle : allHandles) { msg += " " + kieSession.getObject(handle) + "\n"; } System.out.println(msg); } }