How do I get a view part instance in an Eclipse e4 application? - eclipse

I'm trying to get the instance of a view part in an Eclipse e4 application but I can't find the PlatformUI class. Has the name changed since Eclipse 3 or is it located in a different package?

When looking at Eclipse e4 Parts:
bugs like 371405 can be instructive:
org.eclipse.ui.presentations
This API no longer works in 4.2, and we never intend to make it work.
It is incompatible with the pluggable rendering story in 4.2. Decisions that could once be made by the presentation extensions are now up to the renderer.
Affected API that needs deprecation:
Entire API package: org.eclipse.ui.presentations
Extension point:org.eclipse.ui.presentationFactories
org.eclipse.ui.IWorkbenchPreferenceConstants#PRESENTATION_FACTORY_ID
org.eclipse.ui.IWorkbenchWindowConfigurer#getPresentationFactory
org.eclipse.ui.IWorkbenchWindowConfigurer#setPresentationFactory
The rest of the Tutorial explains how to declare "parts" (editors or views)
The OP August Karlstrom mentions:
This used to work:
PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().findView("‌​some view");
Using a singleton like PlatformUI is a bad practice and one of the reason of the introduction, in e4, of Context. See this presentation on Context.
Paul Webster (IBM Eclipse Platform team member) comments:
In Eclipse4 you would use org.eclipse.e4.ui.workbench.modeling.EPartService.findPart(String) to find an MPart by ID.
The MPart contains the injected part in its object property.
As the page Workbench_Services details:
In e4, the notion of a workbench page will not be present.
The part service API will essentially be a merge of the existing 3.x IPartService and WorkbenchPage interfaces.
Note that this isn't ideal, as bug 372488 illustrates (following this thread):
An MPart for an MPartDescriptor is created with EPartService.createPart(descriptor_id), where descriptor_id is the identifier of the MPartDescriptor.
This part can be found again with EPartService.findPart(descriptor_id) -- if there is only one.
The problem is, that one may need do create more than one MPart for one MPartDescriptor.
An editor may be one example: one may want to edit different instances of one and the same kind.
The creation of more than one MPart for a given MPartDescriptor is possible, but there is no convenient method to find these parts.
EPartService.findPart(descriptor_id) will return the first MPart created for a particular MPartDescriptor, even if there is more than one.
So there are three problems, for a given MPartDescriptor:
EPartService.findPart(id) does not tell that there is more than one MPart.
There is no convenient way to get all MParts for this descriptor.
There is no API-way to get the particular MPart for given descriptor and "content" or "reference".
Currently the way to go is using EPartService.getParts() which unfortunately
returns all MParts, not only those corresponding to one particular
MPartDescriptor.
Then one would need to check, whether there is one MPart for the particular MPartDescriptor having a particular "content".
So something is missing that will find an MPart for a given MPartDescriptor
with particular "content" or "reference".

Just have the same question. After found this thread and tried with:
MPart mPart = epartService.findPart("MyPart");
MyPart myPart = (MyPart)mPart.getObject();
then I got my view part.

Related

Customizing content proposal in Xtext for web editors

I have a DSL written in Xtext. In order to add custom content proposal, I have edited the MyDslProposalProvider class in the ui project. The new proposals are present when I debug the plugin in Eclipse, but not in the web editor, which is ultimately what I want. I want to set the custom proposals at a single place and all generated editors to use them. Is it possible to do that with Xtext?
As I had the same problem and struggled a little bit with the solution (as I would like to use both, Eclipse editor and Web editor) I would like to provide some more detailed feedback on a possible solution here, which worked well for me.
In my solution I did the following steps.
Implement a MyDslIdeContentProposalProvider in my.dsl.ide sub project extending from IdeContentProposalProvider, package my.dsl.ide.contentassistant (newly created); an example of such an implementation may be found here.
The implementation is not such convenient as at the well known UI proposal provider for Eclipse. I had to implement switch cases based on MyDslGrammarAccess elements instead of structural grammar elements like in the UI proposal provider. On the other hand, I have only one proposal implementation for all editor cases that way (DRY principle!).
Register the MyDslIdeContentProposalProvider at MyDslIdeModule in the same project (only with that it works already in the web editor).
def Class<? extends IdeContentProposalProvider> bindIdeContentProposalProvider() {
MyDslIdeContentProposalProvider
}
Register the new MyDslIdeContentProposalProvider and the forwarding class UiToIdeContentProposalProvider at the MyDslUiModule in the my.dsl.ui sub project. (That's what took the longest investigation as it cannot be logically derived.)
override Class<? extends IContentProposalProvider> bindIContentProposalProvider() {
return UiToIdeContentProposalProvider
}
def Class<? extends IdeContentProposalProvider> bindIdeContentProposalProvider() {
return JavaPOSConfigLanguageIdeContentProposalProvider
}
For an full example see here.
As I had implemented the MyDslIdeContentProposalProvider in the newly created package my.dsl.ide.contentassistant, this package has to be exported in the MANIFEST.MF file of the sub project my.dsl.ide (the subsequent 2 exports were already there). Otherwise i would get an an error Access restriction: The type is not accessible due to restriction on required project in the MyDslUiModule.
Export-Package: my.dsl.ide.contentassist,
my.dsl.ide.contentassist.antlr,
my.dsl.ide.contentassist.antlr.internal
That way it worked well for for both editors, Eclipse and web.
Thanks Christian again for the initial hint!
... If I could make a wish, I would like to have the same structural grammar element access in the MyDslIdeContentProposalProvider as we have it today in UI proposal provider.
you need to subclass org.eclipse.xtext.ide.editor.contentassist.IdeContentProposalProvider and bind it in YourDslIdeModule and YourDslUiModule. Then (in Xtext 2.13) you can use org.eclipse.xtext.ui.editor.contentassist.UiToIdeContentProposalProvider bound in YourDslUiModule to delegate to that in eclipse ui.

Accessing E4PartWrapper's MPart in Eclipse 3.x RCP application

I am using the ability to add an Eclipse 4.x part to an Eclipse 3.x RCP application's perspective as described in the Vogella chapter on RCP migration. All is well, I can create an 4.x part and view it in a 3.x perspective.
I'd like to access the instantiated 4.x POJO (in my case it contains a Browser widget) and set some parameters for display (the browser URL). However when I try to probe the constructed ViewPart what I have to deal with is an E4PartWrapper object:
E4PartWrapper newPart =
window.getActivePage().
showView(ViewEclipse4x.ID,
String.valueOf(nextId),
IWorkbenchPage.VIEW_ACTIVATE);
I can see from the code that E4PartWrapper does contain the wrapped part, but I don't see a way to access this object.
Is there an alternative to accessing the 4.x POJO underlying the constructed 3.x ViewPart?
Thank you.
Carlos S. Zamudio
Sorry. I can see the MPart can be found using the PartService:
EPartService partService = (EPartService) viewSite.getService(EPartService.class);
MPart part = partService.findPart(partName);

How can I access one Eclipse RAP entry point from another?

I have an Eclipse RAP 2.3 application with two entry points, say /first and /second.
In the GUI of the first entry point, there is a button with which I would like to open the second entry point in a new browser tab. The event handler of that button is currently
UrlLauncher launcher = RWT.getClient().getService( UrlLauncher.class );
launcher.openURL( "/second");
This already doesn't work when the application is deployed as myapp.war in a Tomcat web server (should then be /myapp/second).
My questions:
What's the best way to determine the URL to open within the event handler?
Do I have to fetch the HttpServletRequest, get the context path and so some string manipulation?
Is it actually safe to call RWT.getRequest() at this point?
Update
According to Rüdiger's comment I can acquire the context path in two different ways.
The first approach is
RWT.getRequest().getContextPath();
where RWT.getRequest() is documented with
This method is not recommended
Secondly, I could obtain it with
ApplicationContextImpl ac = (ApplicationContextImpl) RWT.getApplicationContext();
String contextPath = ac.getServletContext().getContextPath();
where the IDE displays the warning
Discouraged access: The type ApplicationContextImpl is not accessible due to restriction on required library ...\org.eclipse.rap.rwt_2.3.2.20150128-1013.jar
Despite the warning, it still works when deploying a WAR file with OSGi bundles to Tomcat.
So, in both cases there is some kind of warning, which makes the solutions look rather like workarounds.
Using RWT.getRequest() is not recommended because usually RWT would shield you from the lower-level servlet API and certain direct interactions with the request could even interfere with RWTs life cycle and yield funny responses.
While in your case it would be safe to access the ServletContext via RWT.getRequest(), I recommend to use
RWT.getUISession( display ).getHttpSession().getServletContext();
to access the servlet context.
The second approach accesses internal classes that aren't part of the public API and therefore shouldn't be use. The accessed classes may change or be (re)moved in the future without further notice and break your application.

How to create view via fragment that is linked to applicatio model eclipse plugin

Using application.e4xmi, I want to create view via fragments using this application model. Could you please tell me the step by step procedure.
what i have tried is, i have created one fragment in the one plugin application. in that i have given application id after that i have created part stack and after that created part. Here i have given class URI is my view class(path of view class in the viewplugin project). But without that view plugin in the runconfigurations, i am unable to see view part.
As far as I understand your question, you wish to have a plugin containing a model fragment which contributes to an application model located in another plugin, and the problem is that a (View-)Part you tried to contribute that way doesn't show in the application window. I hope I didn't get you wrong there and I will assume that the error is not just that the plugin with the model fragment is not included in the run configurations... (?)
You can find a useful tutorial in Lars Vogel's webpages. However, as the various requirements may be confusing, I will summarize the process for potential future readers.
TL;DR:
You might have set a wrong Element ID and/or Featurename for your Part.
Your question implies that you maybe tried to implement a Part model element as a ViewPart, when in E4, there is no longer any interface for a (View) Part to implement, so maybe try creating the Part controls in a #PostConstruct-annotated method instead.
Another possible reason for your contributed Part not showing up is the plugin providing the model fragment not having the correct settings for the bundle options SymbolicName and/or ActivationPolicy ('Plug-in is singleton' and 'Activate when class is loaded').
Application
In order to have an application model to contribute to, we first need an Eclipse4 application project. Create one by selecting File -> New -> Other from the Eclipse main menu. Choose the wizard Eclipse 4 Application Project in the Eclipse 4 category. Name your project as you wish, choose Equinox as OSGI framework, and check the Generate an Activator... option. The newly created project will contain a file Application.e4xmi (your application model) and a *.product file (product definition). Open the latter in and make sure org.eclipse.e4.ui.workbench.swt.E4Application is set as Application in the Overview tab.
Open Application.e4xmi and append a Part Stack somewhere in the model tree, as you probably have already done anyways.
Model fragment
Create a new plugin for the model fragment. Letting it have an Activator class won't harm. It is important, however, that the options Activate this plug-in when one of its classes is loaded and This plug-in is a singleton are both checked in the Overview tab of its plugin.xml editor. Next, create a model fragment with New -> Other... -> Eclipse 4 -> Model -> New Model Fragment in the plugin's Package Explorer context menu. The wizard will automatically create an extension of org.bbaw.bts.ui.pdr.fragment specifying your model fragment file. The plugin's dependencies should include:
org.eclipse.swt
org.eclipse.jface
org.eclipse.e4.core.di
org.eclipse.e4.ui.workbench
javax.inject
org.eclipse.e4.ui.di
Open the model fragment file (fragment.e4xmi by default) and attach a Model Fragment to the Model Fragments node. Your new Model Fragment element needs to specify both an Element ID and a Featurename in order to correctly address the Application Model's element that you want to contribute to. Thus, copy the ID of the Part Stack previously created in the Application Model into the Element ID field of the Model Fragment you've just created. In the Featurename field, type children, as this is the Part stack's attribute we want to contribute to. Then, append a Part to the Model Fragment element and specify the Class URI of the Part's implementation. This class is basically a POJO, no implementation of ViewPart is necessary! It creates its GUI in a method annotated with the #PostConstruct annotation, e.g.
#PostConstruct
public final void createComposite(final Composite parent)
That should be it. When running the application project's product, the Part should appear like expected (given the plugin containing that Part is included in the run configuration...).

How to remove id location strategy from Selenium IDE

the problem is: my web application uses ZK, which automatically generates random UUID for each web element.
When I try to record some basic test-case with Selenium IDE, it automatically tries to use these randomly-generated ID's, without even giving me a good alternative.
Is there a way to forbid Selenium IDE to use IDs while locating elements?
Possible workaraounds:
Implement ID generator in ZK: I've thrown away this possibility, because the application GUI is too complex for this task, and ID should be unique for whole sesion, which make this workaraound really hard to implement, when you have same elements on different page.
Find another recording tool: I've only found XLT script developer, which does the work by writing DOM-path using classes (which zk gives plenty) - but sometimes the location strategy gives false path, which is then not reproducible. Any good alternatives here?
You can change locater builder by changing the order of the locater in options>locater builder.
For example if you want to give first preference to css: name drag it on the top so when you start recording it will first give the preference to css name
Hope this will help you