| /***************************************************************************** |
| * Copyright (c) 2018 CEA LIST. |
| * |
| * |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * CEA LIST - Initial API and implementation |
| * |
| *****************************************************************************/ |
| package org.eclipse.papyrus.moka.ease.parametric; |
| |
| import java.text.SimpleDateFormat; |
| import java.util.ArrayList; |
| import java.util.Date; |
| import java.util.List; |
| |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.emf.transaction.RecordingCommand; |
| import org.eclipse.emf.transaction.TransactionalEditingDomain; |
| import org.eclipse.papyrus.moka.composites.CompositeStructuresExecutionEngine; |
| import org.eclipse.papyrus.moka.composites.Semantics.impl.Loci.LociL3.CS_Executor; |
| import org.eclipse.papyrus.moka.composites.interfaces.Semantics.CompositeStructures.StructuredClasses.ICS_Object; |
| import org.eclipse.papyrus.moka.ease.semantics.proxy.LoggedValue; |
| import org.eclipse.papyrus.moka.ease.semantics.proxy.MapProxy; |
| import org.eclipse.papyrus.moka.ease.semantics.proxy.ParametricInstanceSpecGenerator; |
| import org.eclipse.papyrus.moka.ease.semantics.proxy.ScriptProxy; |
| import org.eclipse.papyrus.moka.ease.semantics.proxy.TimeValue; |
| import org.eclipse.papyrus.moka.engine.IExecutionEngine; |
| import org.eclipse.papyrus.moka.fuml.Semantics.Classes.Kernel.IFeatureValue; |
| import org.eclipse.papyrus.moka.fuml.Semantics.Classes.Kernel.IObject_; |
| import org.eclipse.papyrus.moka.fuml.Semantics.Classes.Kernel.IValue; |
| import org.eclipse.papyrus.moka.fuml.Semantics.Loci.LociL1.ILocus; |
| import org.eclipse.papyrus.moka.fuml.Semantics.impl.Classes.Kernel.Object_; |
| import org.eclipse.papyrus.moka.fuml.Semantics.impl.Classes.Kernel.Reference; |
| import org.eclipse.papyrus.moka.parametric.semantics.ParametricConstructStrategy; |
| import org.eclipse.papyrus.moka.parametric.semantics.ParametricExecutionFactory; |
| import org.eclipse.papyrus.moka.parametric.semantics.ParametricLocus; |
| import org.eclipse.papyrus.moka.parametric.semantics.ParametricObject; |
| import org.eclipse.papyrus.moka.service.IMokaService; |
| import org.eclipse.papyrus.moka.service.MokaServiceRegistry; |
| import org.eclipse.uml2.uml.Class; |
| import org.eclipse.uml2.uml.InstanceSpecification; |
| import org.eclipse.uml2.uml.InstanceValue; |
| import org.eclipse.uml2.uml.Package; |
| import org.eclipse.uml2.uml.Slot; |
| import org.eclipse.uml2.uml.UMLFactory; |
| import org.eclipse.uml2.uml.ValueSpecification; |
| |
| public class QuietCausalParametricInterpreter extends CompositeStructuresExecutionEngine implements IExecutionEngine { |
| |
| private InstanceSpecification result; |
| private List<ParametricObject> objectsToEvalFirst; |
| private IObject_ object; |
| List<Double> time; |
| List<LoggedValue> log = new ArrayList<>(); |
| private MapProxy proxyObject; |
| |
| public QuietCausalParametricInterpreter() { |
| // nothing to do |
| } |
| |
| @Override |
| public ILocus initializeLocus() { |
| ILocus locus = new ParametricLocus(); |
| locus.setExecutor(new CS_Executor()); |
| locus.setFactory(new ParametricExecutionFactory()); |
| return locus; |
| } |
| |
| // Register semantic strategies available in the environment |
| @Override |
| protected void registerSemanticStrategies(ILocus locus) { |
| super.registerSemanticStrategies(locus); |
| locus.getFactory().setStrategy(new ParametricConstructStrategy()); |
| } |
| |
| @Override |
| public void start(IProgressMonitor monitor) { |
| if (!mode.equals(OperatingMode.QUIET)) { |
| // Initialize every service with the parameters of this particular run |
| MokaServiceRegistry registry = MokaServiceRegistry.getInstance(); |
| registry.loadServices(); |
| for (IMokaService service : registry.getAllServices()) { |
| service.init(this.launch, executionEntryPoint); |
| } |
| } |
| |
| if (this.executionEntryPoint != null && this.executionEntryPoint instanceof InstanceSpecification) { |
| initEngine(); |
| |
| // Launches the execution/evaluation |
| IObject_ o = this.evaluateInstanceSpecification((InstanceSpecification) this.executionEntryPoint); |
| // Serialize the object in the papyrus model as an instance spec |
| ValueSpecification v = o.specify(); |
| |
| result = ((InstanceValue) v).getInstance(); |
| } |
| } |
| |
| private void initEngine() { |
| |
| this.locus = this.initializeLocus(); |
| // initializes built-in primitive types |
| this.initializeBuiltInPrimitiveTypes(locus); |
| // Initializes opaque behavior executions |
| this.registerOpaqueBehaviorExecutions(locus); |
| // Initializes system services |
| this.registerSystemServices(locus); |
| // Initializes semantic strategies |
| this.registerSemanticStrategies(locus); |
| // Initializes arguments |
| this.initializeArguments(this.executionArgs); |
| |
| log.clear(); |
| |
| } |
| |
| public Object initEngine(Class constraintClass) { |
| ParametricInstanceSpecGenerator generator = new ParametricInstanceSpecGenerator( |
| UMLFactory.eINSTANCE.createPackage(), false); |
| executionEntryPoint = generator.generateInstanceSpecification(constraintClass); |
| initEngine(); |
| return ScriptProxy.getKernelAdapter() |
| .getProxyFor(constructObjects((InstanceSpecification) executionEntryPoint)); |
| |
| } |
| |
| public Object initEngine(InstanceSpecification instSpec) { |
| executionEntryPoint = instSpec; |
| initEngine(); |
| return ScriptProxy.getKernelAdapter() |
| .getProxyFor(constructObjects((InstanceSpecification) executionEntryPoint)); |
| |
| } |
| |
| |
| |
| /** |
| * Single step evaluation |
| * @return the root Object of the locus |
| */ |
| public IObject_ evaluate() { |
| if (this.containsParametricObjects(object)) { |
| for (ParametricObject o : objectsToEvalFirst) { |
| o.evaluate(); |
| } |
| } |
| if (object instanceof ParametricObject) { |
| ((ParametricObject) object).evaluate(); |
| } |
| |
| logValues(); |
| |
| return object; |
| |
| } |
| |
| /** |
| * Multiple steps evaluation |
| * @return the root Object of the locus |
| */ |
| public IObject_ evaluate(int steps) { |
| //we log initial values |
| logValues(); |
| for (int i = 0; i < steps; i++) { |
| evaluate(); |
| } |
| return object; |
| |
| } |
| |
| |
| /** |
| * Multiple steps evaluation |
| * @return the root Object of the locus |
| */ |
| public IObject_ evaluate(double startTime, double endTime, double dt) { |
| //we create a time value vector |
| TimeValue time = new TimeValue(startTime, dt); |
| log.add(time); |
| //we log initial values |
| logValues(); |
| |
| while (time.getValue() <= endTime) { |
| //evalue will call logValues, which automatically increments time |
| evaluate(); |
| } |
| return object; |
| |
| } |
| |
| |
| /** |
| * Enables the recording of a given variable in the locus |
| * @param variablePath : the "." separated feature path to the variable to log |
| * @param alias : an alias for the variable name |
| */ |
| public void log(String variablePath, String alias) { |
| log.add(new LoggedValue(variablePath, alias, proxyObject)); |
| } |
| |
| /** |
| * Enables the recording of a given variable in the locus, using the variable path as default alias |
| * @param variablePath : the "." separated feature path to the variable to log |
| */ |
| public void log(String variablePath) { |
| log(variablePath, variablePath); |
| } |
| |
| /** |
| * |
| * @return the log containing logged values |
| */ |
| public List<LoggedValue> getLog() { |
| return log; |
| } |
| |
| |
| |
| /** |
| * This method forces the recording of the current value for all logged values |
| */ |
| public void logValues() { |
| |
| for (LoggedValue loggedValue : log) { |
| loggedValue.logValue(); |
| } |
| |
| } |
| |
| private IObject_ constructObjects(InstanceSpecification instance) { |
| object = this.locus.instantiate((Class) instance.getClassifiers().get(0)); |
| ParametricConstructStrategy strategy = (ParametricConstructStrategy) this.locus.getFactory() |
| .getStrategy("constructStrategy"); //$NON-NLS-1$ |
| strategy.constructObject((ICS_Object) object, (Class) object.getTypes().get(0)); |
| if (object instanceof ParametricObject) { |
| ((ParametricObject) object).setSourceInstanceSpec(instance); |
| } |
| List<Slot> instanceSlots = instance.getSlots(); |
| for (int i = 0; i < instanceSlots.size(); i++) { |
| Slot slot = instanceSlots.get(i); |
| List<IValue> values = new ArrayList<IValue>(); |
| List<ValueSpecification> slotValues = slot.getValues(); |
| for (int j = 0; j < slotValues.size(); j++) { |
| ValueSpecification slotValue = slotValues.get(j); |
| values.add(this.locus.getExecutor().evaluate(slotValue)); |
| } |
| object.setFeatureValue(slot.getDefiningFeature(), values, 0); |
| } |
| |
| objectsToEvalFirst = this.computeEvalList((Object_) object); |
| |
| proxyObject = (MapProxy) ScriptProxy.getKernelAdapter().getProxyFor(object); |
| return object; |
| } |
| |
| public IObject_ evaluateInstanceSpecification(InstanceSpecification instance) { |
| |
| if (instance.getClassifiers().isEmpty()) |
| return null; |
| constructObjects(instance); |
| evaluate(); |
| |
| return object; |
| } |
| |
| protected boolean containsParametricObjects(IObject_ object) { |
| if (object instanceof ParametricObject) { |
| return true; |
| } |
| for (IFeatureValue featureValues : object.getFeatureValues()) { |
| for (IValue v : featureValues.getValues()) { |
| if (v instanceof Reference) { |
| IObject_ obj = ((Reference) v).getReferent(); |
| if (obj instanceof ParametricObject) { |
| return true; |
| } |
| return containsParametricObjects(obj); |
| } |
| } |
| } |
| return false; |
| } |
| |
| protected List<ParametricObject> computeEvalList(Object_ object) { |
| List<ParametricObject> objectsToEvalFirst = new ArrayList<ParametricObject>(); |
| for (IFeatureValue featureValues : object.getFeatureValues()) { |
| for (IValue v : featureValues.getValues()) { |
| if (v instanceof Reference) { |
| IObject_ obj = ((Reference) v).getReferent(); |
| if (obj instanceof ParametricObject) { |
| objectsToEvalFirst.add((ParametricObject) obj); |
| } |
| objectsToEvalFirst.addAll(0, this.computeEvalList((Object_) obj)); |
| } |
| } |
| } |
| return objectsToEvalFirst; |
| } |
| |
| protected class SerializeComputationResultCommand extends RecordingCommand { |
| |
| private final InstanceSpecification computed; |
| private final InstanceSpecification sourceInstanceSpec; |
| |
| public SerializeComputationResultCommand(TransactionalEditingDomain domain, InstanceSpecification computed, |
| InstanceSpecification sourceInstanceSpec) { |
| super(domain); |
| this.computed = computed; |
| this.sourceInstanceSpec = sourceInstanceSpec; |
| } |
| |
| private boolean serializeComputationResult(InstanceSpecification computed, InstanceSpecification source) { |
| // For serialization, a new package is created |
| // New instance specifications are created (even if instance specifications |
| // related to the new instance spec could be reused) |
| Package nearestPackage = source.getNearestPackage(); |
| SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// dd/MM/yyyy //$NON-NLS-1$ |
| Date now = new Date(); |
| String strDate = sdfDate.format(now); |
| Package resultPackage = nearestPackage.createNestedPackage("" + source.getName() + " - Exec - " + strDate); //$NON-NLS-1$ //$NON-NLS-2$ |
| |
| List<InstanceSpecification> toBeAdded = new ArrayList<InstanceSpecification>(); |
| toBeAdded.add(computed); |
| while (!toBeAdded.isEmpty()) { |
| InstanceSpecification instance = toBeAdded.remove(0); |
| if (instance.getModel() == null) { |
| resultPackage.getPackagedElements().add(instance); |
| // instance.setName(! instance.getClassifiers().isEmpty() ? |
| // instance.getClassifiers().get(0).getName() : "null") ; |
| } |
| for (Slot s : instance.getSlots()) { |
| for (ValueSpecification v : s.getValues()) { |
| if (v instanceof InstanceValue) { |
| toBeAdded.add(((InstanceValue) v).getInstance()); |
| } |
| } |
| } |
| } |
| |
| computed.setName("" + sourceInstanceSpec.getName()); //$NON-NLS-1$ |
| return true; |
| } |
| |
| @Override |
| protected void doExecute() { |
| serializeComputationResult(computed, sourceInstanceSpec); |
| } |
| } |
| |
| public InstanceSpecification getResult() { |
| return result; |
| } |
| |
| |
| |
| |
| |
| |
| |
| } |