| /******************************************************************************* |
| * Copyright (c) 2004-2008 Gabor Bergmann 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: |
| * Gabor Bergmann - initial API and implementation |
| *******************************************************************************/ |
| |
| package org.eclipse.viatra2.gtasm.patternmatcher.incremental.adapters; |
| |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.LinkedList; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import org.eclipse.emf.common.util.EList; |
| import org.eclipse.viatra2.gtasm.interpreter.executionEnvironment.ASMFunctionContent; |
| import org.eclipse.viatra2.gtasm.interpreter.executionEnvironment.ASMFunctionContentChangeListener; |
| import org.eclipse.viatra2.gtasm.patternmatcher.incremental.rete.boundary.IPredicateTraceListener; |
| import org.eclipse.viatra2.gtasm.patternmatcher.incremental.rete.boundary.PredicateEvaluatorNode; |
| import org.eclipse.viatra2.gtasm.patternmatcher.incremental.rete.boundary.ReteBoundary; |
| import org.eclipse.viatra2.gtasm.patternmatcher.incremental.rete.matcher.ReteEngine; |
| import org.eclipse.viatra2.gtasm.patternmatcher.incremental.rete.tuple.FlatTuple; |
| import org.eclipse.viatra2.gtasm.patternmatcher.incremental.rete.tuple.Tuple; |
| import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.definitions.ASMFunction; |
| |
| |
| /** |
| * Registering/unregistering is synchronized, as well as change notification |
| * sending. Reason: thread safety of Registering/unregistering and message |
| * sending to registered ones |
| * |
| * @author Gabor Bergmann |
| * |
| */ |
| public class ASMFunctionListener implements ASMFunctionContentChangeListener, IPredicateTraceListener { |
| // each registered tuple consists of (a) the ASM function (b) the actual |
| // parameter sequence |
| protected Map<Tuple, Set<PredicateEvaluatorNode>> asmSensitiveTerms; |
| protected ReteEngine<?> engine; |
| protected ReteBoundary<?> boundary; |
| |
| /** |
| * Prerequisite: disconnectables |
| * |
| * @param engine |
| */ |
| public ASMFunctionListener(ReteEngine<?> engine) { |
| this.engine = engine; |
| this.boundary = engine.getBoundary(); |
| this.asmSensitiveTerms = new HashMap<Tuple, Set<PredicateEvaluatorNode>>(); |
| ASMFunctionContent.getInstance().addListener(null, this); |
| engine.addDisconnectable(this); |
| } |
| |
| public void disconnect() { |
| asmSensitiveTerms.clear(); |
| ASMFunctionContent.getInstance().removeListener(null, this); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.viatra2.gtasm.patternmatcher.incremental.adapters.IPredicateTraceListener#registerASMSensitiveTerm(org.eclipse.viatra2.gtasm.patternmatcher.incremental.rete.tuple.Tuple, org.eclipse.viatra2.gtasm.patternmatcher.incremental.adapters.PredicateEvaluatorNode) |
| */ |
| public synchronized void registerSensitiveTrace(Tuple trace, |
| PredicateEvaluatorNode node) { |
| Set<PredicateEvaluatorNode> nodes = asmSensitiveTerms.get(trace); |
| if (nodes == null) { |
| nodes = new HashSet<PredicateEvaluatorNode>(); |
| asmSensitiveTerms.put(trace, nodes); |
| } |
| nodes.add(node); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.viatra2.gtasm.patternmatcher.incremental.adapters.IPredicateTraceListener#unregisterASMSensitiveTerm(org.eclipse.viatra2.gtasm.patternmatcher.incremental.rete.tuple.Tuple, org.eclipse.viatra2.gtasm.patternmatcher.incremental.adapters.PredicateEvaluatorNode) |
| */ |
| public synchronized void unregisterSensitiveTrace(Tuple trace, |
| PredicateEvaluatorNode node) { |
| Set<PredicateEvaluatorNode> nodes = asmSensitiveTerms.get(trace); |
| nodes.remove(node); |
| if (nodes.isEmpty()) { |
| asmSensitiveTerms.remove(trace); |
| } |
| } |
| |
| public void valueChanged(ASMFunction f, EList<Object> key, Object newValue) { |
| //System.out.println("value changed for key:"+key.toString()+", value: " |
| // +newValue.toString()); |
| |
| Object[] traceElements = new Object[key.size() + 1]; |
| int k = 0; |
| traceElements[k++] = f; |
| for (Object o : key) |
| traceElements[k++] = o; |
| Tuple trace = new FlatTuple(traceElements); |
| |
| synchronized (this) { |
| Set<PredicateEvaluatorNode> nodes = asmSensitiveTerms.get(trace); |
| if (nodes != null) { |
| // copy to avoid concurrency exceptions |
| LinkedList<PredicateEvaluatorNode> nodesCopy = new LinkedList<PredicateEvaluatorNode>( |
| nodes); |
| |
| for (PredicateEvaluatorNode node : nodesCopy) { |
| boundary.notifyEvaluator( |
| node.getAsmFunctionTraceNotifier(), trace); |
| } |
| } |
| } |
| } |
| |
| } |