| /******************************************************************************* |
| * 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.lang.ref.WeakReference; |
| import java.util.HashSet; |
| import java.util.Set; |
| |
| import org.eclipse.viatra2.framework.IFramework; |
| import org.eclipse.viatra2.framework.IMachineSetChangedListener; |
| import org.eclipse.viatra2.framework.properties.IViatraPropertyChangedListener; |
| import org.eclipse.viatra2.framework.properties.IViatraPropertyProvider; |
| import org.eclipse.viatra2.gtasm.patternmatcher.incremental.IncrementalPMPropertyProvider; |
| import org.eclipse.viatra2.gtasm.patternmatcher.incremental.rete.matcher.ReteEngine; |
| import org.eclipse.viatra2.gtasm.patternmatcher.incremental.rete.network.Receiver; |
| import org.eclipse.viatra2.gtasm.patternmatcher.incremental.rete.network.Supplier; |
| import org.eclipse.viatra2.gtasm.patternmatcher.incremental.rete.remote.Address; |
| import org.eclipse.viatra2.gtasm.patternmatcher.incremental.simple.SimpleReteBuilder; |
| import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.core.RuntimeAnnotation; |
| import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.core.RuntimeAnnotationElement; |
| import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.definitions.Machine; |
| import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.gt.GTPattern; |
| |
| |
| public class MachineListener implements IMachineSetChangedListener// Disconnectable |
| { |
| WeakReference<IFramework> fw; |
| ReteEngine<GTPattern> engine = null; |
| Set<Machine> sensitiveMachines; |
| int reteThreads; |
| |
| // public MachineListener(ReteEngine engine) { |
| public MachineListener(IFramework framework) { |
| this.fw = new WeakReference<IFramework>(framework); |
| this.sensitiveMachines = new HashSet<Machine>(); |
| |
| IViatraPropertyProvider provider = framework.getProperties() |
| .getProvider(IncrementalPMPropertyProvider.VIATRA_INCREMENTAL_PROVIDER_ID); |
| String threadStr = provider.getProperty(IncrementalPMPropertyProvider.PROP_THREADS); |
| setThreads(threadStr); |
| provider.addListener(new IViatraPropertyChangedListener() { |
| public void propertyChanged(String providerID, String propertyID, String oldVal, String newVal) { |
| if (providerID.equals(IncrementalPMPropertyProvider.VIATRA_INCREMENTAL_PROVIDER_ID) && |
| propertyID.equals(IncrementalPMPropertyProvider.PROP_THREADS)) |
| setThreads(newVal); |
| } |
| }); |
| |
| framework.addMachineSetListener(this); |
| for (Object machine : framework.getMachines()) |
| if (machine instanceof Machine) |
| processMachine((Machine)machine); |
| // engine.addDisconnectable(this); |
| } |
| |
| |
| |
| private void setThreads(String threadStr) { |
| // reteThreads option can only be influenced until the engine is created |
| if (engine == null) { |
| Integer threads = IncrementalPMPropertyProvider.interpretThreads(threadStr); |
| reteThreads = threads==null? 0 : threads; |
| } |
| } |
| |
| |
| |
| // public void disconnect() { |
| // fw.removeMachineSetListener(this); //<-- problematic b/c it is called in |
| // chain with machineRemoved() |
| // machineRemoved() -> engine.reset() -> disconnect() --> causes |
| // ConcurrentModificationException |
| // } |
| |
| public void registerPattern(GTPattern gtPattern) { |
| sensitiveMachines.add(gtPattern.getNamespace()); |
| } |
| |
| public void machineAdded(Object machine) { |
| // reteThreads option can only be influenced until the engine is created |
| if (engine == null && machine instanceof Machine) { |
| processMachine((Machine)machine); |
| } |
| } |
| |
| |
| |
| private void processMachine(Machine machine) { |
| for (Object annot: machine.getRuntimeAnnotations()) |
| { |
| RuntimeAnnotation runtimeAnnotation = (RuntimeAnnotation) annot; |
| if ("@incremental".equals(runtimeAnnotation.getAnnotationName().toLowerCase())) |
| for (Object el : runtimeAnnotation.getElements()) { |
| RuntimeAnnotationElement runtimeAnnotationElement = (RuntimeAnnotationElement)el; |
| String key = runtimeAnnotationElement.getKey().toLowerCase(); |
| if ("parallel".equals(key) || "threads".equals(key) ) { |
| String value = runtimeAnnotationElement.getValue(); |
| Integer threads = IncrementalPMPropertyProvider.interpretThreads(value); |
| if (threads != null) fw.get().getProperties().setRuntimeProperty( |
| IncrementalPMPropertyProvider.VIATRA_INCREMENTAL_PROVIDER_ID, |
| IncrementalPMPropertyProvider.PROP_THREADS, |
| value); |
| } |
| } |
| } |
| } |
| |
| public void machineRemoved(Object machine) { |
| // if our machine is removed, reset all RETEEngines |
| if (sensitiveMachines.contains(machine)) { |
| sensitiveMachines.remove(machine); |
| if (engine !=null) engine.reset(); |
| //initBuilder(); |
| } |
| } |
| |
| private void initEngine() { |
| IFramework framework = fw.get(); |
| VPMGTASMContext context = new VPMGTASMContext(framework); |
| this.engine = new ReteEngine<GTPattern>(context, reteThreads); |
| |
| ReteContainerGTASMBuildable buildable = new ReteContainerGTASMBuildable(engine, engine.getReteNet().getHeadContainer());// prerequisite: network, boundary |
| engine.setBuilder(new SimpleReteBuilder<Address<? extends Supplier>, Address<? extends Receiver>>(buildable, context)); // this.fw = engine.getFramework(); |
| } |
| |
| public ReteEngine<GTPattern> getEngine() { |
| if (engine ==null) initEngine(); |
| return engine; |
| } |
| |
| public void kill() { |
| if (engine !=null) engine.killEngine(); |
| fw = null; |
| sensitiveMachines = null; |
| } |
| |
| } |