package org.drools.util.concurrent; import org.drools.FactHandle; import org.drools.WorkingMemory; import org.drools.spi.AgendaFilter; import org.drools.spi.AgendaGroup; import edu.emory.mathcs.backport.java.util.Queue; import edu.emory.mathcs.backport.java.util.concurrent.Callable; import edu.emory.mathcs.backport.java.util.concurrent.Executor; import edu.emory.mathcs.backport.java.util.concurrent.Executors; import edu.emory.mathcs.backport.java.util.concurrent.Future; import edu.emory.mathcs.backport.java.util.concurrent.FutureTask; import edu.emory.mathcs.backport.java.util.concurrent.LinkedBlockingQueue; public class ConcurrentWorkingMemory { private final WorkingMemory workingMemory; //Gratitously lifted from jdk1.5 javadoc for Executor (SerialExecutor example) private final Executor executor = new Executor() { final Queue tasks = new LinkedBlockingQueue(); final Executor executor = Executors.newSingleThreadExecutor(); Runnable active; public synchronized void execute(final Runnable r) { tasks.offer(new Runnable() { public void run() { try { r.run(); } finally { scheduleNext(); } } }); if (active == null) { scheduleNext(); } } protected synchronized void scheduleNext() { if ((active = (Runnable)tasks.poll()) != null) { executor.execute(active); } } }; public ConcurrentWorkingMemory(WorkingMemory workingMemory) { super(); this.workingMemory = workingMemory; } private Future go(Callable callable) { FutureTask future = new FutureTask(callable); executor.execute(future); return future; } public Future fireAllRules() { return go(new Callable() { public Object call() { workingMemory.fireAllRules(); return null; } }); } public Future fireAllRules(final AgendaFilter agendaFilter) { return go(new Callable() { public Object call() { workingMemory.fireAllRules(agendaFilter); return null; } }); } public Future getObject(final FactHandle handle) { return go(new Callable() { public Object call() { return workingMemory.getObject(handle); } }); } public Future getFactHandle(final Object object) { return go(new Callable() { public Object call() { return workingMemory.getFactHandle(object); } }); } public Future getObjects() { return go(new Callable() { public Object call() { return workingMemory.getObjects(); } }); } public Future getObjects(final Class objectClass) { return go(new Callable() { public Object call() { return workingMemory.getObjects(objectClass); } }); } public Future getFocus() { return go(new Callable() { public Object call() { return workingMemory.getFocus(); } }); } public Future setFocus(final String focus) { return go(new Callable() { public Object call() { workingMemory.setFocus(focus); return null; } }); } public Future setFocus(final AgendaGroup focus) { return go(new Callable() { public Object call() { workingMemory.setFocus(focus); return null; } }); } public Future getFactHandles() { return go(new Callable() { public Object call() { return workingMemory.getFactHandles(); } }); } public Future containsObject(final FactHandle handle) { return go(new Callable() { public Object call() { return new Boolean(workingMemory.containsObject(handle)); } }); } public Future assertObject(final Object object) { return go(new Callable() { public Object call() { return workingMemory.assertObject(object); } }); } public Future assertObject(final Object object, final boolean dynamic) { return go(new Callable() { public Object call() { return workingMemory.assertObject(object, dynamic); } }); } public Future getQueryResults(final String query) { return go(new Callable() { public Object call() { return workingMemory.getQueryResults(query); } }); } public Future retractObject(final FactHandle handle) { return go(new Callable() { public Object call() { workingMemory.retractObject(handle); return null; } }); } public Future modifyObject(final FactHandle handle, final Object object) { return go(new Callable() { public Object call() { workingMemory.modifyObject(handle, object); return null; } }); } public Future clearAgenda() { return go(new Callable() { public Object call() { workingMemory.clearAgenda(); return null; } }); } public Future dispose() { return go(new Callable() { public Object call() { workingMemory.dispose(); return null; } }); } }