| /***************************************************************************** |
| * Copyright (c) 2019 CEA LIST |
| * |
| * 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: |
| * David Lopez david.lopez@cea.fr(CEA LIST) |
| * |
| *****************************************************************************/ |
| package org.eclipse.papyrus.moka.engine.suml.opaquebehaviors; |
| |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.HashMap; |
| import java.util.List; |
| |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.ecore.resource.ResourceSet; |
| import org.eclipse.papyrus.moka.engine.suml.accessor.AccessAdapterRegistry; |
| import org.eclipse.papyrus.moka.engine.suml.accessor.ComponentAccessor; |
| import org.eclipse.papyrus.moka.engine.suml.accessor.ValueTypeWrapper; |
| import org.eclipse.papyrus.moka.engine.suml.accessor.locus.IValueConverter; |
| import org.eclipse.papyrus.moka.engine.suml.accessor.structures.ListAccess; |
| import org.eclipse.papyrus.moka.fuml.commonbehavior.IExecution; |
| import org.eclipse.papyrus.moka.fuml.commonbehavior.IParameterValue; |
| import org.eclipse.papyrus.moka.fuml.commonbehavior.ParameterValue; |
| import org.eclipse.papyrus.moka.fuml.commonbehavior.SignalEventOccurrence; |
| import org.eclipse.papyrus.moka.fuml.loci.ILocus; |
| import org.eclipse.papyrus.moka.fuml.simpleclassifiers.EnumerationValue; |
| import org.eclipse.papyrus.moka.fuml.simpleclassifiers.IEnumerationValue; |
| import org.eclipse.papyrus.moka.fuml.simpleclassifiers.IValue; |
| import org.eclipse.papyrus.moka.fuml.simpleclassifiers.SignalInstance; |
| import org.eclipse.papyrus.moka.fuml.structuredclassifiers.IObject_; |
| import org.eclipse.papyrus.moka.fuml.structuredclassifiers.IReference; |
| import org.eclipse.papyrus.moka.fuml.structuredclassifiers.Reference; |
| import org.eclipse.uml2.uml.Behavior; |
| import org.eclipse.uml2.uml.Class; |
| import org.eclipse.uml2.uml.Classifier; |
| import org.eclipse.uml2.uml.Enumeration; |
| import org.eclipse.uml2.uml.EnumerationLiteral; |
| import org.eclipse.uml2.uml.NamedElement; |
| import org.eclipse.uml2.uml.Operation; |
| import org.eclipse.uml2.uml.Parameter; |
| import org.eclipse.uml2.uml.ParameterDirectionKind; |
| import org.eclipse.uml2.uml.Property; |
| import org.eclipse.uml2.uml.Signal; |
| |
| public class LocusAdapter { |
| private IObject_ ctxInstance; |
| |
| public void setExecutionInstance(IObject_ context) { |
| this.ctxInstance = context; |
| } |
| |
| private ILocus getLocus() { |
| return ctxInstance.getLocus(); |
| } |
| |
| private Classifier getContextType() { |
| return ctxInstance.getTypes().get(0); |
| } |
| |
| private NamedElement findNamedElement(String qualifiedName) { |
| |
| Classifier context = getContextType(); |
| |
| if( qualifiedName.startsWith("::") ) { |
| String parent = context.getPackage().getQualifiedName(); |
| qualifiedName = parent + qualifiedName; |
| } |
| |
| if ( !(context instanceof EObject) || (((EObject)context).eResource() == null) ) |
| throw new RuntimeException("Failed to find a contextual resource for object"); |
| |
| ResourceSet resSet = ((EObject)context).eResource().getResourceSet(); |
| |
| Collection<NamedElement> elems = org.eclipse.uml2.uml.util.UMLUtil.findNamedElements(resSet, qualifiedName); |
| if (!elems.isEmpty()) { |
| return elems.iterator().next(); |
| }else { |
| throw new RuntimeException("Failed to find a NamedElement with qualified name: "+ qualifiedName); |
| } |
| } |
| |
| public Object importEnumeration(String qualifiedName) { |
| NamedElement elm = findNamedElement(qualifiedName); |
| if( !(elm instanceof Enumeration) ) |
| throw new RuntimeException("The NamedElement is not an Enumeration: "+ qualifiedName); |
| |
| Enumeration enumeration = (Enumeration) elm; |
| //Map with IEnumValues |
| HashMap<String, IEnumerationValue> enumObject = new HashMap<String, IEnumerationValue>(); |
| |
| for(EnumerationLiteral lit : enumeration.getOwnedLiterals()) { |
| EnumerationValue eValue = new EnumerationValue(); |
| eValue.literal = lit; |
| eValue.type = enumeration; |
| enumObject.put(lit.getName(), eValue ); |
| } |
| |
| return enumObject; |
| } |
| |
| public Object instantiate(String qualifiedName) { |
| NamedElement elm = findNamedElement(qualifiedName); |
| |
| if( !(elm instanceof org.eclipse.uml2.uml.Class) ) |
| throw new RuntimeException("The NamedElement is not a class: "+ qualifiedName); |
| |
| ILocus locus = getLocus(); |
| //Wrap it |
| Reference reference = new Reference(); |
| reference.referent = locus.instantiate((Class) elm); |
| |
| Class type = (Class)reference.referent.getTypes().get(0); |
| |
| //Start behavior if it's not null |
| if( type.getClassifierBehavior() != null ) |
| reference.referent.startBehavior(type, new ArrayList<IParameterValue>()); |
| |
| return AccessAdapterRegistry.getInstance().getComponentAccessor().valueToScript( reference ); |
| } |
| |
| |
| public Object callBehavior( String qualifiedName ) { |
| return callBehavior(qualifiedName, ctxInstance); |
| } |
| |
| public Object callBehavior(String qualifiedName, Object context) { |
| return callBehavior(qualifiedName, context, null); |
| } |
| |
| private IObject_ getRightContext(Object context) { |
| if( context == null ) |
| return ctxInstance; |
| |
| if( context instanceof IObject_ ) |
| return (IObject_) context; |
| |
| if( !(context instanceof ValueTypeWrapper) ) |
| throw new RuntimeException("The object "+ context + " is not a valid Reference, and can't be the context of a behavior call"); |
| |
| ValueTypeWrapper<IValue> target = (ValueTypeWrapper<IValue>)context; |
| return ((IReference)target.unwrap()).getReferent(); |
| } |
| |
| public Object toLocusList(List<Object> params) { |
| |
| if( params == null ) |
| return null; |
| |
| ArrayList locusList = new ArrayList<IValue>(); |
| |
| for(Object o : params) |
| locusList.add(o); |
| |
| return locusList; |
| } |
| |
| public Object callBehavior( String qualifiedName , Object context, List<Object> params ) { |
| NamedElement element = findNamedElement(qualifiedName); |
| |
| if( !(element instanceof Behavior ) ) |
| throw new RuntimeException("The class "+ qualifiedName + " is not a behavior"); |
| |
| |
| Behavior behavior = (Behavior)element; |
| IExecution execution = getLocus().getFactory().createExecution(behavior, getRightContext(context)); |
| |
| IValueConverter conv = AccessAdapterRegistry.getInstance().getConverterForClass(IValue.class); |
| |
| ComponentAccessor accesor = AccessAdapterRegistry.getInstance().getComponentAccessor(); |
| |
| if( params != null ) { |
| for( int i = 0; i < params.size(); i++ ) { |
| Parameter p = behavior.getOwnedParameters().get(i); |
| |
| ParameterValue pv = new ParameterValue(); |
| pv.parameter = p; |
| pv.values = new ArrayList<IValue>(); |
| pv.values.add( conv.newValue(params.get(i)) ); |
| execution.setParameterValue(pv); |
| } |
| } |
| |
| execution.execute(); |
| |
| Object returnObject = Void.TYPE; |
| |
| for( IParameterValue pv : execution.getOutputParameterValues() ) |
| if( pv.getParameter().getDirection() == ParameterDirectionKind.RETURN_LITERAL ) { |
| returnObject = accesor.valueListToScript( pv.getValues() ); |
| break; |
| } |
| |
| execution.destroy(); |
| |
| return returnObject; |
| } |
| |
| public Object callOperation(Operation operation, IReference reference, List<Object> params) { |
| IExecution callExecution = reference.dispatch(operation); |
| |
| if( params != null ) { |
| IValueConverter conv = AccessAdapterRegistry.getInstance().getConverterForClass(IValue.class); |
| |
| List<Parameter> parameters = callExecution.getBehavior().getOwnedParameters(); |
| |
| for( int i = 0; i < parameters.size(); i++ ) { |
| Parameter parameter = parameters.get(i); |
| ParameterValue parameterValue = new ParameterValue(); |
| parameterValue.parameter = parameter; |
| parameterValue.values = new ArrayList<IValue>(); |
| callExecution.setParameterValue(parameterValue); |
| |
| if( parameter.getDirection() == ParameterDirectionKind.RETURN_LITERAL || |
| parameter.getDirection() == ParameterDirectionKind.OUT_LITERAL) |
| continue; |
| |
| parameterValue.values.add( conv.newValue(params.get(i))); |
| } |
| |
| } |
| |
| callExecution.execute(); |
| |
| ComponentAccessor accesor = AccessAdapterRegistry.getInstance().getComponentAccessor(); |
| |
| Object returnObject = Void.TYPE; |
| |
| for( IParameterValue pv : callExecution.getOutputParameterValues() ) |
| if( pv.getParameter().getDirection() == ParameterDirectionKind.RETURN_LITERAL ) { |
| returnObject = accesor.valueListToScript( pv.getValues() ); |
| break; |
| } |
| |
| callExecution.destroy(); |
| |
| return returnObject; |
| } |
| |
| public Object callOperation( String opName, Object obj, List<Object> params) { |
| if( !(obj instanceof ValueTypeWrapper) ) |
| throw new RuntimeException("The object "+ obj + " is not a valid Reference, and can't be targeted by a signal"); |
| |
| ValueTypeWrapper<IValue> target = (ValueTypeWrapper<IValue>)obj; |
| IReference ref = (IReference) target.unwrap(); |
| |
| Classifier c = ref.getTypes().get(0); |
| Operation operation = null; |
| for( Operation op : c.getOperations() ) { |
| if( op.getName().equals(opName) ) { |
| operation = op; |
| break; |
| } |
| } |
| |
| if( operation == null ) |
| throw new RuntimeException("The operation "+ opName + " doesn't exist in the object " + obj); |
| |
| return callOperation(operation, ref, params); |
| } |
| |
| public void sendSignal(String qualifiedName, Object obj, List<Object> params ) { |
| |
| if( !(obj instanceof ValueTypeWrapper) ) |
| throw new RuntimeException("The object "+ obj + " is not a valid Reference, and can't be targeted by a signal"); |
| |
| ValueTypeWrapper<IValue> target = (ValueTypeWrapper<IValue>)obj; |
| |
| NamedElement element = findNamedElement(qualifiedName); |
| |
| if( !(element instanceof Signal ) ) |
| throw new RuntimeException("The signal "+ qualifiedName + " does not exist"); |
| |
| Signal signal = (Signal)element; |
| |
| SignalInstance signalInstance = new SignalInstance(); |
| signalInstance.type = signal; |
| |
| IValueConverter conv = AccessAdapterRegistry.getInstance().getConverterForClass(IValue.class); |
| |
| if( params != null ) { |
| List<Property> attributes = signal.getOwnedAttributes(); |
| for (int i = 0; i < attributes.size(); i++) { |
| Property attribute = attributes.get(i); |
| List<IValue> values = new ArrayList<IValue>(); |
| values.add( conv.newValue(params.get(i)) ); |
| signalInstance.setFeatureValue(attribute, values, 0); |
| } |
| } |
| |
| SignalEventOccurrence signalEventOccurrence = new SignalEventOccurrence(); |
| signalEventOccurrence.signalInstance = (SignalInstance) signalInstance.copy(); |
| signalEventOccurrence.sendTo((IReference) target.unwrap()); |
| } |
| |
| |
| } |