/** * Copyright (c) 1997, 2015 by ProSyst Software GmbH and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ package org.eclipse.smarthome.automation.core.internal; import java.util.Map; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import org.eclipse.smarthome.automation.Rule; import org.eclipse.smarthome.automation.Trigger; import org.eclipse.smarthome.automation.handler.RuleEngineCallback; /** * This class is implementation of {@link RuleEngineCallback} used by the {@link Trigger}s to notify rule engine about * appearing of new triggered data. There is one and only one {@link RuleEngineCallback} per Rule and it is used by all * rule's {@link Trigger}s. * * @author Yordan Mihaylov - Initial Contribution * @author Kai Kreuzer - improved stability */ public class RuleEngineCallbackImpl implements RuleEngineCallback { private RuntimeRule r; private ExecutorService executor; private Future<?> future; private RuleEngine re; protected RuleEngineCallbackImpl(RuleEngine re, RuntimeRule r) { this.re = re; this.r = r; executor = Executors.newSingleThreadExecutor(); } @Override public void triggered(Trigger trigger, Map<String, ?> outputs) { synchronized (this) { if (executor == null) { return; } future = executor.submit(new TriggerData(trigger, outputs)); } re.logger.debug("The trigger '{}' of rule '{}' is triggered.", trigger.getId(), r.getUID()); } public Rule getRule() { return r; } public boolean isRunning() { Future<?> future = this.future; return future == null || !future.isDone(); } class TriggerData implements Runnable { private Trigger trigger; public Trigger getTrigger() { return trigger; } public Map<String, ?> getOutputs() { return outputs; } private Map<String, ?> outputs; public TriggerData(Trigger t, Map<String, ?> outputs) { this.trigger = t; this.outputs = outputs; } @Override public void run() { re.runRule(r, this); } } public void dispose() { synchronized (this) { executor.shutdownNow(); executor = null; } } }