/** * Copyright (c) 2012-2016 Marsha Chechik, Alessio Di Sandro, Michalis Famelis, * Rick Salay. * 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: * Alessio Di Sandro - Implementation. */ package edu.toronto.cs.se.mmint.mid.operator.impl; import java.io.File; import java.io.FileInputStream; import java.lang.reflect.InvocationTargetException; import java.net.URL; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import java.util.ArrayList; import java.util.Collection; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; import java.util.jar.JarFile; import java.util.stream.Collectors; import java.util.stream.Stream; import java.util.zip.ZipEntry; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.FileLocator; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.common.notify.NotificationChain; import org.eclipse.emf.common.util.BasicEList; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.InternalEObject; import org.eclipse.emf.ecore.impl.ENotificationImpl; import org.eclipse.emf.ecore.util.EObjectContainmentEList; import org.eclipse.emf.ecore.util.InternalEList; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; import org.osgi.framework.Bundle; import edu.toronto.cs.se.mmint.MMINT; import edu.toronto.cs.se.mmint.MMINTConstants; import edu.toronto.cs.se.mmint.MMINTException; import edu.toronto.cs.se.mmint.MIDTypeHierarchy; import edu.toronto.cs.se.mmint.MIDTypeRegistry; import edu.toronto.cs.se.mmint.mid.ExtendibleElement; import edu.toronto.cs.se.mmint.mid.GenericElement; import edu.toronto.cs.se.mmint.mid.MID; import edu.toronto.cs.se.mmint.mid.MIDLevel; import edu.toronto.cs.se.mmint.mid.MIDPackage; import edu.toronto.cs.se.mmint.mid.Model; import edu.toronto.cs.se.mmint.mid.ModelEndpoint; import edu.toronto.cs.se.mmint.mid.impl.GenericElementImpl; import edu.toronto.cs.se.mmint.mid.operator.ConversionOperator; import edu.toronto.cs.se.mmint.mid.operator.GenericEndpoint; import edu.toronto.cs.se.mmint.mid.operator.Operator; import edu.toronto.cs.se.mmint.mid.operator.OperatorConstraint; import edu.toronto.cs.se.mmint.mid.operator.OperatorConstraintParameter; import edu.toronto.cs.se.mmint.mid.operator.OperatorConstraintRule; import edu.toronto.cs.se.mmint.mid.operator.OperatorFactory; import edu.toronto.cs.se.mmint.mid.operator.OperatorGeneric; import edu.toronto.cs.se.mmint.mid.operator.OperatorInput; import edu.toronto.cs.se.mmint.mid.operator.OperatorPackage; import edu.toronto.cs.se.mmint.mid.reasoning.MIDConstraintChecker; import edu.toronto.cs.se.mmint.mid.relationship.ModelRel; import edu.toronto.cs.se.mmint.mid.ui.MIDDialogs; import edu.toronto.cs.se.mmint.mid.utils.FileUtils; import edu.toronto.cs.se.mmint.mid.utils.MIDOperatorIOUtils; import edu.toronto.cs.se.mmint.mid.utils.MIDRegistry; /** * <!-- begin-user-doc --> * An implementation of the model object '<em><b>Operator</b></em>'. * <!-- end-user-doc --> * <p> * The following features are implemented: * </p> * <ul> * <li>{@link edu.toronto.cs.se.mmint.mid.operator.impl.OperatorImpl#getInputs <em>Inputs</em>}</li> * <li>{@link edu.toronto.cs.se.mmint.mid.operator.impl.OperatorImpl#getOutputs <em>Outputs</em>}</li> * <li>{@link edu.toronto.cs.se.mmint.mid.operator.impl.OperatorImpl#getGenerics <em>Generics</em>}</li> * <li>{@link edu.toronto.cs.se.mmint.mid.operator.impl.OperatorImpl#getInputSubdir <em>Input Subdir</em>}</li> * <li>{@link edu.toronto.cs.se.mmint.mid.operator.impl.OperatorImpl#getPreviousOperator <em>Previous Operator</em>}</li> * <li>{@link edu.toronto.cs.se.mmint.mid.operator.impl.OperatorImpl#isUpdateMID <em>Update MID</em>}</li> * <li>{@link edu.toronto.cs.se.mmint.mid.operator.impl.OperatorImpl#getExecutionTime <em>Execution Time</em>}</li> * <li>{@link edu.toronto.cs.se.mmint.mid.operator.impl.OperatorImpl#isCommutative <em>Commutative</em>}</li> * </ul> * * @generated */ public class OperatorImpl extends GenericElementImpl implements Operator { /** * The cached value of the '{@link #getInputs() <em>Inputs</em>}' containment reference list. * <!-- begin-user-doc --> * <!-- end-user-doc --> * @see #getInputs() * @generated * @ordered */ protected EList<ModelEndpoint> inputs; /** * The cached value of the '{@link #getOutputs() <em>Outputs</em>}' containment reference list. * <!-- begin-user-doc --> * <!-- end-user-doc --> * @see #getOutputs() * @generated * @ordered */ protected EList<ModelEndpoint> outputs; /** * The cached value of the '{@link #getGenerics() <em>Generics</em>}' containment reference list. * <!-- begin-user-doc --> * <!-- end-user-doc --> * @see #getGenerics() * @generated * @ordered */ protected EList<GenericEndpoint> generics; /** * The default value of the '{@link #getInputSubdir() <em>Input Subdir</em>}' attribute. * <!-- begin-user-doc --> * <!-- end-user-doc --> * @see #getInputSubdir() * @generated * @ordered */ protected static final String INPUT_SUBDIR_EDEFAULT = null; /** * The cached value of the '{@link #getInputSubdir() <em>Input Subdir</em>}' attribute. * <!-- begin-user-doc --> * <!-- end-user-doc --> * @see #getInputSubdir() * @generated * @ordered */ protected String inputSubdir = INPUT_SUBDIR_EDEFAULT; /** * The cached value of the '{@link #getPreviousOperator() <em>Previous Operator</em>}' reference. * <!-- begin-user-doc --> * <!-- end-user-doc --> * @see #getPreviousOperator() * @generated * @ordered */ protected Operator previousOperator; /** * The default value of the '{@link #isUpdateMID() <em>Update MID</em>}' attribute. * <!-- begin-user-doc --> * <!-- end-user-doc --> * @see #isUpdateMID() * @generated * @ordered */ protected static final boolean UPDATE_MID_EDEFAULT = false; /** * The cached value of the '{@link #isUpdateMID() <em>Update MID</em>}' attribute. * <!-- begin-user-doc --> * <!-- end-user-doc --> * @see #isUpdateMID() * @generated * @ordered */ protected boolean updateMID = UPDATE_MID_EDEFAULT; /** * The default value of the '{@link #getExecutionTime() <em>Execution Time</em>}' attribute. * <!-- begin-user-doc --> * <!-- end-user-doc --> * @see #getExecutionTime() * @generated * @ordered */ protected static final long EXECUTION_TIME_EDEFAULT = 0L; /** * The cached value of the '{@link #getExecutionTime() <em>Execution Time</em>}' attribute. * <!-- begin-user-doc --> * <!-- end-user-doc --> * @see #getExecutionTime() * @generated * @ordered */ protected long executionTime = EXECUTION_TIME_EDEFAULT; /** * The default value of the '{@link #isCommutative() <em>Commutative</em>}' attribute. * <!-- begin-user-doc --> * <!-- end-user-doc --> * @see #isCommutative() * @generated * @ordered */ protected static final boolean COMMUTATIVE_EDEFAULT = false; /** * The cached value of the '{@link #isCommutative() <em>Commutative</em>}' attribute. * <!-- begin-user-doc --> * <!-- end-user-doc --> * @see #isCommutative() * @generated * @ordered */ protected boolean commutative = COMMUTATIVE_EDEFAULT; /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated NOT */ public OperatorImpl() { super(); } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ @Override protected EClass eStaticClass() { return OperatorPackage.Literals.OPERATOR; } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public EList<ModelEndpoint> getInputs() { if (inputs == null) { inputs = new EObjectContainmentEList<ModelEndpoint>(ModelEndpoint.class, this, OperatorPackage.OPERATOR__INPUTS); } return inputs; } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public EList<ModelEndpoint> getOutputs() { if (outputs == null) { outputs = new EObjectContainmentEList<ModelEndpoint>(ModelEndpoint.class, this, OperatorPackage.OPERATOR__OUTPUTS); } return outputs; } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public EList<GenericEndpoint> getGenerics() { if (generics == null) { generics = new EObjectContainmentEList<GenericEndpoint>(GenericEndpoint.class, this, OperatorPackage.OPERATOR__GENERICS); } return generics; } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public String getInputSubdir() { return inputSubdir; } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public void setInputSubdir(String newInputSubdir) { String oldInputSubdir = inputSubdir; inputSubdir = newInputSubdir; if (eNotificationRequired()) eNotify(new ENotificationImpl(this, Notification.SET, OperatorPackage.OPERATOR__INPUT_SUBDIR, oldInputSubdir, inputSubdir)); } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public Operator getPreviousOperator() { if (previousOperator != null && previousOperator.eIsProxy()) { InternalEObject oldPreviousOperator = (InternalEObject)previousOperator; previousOperator = (Operator)eResolveProxy(oldPreviousOperator); if (previousOperator != oldPreviousOperator) { if (eNotificationRequired()) eNotify(new ENotificationImpl(this, Notification.RESOLVE, OperatorPackage.OPERATOR__PREVIOUS_OPERATOR, oldPreviousOperator, previousOperator)); } } return previousOperator; } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public Operator basicGetPreviousOperator() { return previousOperator; } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public void setPreviousOperator(Operator newPreviousOperator) { Operator oldPreviousOperator = previousOperator; previousOperator = newPreviousOperator; if (eNotificationRequired()) eNotify(new ENotificationImpl(this, Notification.SET, OperatorPackage.OPERATOR__PREVIOUS_OPERATOR, oldPreviousOperator, previousOperator)); } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public boolean isUpdateMID() { return updateMID; } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public void setUpdateMID(boolean newUpdateMID) { boolean oldUpdateMID = updateMID; updateMID = newUpdateMID; if (eNotificationRequired()) eNotify(new ENotificationImpl(this, Notification.SET, OperatorPackage.OPERATOR__UPDATE_MID, oldUpdateMID, updateMID)); } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public long getExecutionTime() { return executionTime; } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public void setExecutionTime(long newExecutionTime) { long oldExecutionTime = executionTime; executionTime = newExecutionTime; if (eNotificationRequired()) eNotify(new ENotificationImpl(this, Notification.SET, OperatorPackage.OPERATOR__EXECUTION_TIME, oldExecutionTime, executionTime)); } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public boolean isCommutative() { return commutative; } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public void setCommutative(boolean newCommutative) { boolean oldCommutative = commutative; commutative = newCommutative; if (eNotificationRequired()) eNotify(new ENotificationImpl(this, Notification.SET, OperatorPackage.OPERATOR__COMMUTATIVE, oldCommutative, commutative)); } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ @Override public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) { switch (featureID) { case OperatorPackage.OPERATOR__INPUTS: return ((InternalEList<?>)getInputs()).basicRemove(otherEnd, msgs); case OperatorPackage.OPERATOR__OUTPUTS: return ((InternalEList<?>)getOutputs()).basicRemove(otherEnd, msgs); case OperatorPackage.OPERATOR__GENERICS: return ((InternalEList<?>)getGenerics()).basicRemove(otherEnd, msgs); } return super.eInverseRemove(otherEnd, featureID, msgs); } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ @Override public Object eGet(int featureID, boolean resolve, boolean coreType) { switch (featureID) { case OperatorPackage.OPERATOR__INPUTS: return getInputs(); case OperatorPackage.OPERATOR__OUTPUTS: return getOutputs(); case OperatorPackage.OPERATOR__GENERICS: return getGenerics(); case OperatorPackage.OPERATOR__INPUT_SUBDIR: return getInputSubdir(); case OperatorPackage.OPERATOR__PREVIOUS_OPERATOR: if (resolve) return getPreviousOperator(); return basicGetPreviousOperator(); case OperatorPackage.OPERATOR__UPDATE_MID: return isUpdateMID(); case OperatorPackage.OPERATOR__EXECUTION_TIME: return getExecutionTime(); case OperatorPackage.OPERATOR__COMMUTATIVE: return isCommutative(); } return super.eGet(featureID, resolve, coreType); } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ @SuppressWarnings("unchecked") @Override public void eSet(int featureID, Object newValue) { switch (featureID) { case OperatorPackage.OPERATOR__INPUTS: getInputs().clear(); getInputs().addAll((Collection<? extends ModelEndpoint>)newValue); return; case OperatorPackage.OPERATOR__OUTPUTS: getOutputs().clear(); getOutputs().addAll((Collection<? extends ModelEndpoint>)newValue); return; case OperatorPackage.OPERATOR__GENERICS: getGenerics().clear(); getGenerics().addAll((Collection<? extends GenericEndpoint>)newValue); return; case OperatorPackage.OPERATOR__INPUT_SUBDIR: setInputSubdir((String)newValue); return; case OperatorPackage.OPERATOR__PREVIOUS_OPERATOR: setPreviousOperator((Operator)newValue); return; case OperatorPackage.OPERATOR__UPDATE_MID: setUpdateMID((Boolean)newValue); return; case OperatorPackage.OPERATOR__EXECUTION_TIME: setExecutionTime((Long)newValue); return; case OperatorPackage.OPERATOR__COMMUTATIVE: setCommutative((Boolean)newValue); return; } super.eSet(featureID, newValue); } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ @Override public void eUnset(int featureID) { switch (featureID) { case OperatorPackage.OPERATOR__INPUTS: getInputs().clear(); return; case OperatorPackage.OPERATOR__OUTPUTS: getOutputs().clear(); return; case OperatorPackage.OPERATOR__GENERICS: getGenerics().clear(); return; case OperatorPackage.OPERATOR__INPUT_SUBDIR: setInputSubdir(INPUT_SUBDIR_EDEFAULT); return; case OperatorPackage.OPERATOR__PREVIOUS_OPERATOR: setPreviousOperator((Operator)null); return; case OperatorPackage.OPERATOR__UPDATE_MID: setUpdateMID(UPDATE_MID_EDEFAULT); return; case OperatorPackage.OPERATOR__EXECUTION_TIME: setExecutionTime(EXECUTION_TIME_EDEFAULT); return; case OperatorPackage.OPERATOR__COMMUTATIVE: setCommutative(COMMUTATIVE_EDEFAULT); return; } super.eUnset(featureID); } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ @Override public boolean eIsSet(int featureID) { switch (featureID) { case OperatorPackage.OPERATOR__INPUTS: return inputs != null && !inputs.isEmpty(); case OperatorPackage.OPERATOR__OUTPUTS: return outputs != null && !outputs.isEmpty(); case OperatorPackage.OPERATOR__GENERICS: return generics != null && !generics.isEmpty(); case OperatorPackage.OPERATOR__INPUT_SUBDIR: return INPUT_SUBDIR_EDEFAULT == null ? inputSubdir != null : !INPUT_SUBDIR_EDEFAULT.equals(inputSubdir); case OperatorPackage.OPERATOR__PREVIOUS_OPERATOR: return previousOperator != null; case OperatorPackage.OPERATOR__UPDATE_MID: return updateMID != UPDATE_MID_EDEFAULT; case OperatorPackage.OPERATOR__EXECUTION_TIME: return executionTime != EXECUTION_TIME_EDEFAULT; case OperatorPackage.OPERATOR__COMMUTATIVE: return commutative != COMMUTATIVE_EDEFAULT; } return super.eIsSet(featureID); } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ @Override public int eDerivedOperationID(int baseOperationID, Class<?> baseClass) { if (baseClass == ExtendibleElement.class) { switch (baseOperationID) { case MIDPackage.EXTENDIBLE_ELEMENT___GET_METATYPE: return OperatorPackage.OPERATOR___GET_METATYPE; case MIDPackage.EXTENDIBLE_ELEMENT___GET_MID_CONTAINER: return OperatorPackage.OPERATOR___GET_MID_CONTAINER; default: return super.eDerivedOperationID(baseOperationID, baseClass); } } return super.eDerivedOperationID(baseOperationID, baseClass); } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ @Override @SuppressWarnings("unchecked") public Object eInvoke(int operationID, EList<?> arguments) throws InvocationTargetException { switch (operationID) { case OperatorPackage.OPERATOR___GET_METATYPE: return getMetatype(); case OperatorPackage.OPERATOR___GET_SUPERTYPE: return getSupertype(); case OperatorPackage.OPERATOR___GET_MID_CONTAINER: return getMIDContainer(); case OperatorPackage.OPERATOR___CREATE_SUBTYPE__STRING_STRING: try { return createSubtype((String)arguments.get(0), (String)arguments.get(1)); } catch (Throwable throwable) { throw new InvocationTargetException(throwable); } case OperatorPackage.OPERATOR___DELETE_TYPE: try { deleteType(); return null; } catch (Throwable throwable) { throw new InvocationTargetException(throwable); } case OperatorPackage.OPERATOR___OPEN_TYPE: try { openType(); return null; } catch (Throwable throwable) { throw new InvocationTargetException(throwable); } case OperatorPackage.OPERATOR___FIND_ALLOWED_INPUTS__ELIST: try { return findAllowedInputs((EList<MID>)arguments.get(0)); } catch (Throwable throwable) { throw new InvocationTargetException(throwable); } case OperatorPackage.OPERATOR___FIND_FIRST_ALLOWED_INPUT__ELIST: try { return findFirstAllowedInput((EList<MID>)arguments.get(0)); } catch (Throwable throwable) { throw new InvocationTargetException(throwable); } case OperatorPackage.OPERATOR___CHECK_ALLOWED_INPUTS__ELIST: try { return checkAllowedInputs((EList<Model>)arguments.get(0)); } catch (Throwable throwable) { throw new InvocationTargetException(throwable); } case OperatorPackage.OPERATOR___GET_OUTPUTS_BY_NAME: try { return getOutputsByName(); } catch (Throwable throwable) { throw new InvocationTargetException(throwable); } case OperatorPackage.OPERATOR___GET_OUTPUT_MODELS: try { return getOutputModels(); } catch (Throwable throwable) { throw new InvocationTargetException(throwable); } case OperatorPackage.OPERATOR___CREATE_INSTANCE__MID: try { return createInstance((MID)arguments.get(0)); } catch (Throwable throwable) { throw new InvocationTargetException(throwable); } case OperatorPackage.OPERATOR___DELETE_INSTANCE: try { deleteInstance(); return null; } catch (Throwable throwable) { throw new InvocationTargetException(throwable); } case OperatorPackage.OPERATOR___SELECT_ALLOWED_GENERICS__ELIST: try { return selectAllowedGenerics((EList<OperatorInput>)arguments.get(0)); } catch (Throwable throwable) { throw new InvocationTargetException(throwable); } case OperatorPackage.OPERATOR___IS_ALLOWED_GENERIC__GENERICENDPOINT_GENERICELEMENT_ELIST: try { return isAllowedGeneric((GenericEndpoint)arguments.get(0), (GenericElement)arguments.get(1), (EList<OperatorInput>)arguments.get(2)); } catch (Throwable throwable) { throw new InvocationTargetException(throwable); } case OperatorPackage.OPERATOR___GET_INPUT_PROPERTIES: return getInputProperties(); case OperatorPackage.OPERATOR___READ_INPUT_PROPERTIES__PROPERTIES: try { readInputProperties((Properties)arguments.get(0)); return null; } catch (Throwable throwable) { throw new InvocationTargetException(throwable); } case OperatorPackage.OPERATOR___RUN__MAP_MAP_MAP: try { return run((Map<String, Model>)arguments.get(0), (Map<String, GenericElement>)arguments.get(1), (Map<String, MID>)arguments.get(2)); } catch (Throwable throwable) { throw new InvocationTargetException(throwable); } case OperatorPackage.OPERATOR___START_INSTANCE__ELIST_PROPERTIES_ELIST_MAP_MID: try { return startInstance((EList<OperatorInput>)arguments.get(0), (Properties)arguments.get(1), (EList<OperatorGeneric>)arguments.get(2), (Map<String, MID>)arguments.get(3), (MID)arguments.get(4)); } catch (Throwable throwable) { throw new InvocationTargetException(throwable); } case OperatorPackage.OPERATOR___OPEN_INSTANCE: try { openInstance(); return null; } catch (Throwable throwable) { throw new InvocationTargetException(throwable); } case OperatorPackage.OPERATOR___CREATE_WORKFLOW_INSTANCE__MID: try { return createWorkflowInstance((MID)arguments.get(0)); } catch (Throwable throwable) { throw new InvocationTargetException(throwable); } case OperatorPackage.OPERATOR___DELETE_WORKFLOW_INSTANCE: try { deleteWorkflowInstance(); return null; } catch (Throwable throwable) { throw new InvocationTargetException(throwable); } case OperatorPackage.OPERATOR___START_WORKFLOW_INSTANCE__ELIST_ELIST_MID: try { return startWorkflowInstance((EList<OperatorInput>)arguments.get(0), (EList<OperatorGeneric>)arguments.get(1), (MID)arguments.get(2)); } catch (Throwable throwable) { throw new InvocationTargetException(throwable); } case OperatorPackage.OPERATOR___OPEN_WORKFLOW_INSTANCE: try { openWorkflowInstance(); return null; } catch (Throwable throwable) { throw new InvocationTargetException(throwable); } } return super.eInvoke(operationID, arguments); } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public String toStringGen() { if (eIsProxy()) return super.toString(); StringBuffer result = new StringBuffer(super.toString()); result.append(" (inputSubdir: "); result.append(inputSubdir); result.append(", updateMID: "); result.append(updateMID); result.append(", executionTime: "); result.append(executionTime); result.append(", commutative: "); result.append(commutative); result.append(')'); return result.toString(); } /** * @generated NOT */ @Override public String toString() { String label = (getName() == null) ? "" : getName(); if (!getGenerics().isEmpty()) { label += "<" + getGenerics().stream() .map(GenericEndpoint::getName) .collect(Collectors.joining(",")) + ">"; } return label; } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public Operator getMetatype() { ExtendibleElement metatype = super.getMetatype(); return (metatype == null) ? null : (Operator) metatype; } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public Operator getSupertype() { ExtendibleElement supertype = super.getSupertype(); return (supertype == null) ? null : (Operator) supertype; } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public MID getMIDContainer() { return (MID) this.eContainer(); } /** * Adds a subtype of this operator type to the Type MID. * * @param newOperatorType * The new operator type to be added. * @param newOperatorTypeName * The name of the new operator type. * @param implementationUri * The uri of the new operator's implementation (a Java class inheriting from this class). * @throws MMINTException * If the uri of the new operator type is already registered in the Type MID. * @generated NOT */ protected void addSubtype(Operator newOperatorType, String newOperatorTypeName, String implementationUri) throws MMINTException { //TODO MMINT[OPERATOR] Implement a simple way to run a java class pointed by implementationUri } /** * @generated NOT */ public Operator createSubtype(String newOperatorTypeName, String implementationUri) throws MMINTException { MMINTException.mustBeType(this); Operator newOperatorType = super.createThisEClass(); this.addSubtype(newOperatorType, newOperatorTypeName, implementationUri); return newOperatorType; } /** * @generated NOT */ public void deleteType() throws MMINTException { MMINTException.mustBeType(this); MID typeMID = this.getMIDContainer(); // delete the "thing" getInputs().forEach(modelTypeEndpoint -> super.delete(modelTypeEndpoint.getUri(), typeMID)); getOutputs().forEach(modelTypeEndpoint -> super.delete(modelTypeEndpoint.getUri(), typeMID)); getGenerics().forEach(genericTypeEndpoint -> super.delete(genericTypeEndpoint.getUri(), typeMID)); super.delete(); typeMID.getOperators().remove(this); // delete the subtypes of the "thing" for (Operator operatorSubtype : MIDTypeHierarchy.getDirectSubtypes(this, typeMID)) { operatorSubtype.deleteType(); } } /** * @generated NOT */ public void openType() throws Exception { MMINTException.mustBeType(this); // get java source file from bundle Bundle bundle = MIDTypeRegistry.getTypeBundle(this.getUri()); if (bundle == null) { throw new MMINTException("Can't find " + this.getName() + " bundle"); } String javaFileName = this.getClass().getSimpleName() + ".java"; String bundleFilePath = this.getClass().getProtectionDomain().getCodeSource().getLocation().getFile(); String operatorImplPath; if (bundleFilePath.endsWith("jar")) { // binary installation int separator = bundleFilePath.lastIndexOf("_"); bundleFilePath = bundleFilePath.substring(0, separator) + ".source" + bundleFilePath.substring(separator); if (!FileUtils.isFile(bundleFilePath, false)) { throw new MMINTException("Can't find the source java file for " + this.getName() + " (did you install mmint.sdk?)"); } JarFile bundleJar = new JarFile(new File(bundleFilePath)); ZipEntry bundleJarEntry = bundleJar.getEntry(this.getClass().getName().replace(".", File.separator) + ".java"); Path tmpFilePath = Paths.get(System.getProperty("java.io.tmpdir") + "/" + javaFileName); Files.copy(bundleJar.getInputStream(bundleJarEntry), tmpFilePath, StandardCopyOption.REPLACE_EXISTING); operatorImplPath = tmpFilePath.toString(); bundleJar.close(); } else { // running from the sources Enumeration<URL> bundleEntries = bundle.findEntries("/", javaFileName, true); if (bundleEntries == null || !bundleEntries.hasMoreElements()) { throw new MMINTException("Can't find the source java file for " + this.getName()); } operatorImplPath = FileLocator.toFileURL(bundleEntries.nextElement()).getFile(); } // open editor FileUtils.openEclipseEditor(operatorImplPath, null, false); } /** * Computes the cartesian product of inputs for this operator type. * * @param modelTypeEndpointInputs * The allowed inputs for each formal parameter. * @param firstOnly * True if only the first input is returned, false if the whole cartesian product is returned. * @return A set of inputs to the operator type, including necessary conversions. * @generated NOT */ private @NonNull Set<EList<OperatorInput>> getOperatorTypeInputs(@NonNull EList<EList<OperatorInput>> modelTypeEndpointInputs, boolean firstOnly) { Set<EList<OperatorInput>> operatorTypeInputSet = new HashSet<>(); // if at least one is empty, there is no way to have a proper input for this operator if (modelTypeEndpointInputs.stream().anyMatch(modelTypeEndpointInput -> modelTypeEndpointInput.isEmpty())) { return operatorTypeInputSet; } Set<Set<Model>> operatorTypeInputSetCommutative = new HashSet<>(); int[] indexes = new int[modelTypeEndpointInputs.size()]; for (int i = 0; i < indexes.length; i++) { indexes[i] = 0; } while (true) { // get current inputs EList<OperatorInput> operatorTypeInputs = new BasicEList<>(); for (int i = 0; i < indexes.length; i++) { EList<OperatorInput> modelTypeEndpointInput = modelTypeEndpointInputs.get(i); operatorTypeInputs.add(modelTypeEndpointInput.get(indexes[i])); } try { // add only if allowed and passes commutativity check Map<String, Model> inputsByName = createInputsByName(operatorTypeInputs, false, null); if (MIDConstraintChecker.checkOperatorInputConstraint(this, inputsByName)) { boolean commutative = false; if (this.isCommutative()) { Set<Model> operatorTypeInputsCommutative = new HashSet<>(inputsByName.values()); if (operatorTypeInputSetCommutative.contains(operatorTypeInputsCommutative)) { commutative = true; } else { operatorTypeInputSetCommutative.add(operatorTypeInputsCommutative); } } if (!commutative) { operatorTypeInputSet.add(operatorTypeInputs); if (firstOnly) { // just return the first allowed return operatorTypeInputSet; } } } } catch (Exception e) { // do nothing } // move indexes int j = indexes.length - 1; while (true) { indexes[j] += 1; if (indexes[j] < modelTypeEndpointInputs.get(j).size()) { break; } indexes[j] = 0; j -= 1; if (j < 0) { // overflow, cartesian product done return operatorTypeInputSet; } } } } /** * Checks if an input model can be used as actual parameter for a formal parameter of an operator type. * * @param inputModelTypeEndpoint * The model type endpoint representing the formal parameter of an operator type. * @param inputModel * The input model. * @return The input to the operator, including necessary conversions, or null if the input model can't be used. * @generated NOT */ private @Nullable OperatorInput checkAllowedInput(@NonNull ModelEndpoint inputModelTypeEndpoint, @NonNull Model inputModel) { List<ConversionOperator> conversions = MIDTypeHierarchy.instanceOf(inputModel, inputModelTypeEndpoint.getTargetUri()); if (conversions == null) { return null; } OperatorInput input = OperatorFactory.eINSTANCE.createOperatorInput(); input.setModel(inputModel); input.setModelTypeEndpoint(inputModelTypeEndpoint); input.getConversions().addAll(conversions); return input; } /** * Gets all allowed inputs for each formal parameter of this operator type. * * @param inputMIDs * A list of instance MIDs where to get input models. Each formal parameter gets input models from a * different instance MID, following their order. If there are not enough instance MIDs, the last * instance MID is used for all subsequent formal parameters. * @return The allowed inputs for each formal parameter, including necessary conversions. * @generated NOT */ private @NonNull EList<EList<OperatorInput>> getModelTypeEndpointInputs(@NonNull EList<MID> inputMIDs) { //TODO MMINT[MAP] Add support for upper bound = -1 EList<EList<OperatorInput>> modelTypeEndpointInputs = new BasicEList<>(); for (int i = 0; i < this.getInputs().size(); i++) { ModelEndpoint inputModelTypeEndpoint = this.getInputs().get(i); // TODO MMINT[MAP] Add support for arbitrary combinations of input MIDs to input arguments MID inputMID; if (i < inputMIDs.size()) { inputMID = inputMIDs.get(i); } else { inputMID = inputMIDs.get(inputMIDs.size()-1); } EList<OperatorInput> modelTypeEndpointInputSet = new BasicEList<>(); modelTypeEndpointInputs.add(modelTypeEndpointInputSet); for (Model inputModel : inputMID.getModels()) { OperatorInput operatorInput = checkAllowedInput(inputModelTypeEndpoint, inputModel); if (operatorInput == null) { continue; } modelTypeEndpointInputSet.add(operatorInput); } } return modelTypeEndpointInputs; } /** * @generated NOT */ public Set<EList<OperatorInput>> findAllowedInputs(EList<MID> inputMIDs) throws MMINTException { MMINTException.mustBeType(this); // get inputs by model type endpoint EList<EList<OperatorInput>> modelTypeEndpointInputs = getModelTypeEndpointInputs(inputMIDs); // do cartesian product of inputs Set<EList<OperatorInput>> operatorTypeInputSet = getOperatorTypeInputs(modelTypeEndpointInputs, false); return operatorTypeInputSet; } /** * @generated NOT */ public EList<OperatorInput> findFirstAllowedInput(EList<MID> inputMIDs) throws MMINTException { MMINTException.mustBeType(this); // get inputs by model type endpoint EList<EList<OperatorInput>> modelTypeEndpointInputs = getModelTypeEndpointInputs(inputMIDs); // get the first allowed input Set<EList<OperatorInput>> operatorTypeInputSet = getOperatorTypeInputs(modelTypeEndpointInputs, true); if (operatorTypeInputSet.isEmpty()) { return null; } return operatorTypeInputSet.iterator().next(); } /** * @generated NOT */ public EList<OperatorInput> checkAllowedInputs(EList<Model> inputModels) throws MMINTException { MMINTException.mustBeType(this); // check actual parameters EList<OperatorInput> inputs = new BasicEList<>(); int i = 0; for (ModelEndpoint inputModelTypeEndpoint : getInputs()) { // check 1: not enough actual parameters, considering formal parameters with upper bound > 1 too if (i >= inputModels.size()) { return null; } // check 2: type or substitutable types while (i < inputModels.size()) { OperatorInput operatorInput = this.checkAllowedInput(inputModelTypeEndpoint, inputModels.get(i)); if (operatorInput == null) { return null; } inputs.add(operatorInput); i++; if (inputModelTypeEndpoint.getUpperBound() == 1) { break; } } } // check 3: too many actual parameters if (i < inputModels.size()) { return null; } // check 4: operator-specific constraints other than types (e.g. 2 model rels as input connected by same model) Map<String, Model> inputsByName = null; try { inputsByName = this.createInputsByName(inputs, false, null); } catch (Exception e) { // never happens } if (!MIDConstraintChecker.checkOperatorInputConstraint(this, inputsByName)) { //TODO MMINT[OPERATOR] Can there be conflicts since conversions are not run? return null; } return inputs; } /** * @generated NOT */ public Map<String, Model> getOutputsByName() throws MMINTException { MMINTException.mustBeInstance(this); return this.getOutputs().stream() .collect(Collectors.toMap( outputModelEndpoint -> outputModelEndpoint.getName(), outputModelEndpoint -> outputModelEndpoint.getTarget())); } /** * @generated NOT */ public EList<Model> getOutputModels() throws MMINTException { MMINTException.mustBeInstance(this); return new BasicEList<>( this.getOutputs().stream() .map(outputModelEndpoint -> outputModelEndpoint.getTarget()) .collect(Collectors.toList())); } /** * Adds an operator instance of this operator type to an Instance or Workflow MID. * * @param newOperator * The new operator to be added. * @param midLevel * The kind of MID (Instance or Workflow) that could contain the new operator, regardless of whether it * is or isn't going to be contained in one. * @param instanceMID * An Instance or Workflow MID, null if the operator isn't going to be contained in one. * @generated NOT */ protected void addInstance(@NonNull Operator newOperator, @NonNull MIDLevel midLevel, @Nullable MID instanceMID) { super.addBasicInstance(newOperator, null, this.getName(), midLevel); newOperator.setCommutative(false); if (instanceMID != null) { instanceMID.getOperators().add(newOperator); } } /** * @generated NOT */ public Operator createInstance(MID instanceMID) throws MMINTException { MMINTException.mustBeType(this); Operator newOperator; try { newOperator = this.getClass().newInstance(); } catch (Exception e) { throw new MMINTException("Can't invoke constructor"); } if (this.getPreviousOperator() != null) { newOperator.setPreviousOperator(this.getPreviousOperator()); } this.addInstance(newOperator, MIDLevel.INSTANCES, instanceMID); return newOperator; } /** * Deletes this operator instance from an Instance or Workflow MID. * * @param instanceMID * The Instance or Workflow MID that contains the operator. * * @generated NOT */ protected void deleteInstance(MID instanceMID) { instanceMID.getOperators().remove(this); } /** * @generated NOT */ public void deleteInstance() throws MMINTException { MMINTException.mustBeInstance(this); this.deleteInstance(this.getMIDContainer()); } /** * @generated NOT */ public EList<OperatorGeneric> selectAllowedGenerics(EList<OperatorInput> inputs) throws MMINTException { MMINTException.mustBeType(this); EList<OperatorGeneric> generics = new BasicEList<>(); for (GenericEndpoint genericSuperTypeEndpoint : this.getGenerics()) { GenericElement genericType = MIDDialogs.selectGenericTypeToCreate(genericSuperTypeEndpoint, inputs); OperatorGeneric generic = OperatorFactory.eINSTANCE.createOperatorGeneric(); generic.setGenericSuperTypeEndpoint(genericSuperTypeEndpoint); generic.setGeneric(genericType); generics.add(generic); } return generics; } /** * @generated NOT */ public boolean isAllowedGeneric(GenericEndpoint genericTypeEndpoint, GenericElement genericType, EList<OperatorInput> inputs) throws MMINTException { MMINTException.mustBeType(this); return true; } /** * Gets the uri of the properties file of this operator. * * @param suffix * The suffix of the properties file. * @return The uri of the properties file. * @generated NOT */ private String getPropertiesUri(@NonNull String suffix) { IFile instanceMIDFile = MMINT.getActiveInstanceMIDFile(); if (instanceMIDFile == null) { // can happen when an operator is invoked from a model editor return null; } String propertiesUri = FileUtils.prependWorkspacePathToUri(instanceMIDFile.getParent().getFullPath().toString()); propertiesUri += IPath.SEPARATOR + this.getName() + suffix + MIDOperatorIOUtils.PROPERTIES_SUFFIX; return propertiesUri; } /** * @generated NOT */ public Properties getInputProperties() { String propertiesUri = getPropertiesUri(MIDOperatorIOUtils.INPUT_PROPERTIES_SUFFIX); Properties inputProperties = new Properties(); try { inputProperties.load(new FileInputStream(propertiesUri)); } catch (Exception e) { // do nothing } return inputProperties; } /** * @generated NOT */ public void readInputProperties(Properties inputProperties) throws MMINTException { setUpdateMID( MIDOperatorIOUtils.getOptionalBoolProperty(inputProperties, MIDOperatorIOUtils.PROPERTY_IN_UPDATEMID, true) ); setInputSubdir( MIDOperatorIOUtils.getOptionalStringProperty(inputProperties, MIDOperatorIOUtils.PROPERTY_IN_SUBDIR, null) ); } /** * @generated NOT */ public Map<String, Model> run(Map<String, Model> inputsByName, Map<String, GenericElement> genericsByName, Map<String, MID> outputMIDsByName) throws Exception { throw new MMINTException("The default run() function must be overridden"); } /** * Creates a map of input model instances, identified by their formal parameter name. * * @param inputs * A list of inputs to the operator instance, including necessary conversions. * @param runConversions * True if conversions have to be run, false otherwise. * @param newOperator * The operator instance that will be invoked with the input models, null if operator traceability is not * needed. * @return The map of input model instances, identified by their formal parameter name. * @throws Exception * If something went wrong running the conversions. * @generated NOT */ protected Map<String, Model> createInputsByName(@NonNull EList<OperatorInput> inputs, boolean runConversions, @Nullable Operator newOperator) throws Exception { //TODO MMINT[OPERATOR] This is used for two purposes, just to create the map and to populate an operator: split boolean coerced = false; Map<String, Model> inputsByName = new HashMap<>(); for (OperatorInput input : inputs) { ModelEndpoint modelEndpoint = null; if (newOperator != null) { modelEndpoint = input.getModelTypeEndpoint().createInstance( input.getModel(), newOperator, OperatorPackage.eINSTANCE.getOperator_Inputs().getName() ); } String inputName = input.getModelTypeEndpoint().getName(); if (input.getModelTypeEndpoint().getUpperBound() == -1) { int i = 0; while (inputsByName.get(inputName + i) != null) { i++; } inputName += i; if (newOperator != null) { modelEndpoint.setName(inputName); } } if (input.getConversions().isEmpty() || !runConversions) { inputsByName.put(inputName, input.getModel()); continue; } coerced = true; Model convertedInputModel = input.getModel(); for (ConversionOperator conversion : input.getConversions()) { //TODO MMINT[WORKFLOW] Implement this as a simplified workflow? Properties inputProperties = conversion.getInputProperties(); conversion.readInputProperties(inputProperties); Map<String, Model> conversionInputsByName = new HashMap<>(); conversionInputsByName.put(conversion.getInputs().get(0).getName(), convertedInputModel); Map<String, MID> conversionOutputMIDsByName = new HashMap<>(); conversionOutputMIDsByName.put(conversion.getOutputs().get(0).getName(), null); convertedInputModel = conversion.run(conversionInputsByName, new HashMap<>(), conversionOutputMIDsByName) .get(conversion.getOutputs().get(0).getName()); } inputsByName.put(inputName, convertedInputModel); } if (coerced && newOperator != null) { newOperator.setName(newOperator.getName() + " (coerced)"); } return inputsByName; } /** * Creates a map of generic instances, identified by their name. * * @param generics * A list of generic types for the operator instance. * @param newOperator * The operator instance that will be invoked with the generics. * @return The map of generic instances, identified by their name. * @throws MMINTException * If any generic type is an instance instead. * @generated NOT */ private Map<String, GenericElement> createGenericsByName(@NonNull EList<OperatorGeneric> generics, @NonNull Operator newOperator) throws MMINTException { Map<String, GenericElement> genericsByName = new HashMap<>(); for (OperatorGeneric generic : generics) { GenericEndpoint genericSuperTypeEndpoint = generic.getGenericSuperTypeEndpoint(); GenericElement genericType = generic.getGeneric(); genericSuperTypeEndpoint.createInstance(genericType, newOperator); genericsByName.put(genericSuperTypeEndpoint.getName(), genericType); } return genericsByName; } /** * @generated NOT */ public Operator startInstance(EList<OperatorInput> inputs, Properties inputProperties, EList<OperatorGeneric> generics, Map<String, MID> outputMIDsByName, MID instanceMID) throws Exception { MMINTException.mustBeType(this); //TODO MMINT[OPERATOR] Run in its own thread to avoid blocking the user interface (needs ui parts to be passed for GMFDiagramUtils functions to work) if (!Boolean.parseBoolean(MMINT.getPreference(MMINTConstants.PREFERENCE_MENU_OPERATORS_ENABLED))) { instanceMID = null; } Operator newOperator = this.createInstance(instanceMID); // generics, inputs and conversions Map<String, GenericElement> genericsByName = this.createGenericsByName(generics, newOperator); Map<String, Model> inputsByName = this.createInputsByName(inputs, true, newOperator); // run operator if (inputProperties == null) { inputProperties = newOperator.getInputProperties(); } newOperator.readInputProperties(inputProperties); long startTime = System.nanoTime(); Map<String, Model> outputsByName = newOperator.run(inputsByName, genericsByName, outputMIDsByName); newOperator.setExecutionTime(System.nanoTime()-startTime); // outputs for (ModelEndpoint outputModelTypeEndpoint : this.getOutputs()) { List<Model> outputModels; if (outputModelTypeEndpoint.getUpperBound() == -1) { outputModels = MIDOperatorIOUtils.getVarargs(outputsByName, outputModelTypeEndpoint.getName()); } else { outputModels = new ArrayList<>(); outputModels.add(outputsByName.get(outputModelTypeEndpoint.getName())); } for (int i = 0; i < outputModels.size(); i++) { ModelEndpoint outputModelEndpoint = outputModelTypeEndpoint.createInstance( outputModels.get(i), newOperator, OperatorPackage.eINSTANCE.getOperator_Outputs().getName() ); if (outputModelTypeEndpoint.getUpperBound() == -1) { outputModelEndpoint.setName(outputModelEndpoint.getName() + i); } } } // clean up conversions for (OperatorInput input : inputs) { if (input.getConversions().isEmpty()) { continue; } for (ConversionOperator conversion : input.getConversions()) { conversion.cleanup(); } } return newOperator; } /** * Opens the java implementation of the metatype of this operator instance. * * @throws Exception * If the java editor can't be opened. * @generated NOT */ protected void openInstanceMetatype() throws Exception { this.getMetatype().openType(); } /** * @generated NOT */ public void openInstance() throws Exception { MMINTException.mustBeInstance(this); this.openInstanceMetatype(); } /** * @generated NOT */ public Operator createWorkflowInstance(MID workflowMID) throws MMINTException { MMINTException.mustBeType(this); Operator newOperator = OperatorFactory.eINSTANCE.createOperator(); this.addInstance(newOperator, MIDLevel.WORKFLOWS, workflowMID); return newOperator; } /** * @generated NOT */ public void deleteWorkflowInstance() throws MMINTException { MMINTException.mustBeWorkflow(this); this.deleteInstance(this.getMIDContainer()); for (ModelEndpoint outputModelEndpoint : this.getOutputs()) { Model outputModel = outputModelEndpoint.getTarget(); if (outputModel.getMIDContainer() == null) { // already deleted continue; } outputModel.deleteWorkflowInstance(); } } /** * @generated NOT */ public Operator startWorkflowInstance(EList<OperatorInput> inputs, EList<OperatorGeneric> generics, MID workflowMID) throws MMINTException { MMINTException.mustBeType(this); Set<String> inputNames = new HashSet<>(); Operator newOperator = this.createWorkflowInstance(workflowMID); // generics and inputs for (OperatorGeneric generic : generics) { GenericEndpoint genericSuperTypeEndpoint = generic.getGenericSuperTypeEndpoint(); GenericElement genericType = generic.getGeneric(); genericSuperTypeEndpoint.createWorkflowInstance(genericType, newOperator); } for (OperatorInput input : inputs) { ModelEndpoint modelEndpoint = input.getModelTypeEndpoint().createWorkflowInstance( input.getModel(), newOperator, OperatorPackage.eINSTANCE.getOperator_Inputs().getName()); String inputName = input.getModelTypeEndpoint().getName(); if (input.getModelTypeEndpoint().getUpperBound() == -1) { int i = 0; while (inputNames.contains(inputName + i) != false) { i++; } inputName += i; modelEndpoint.setName(inputName); } inputNames.add(inputName); } // outputs for (ModelEndpoint outputModelTypeEndpoint : this.getOutputs()) { if (outputModelTypeEndpoint.getUpperBound() == -1) { try { if (this.getClass().getMethod("startWorkflowInstance", EList.class, EList.class, MID.class).getDeclaringClass() == OperatorImpl.class) { throw new MMINTException(this.getClass().getSimpleName() + " has a variable number of outputs and must override startWorkflowInstance()"); } } catch (NoSuchMethodException | SecurityException e) { MMINTException.print(IStatus.WARNING, this.getClass().getSimpleName() + " has a variable number of outputs and startWorkflowInstance() can't be reflected, skipping outputs", e); } break; } String outputModelId = MIDRegistry.getNextWorkflowID(workflowMID); Model outputModel = outputModelTypeEndpoint.getTarget().createWorkflowInstance(outputModelId, workflowMID); outputModelTypeEndpoint.createWorkflowInstance( outputModel, newOperator, OperatorPackage.eINSTANCE.getOperator_Outputs().getName()); } OperatorConstraint constraint = (OperatorConstraint) this.getConstraint(); if (constraint != null) { // create output model rel endpoints after all outputs are created for (OperatorConstraintRule rule : constraint.getRules()) { ModelEndpoint outputModelRelTypeEndpoint = rule.getOutputModelRel().getParameterRef().getObject(); //TODO MMINT[WORKFLOW] Simply do the following when proper operator endpoint types are used //newOperator.getOutputs().stream().filter(outputModelEndpoint -> outputModelEndpoint.getMetatype() == outputModelRelTypeEndpoint); ModelRel outputModelRel = (ModelRel) newOperator.getOutputs().stream() .filter(outputModelEndpoint -> outputModelEndpoint.getName().equals(outputModelRelTypeEndpoint.getName())) .findFirst() .get() .getTarget(); for (OperatorConstraintParameter param : rule.getEndpointModels()) { ModelEndpoint operatorModelTypeEndpoint = param.getParameterRef().getObject(); //TODO MMINT[WORKFLOW] Make it a function? Model endpointModel = Stream.concat(newOperator.getInputs().stream(), newOperator.getOutputs().stream()) .filter(modelEndpoint -> modelEndpoint.getName().equals(operatorModelTypeEndpoint.getName())) .findFirst() .get() .getTarget(); if (param.getEndpointIndex() >= 0 && endpointModel instanceof ModelRel) { endpointModel = ((ModelRel) endpointModel).getModelEndpoints().get(param.getEndpointIndex()).getTarget(); } String modelTypeEndpointUri = MIDConstraintChecker.getAllowedModelEndpoints(outputModelRel, null, endpointModel).get(0); ModelEndpoint modelTypeEndpoint = MIDTypeRegistry.getType(modelTypeEndpointUri); modelTypeEndpoint.createWorkflowInstance(endpointModel, outputModelRel); } } } return newOperator; } /** * @generated NOT */ public void openWorkflowInstance() throws Exception { MMINTException.mustBeWorkflow(this); this.openInstanceMetatype(); } } //OperatorImpl