Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » QVT-OML » Swapping out EvaluationVisitor to add instrumentation (dependency injection...?)
Swapping out EvaluationVisitor to add instrumentation (dependency injection...?) [message #1251793] Thu, 20 February 2014 15:58 Go to next message
Christine Gerpheide is currently offline Christine Gerpheide
Messages: 21
Registered: January 2014
Location: Netherlands
Junior Member

We're working on a code coverage tool for QVTo. Basically we run some transformations with specified inputs, and we want to record every mapping/helper/etc that are visited.

To do that, it seems like it would be nice to override some of the methods inside the QvtOperationalEvaluationVisitorImpl class, namely visitMappingOperation(), visitHelper(), etc.

We currently have this working the following way:
Our test cases are run by using jUnit to call classes which execute a transformation with input in a standalone way, by creating a new InternalTransformationExecutor() and running execute(). Before we call execute(), however, we perform executor.setEnvironmentFactory(ourEnvFactory), passing in a class we created that extends QvtOperationalEnvFactory, overriding its createEvaluationVisitor() method so that it provides an instance of QvtOperationalEvaluationVisitorImpl() which has the visit* operations overridden. Whew. In (pseudo)code:

public class OurEnvFactory extends QvtOperationalEnvFactory {
	
	@Override
	public EvaluationVisitor<stuff> createEvaluationVisitor(stuff)
	{
		return new QvtOperationalEvaluationVisitorImpl((QvtOperationalEnv)env, (QvtOperationalEvaluationEnv)evalEnv)
		{
			
			@Override
			public Object visitMappingOperation(MappingOperation mappingOperation)
			{
				// our new code here!
				
				return super.visitMappingOperation(mappingOperation);
			}
		};
	}
}

// And to actually execute

...
internalExecutor.setEnvironmentFactory(ourEnvFactory); // Instrumented visitor
ExecutionDiagnostic result = internalExecutor.execute(context1, input,output);
...



Honestly, this way works for us, since we manually create the InternalTransformationExecutor anyway, and we can just say "if java argument COMPUTECOVERAGE set then set our new envFactory first" inside our code. Or ideally we actually create a new launch mode like the EclEmma tool, but internally in our code it would still have that if statement.

But it seems like there ought to be a more generic way, a la dependency injection or so? Basically, we'd ideally have it so you could take any QVTo run config you have and run it in coverage mode, which would somehow get the EvaluationVisitor swapped out with the instrumented one. Then it's useful for people besides us, and we'd like to open source this afterwards if we can.

We also thought of using the bytecode instrumenting capabilities of java.lang.instrumentor, but hopefully that's overkill.

So, for you who understand design patterns and things much better than me, is there a nicer way? Either by cleverly extending/overriding classes or hints for patches we could submit for QVTo that would make this easier?

Thanks in advance for any ideas,
Christine


[Updated on: Thu, 20 February 2014 15:58]

Report message to a moderator

Re: Swapping out EvaluationVisitor to add instrumentation (dependency injection...?) [message #1251821 is a reply to message #1251793] Thu, 20 February 2014 16:30 Go to previous messageGo to next message
Ed Willink is currently offline Ed Willink
Messages: 4098
Registered: July 2009
Senior Member
Hi

You'll see that the underlying OCL EvaluationVisitor is designed tio
have decorators such as a tracer. So you don't need to derive, you can
just deciorate (provided that all the WQVTo calls observe the
getVisitor() protocol.

See org.eclipse.ocl.internal.evaluation.TracingEvaluationVisitor.

Regards

Ed Willink

On 20/02/2014 15:58, Chris Gerpheide wrote:
> We're working on a code coverage tool for QVTo. Basically we run some
> transformations with specified inputs, and we want to record every
> mapping/helper/etc that are visited.
> To do that, it seems like it would be nice to override some of the
> methods inside the QvtOperationalEvaluationVisitorImpl class, namely
> visitMappingOperation(), visitHelper(), etc.
>
> We currently have this working the following way:
> Our test cases are run by using jUnit to call classes which execute a
> transformation with input in a standalone way, by creating a new
> InternalTransformationExecutor() and running execute(). Before we call
> execute(), however, we perform
> executor.setEnvironmentFactory(ourEnvFactory), passing in a class we
> created that extends QvtOperationalEnvFactory, overriding its
> createEvaluationVisitor() method so that it provides an instance of
> QvtOperationalEvaluationVisitorImpl() which has the visit* operations
> overridden. Whew. In (pseudo)code:
>
>
> public class OurEnvFactory extends QvtOperationalEnvFactory {
>
> @Override
> public EvaluationVisitor<stuff> createEvaluationVisitor(stuff)
> {
> return new
> QvtOperationalEvaluationVisitorImpl((QvtOperationalEnv)env,
> (QvtOperationalEvaluationEnv)evalEnv)
> {
>
> @Override
> public Object visitMappingOperation(MappingOperation
> mappingOperation)
> {
> // our new code here!
>
> return super.visitMappingOperation(mappingOperation);
> return result;
> }
> };
> }
> }
>
> // And to actually execute
>
> ...
> internalExecutor.setEnvironmentFactory(ourEnvFactory); // Instrumented
> visitor
> ExecutionDiagnostic result = internalExecutor.execute(context1,
> input,output);
> ...
>
>
>
> Honestly, this way works for us, since we manually create the
> InternalTransformationExecutor anyway, and we can just say "if java
> argument COMPUTECOVERAGE set then set our new envFactory first" inside
> our code. Or ideally we actually create a new launch mode like the
> EclEmma tool, but internally in our code it would still have that if
> statement.
>
> But it seems like there ought to be a more generic way, a la
> dependency injection or so? Basically, we'd ideally have it so you
> could take any QVTo run config you have and run it in coverage mode,
> which would somehow get the EvaluationVisitor swapped out with the
> instrumented one. Then it's useful for people besides us, and we'd
> like to open source this afterwards if we can.
>
> We also thought of using the bytecode instrumenting capabilities of
> java.lang.instrumentor, but hopefully that's overkill.
> So, for you who understand design patterns and things much better than
> me, is there a nicer way? Either by cleverly extending/overriding
> classes or hints for patches we could submit for QVTo that would make
> this easier?
>
> Thanks in advance for any ideas,
> Christine
>
>
>
Re: Swapping out EvaluationVisitor to add instrumentation (dependency injection...?) [message #1251891 is a reply to message #1251821] Thu, 20 February 2014 18:13 Go to previous messageGo to next message
Christine Gerpheide is currently offline Christine Gerpheide
Messages: 21
Registered: January 2014
Location: Netherlands
Junior Member

Hi Ed,

Could you provide a little more guidance? Are you suggesting then that I could extend the EvaluationVisitorDecorator instead of the QvtOperationalEvaluationVisitorImpl, and provide the wrapped object as the return for createEvaluationVisitor() in my EnvFactory as above? Like:

public class OurEnvFactory extends QvtOperationalEnvFactory {
	
	@Override
	public EvaluationVisitor<stuff> createEvaluationVisitor(stuff)
	{
		return new MyVisitorDecorator(new QvtOperationalEvaluationVisitorImpl((QvtOperationalEnv)env, (QvtOperationalEvaluationEnv)evalEnv));
	}
}


public class MyVisitorDecorator<stuff> extends EvaluationVisitorDecorator<stuff> {
// Would prefer not to implement InternalEvaluator since there are so many methods

	private QvtOperationalEvaluationVisitorImpl delegate;
	
    public MyVisitorDecorator(EvaluationVisitor<stuff> decorated) {
        super(decorated);
        if (decorated instanceof QvtOperationalEvaluationVisitorImpl) {
        	delegate = (QvtOperationalEvaluationVisitorImpl) decorated;
        }
    }
    
	public Object visitMappingOperation(MappingOperation mappingOperation)
	{
		return delegate.visitMappingOperation(mappingOperation); 
	}


If so, I'm a little confused how to make that work, since the EvaluationVisitorDecorator doesn't implement all the interfaces that QvtOperationalEvaluationVisitorImpl needs to (like org.eclipse.m2m.internal.qvt.oml.evaluator.InternalEvaluator), and adding implementation for all the methods for InternalEvaluator is a lot (so then it puts be back to wanting to extend QvtOperationalEvaluationVisitorImpl instead of decorate it). Furthermore, if this is what you meant, is it actually nicer, since I stil have to create and set my own envFactory? Or are there other decorators/interfaces you were referring to?

Thanks again for the direction,
Christine
Re: Swapping out EvaluationVisitor to add instrumentation (dependency injection...?) [message #1251896 is a reply to message #1251891] Thu, 20 February 2014 18:17 Go to previous messageGo to next message
Ed Willink is currently offline Ed Willink
Messages: 4098
Registered: July 2009
Senior Member
Hi

Sorry, I was only outlining the underlying design. I'm afraid that I'm
not sure whether QVTo fully implements it.


Regards

Ed Willink

On 20/02/2014 18:13, Chris Gerpheide wrote:
> Hi Ed,
>
> Could you provide a little more guidance? Are you suggesting then that
> I could extend the EvaluationVisitorDecorator instead of the
> QvtOperationalEvaluationVisitorImpl, and provide the wrapped object as
> the return for createEvaluationVisitor() in my EnvFactory as above? Like:
>
>
> public class OurEnvFactory extends QvtOperationalEnvFactory {
>
> @Override
> public EvaluationVisitor<stuff> createEvaluationVisitor(stuff)
> {
> return new MyVisitorDecorator(new
> QvtOperationalEvaluationVisitorImpl((QvtOperationalEnv)env,
> (QvtOperationalEvaluationEnv)evalEnv));
> }
> }
>
>
> public class MyVisitorDecorator<stuff> extends
> EvaluationVisitorDecorator<stuff> {
> // Would prefer not to implement InternalEvaluator since there are so
> many methods
>
> private QvtOperationalEvaluationVisitorImpl delegate;
>
> public MyVisitorDecorator(EvaluationVisitor<stuff> decorated) {
> super(decorated);
> if (decorated instanceof QvtOperationalEvaluationVisitorImpl) {
> delegate = (QvtOperationalEvaluationVisitorImpl) decorated;
> }
> }
> public Object visitMappingOperation(MappingOperation
> mappingOperation)
> {
> return delegate.visitMappingOperation(mappingOperation); }
>
>
> If so, I'm a little confused how to make that work, since the
> EvaluationVisitorDecorator doesn't implement all the interfaces that
> QvtOperationalEvaluationVisitorImpl needs to (like
> org.eclipse.m2m.internal.qvt.oml.evaluator.InternalEvaluator), and
> adding implementation for all the methods for InternalEvaluator is a
> lot (so then it puts be back to wanting to extend
> QvtOperationalEvaluationVisitorImpl instead of decorate it).
> Furthermore, if this is what you meant, is it actually nicer, since I
> stil have to create and set my own envFactory? Or are there other
> decorators/interfaces you were referring to?
>
> Thanks again for the direction,
> Christine
Re: Swapping out EvaluationVisitor to add instrumentation (dependency injection...?) [message #1252829 is a reply to message #1251896] Fri, 21 February 2014 16:47 Go to previous messageGo to next message
Christine Gerpheide is currently offline Christine Gerpheide
Messages: 21
Registered: January 2014
Location: Netherlands
Junior Member

That's fine, just wanted to make sure I understood. For now we'll have an if-statement in our standalone executor that we use to run our tests which just checks if it should do code coverage, and if so, set the new envFactory. I'll post back here if we discover a nicer way in the process. Thank you!
Re: Swapping out EvaluationVisitor to add instrumentation (dependency injection...?) [message #1257253 is a reply to message #1251891] Wed, 26 February 2014 08:10 Go to previous messageGo to next message
Sergey Boyko is currently offline Sergey Boyko
Messages: 162
Registered: July 2009
Senior Member
Chris Gerpheide wrote on Thu, 20 February 2014 13:13
Hi Ed,

...

If so, I'm a little confused how to make that work, since the EvaluationVisitorDecorator doesn't implement all the interfaces that QvtOperationalEvaluationVisitorImpl needs to (like org.eclipse.m2m.internal.qvt.oml.evaluator.InternalEvaluator), and adding implementation for all the methods for InternalEvaluator is a lot (so then it puts be back to wanting to extend QvtOperationalEvaluationVisitorImpl instead of decorate it). Furthermore, if this is what you meant, is it actually nicer, since I stil have to create and set my own envFactory? Or are there other decorators/interfaces you were referring to?

Thanks again for the direction,
Christine


Hi Chris,

In order to follow visitor decoration pattern you'd better use of org.eclipse.m2m.internal.qvt.oml.evaluator.QvtGenericEvaluationVisitor class.
Thus class MyVisitorDecorator might look like:

class MyVisitorDecorator extends QvtGenericEvaluationVisitor {
	
	private QvtOperationalEvaluationVisitor delegate;

	public MyVisitorDecorator(QvtOperationalEvaluationVisitor qvtExtVisitor) {
		super(qvtExtVisitor);
		delegate = qvtExtVisitor;
	}

	public IContext getContext() {
		return delegate.getContext();
	}

	public void setOperationalEvaluationEnv(QvtOperationalEvaluationEnv evalEnv) {
		delegate.setOperationalEvaluationEnv(evalEnv);
	}

	public QvtOperationalEvaluationEnv getOperationalEvaluationEnv() {
		return delegate.getOperationalEvaluationEnv();
	}
	
}


And instantiation code in OurEnvFactory:

public EvaluationVisitor<..> createEvaluationVisitor(...) {

	EvaluationVisitorDecorator<..> decorator = 
		new MyVisitorDecorator((QvtOperationalEvaluationVisitor) super.createEvaluationVisitor(env, evalEnv, extentMap)) {

		@Override
		public Object visitMappingBody(MappingBody mappingBody) {
			...
			return super.visitMappingBody(mappingBody);
		}
		
	};

	return decorator;
}


Btw, have you looked at Eclipse AspectJ project (http://eclipse.org/aspectj/)? It provides elegant and consistent means to inject whatever logic without affecting source code.

Regards,
Sergey
Re: Swapping out EvaluationVisitor to add instrumentation (dependency injection...?) [message #1272224 is a reply to message #1257253] Mon, 17 March 2014 11:59 Go to previous messageGo to next message
Christine Gerpheide is currently offline Christine Gerpheide
Messages: 21
Registered: January 2014
Location: Netherlands
Junior Member

Hello Sergey!

Apparently I didn't have notifications set, so I didn't see this reply. I think these are great suggestions to try. I am looking now at AspectJ to see if I can use it somehow. With the first suggestion though, I'm not sure if a decorator can be created so simply:

I've been trying to use the QvtGenericEvaluationVisitor class as you suggested, but it doesn't seem to call any overridden visit* methods. I haven't yet figured out exactly where it goes awry (I still struggle with how all the internal QVT classes fit together), but maybe it's something like QVT calls a decorated method which internally in the delegate class calls other methods, thus bypassing the decorated instance. Is that possible? I do see that QvtGenericEvaluationVisitor is used by the DebugInterceptor, but that also makes use of the QVTODebugEvaluator that encapsulates it (which extends QvtOperationalEvaluationVisitorImpl), so maybe that's why that one works. So at least so far, I haven't figured out how to use a Decorator without also having a class extending QvtOperationalEvaluationVisitorImpl anyway (and then I'm not sure why to use a decorator instead of the visitor subclass directly). It would be nice if I could just use such a decorator though, since I suppose that's what it's there for.

If this is just me not understanding how to use it properly, please let me know. Or, if this is something that should be improved in the QVT code to make this easier, I'd be happy to try to submit a patch with a little guidance.

Again, thanks for the suggestions,
Chris
Re: Swapping out EvaluationVisitor to add instrumentation (dependency injection...?) [message #1272588 is a reply to message #1272224] Tue, 18 March 2014 09:11 Go to previous messageGo to next message
Christine Gerpheide is currently offline Christine Gerpheide
Messages: 21
Registered: January 2014
Location: Netherlands
Junior Member

Update: I have got a working decorator that extends QvtGenericEvaluationVisitor. It does however need (as far as I can tell) a class extending QvtOperationalEvaluationVisitorImpl to encapsulate it. At first I wasn't sure why the decorator would be useful then if I needed to have my own visitor class anyway, but at the very least the genericPostVisitAST() methods are very convenient. I've added my notes below so anyone can see what is needed to make it work.

Notes to use a visitor decorator:
- The decorator (call it OurDecorator, which extends QvtGenericEvaluationVisitor) should also implement InternalEvaluator, since the Visitor it wraps has to implement that.
- In order to implement InternalEvaluator, the decorator must be encapsulated in an instance of QvtOperationalEvaluationVisitorImpl, since one of the methods it must implement requires access to OperationCallResult, a protected nested class of QvtOperationalEvaluationVisitorImpl.
- The visitor class (call it OurVisitor, which extends QvtOperationalEvaluationVisitorImpl) must override createInterruptibleVisitor() to return itself wrapped in OurDecorator.
- In the env factory (extending QvtOperationalEnvFactory), the new MyVisitor should be returned from createEvaluationVisitor, buthave createInterruptibleVisitor() called on that visitor first.
- Then as described in the above posts, the env factory should be set on the InternalTransformationExecutor before the transformation executes.

Now, the implementation in code:

...
public class OurVisitor extends QvtOperationalEvaluationVisitorImpl implements InternalEvaluator, DeferredAssignmentListener {

	public OurVisitor (QvtOperationalEnv env, QvtOperationalEvaluationEnv evalEnv) {
		super(env, evalEnv);
	}
	
	@Override
	protected InternalEvaluator createInterruptibleVisitor() {
		return new OurDecorator(this);
	}
	
	protected class OurDecorator extends QvtGenericEvaluationVisitor implements InternalEvaluator{
		
		private QvtOperationalEvaluationVisitorImpl delegate;
		
		public OurDecorator(QvtOperationalEvaluationVisitorImpl qvtOperationalEvaluationVisitor) {
			super(qvtOperationalEvaluationVisitor);
			delegate = qvtOperationalEvaluationVisitor;
		}
		
		@Override
		protected Object genericPostVisitAST(ASTNode element,
				Object preVisitState, Object result) {
			
			// Do you interesting stuff here, or in visit* methods.
			
			return super.genericPostVisitAST(element, preVisitState, result);
		}

		@Override
		public IContext getContext() {
			return delegate.getContext();
		}

		@Override
		public void setOperationalEvaluationEnv(QvtOperationalEvaluationEnv evalEnv) {
			delegate.setOperationalEvaluationEnv(evalEnv);
		}

		@Override
		public QvtOperationalEvaluationEnv getOperationalEvaluationEnv() {
			return delegate.getOperationalEvaluationEnv();
		}

		@Override
		public ModuleInstance callTransformationImplicitConstructor(OperationalTransformation transformation, List<ModelInstance> args) {
			return delegate.callTransformationImplicitConstructor(transformation, args);
		}
		
		@Override
		public OperationCallResult runMainEntry(OperationalTransformation transformation, List<Object> args) {
			return delegate.runMainEntry(transformation, args);
		}

		@Override
		public Object execute(OperationalTransformation transformation) throws QvtRuntimeException {
			return delegate.execute(transformation);
		}
	}	
}

...

public class OurEnvFactory extends QvtOperationalEnvFactory{
	
	public QVTOCoverageEnvFactory() {
	}
	
	@Override
	public
	EvaluationVisitor<stuff> createEvaluationVisitor(stuff) {
		
		return new OurVisitor((QvtOperationalEnv) env, (QvtOperationalEvaluationEnv) evalEnv).createInterruptibleVisitor();
	}
}

...

public class OurExecutor extends InternalTransformationExecutor {

	public OurExecutor(URI uri) {
		super(uri);
	}

	@Override
	public ExecutionDiagnostic execute(ExecutionContext executionContext,
			ModelExtent... modelParameters) {
		
		setEnvironmentFactory(new OurEnvFactory());
		return super.execute(executionContext, modelParameters);
	}
}


So that seems to be the current state of affairs with decorators. Seems to be a bit of a hassle (mostly the OurVisitor/OurDecorator classes have more stuff than they should need). I'm not sure the best way to improve it, perhaps start with making the QvtGenericEvaluationVisitor implement InternalEvaluator from the start (which would need OperationCallResult to become a visible class). Then perhaps it would work to just wrap our decorator around a the (new QvtOperationalEvaluationVisitorImpl().createInterruptibleVisitor()). I haven't tested those things yet though.

Chris
Re: Swapping out EvaluationVisitor to add instrumentation (dependency injection...?) [message #1272612 is a reply to message #1272588] Tue, 18 March 2014 10:31 Go to previous messageGo to next message
Ed Willink is currently offline Ed Willink
Messages: 4098
Registered: July 2009
Senior Member
Hi

We can eliminate the needs for workarounds, so that your added
functionality is a clean addition.

If you check out the QVTo sources from GIT you can modify them, raise a
Bugzilla and attach a patch of your changes for us to review. If you
want this to appear in the Luna release you need to react fast since we
are getting close to the Release Candidate stage and strictly limited
enthusiasm for changes.

Regards

Ed Willink

On 18/03/2014 09:11, Christine Gerpheide wrote:
> Update: I have got a working decorator that extends
> QvtGenericEvaluationVisitor. It does however need (as far as I can
> tell) a class extending QvtOperationalEvaluationVisitorImpl to
> encapsulate it. At first I wasn't sure why the decorator would be
> useful then if I needed to have my own visitor class anyway, but at
> the very least the genericPostVisitAST() methods are very convenient.
> I've added my notes below so anyone can see what is needed to make it
> work.
>
> Notes to use a visitor decorator:
> - The decorator (call it OurDecorator, which extends
> QvtGenericEvaluationVisitor) should also implement InternalEvaluator,
> since the Visitor it wraps has to implement that.
> - In order to implement InternalEvaluator, the decorator must be
> encapsulated in an instance of QvtOperationalEvaluationVisitorImpl,
> since one of the methods it must implement requires access to
> OperationCallResult, a protected nested class of
> QvtOperationalEvaluationVisitorImpl.
> - The visitor class (call it OurVisitor, which extends
> QvtOperationalEvaluationVisitorImpl) must override
> createInterruptibleVisitor() to return itself wrapped in OurDecorator.
> - In the env factory (extending QvtOperationalEnvFactory), the new
> MyVisitor should be returned from createEvaluationVisitor, buthave
> createInterruptibleVisitor() called on that visitor first.
> - Then as described in the above posts, the env factory should be set
> on the InternalTransformationExecutor before the transformation executes.
>
> Now, the implementation in code:
>
>
> ...
> public class OurVisitor extends QvtOperationalEvaluationVisitorImpl
> implements InternalEvaluator, DeferredAssignmentListener {
>
> public OurVisitor (QvtOperationalEnv env,
> QvtOperationalEvaluationEnv evalEnv) {
> super(env, evalEnv);
> }
>
> @Override
> protected InternalEvaluator createInterruptibleVisitor() {
> return new OurDecorator(this);
> }
>
> protected class OurDecorator extends QvtGenericEvaluationVisitor
> implements InternalEvaluator{
>
> private QvtOperationalEvaluationVisitorImpl delegate;
>
> public OurDecorator(QvtOperationalEvaluationVisitorImpl
> qvtOperationalEvaluationVisitor) {
> super(qvtOperationalEvaluationVisitor);
> delegate = qvtOperationalEvaluationVisitor;
> }
>
> @Override
> protected Object genericPostVisitAST(ASTNode element,
> Object preVisitState, Object result) {
>
> // Do you interesting stuff here, or in visit* methods.
>
> return super.genericPostVisitAST(element, preVisitState,
> result);
> }
>
> @Override
> public IContext getContext() {
> return delegate.getContext();
> }
>
> @Override
> public void
> setOperationalEvaluationEnv(QvtOperationalEvaluationEnv evalEnv) {
> delegate.setOperationalEvaluationEnv(evalEnv);
> }
>
> @Override
> public QvtOperationalEvaluationEnv
> getOperationalEvaluationEnv() {
> return delegate.getOperationalEvaluationEnv();
> }
>
> @Override
> public ModuleInstance
> callTransformationImplicitConstructor(OperationalTransformation
> transformation, List<ModelInstance> args) {
> return
> delegate.callTransformationImplicitConstructor(transformation, args);
> }
>
> @Override
> public OperationCallResult
> runMainEntry(OperationalTransformation transformation, List<Object>
> args) {
> return delegate.runMainEntry(transformation, args);
> }
>
> @Override
> public Object execute(OperationalTransformation
> transformation) throws QvtRuntimeException {
> return delegate.execute(transformation);
> }
> }
> }
>
> ...
>
> public class OurEnvFactory extends QvtOperationalEnvFactory{
>
> public QVTOCoverageEnvFactory() {
> }
>
> @Override
> public
> EvaluationVisitor<stuff> createEvaluationVisitor(stuff) {
>
> return new OurVisitor((QvtOperationalEnv) env,
> (QvtOperationalEvaluationEnv) evalEnv).createInterruptibleVisitor();
> }
> }
>
> ...
>
> public class OurExecutor extends InternalTransformationExecutor {
>
> public OurExecutor(URI uri) {
> super(uri);
> }
>
> @Override
> public ExecutionDiagnostic execute(ExecutionContext executionContext,
> ModelExtent... modelParameters) {
>
> setEnvironmentFactory(new OurEnvFactory());
> return super.execute(executionContext, modelParameters);
> }
> }
>
>
> So that seems to be the current state of affairs with decorators.
> Seems to be a bit of a hassle (mostly the OurVisitor/OurDecorator
> classes have more stuff than they should need). I'm not sure the best
> way to improve it, perhaps start with making the
> QvtGenericEvaluationVisitor implement InternalEvaluator from the start
> (which would need OperationCallResult to become a visible class).
> Then perhaps it would work to just wrap our decorator around a the
> (new
> QvtOperationalEvaluationVisitorImpl().createInterruptibleVisitor()). I
> haven't tested those things yet though.
>
> Chris
Re: Swapping out EvaluationVisitor to add instrumentation (dependency injection...?) [message #1273122 is a reply to message #1272612] Wed, 19 March 2014 14:54 Go to previous messageGo to next message
Christine Gerpheide is currently offline Christine Gerpheide
Messages: 21
Registered: January 2014
Location: Netherlands
Junior Member

Bug has been raised with a patch exemplifying a possible solution here:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=430677
Re: Swapping out EvaluationVisitor to add instrumentation (dependency injection...?) [message #1273254 is a reply to message #1272588] Wed, 19 March 2014 19:53 Go to previous message
Sergey Boyko is currently offline Sergey Boyko
Messages: 162
Registered: July 2009
Senior Member
Christine Gerpheide wrote on Tue, 18 March 2014 05:11
Update: I have got a working decorator that extends QvtGenericEvaluationVisitor. It does however need (as far as I can tell) a class extending QvtOperationalEvaluationVisitorImpl to encapsulate it. At first I wasn't sure why the decorator would be useful then if I needed to have my own visitor class anyway, but at the very least the genericPostVisitAST() methods are very convenient. I've added my notes below so anyone can see what is needed to make it work.

...

So that seems to be the current state of affairs with decorators. Seems to be a bit of a hassle (mostly the OurVisitor/OurDecorator classes have more stuff than they should need). I'm not sure the best way to improve it, perhaps start with making the QvtGenericEvaluationVisitor implement InternalEvaluator from the start (which would need OperationCallResult to become a visible class). Then perhaps it would work to just wrap our decorator around a the (new QvtOperationalEvaluationVisitorImpl().createInterruptibleVisitor()). I haven't tested those things yet though.



Hi Chris,

All complications in your solution have arisen from the fact that you chose class InternalTransformationExecutor to reuse. While in principal it is possible to use this class it has a lot of internal assumptions and variation points so making it quite difficult for reusing externally.

Much easier is to reuse QvtInterpretedTransformation class. Among other things this class is heavily used by QVTo JUnit testing framework. Take a look at TestQvtInterpreter class in 'org.eclipse.m2m.tests.qvt.oml' plug-in.

Taking two snippets from my previous post to this thread you can extend TestQvtInterpreter like the following:
public class MyQvtInterpretedTransformation extends QvtInterpretedTransformation {

	public MyQvtInterpretedTransformation(IFile transformationFile) {
		super(transformationFile);
		setEnvironmentFactory(new OurEnvFactory());
	}

	public MyQvtInterpretedTransformation(QvtModule qvtModule) {
		super(qvtModule);
		setEnvironmentFactory(new OurEnvFactory());
	}

}


Both mentioned snippets go without any modification.

Then replace 'new QvtInterpretedTransformation(..)' with 'new MyQvtInterpretedTransformation(..)' in TestQvtInterpreter class and you will see that all visit* methods are called.

Regards,
Sergey.
Previous Topic:Adding qvto editor in RCP application
Next Topic:Pass a type as an argument
Goto Forum:
  


Current Time: Sun Oct 26 02:08:20 GMT 2014

Powered by FUDForum. Page generated in 0.01928 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software