/*******************************************************************************
* Copyright (c) 2010-2012, Tamas Szabo, Abel Hegedus, Istvan Rath and Daniel Varro
* 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
*
* Contributors:
* Tamas Szabo, Abel Hegedus - initial API and implementation
*******************************************************************************/
package org.eclipse.incquery.runtime.triggerengine.api;
import java.lang.ref.WeakReference;
import java.util.Map;
import java.util.WeakHashMap;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.incquery.runtime.api.EngineManager;
import org.eclipse.incquery.runtime.api.IncQueryEngine;
import org.eclipse.incquery.runtime.exception.IncQueryException;
import org.eclipse.incquery.runtime.triggerengine.specific.DefaultRuleFactory;
/**
* The AbstractRule engine extends the functionality of EMF-IncQuery by providing the basic facilities to create
* transformation rules. A transformation rule consists of the precondition being an EMF-IncQuery pattern and the
* postcondition defined as a portion of an arbitrary Java code.
*
* <p>
* This class can be used to instantiate and lookup Agendas for a specific {@link Notifier} or {@link IncQueryEngine}
* instance. The Agenda acts as an up-to-date collection of the fireable rule activations (similar to the term known
* from the context of rule based expert systems).
*
* @author Tamas Szabo
*
*/
public class RuleEngine {
private static RuleEngine instance;
private Map<IncQueryEngine, WeakReference<IAgenda>> agendaMap;
private IRuleFactory defaultRuleFactory;
public static synchronized RuleEngine getInstance() {
if (instance == null) {
instance = new RuleEngine();
}
return instance;
}
protected RuleEngine() {
this.agendaMap = new WeakHashMap<IncQueryEngine, WeakReference<IAgenda>>();
this.defaultRuleFactory = new DefaultRuleFactory();
}
public IAgenda getOrCreateAgenda(Notifier notifier) {
return getOrCreateAgenda(notifier, false);
}
public IAgenda getOrCreateAgenda(Notifier notifier, boolean allowMultipleFiring) {
IncQueryEngine engine;
try {
engine = EngineManager.getInstance().getIncQueryEngine(notifier);
return getOrCreateAgenda(engine, allowMultipleFiring);
} catch (IncQueryException e) {
return null;
}
}
public IAgenda getOrCreateAgenda(IncQueryEngine engine) {
return getOrCreateAgenda(engine, false);
}
public IAgenda getOrCreateAgenda(IncQueryEngine engine, boolean allowMultipleFiring) {
IAgenda agenda = getAgenda(engine);
if (agenda == null) {
Agenda newAgenda = new Agenda(engine, allowMultipleFiring);
newAgenda.setRuleFactory(defaultRuleFactory);
agenda = newAgenda;
agendaMap.put(engine, new WeakReference<IAgenda>(agenda));
}
return agenda;
}
private IAgenda getAgenda(IncQueryEngine iqEngine) {
WeakReference<IAgenda> agendaRef = agendaMap.get(iqEngine);
if (agendaRef != null) {
return agendaRef.get();
} else {
return null;
}
}
}