Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » How to bind IContextualOutputConfigurationProvider as ConfigurationsProvider
How to bind IContextualOutputConfigurationProvider as ConfigurationsProvider [message #1752749] Thu, 26 January 2017 20:59 Go to next message
Thomas Trocha is currently offline Thomas TrochaFriend
Messages: 11
Registered: October 2011
Junior Member
Hi there,

I'm trying to bind IContextualOutputConfigurationProvider to get a reference to the current resource when providing my custom output configurations, but I can't get it to work. Just binding it doesn't work. At least my implementation is not called at any time.

	    binder.bind(IContextualOutputConfigurationProvider)
	        .to(CustomOutputConfigurationProvider)
	        .in(Singleton);


Hints would be very very very appreciated.

EDIT:
I tried to override EclipseOutputConfigurationProvider in the ui-project which would make absolute sense. But for some reason the EclipseOutputConifugrationProvider stays in charge...!?

In the UiModule:
	override Class<? extends IContextualOutputConfigurationProvider> bindIContextualOutputConfigurationProvider() {
		return CustomOutputConfigurationProvider;
	}


Thx

[Updated on: Thu, 26 January 2017 21:24]

Report message to a moderator

Re: How to bind IContextualOutputConfigurationProvider as ConfigurationsProvider [message #1752751 is a reply to message #1752749] Thu, 26 January 2017 21:15 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 11202
Registered: July 2009
Senior Member
hmmm the following works fine for me

class MyDslRuntimeModule extends AbstractMyDslRuntimeModule {
	
	def Class<? extends IOutputConfigurationProvider> bindIOutputConfigurationProvider() {
		MyDslOutputConfigurationProvider
	}
	def Class<? extends IContextualOutputConfigurationProvider2> bindIContextualOutputConfigurationProvider2() {
		MyDslOutputConfigurationProvider
	}
	def Class<? extends IContextualOutputConfigurationProvider> bindIContextualOutputConfigurationProvider() {
		MyDslOutputConfigurationProvider
	}
}


or short

class MyDslRuntimeModule extends AbstractMyDslRuntimeModule {

	def Class<? extends OutputConfigurationProvider> bindIOutputConfigurationProvider() {
		MyDslOutputConfigurationProvider
	}

}


Need professional support for Xtext, Xpand, EMF?
Go to: http://xtext.itemis.com
Twitter : @chrdietrich
Blog : christiandietrich.wordpress.com
Re: How to bind IContextualOutputConfigurationProvider as ConfigurationsProvider [message #1752760 is a reply to message #1752751] Thu, 26 January 2017 22:04 Go to previous messageGo to next message
Thomas Trocha is currently offline Thomas TrochaFriend
Messages: 11
Registered: October 2011
Junior Member
Thx for your fast reply.

Still not working for me. Ok, my CustomOutputConfigurationProvider is bound but as long as this EclipseOutputConfigurationProvider is inbetween, I do not see a chance that the callback for IContextualOutputConfigurationProvider or IContextualOutputConfigurationProvider2 is called.

Here only the default context-less getOutputConfiguration() is called:

	public Set<OutputConfiguration> getOutputConfigurations(IProject project) {
		IPreferenceStore store = getPreferenceStoreAccess().getContextPreferenceStore(project);
		Set<OutputConfiguration> outputConfigurations = new LinkedHashSet<OutputConfiguration>(getOutputConfigurations().size());
		for (OutputConfiguration output : getOutputConfigurations()) {
			OutputConfiguration configuration = createAndOverlayOutputConfiguration(project, store, output);
			outputConfigurations.add(configuration);
		}
		return outputConfigurations;
	}


If I would be able to override EclipseOutputConfigurationProvider in the UI-Module that might a solution.
Re: How to bind IContextualOutputConfigurationProvider as ConfigurationsProvider [message #1752761 is a reply to message #1752760] Thu, 26 January 2017 22:12 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 11202
Registered: July 2009
Senior Member
That do you exactly want to change and where is the client place where it is not working?

Need professional support for Xtext, Xpand, EMF?
Go to: http://xtext.itemis.com
Twitter : @chrdietrich
Blog : christiandietrich.wordpress.com
Re: How to bind IContextualOutputConfigurationProvider as ConfigurationsProvider [message #1752762 is a reply to message #1752761] Thu, 26 January 2017 22:21 Go to previous messageGo to next message
Thomas Trocha is currently offline Thomas TrochaFriend
Messages: 11
Registered: October 2011
Junior Member
This is my CustomOutputConfigurationProvider. I do need one of the Contextual-methods to be called e.g. getOutputConfigurations(Resource res). But
I get only the context-less call through. When debugging I see that my custom provider is set a delegate in the EclipseOuputConfigurationProvider. But this is never
calling the context-specific provider (see the code-snippet in my last post)

I do need the context because I have project-specific properties and I need from somewhere the current IProject.

public class CustomOutputConfigurationProvider extends OutputConfigurationProvider {

	public static final String GEN_ONCE_OUTPUT = "gen-once";

	/**
	 * @return a set of {@link OutputConfiguration} available for the generator
	 */
	override def Set<OutputConfiguration> getOutputConfigurations() {
		// This IS called! But I don't want or need this one! I need getOutputConfigurations(Resource context) to be called
		val OutputConfiguration defaultOutput = new OutputConfiguration(IFileSystemAccess.DEFAULT_OUTPUT);
		defaultOutput.setDescription("Default Output - Overwrite");
		defaultOutput.setOutputDirectory("./out-src/src-gen");
		defaultOutput.setOverrideExistingResources(true);
		defaultOutput.setCreateOutputDirectory(true);
		defaultOutput.setCleanUpDerivedResources(true);
		defaultOutput.setSetDerivedProperty(true);
		defaultOutput.useOutputPerSourceFolder = true;

		return newHashSet(defaultOutput);
	}

	override getOutputConfigurations(Resource context) {
		// THIS CALL I DO NEED. I have project-specific properties and to retrieve those I do need to have a resource
		// with which I can get the IProject 
	}

	override getOutputConfigurations(ResourceSet context) {
		// SAME APPLIES HERE
	}
}
Re: How to bind IContextualOutputConfigurationProvider as ConfigurationsProvider [message #1752765 is a reply to message #1752762] Thu, 26 January 2017 23:26 Go to previous messageGo to next message
Thomas Trocha is currently offline Thomas TrochaFriend
Messages: 11
Registered: October 2011
Junior Member
Ok, I got it to work but it feels a bit hacky. Here is what I did.

1) Write OutputConfigurationProvider that implements IContextualOutputProvider2 and place it somewhere in your MyDSL-Modules main-module
public class CustomOutputConfigurationProvider  implements IContextualOutputConfigurationProvider2 {

	override getOutputConfigurations(ResourceSet context) {
		if (context.resources.size()>0){
			// we are now context-aware. With the resource we can access the project
			val Resource res = context.resources.get(0);
			val path = res.URI.toPlatformString(true);
			val file = ResourcesPlugin.workspace.root.findMember(path) as IFile;
			val IProject project = file.project		
			// do what you want! e.g. read properties (as I intend to do)
			val OutputConfiguration defaultOutput = new OutputConfiguration(IFileSystemAccess.DEFAULT_OUTPUT);
			defaultOutput.setDescription("Default Output - Overwrite");
			defaultOutput.setOutputDirectory("./out-src/src-gen");
			defaultOutput.setOverrideExistingResources(true);
			defaultOutput.setCreateOutputDirectory(true);
			defaultOutput.setCleanUpDerivedResources(true);
			defaultOutput.setSetDerivedProperty(true);
			defaultOutput.useOutputPerSourceFolder = true;
			return newHashSet(defaultOutput);
		}
		return newHashSet();
	}
}


2) Bind it in your MyDSLRuntimeModule:
	def Class<? extends IContextualOutputConfigurationProvider2> bindIContextualOutputConfigurationProvider2() {
		CustomOutputConfigurationProvider
	}


3)In the UI-Module create a CustomBuilderParticipant that derives from BuilderPartiticpant:
public class CustomBuilderParticipant extends BuilderParticipant {

	@Inject
	private IContextualOutputConfigurationProvider2 outputConfigurationProvider;
	
	@Override
	protected Map<String, OutputConfiguration> getOutputConfigurations(IBuildContext context) {
		Set<OutputConfiguration> configurations = outputConfigurationProvider.getOutputConfigurations(context
				.getResourceSet());
		return uniqueIndex(configurations, new Function<OutputConfiguration, String>() {
			@Override
			public String apply(OutputConfiguration from) {
				return from.getName();
			}
		});
	}
}


4) Bind this in your UI-Modules MsDSLUIModule.xtend:
	override Class<? extends IXtextBuilderParticipant> bindIXtextBuilderParticipant() {
		return CustomBuilderParticipant;
	}


That's it. Seems to work.
Re: How to bind IContextualOutputConfigurationProvider as ConfigurationsProvider [message #1752774 is a reply to message #1752765] Fri, 27 January 2017 08:14 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 11202
Registered: July 2009
Senior Member
well should the properties reading done by

org.eclipse.xtext.builder.EclipseOutputConfigurationProvider.createAndOverlayOutputConfiguration(IProject, IPreferenceStore, OutputConfiguration)


Need professional support for Xtext, Xpand, EMF?
Go to: http://xtext.itemis.com
Twitter : @chrdietrich
Blog : christiandietrich.wordpress.com
Re: How to bind IContextualOutputConfigurationProvider as ConfigurationsProvider [message #1752776 is a reply to message #1752774] Fri, 27 January 2017 08:25 Go to previous messageGo to next message
Thomas Trocha is currently offline Thomas TrochaFriend
Messages: 11
Registered: October 2011
Junior Member
Yes, global properties((Window->Preferences->MyDSL)) are processed via this method . But I need and want settings on a per project basis. (Right-Click on Project where I use my DSL with xtext-nature=>MyDSL=>my-projectspecific prefs). For sure there are more elgant ways to achieve this Wink I love that xText is using so heaviliy dependency injection. *thumbs up*
Thx, for your input. It is highly appreciated.
Re: How to bind IContextualOutputConfigurationProvider as ConfigurationsProvider [message #1752783 is a reply to message #1752776] Fri, 27 January 2017 09:09 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 11202
Registered: July 2009
Senior Member
i i still dont get that.

if i go to a projects properties.
then i do to mydsl, then to compiler
then i select "enable project specific settings"
then i can set the output config stuff project specific


Need professional support for Xtext, Xpand, EMF?
Go to: http://xtext.itemis.com
Twitter : @chrdietrich
Blog : christiandietrich.wordpress.com
Re: How to bind IContextualOutputConfigurationProvider as ConfigurationsProvider [message #1752787 is a reply to message #1752783] Fri, 27 January 2017 10:25 Go to previous message
Thomas Trocha is currently offline Thomas TrochaFriend
Messages: 11
Registered: October 2011
Junior Member
Yes, you are right. You can do it this way. I guess it should/could have been my way to go, preventing all that headache Wink
In the end I wanted to use the properties from my data because I actually don't want the 'end user' to be able to configure the output-configurations and therefore created the custom property-page, where
much more other options can be set.

Thanks a lot for leading me through this. If going off the road has one good thing about, it is that you do learn a lot. And that I did Wink
Previous Topic:Loading Xtext model without direct dependency to xtext plugin
Next Topic:Formatting after external EMF change
Goto Forum:
  


Current Time: Tue Sep 19 15:37:19 GMT 2017

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

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