Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Eclipse Platform » How to add a perspective dynamically(A master token is needed)
How to add a perspective dynamically [message #898859] Sat, 28 July 2012 10:35 Go to next message
Gabriel Llamas is currently offline Gabriel Llamas
Messages: 1
Registered: July 2012
Junior Member
I want to add a perspective dynamically from the code without using the plugin.xml file. All the information I've obtained about this is that's impossible without "hacking" the Equinox plugin.

Please, see: https://bugs.eclipse.org/bugs/show_bug.cgi?id=295035

The problem is that I cannot add a contribution to the ExtensionRegistry because I need a user or master token, but these tokens cannot be obtained from anywhere, they are created and used internally by the Equinox plugin. The reason they give is to prevent the plugins to add "heavy consuming memory stuff".

The guy that posted the "bug" in the previous link ended with a workarround but he didn't post the solution. The post was made in 2009.

Now, 3 years later what's the status about this? How can I add perspectives dynamically?

This is what I have:

String perspective =
		"<extension " +
				"point=\"org.eclipse.ui.perspectives\">" +
			"<perspective " +
				"class=\"perspectivefactory.PerspectiveFactory2\" " +
				"icon=\"icons/error.gif\" " +
				"id=\"Perspective Creator.perspective2\" " +
				"name=\"name\">" +
			"</perspective>" +
		"</extension>";

try (InputStream in = new ByteArrayInputStream (perspective.getBytes (Charset.defaultCharset ()))){
	IContributor contributor = ContributorFactoryOSGi.createContributor (Platform.getBundle (Activator.PLUGIN_ID));
	Platform.getExtensionRegistry ().addContribution (in, contributor, false, null, null, null);
}catch (UnsupportedEncodingException e){
}catch (IOException e){
	Utils.log (e);
}



but I get the error:

org.eclipse.e4.core.di.InjectionException: java.lang.IllegalArgumentException: Unauthorized access to the ExtensionRegistry.addContribution() method. Check if proper access token is supplied.


That's because I need a master token. using Reflection I can get it:

public static boolean addContribution (String contribution){
	boolean added = false;
	
	try (InputStream in =
			new ByteArrayInputStream (contribution.getBytes (Charset.defaultCharset ()));){
		IContributor contributor =
				ContributorFactoryOSGi.createContributor (Platform
						.getBundle (Activator.PLUGIN_ID));
		IExtensionRegistry registry = Platform.getExtensionRegistry ();
		
		/*
		 * To add a contribution we need a user or master token. These tokens cannot be
		 * obtained explicitly because the Equinox bundle creates and uses them internally
		 * to prevent the addition of heavy consuming memory stuff.
		 * See: https://bugs.eclipse.org/bugs/show_bug.cgi?id=295035
		 * 
		 * But there's still a way to obtain a master token. See below. The warning
		 * supression is because the unauthorized access to the ExtensionRegistry.
		 */
		@SuppressWarnings ("restriction")
		Field field =
				org.eclipse.core.internal.registry.ExtensionRegistry.class
						.getDeclaredField ("masterToken");
		field.setAccessible (true);
		Object masterToken = field.get (registry);
		
		added = registry.addContribution (in, contributor, false, null, null, masterToken);
	}catch (UnsupportedEncodingException e){
	}catch (NoSuchFieldException e){
		Log.error (e);
	}catch (SecurityException e){
		Log.error (e);
	}catch (IllegalArgumentException e){
		Log.error (e);
	}catch (IllegalAccessException e){
		Log.error (e);
	}catch (IOException e){
		Log.error (e);
	}
	
	return added;
}


This function returns true with the following addition but when I search in the perspective registry I can't find it.

boolean added = Registry.addContribution (
		"<extension " +
				"point=\"org.eclipse.ui.perspectives\">" +
			"<perspective " +
				"class=\"gll.perspective_creator.ui.EmptyPerspective\" " +
				"icon=\"images/error.gif\" " +
				"id=\"gll.perspective_creator.emptyPerspective\" " +
				"name=\"Empty Perspective\">" +
			"</perspective>" +
		"</extension>");




So, concluding, how can I add a perspective dynamically?

Thanks.
Re: How to add a perspective dynamically [message #899001 is a reply to message #898859] Mon, 30 July 2012 06:25 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas Schindl
Messages: 5331
Registered: July 2009
Senior Member
You won't get a solution to this in 3.x - in 4.x the model is accessible
to anyone so you can add perspectives, ... link you want it.

So what version of Eclipse are you targeting?

Tom

Am 28.07.12 12:36, schrieb Gabriel Llamas:
> I want to add a perspective dynamically from the code without using the
> plugin.xml file. All the information I've obtained about this is that's
> impossible without "hacking" the Equinox plugin.
>
> Please, see: https://bugs.eclipse.org/bugs/show_bug.cgi?id=295035
>
> The problem is that I cannot add a contribution to the ExtensionRegistry
> because I need a user or master token, but these tokens cannot be
> obtained from anywhere, they are created and used internally by the
> Equinox plugin. The reason they give is to prevent the plugins to add
> "heavy consuming memory stuff".
>
> The guy that posted the "bug" in the previous link ended with a
> workarround but he didn't post the solution. The post was made in 2009.
>
> Now, 3 years later what's the status about this? How can I add
> perspectives dynamically?
>
> This is what I have:
>
> String perspective =
> "<extension " +
> "point=\"org.eclipse.ui.perspectives\">" +
> "<perspective " +
> "class=\"perspectivefactory.PerspectiveFactory2\" " +
> "icon=\"icons/error.gif\" " +
> "id=\"Perspective Creator.perspective2\" " +
> "name=\"name\">" +
> "</perspective>" +
> "</extension>";
>
> try (InputStream in = new ByteArrayInputStream (perspective.getBytes
> (Charset.defaultCharset ()))){
> IContributor contributor = ContributorFactoryOSGi.createContributor
> (Platform.getBundle (Activator.PLUGIN_ID));
> Platform.getExtensionRegistry ().addContribution (in, contributor,
> false, null, null, null);
> }catch (UnsupportedEncodingException e){
> }catch (IOException e){
> Utils.log (e);
> }
>
>
> but I get the error:
>
> org.eclipse.e4.core.di.InjectionException:
> java.lang.IllegalArgumentException: Unauthorized access to the
> ExtensionRegistry.addContribution() method. Check if proper access token
> is supplied.
>
> That's because I need a master token. using Reflection I can get it:
>
> public static boolean addContribution (String contribution){
> boolean added = false;
>
> try (InputStream in =
> new ByteArrayInputStream (contribution.getBytes
> (Charset.defaultCharset ()));){
> IContributor contributor =
> ContributorFactoryOSGi.createContributor (Platform
> .getBundle (Activator.PLUGIN_ID));
> IExtensionRegistry registry = Platform.getExtensionRegistry ();
>
> /*
> * To add a contribution we need a user or master token. These
> tokens cannot be
> * obtained explicitly because the Equinox bundle creates and
> uses them internally
> * to prevent the addition of heavy consuming memory stuff.
> * See: https://bugs.eclipse.org/bugs/show_bug.cgi?id=295035
> * * But there's still a way to obtain a master token.
> See below. The warning
> * supression is because the unauthorized access to the
> ExtensionRegistry.
> */
> @SuppressWarnings ("restriction")
> Field field =
> org.eclipse.core.internal.registry.ExtensionRegistry.class
> .getDeclaredField ("masterToken");
> field.setAccessible (true);
> Object masterToken = field.get (registry);
>
> added = registry.addContribution (in, contributor, false, null,
> null, masterToken);
> }catch (UnsupportedEncodingException e){
> }catch (NoSuchFieldException e){
> Log.error (e);
> }catch (SecurityException e){
> Log.error (e);
> }catch (IllegalArgumentException e){
> Log.error (e);
> }catch (IllegalAccessException e){
> Log.error (e);
> }catch (IOException e){
> Log.error (e);
> }
>
> return added;
> }
>
> This function returns true with the following addition but when I search
> in the perspective registry I can't find it.
>
> boolean added = Registry.addContribution (
> "<extension " +
> "point=\"org.eclipse.ui.perspectives\">" +
> "<perspective " +
> "class=\"gll.perspective_creator.ui.EmptyPerspective\" " +
> "icon=\"images/error.gif\" " +
> "id=\"gll.perspective_creator.emptyPerspective\" " +
> "name=\"Empty Perspective\">" +
> "</perspective>" +
> "</extension>");
>
>
>
> So, concluding, how can I add a perspective dynamically?
>
> Thanks.
Re: How to add a perspective dynamically [message #902858 is a reply to message #898859] Mon, 20 August 2012 18:24 Go to previous message
Paul Webster is currently offline Paul Webster
Messages: 6859
Registered: July 2009
Location: Ottawa
Senior Member

In an RCP app, you would run with a property that set the user token to null, then your RCP app can easily add contributions to the registry.

In an application that you don't control, those tokens still aren't exposed anywhere.

PW


Previous Topic:Add a Command Contribution Item to the editor/view Tab popup menu
Next Topic:Dynamic Context Menus not working in Eclipse 4.2
Goto Forum:
  


Current Time: Tue Sep 23 06:38:58 GMT 2014

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

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