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: 10544
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
	}

}
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: 10544
Registered: July 2009
Senior Member
That do you exactly want to change and where is the client place where it is not working?
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: 10544
Registered: July 2009
Senior Member
well should the properties reading done by

org.eclipse.xtext.builder.EclipseOutputConfigurationProvider.createAndOverlayOutputConfiguration(IProject, IPreferenceStore, OutputConfiguration)
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: 10544
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
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: Fri May 26 13:10:00 GMT 2017

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

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