Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » How to pass object to the Xtext plugin
How to pass object to the Xtext plugin [message #1278392] Thu, 27 March 2014 09:14 Go to next message
Marcus Höpfner is currently offline Marcus HöpfnerFriend
Messages: 53
Registered: February 2014
Member
Hi,

I have generated a grammar out of an element of my ecore.
Let's say my ecore is UNIVERSE and the grammar is for EARTH which is an element in UNIVERSE.

I have an eclipse ui plugin which uses the xtext grammar plugin for EARTH and is showing the EARTH grammar in a popup (org.eclipse.xtext.ui.editor.embedded.EmbeddedEditor).
In an xtext value converter I need access to UNIVERSE. So I added a method in the runtime module which returns UNIVERSE and is annotated with @Provides (Guice).

My question is how do I pass UNIVERSE to the my xtext plugin?
One solution would be a constructor accepting UNIVERSE in RuntimeModule. And then pass it through the plugin's activator. But then I need to change some other classes (StandaloneSetupGenerated, ExecutableExtensionFactory, ...) which are creating RuntimeModule.

I also did not find a solution to pass it to the XtextResource for EARTH.

Thanks in advance.

Regards, Marcus
Re: How to pass object to the Xtext plugin [message #1278753 is a reply to message #1278392] Thu, 27 March 2014 20:07 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 13373
Registered: July 2009
Senior Member
Hi,

i dont get your point, can you be a bit more specific?


Need professional support for Xtext, Xpand, EMF?
Go to: https://www.itemis.com/en/xtext/
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: How to pass object to the Xtext plugin [message #1279123 is a reply to message #1278753] Fri, 28 March 2014 09:01 Go to previous messageGo to next message
Marcus Höpfner is currently offline Marcus HöpfnerFriend
Messages: 53
Registered: February 2014
Member
Hi,

in my Xtext plugin I need access to SOMETHING which comes from the outside.
As far as I understand Google Guice I would write a method in the RuntimeModule which returns SOMETHING and which is annotated with @Provides.
But how to pass an instance of SOMETHING to the RuntimeModule. I thought through constructor. But then I need to change a bunch of calls to runtime module and I need to pass SOMETHING to some methods of the plugin's Activator.
So I was wondering whether this is the right way whenever Xtext grammar plugins have a dependency to objects from outside.

Did you get my point?

Here is some coding snippet of the RuntimeModule if I would change it:
/*
 * generated by Xtext
 */
package com.sap.bw.qd.formula;

import org.eclipse.xtext.conversion.IValueConverterService;

import com.google.inject.Provides;
import com.sap.bw.qd.formula.valueconverter.ValueConverterService;
import com.sap.bw.qd.model.query.Query;

/**
 * Use this class to register components to be used at runtime / without the
 * Equinox extension registry.
 */
public class QueryFormulaRuntimeModule extends AbstractQueryFormulaRuntimeModule {
	private Query query;

	public QueryFormulaRuntimeModule(Query query) {
		super();
		this.query = query;
	}

	@Override
	public Class<? extends IValueConverterService> bindIValueConverterService() {
		return ValueConverterService.class;
	}


	@Provides
	Query provideQuery() {
		return query;
	}

}

And the plugin's activator (also already changed). You can see that I need to pass Query through some methods.
/*
 * generated by Xtext
 */
package com.sap.bw.qd.formula.ui.internal;

import java.util.Collections;
import java.util.Map;

import org.apache.log4j.Logger;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.eclipse.xtext.ui.shared.SharedStateModule;
import org.eclipse.xtext.util.Modules2;
import org.osgi.framework.BundleContext;

import com.google.common.collect.Maps;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Module;
import com.sap.bw.qd.model.query.Query;

/**
 * This class was generated. Customizations should only happen in a newly
 * introduced subclass. 
 */
public class QueryFormulaActivator extends AbstractUIPlugin {
	
	public static final String COM_SAP_BW_QD_FORMULA_QUERYFORMULA = "com.sap.bw.qd.formula.QueryFormula";
	
	private static final Logger logger = Logger.getLogger(QueryFormulaActivator.class);
	
	private static QueryFormulaActivator INSTANCE;
	
	private Map<String, Injector> injectors = Collections.synchronizedMap(Maps.<String, Injector> newHashMapWithExpectedSize(1));
	
	@Override
	public void start(BundleContext context) throws Exception {
		super.start(context);
		INSTANCE = this;
	}
	
	@Override
	public void stop(BundleContext context) throws Exception {
		injectors.clear();
		INSTANCE = null;
		super.stop(context);
	}
	
	public static QueryFormulaActivator getInstance() {
		return INSTANCE;
	}
	
	public Injector getInjector(String language, Query query) {
		synchronized (injectors) {
			Injector injector = injectors.get(language);
			if (injector == null) {
				injectors.put(language, injector = createInjector(language, query));
			}
			return injector;
		}
	}
	
	protected Injector createInjector(String language, Query query) {
		try {
			Module runtimeModule = getRuntimeModule(language, query);
			Module sharedStateModule = getSharedStateModule();
			Module uiModule = getUiModule(language);
			Module mergedModule = Modules2.mixin(runtimeModule, sharedStateModule, uiModule);
			return Guice.createInjector(mergedModule);
		} catch (Exception e) {
			logger.error("Failed to create injector for " + language);
			logger.error(e.getMessage(), e);
			throw new RuntimeException("Failed to create injector for " + language, e);
		}
	}

	protected Module getRuntimeModule(String grammar, Query query) {
		if (COM_SAP_BW_QD_FORMULA_QUERYFORMULA.equals(grammar)) {
			return new com.sap.bw.qd.formula.QueryFormulaRuntimeModule(query);
		}
		
		throw new IllegalArgumentException(grammar);
	}
	
	protected Module getUiModule(String grammar) {
		if (COM_SAP_BW_QD_FORMULA_QUERYFORMULA.equals(grammar)) {
			return new com.sap.bw.qd.formula.ui.QueryFormulaUiModule(this);
		}
		
		throw new IllegalArgumentException(grammar);
	}
	
	protected Module getSharedStateModule() {
		return new SharedStateModule();
	}
	
}


And additionally I would need to adapt:


  • QueryFormulaStandaloneSetupGenerated
  • QueryFormulaExecutableExtensionFactory
  • QueryFormulaUiInjectorProvider

Because the either call Activator.createInjector or they construct an instance of the RuntimeModule.


Thanks, Marcus

Re: How to pass object to the Xtext plugin [message #1279148 is a reply to message #1279123] Fri, 28 March 2014 09:47 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 13373
Registered: July 2009
Senior Member
Hi I still don't understand what something is and where it comes from
and how it is created.
Depending on how this is done a simple bind method in the runtime or
uimodule may do the job.

So can you be a bit more specific about the use case.

--
Need training, onsite consulting or any other kind of help for Xtext?
Go visit http://xtext.itemis.com or send a mail to xtext at itemis dot de


Need professional support for Xtext, Xpand, EMF?
Go to: https://www.itemis.com/en/xtext/
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: How to pass object to the Xtext plugin [message #1279178 is a reply to message #1279148] Fri, 28 March 2014 10:45 Go to previous messageGo to next message
Uli Merkel is currently offline Uli MerkelFriend
Messages: 248
Registered: June 2013
Senior Member
not sure, but have a look at: http://christiandietrich.wordpress.com/2012/08/07/xtext-referencing-elements-of-one-dsl-from-another-dsl/ ?
Re: How to pass object to the Xtext plugin [message #1279224 is a reply to message #1279178] Fri, 28 March 2014 12:25 Go to previous messageGo to next message
Marcus Höpfner is currently offline Marcus HöpfnerFriend
Messages: 53
Registered: February 2014
Member
Ok. Sorry. Let's put it simple.
Keep aside the fact that this is Xtext for a moment.

Imagine I have a plugin which depends on another one which uses Guice. In order to pass an object to the plugin I'd call
Guice.createInjector(new Module(myObjectIWantToPass));
from the first plugin.


In Xtext the RuntimeModule is created by the Activator. Do I have to pass my object (which is just a java class) to the Activator and all the protected methods inside like this:
Activator.getInstance().getInjector(myGrammar, myObjectIWantToPass)
and then to the constructor of the RuntimeModule (I need the object in the RuntimeModule!)?

Then I need to adapt quite some coding! Because beside RuntimeModule there are other generated (by Xtext project wizard) modules depending on it. Is this how it should be done?

This is not about using as DSL in another one. This is just about creating an Injector for the Xtext plugin and pass in some objects which it need to know. Just Java classes.

Probably this is so simple and I cannot see it/believe it.
Re: How to pass object to the Xtext plugin [message #1279227 is a reply to message #1279224] Fri, 28 March 2014 12:28 Go to previous messageGo to next message
Joerg Reichert is currently offline Joerg ReichertFriend
Messages: 80
Registered: July 2009
Location: Leipzig
Member
Hi Marcus,

maybe this helps you:
http://koehnlein.blogspot.de/2012/11/xtext-tip-how-do-i-get-guice-injector.html

Best regards,
Joerg


--
Need professional support for Xtext and EMF?
Go to: http://xtext.itemis.com
Re: How to pass object to the Xtext plugin [message #1279274 is a reply to message #1279227] Fri, 28 March 2014 13:52 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 13373
Registered: July 2009
Senior Member
Hi,

i still have no idea what "an object" is. can you be a bit more specific on that? and from what context do you want to pass it to the plugin?


Need professional support for Xtext, Xpand, EMF?
Go to: https://www.itemis.com/en/xtext/
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: How to pass object to the Xtext plugin [message #1279280 is a reply to message #1279274] Fri, 28 March 2014 14:04 Go to previous messageGo to next message
Marcus Höpfner is currently offline Marcus HöpfnerFriend
Messages: 53
Registered: February 2014
Member
Hi,

I have no more ideas how to explain it.

An object is an instance of a simple java class. Whatever you like. It doesn't matter.


This object xyz is created by plugin A.

Afterwards the Xtext mydsl plugin B is accessed by A by
Injector i = <MyDSL>Activator.getInstance().getInjector(<MyDsl>)
.
Because A want to show the dsl in a popup.

In B an IValueConverter is used which needs the object xyz from A.

How does xyz go to the IValueConverter implementation?



Re: How to pass object to the Xtext plugin [message #1279313 is a reply to message #1279280] Fri, 28 March 2014 15:09 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 13373
Registered: July 2009
Senior Member
sorry i have no idea on that without knowing anything about "the object" in eclipse there are several possibilities to share things. ususally NOT by direct access.


so is the object a string? or a service? or an hibernate entity or whatever?

and what kind of access it that? creating an injector i would not call "calling"


Need professional support for Xtext, Xpand, EMF?
Go to: https://www.itemis.com/en/xtext/
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de

[Updated on: Fri, 28 March 2014 15:11]

Report message to a moderator

Re: How to pass object to the Xtext plugin [message #1279320 is a reply to message #1279280] Fri, 28 March 2014 15:16 Go to previous messageGo to next message
Joerg Reichert is currently offline Joerg ReichertFriend
Messages: 80
Registered: July 2009
Location: Leipzig
Member
Maybe you should get more clearer about the workflow

My assumtion:

Runtime time
- Project
- myquery.query
- myformula.formula

You open the myformula file and there might be some element in the DSL for which you want to show the content of some query defined in myquery as pop up / hover. The matching between formula and query might be only by some naming convention, so there might be no direct relationship between formula and query required. But for this need to load the content the matching query DSL artifact on the class path, transform it via value converter to show it in the hover.

Does this describe your use case?


--
Need professional support for Xtext and EMF?
Go to: http://xtext.itemis.com
Re: How to pass object to the Xtext plugin [message #1279321 is a reply to message #1279313] Fri, 28 March 2014 15:18 Go to previous messageGo to next message
Marcus Höpfner is currently offline Marcus HöpfnerFriend
Messages: 53
Registered: February 2014
Member
@Joerg: it is much simpler. Smile
Replying to Christian.

Ah ok, sorry!

It is an EMF Object called Query.

A Query contains a FormulaDefinition.
The Xtext plugin was generated for the FormulaDefinition.

From the "query editor" the formula defintion is opened in a popup.
Within the xtext plugin's one ValueConverter needs access to other objects of the Query.

[Updated on: Fri, 28 March 2014 15:20]

Report message to a moderator

Re: How to pass object to the Xtext plugin [message #1279325 is a reply to message #1279321] Fri, 28 March 2014 15:26 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 13373
Registered: July 2009
Senior Member
Hi,

do you pass the resource that contains the query AND the formula to the embbeded editor?
if so you could use the INOde in the valueconverter to obtain the eobject for the formula (using nodemodelutil)
and go the container hierarchy up to get the query.


Need professional support for Xtext, Xpand, EMF?
Go to: https://www.itemis.com/en/xtext/
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: How to pass object to the Xtext plugin [message #1279340 is a reply to message #1279325] Fri, 28 March 2014 15:55 Go to previous message
Marcus Höpfner is currently offline Marcus HöpfnerFriend
Messages: 53
Registered: February 2014
Member
Hi,

I'm not sure whether this is possible since Query is not an Xtext resource.
I get the formula definition as eobject, serialize it and pass the result string to EmbeddedEditor.createPartialEditor.
Also in the ValueService I need the Query in both, getValue and getString. But the node is passed to getValue only.

I did something else. I implemented a DataContainer class in the Xtext plugin and bound it as singleton in the RuntimeModule.
It looks like this:
package com.sap.bw.qd.formula.datacontainer;

import com.sap.bw.qd.model.query.Query;

public class DataContainer implements IDataContainer {
	private Query query;

	@Override
	public Query getQuery() {
		return query;
	}

	@Override
	public void setQuery(Query query) {
		this.query = query;
	}

}


In the query editor plugin after created the Injector I do
injector.getInstance(IDataContainer.class).setQuery(query);


Everywhere I need it, e.g. ValueConverter, I inject the IDataContainer.

What do you think?
Previous Topic:Xtext 2.5.0 missing from update site
Next Topic:Xtext Functionality doesnot work when eclipse.ui plugins are supressed
Goto Forum:
  


Current Time: Sat Feb 29 10:17:57 GMT 2020

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

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

Back to the top