From 95a1f414f0a19493f767b364caecd22085d3eaa7 Mon Sep 17 00:00:00 2001 From: Didier Vojtisek Date: Fri, 13 Mar 2020 14:15:08 +0100 Subject: [PATCH] new CompositeDynamicPartAccessor contributes to https://github.com/eclipse/gemoc-studio-modeldebugging/issues/155 by adding a CompositeDynamicPartAccessor that allows to combine several IDynamicPartAccessor/IMutableFieldExtractor so they can provide an unified vision of the RTD to both the Variable view (ie.debugger) and the timeline (ie. generic trace manager) Signed-off-by: Didier Vojtisek --- .../CompositeDynamicPartAccessor.xtend | 36 +++++ .../IntrospectiveMutableFieldExtractor.xtend | 4 +- .../K3AspectDynamicPartAccessor.xtend | 135 ++++++++++++++++++ .../.classpath | 1 + .../META-INF/MANIFEST.MF | 3 +- 5 files changed, 175 insertions(+), 4 deletions(-) create mode 100644 framework/execution_framework/plugins/org.eclipse.gemoc.executionframework.debugger/src/org/eclipse/gemoc/executionframework/debugger/CompositeDynamicPartAccessor.xtend create mode 100644 framework/execution_framework/plugins/org.eclipse.gemoc.executionframework.debugger/src/org/eclipse/gemoc/executionframework/debugger/K3AspectDynamicPartAccessor.xtend diff --git a/framework/execution_framework/plugins/org.eclipse.gemoc.executionframework.debugger/src/org/eclipse/gemoc/executionframework/debugger/CompositeDynamicPartAccessor.xtend b/framework/execution_framework/plugins/org.eclipse.gemoc.executionframework.debugger/src/org/eclipse/gemoc/executionframework/debugger/CompositeDynamicPartAccessor.xtend new file mode 100644 index 000000000..126745a4d --- /dev/null +++ b/framework/execution_framework/plugins/org.eclipse.gemoc.executionframework.debugger/src/org/eclipse/gemoc/executionframework/debugger/CompositeDynamicPartAccessor.xtend @@ -0,0 +1,36 @@ +package org.eclipse.gemoc.executionframework.debugger + +import org.eclipse.emf.ecore.EObject +import java.util.ArrayList +import java.util.List + + +/** + * Dynamic partAccessor that compose the behavior of several IDynamicPartAccessor + * The order in which they are declared is used to ignore conflicting properties/features + */ +class CompositeDynamicPartAccessor implements IDynamicPartAccessor { + + List internalDynamicPartAccessors = new ArrayList(); + + + new(List internalDynamicPartAccessors) { + this.internalDynamicPartAccessors.addAll(internalDynamicPartAccessors); + } + + override isDynamic(EObject obj) { + return internalDynamicPartAccessors.exists[accessor | accessor.isDynamic(obj)] + } + + override extractMutableField(EObject eObject) { + val List res = new ArrayList(); + for(IDynamicPartAccessor accessor : internalDynamicPartAccessors){ + val List candidateMutableFields = accessor.extractMutableField(eObject) + // consider mutable field only if there is no previously found mutable field with the same name + val List acceptedMutableFields = candidateMutableFields.filter[mf1 | ! res.exists[mf2 | mf1.name == mf2.name]].toList + res.addAll(acceptedMutableFields) + } + return res; + } + +} \ No newline at end of file diff --git a/framework/execution_framework/plugins/org.eclipse.gemoc.executionframework.debugger/src/org/eclipse/gemoc/executionframework/debugger/IntrospectiveMutableFieldExtractor.xtend b/framework/execution_framework/plugins/org.eclipse.gemoc.executionframework.debugger/src/org/eclipse/gemoc/executionframework/debugger/IntrospectiveMutableFieldExtractor.xtend index 361495e8d..f3178a11f 100644 --- a/framework/execution_framework/plugins/org.eclipse.gemoc.executionframework.debugger/src/org/eclipse/gemoc/executionframework/debugger/IntrospectiveMutableFieldExtractor.xtend +++ b/framework/execution_framework/plugins/org.eclipse.gemoc.executionframework.debugger/src/org/eclipse/gemoc/executionframework/debugger/IntrospectiveMutableFieldExtractor.xtend @@ -93,7 +93,7 @@ class IntrospectiveMutableFieldExtractor implements IMutableFieldExtractor { } } - private def String findDataName(EObject eObject) { + protected def String findDataName(EObject eObject) { val name = findName(eObject.class, eObject) if (name === null) { val id = findId(eObject.class, eObject) @@ -107,7 +107,7 @@ class IntrospectiveMutableFieldExtractor implements IMutableFieldExtractor { } } - private def List getMutableFieldsFromAspect(EObject eObject, Class properties, Class aspect) { + protected def List getMutableFieldsFromAspect(EObject eObject, Class properties, Class aspect) { val result = new ArrayList diff --git a/framework/execution_framework/plugins/org.eclipse.gemoc.executionframework.debugger/src/org/eclipse/gemoc/executionframework/debugger/K3AspectDynamicPartAccessor.xtend b/framework/execution_framework/plugins/org.eclipse.gemoc.executionframework.debugger/src/org/eclipse/gemoc/executionframework/debugger/K3AspectDynamicPartAccessor.xtend new file mode 100644 index 000000000..5c69d6c45 --- /dev/null +++ b/framework/execution_framework/plugins/org.eclipse.gemoc.executionframework.debugger/src/org/eclipse/gemoc/executionframework/debugger/K3AspectDynamicPartAccessor.xtend @@ -0,0 +1,135 @@ +package org.eclipse.gemoc.executionframework.debugger + +import org.eclipse.gemoc.executionframework.debugger.IntrospectiveMutableFieldExtractor +import org.eclipse.gemoc.executionframework.debugger.IDynamicPartAccessor +import org.eclipse.emf.ecore.EObject +import org.eclipse.gemoc.xdsmlframework.commons.DynamicAnnotationHelper +import org.eclipse.gemoc.xdsmlframework.api.core.IExecutionEngine +import java.util.List +import java.util.ArrayList +import org.eclipse.emf.ecore.EStructuralFeature +import java.lang.reflect.Field +import org.eclipse.emf.ecore.resource.Resource +import org.eclipse.emf.common.util.URI +import org.eclipse.emf.ecore.EClass +import org.eclipse.emf.ecore.EPackage +import org.eclipse.emf.ecore.EcoreFactory +import org.eclipse.emf.transaction.util.TransactionUtil +import org.eclipse.emf.transaction.RecordingCommand +import org.eclipse.gemoc.executionframework.engine.core.CommandExecution + +class K3AspectDynamicPartAccessor extends IntrospectiveMutableFieldExtractor implements IDynamicPartAccessor { + IExecutionEngine engine; + + Resource aspectEMFResource = null; + + new(String languageName, IExecutionEngine engine) { + super(languageName) + this.engine = engine + } + + override isDynamic(EObject obj) { + if(obj === null) { + return false; + } + + return DynamicAnnotationHelper.isDynamic(obj.eClass()); + } + + protected override List getMutableFieldsFromAspect(EObject eObject, Class properties, Class aspect) { + + val result = new ArrayList + + val fields = properties.fields + + if (!fields.empty) { + fields.forEach [ f | + val methods = aspect.methods.filter[m|m.name.equals(f.name)] + val getter = methods.findFirst[m|m.parameterCount == 1] + val setter = methods.findFirst[m|m.parameterCount == 2] + if (getter !== null && setter !== null) { + val data = new MutableField( + f.name+" ("+findDataName(eObject)+ " :"+eObject.eClass().getName() +")", + eObject, + getFeatureForField(aspect, f), + [getter.invoke(null, eObject)], + [t|setter.invoke(null, eObject, t)] + ) + result.add(data) + } + ] + } + + return result + } + + /* + * + */ + protected def EStructuralFeature getFeatureForField(Class aspect, Field field){ + val c = getAspectEClass(aspect) + var res = getAspectEClass(aspect).EStructuralFeatures.filter(EStructuralFeature).findFirst[f | f.name == field.name] + if( res === null) { + val t = field.type + // if ref + val eRef = EcoreFactory.eINSTANCE.createEReference + eRef.name = aspect.name + val ed = TransactionUtil.getEditingDomain(getAspectResource()); + var RecordingCommand command = new RecordingCommand(ed, + "Creating EReference for aspect class coming from K3") { + protected override void doExecute() { + c.getEStructuralFeatures.add(eRef) + } + }; + CommandExecution.execute(ed, command); + + // else if attribute + // TODO + res = eRef + } + return res + } + + protected def EClass getAspectEClass(Class aspect){ + val p = getAspectEPackage(aspect) + var res = p.EClassifiers.filter(EClass).findFirst[c | c.name == aspect.simpleName] + if(res === null) { + val c = EcoreFactory.eINSTANCE.createEClass + c.name = aspect.simpleName + val ed = TransactionUtil.getEditingDomain(getAspectResource()); + var RecordingCommand command = new RecordingCommand(ed, + "Creating EClass for aspect class coming from K3") { + protected override void doExecute() { + p.EClassifiers.add(c) + } + }; + CommandExecution.execute(ed, command); + + res = c + } + return res + } + protected def EPackage getAspectEPackage(Class aspect){ + var res = getAspectResource().contents.filter(EPackage).findFirst[p | p.name == aspect.package.name] + if(res === null) { + val p = EcoreFactory.eINSTANCE.createEPackage + p.name = aspect.package.name + val ed = TransactionUtil.getEditingDomain(getAspectResource()); + var RecordingCommand command = new RecordingCommand(ed, + "Creating EPackage for aspect class coming from K3") { + protected override void doExecute() { + getAspectResource().contents.add(p) + } + }; + CommandExecution.execute(ed, command); + res = p + } + return res + } + protected def Resource getAspectResource() { + if(aspectEMFResource === null) { + aspectEMFResource = engine.executionContext.resourceModel.resourceSet.createResource(URI.createURI("dummyResourceForK3Aspects")); + } + return aspectEMFResource + } +} \ No newline at end of file diff --git a/trace/manager/plugins/org.eclipse.gemoc.addon.multidimensional.timeline/.classpath b/trace/manager/plugins/org.eclipse.gemoc.addon.multidimensional.timeline/.classpath index 35506931e..54c1d2f00 100644 --- a/trace/manager/plugins/org.eclipse.gemoc.addon.multidimensional.timeline/.classpath +++ b/trace/manager/plugins/org.eclipse.gemoc.addon.multidimensional.timeline/.classpath @@ -3,5 +3,6 @@ + diff --git a/trace/manager/plugins/org.eclipse.gemoc.addon.multidimensional.timeline/META-INF/MANIFEST.MF b/trace/manager/plugins/org.eclipse.gemoc.addon.multidimensional.timeline/META-INF/MANIFEST.MF index e35895931..290949f66 100644 --- a/trace/manager/plugins/org.eclipse.gemoc.addon.multidimensional.timeline/META-INF/MANIFEST.MF +++ b/trace/manager/plugins/org.eclipse.gemoc.addon.multidimensional.timeline/META-INF/MANIFEST.MF @@ -21,8 +21,7 @@ Require-Bundle: org.eclipse.gemoc.timeline;bundle-version="1.0.0", org.eclipse.gemoc.dsl.debug.ide.sirius.ui;bundle-version="1.0.0", org.eclipse.gemoc.dsl.debug.ide, org.eclipse.gemoc.xdsmlframework.api, - org.eclipse.gemoc.executionframework.debugger, - org.eclipse.fx.core + org.eclipse.gemoc.executionframework.debugger Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Export-Package: org.eclipse.gemoc.addon.multidimensional.timeline,