Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Eclipse 4 » Best practices: Where should I maintain my model status?
Best practices: Where should I maintain my model status? [message #884838] Mon, 11 June 2012 23:25 Go to next message
Mauro Condarelli is currently offline Mauro Condarelli
Messages: 417
Registered: September 2009
Senior Member
I want to write a pure e4 application to edit and display in various
ways a single EMF model.
Only one model can be open at any given time in my app.
On the other hand I can have several ways to look at it and thus I have
a certain number (currently 4) of different perspectives.
My problem is to understand where I should make the link between the e4
"MPart"s and my EMF model.

I started writing a single perspective: a Master/details Overview of the
model.
I load my model in the OpenHandler and call a specific "setModel(Model
model)" API in my Master MPart.
This way Master MPart becomes the "owner of the Model and is responsible
to provide it to all the various "details" MParts.
Master MPart implements the MDirtyable interface.

I strongly doubt this is the "Right Way" to handle my needs.
Even forgetting I'm not decoupling the various MParts and that I do not
(currently) use DI to provide the model around, I now discovered that I
cannot get access to my Master MPart (and thus to the model!) form
MParts that are in "other" Perspectives.

I *think* I should add my model somehow to the IEclipseContext and rely
on the framework itself to re-inject it whenever it changes (i.e.: when
I close one model and open another one).

If I understand it correctly I can add my model to the context via:

@Execute
public void execute(IEclipseContext context,
@Optional Model model,
@Named(IServiceConstants.ACTIVE_SHELL) Shell shell)
throws InvocationTargetException, InterruptedException {
if (model != null) {
// save and discard old model
}
FileDialog dialog = new FileDialog(shell);
String selected = dialog.open();
if (selected != null) {
model = new Model(selected);
context.set(Model.class, model);
}
}

Is this correct?

I would then need some @Inject-able method in my MParts that will be
called when the Model chenges (i.e.: when I call
"context.set(Model.class, model)").
I couldn't find out what kind of Annotation I should use to get this
behavior.
Using something like:
@Inject
public void setModel(@Optional Model model) {
...
}
is *almost* working, but sometimes I get "null" values for the model and
I don't understand exactly why.

Am I completely off-track?
Please comment.

TiA
Mauro
Re: Best practices: Where should I maintain my model status? [message #884841 is a reply to message #884838] Mon, 11 June 2012 23:39 Go to previous messageGo to next message
Sopot Cela is currently offline Sopot Cela
Messages: 597
Registered: December 2010
Senior Member

Your parts first search their context, then go up to their perspective's context and then up to the MApplication's context and then up to the OSGi layer. If your Model is shared among perspectives it would be good to put it in the MApplication's context. Also you can give it a name and put it in the context like MApplication.getContext().set("my.app.data.model",modelObject); and inject it from anywhere (any part or handler) with
@Inject
@Named("my.app.data.model")
Re: Best practices: Where should I maintain my model status? [message #884935 is a reply to message #884841] Tue, 12 June 2012 06:01 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas Schindl
Messages: 5330
Registered: July 2009
Senior Member
Sopot is correct - do not directly inject your model in the
IEclipseContext you get in the execute of your handler.

The context you get there is a temporary child context of the current
active part and so it is too low in the DI hierarchy.

Tom

Am 12.06.12 01:39, schrieb Sopot Cela:
> Your parts first search their context, then go up to their perspective's
> context and then up to the MApplication's context and then up to the
> OSGi layer. If your Model is shared among perspectives it would be good
> to put it in the MApplication's context. Also you can give it a name and
> put it in the context like
> MApplication.getContext().set("my.app.data.model",modelObject); and
> inject it from anywhere (any part or handler) with
> @Inject
> @Named("my.app.data.model")
>
Re: Best practices: Where should I maintain my model status? [message #885071 is a reply to message #884935] Tue, 12 June 2012 12:06 Go to previous messageGo to next message
Mauro Condarelli is currently offline Mauro Condarelli
Messages: 417
Registered: September 2009
Senior Member
On 12/06/2012 08:01, Tom Schindl wrote:
> Sopot is correct - do not directly inject your model in the
> IEclipseContext you get in the execute of your handler.
>
> The context you get there is a temporary child context of the current
> active part and so it is too low in the DI hierarchy.

Thanks.
It works much better now ;)

Main question remains:
What is the "right way" to implement my model life-cycle?
I understand I should use the Dirtyable interface, but where?
Directly in my model?
In a wrapper?
Should that be created via ContextInjectionFactory.make() or is there
some facility in e4 Application.e4xmi to create non-ui classes?

I also have some problems understanding how to programmatically activate
commands.
I would like to be able to switch perspectives (implemented as
radio-button menu entries); if I do it directly calling
MPerspectiveStack.setSelectedElement() menu is not updated (unsurprisingly).
I also would like to call my stock SaveHandler at program termination
(if Model is dirty)
ICommandService does not seem to be available in e4 (and it wouldn't
solve the menu problem anyhow).

Thanks
Mauro
Re: Best practices: Where should I maintain my model status? [message #885076 is a reply to message #885071] Tue, 12 June 2012 12:22 Go to previous messageGo to next message
Sopot Cela is currently offline Sopot Cela
Messages: 597
Registered: December 2010
Senior Member


Mauro Condarelli wrote on Tue, 12 June 2012 15:06

I also have some problems understanding how to programmatically activate
commands.

Take a look at EHandlerService's methods . executeHandler() should suit your need.
Re: Best practices: Where should I maintain my model status? [message #885078 is a reply to message #885071] Tue, 12 June 2012 12:24 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas Schindl
Messages: 5330
Registered: July 2009
Senior Member
MDirtyable is a mixing interface implemented by MPart. So you are not
able to create an instance of it.

It might make sense in future to let MApplication also implement it but
as of now you can only call MDirtable-API on MPart instances.

For switching perspectives you should use EPartService.

To intercept the workbench closing and save your Model you should push
an IWindowCloseHandler to the IEclipseContext of the MApplication (might
be best done using an Addon).

Tom

Am 12.06.12 14:06, schrieb Mauro Condarelli:
> On 12/06/2012 08:01, Tom Schindl wrote:
>> Sopot is correct - do not directly inject your model in the
>> IEclipseContext you get in the execute of your handler.
>>
>> The context you get there is a temporary child context of the current
>> active part and so it is too low in the DI hierarchy.
>
> Thanks.
> It works much better now ;)
>
> Main question remains:
> What is the "right way" to implement my model life-cycle?
> I understand I should use the Dirtyable interface, but where?
> Directly in my model?
> In a wrapper?
> Should that be created via ContextInjectionFactory.make() or is there
> some facility in e4 Application.e4xmi to create non-ui classes?
>
> I also have some problems understanding how to programmatically activate
> commands.
> I would like to be able to switch perspectives (implemented as
> radio-button menu entries); if I do it directly calling
> MPerspectiveStack.setSelectedElement() menu is not updated (unsurprisingly).
> I also would like to call my stock SaveHandler at program termination
> (if Model is dirty)
> ICommandService does not seem to be available in e4 (and it wouldn't
> solve the menu problem anyhow).
>
> Thanks
> Mauro
Re: Best practices: Where should I maintain my model status? [message #885283 is a reply to message #885078] Tue, 12 June 2012 18:31 Go to previous messageGo to next message
Mauro Condarelli is currently offline Mauro Condarelli
Messages: 417
Registered: September 2009
Senior Member
On 12/06/2012 14:24, Tom Schindl wrote:
>
> For switching perspectives you should use EPartService.

I tried several approaches:

EPartService partService = window.getContext().get(EPartService.class);
MPart p = partService.findPart("it.condarelli.e4.writer.perspectives.overview");
if (p instanceof MPerspective) {
MPerspective pp = (MPerspective) p;
partService.switchPerspective(pp);
}
Does *not* work (p == null) why?

ECommandService cmndService = window.getContext().get(ECommandService.class);
Map<String, String> params = new HashMap<String, String>();
params.put("it.condarelli.e4.writer.commands.perspective.perspectiveId","it.condarelli.e4.writer.perspectives.overview");
ParameterizedCommand pc = cmndService.createCommand("it.condarelli.e4.writer.commands.perspective", params);
EHandlerService hdlrService = window.getContext().get(EHandlerService.class);
hdlrService.executeHandler(pc);
Does work but does *not* update correctly Radio-button menus (WHy????)

MPerspectiveStack pStack = null;
if (window != null) {
for (MWindowElement e : window.getChildren()) {
if (e instanceof MPerspectiveStack) {
pStack = (PerspectiveStackImpl) e;
pStack.setSelectedElement(pStack.getChildren().get(0));
break;
}
}
}
Does work but does *not* update correctly Radio-button menus (this I can understand).

Menu are defined as:
....
<children xsi:type="menu:Menu" xmi:id="_sDDYgLOxEeGYPfNb9t2Dzg" elementId="" label="Window">
<children xsi:type="menu:Menu" xmi:id="_RQzfMLPLEeGPw52VnjeJdg" label="Perspectives">
<children xsi:type="menu:HandledMenuItem" xmi:id="_VHBi0LPLEeGPw52VnjeJdg" label="Overview" selected="true" type="Radio" command="_v7qkoLO4EeGYPfNb9t2Dzg">
<parameters xmi:id="_J_nvkLPWEeGPw52VnjeJdg" elementId="" name="it.condarelli.e4.writer.commands.perspective.perspectiveId" value="it.condarelli.e4.writer.perspectives.overview"/>
</children>
<children xsi:type="menu:HandledMenuItem" xmi:id="_dH_voLPLEeGPw52VnjeJdg" label="Review" type="Radio" command="_v7qkoLO4EeGYPfNb9t2Dzg">
<parameters xmi:id="_SCFKILPWEeGPw52VnjeJdg" elementId="" name="it.condarelli.e4.writer.commands.perspective.perspectiveId" value="it.condarelli.e4.writer.perspectives.review"/>
</children>
<children xsi:type="menu:HandledMenuItem" xmi:id="_gAoJoLPLEeGPw52VnjeJdg" label="Printing" type="Radio" command="_v7qkoLO4EeGYPfNb9t2Dzg">
<parameters xmi:id="_VcLScLPWEeGPw52VnjeJdg" elementId="" name="it.condarelli.e4.writer.commands.perspective.perspectiveId" value="it.condarelli.e4.writer.perspectives.printing"/>
</children>
</children>
</children>
....
What should I do to keep them in sync?


> To intercept the workbench closing and save your Model you should push
> an IWindowCloseHandler to the IEclipseContext of the MApplication (might
> be best done using an Addon).
Everything ok but the last part: what do You mean with: "might be best done using an Addon" ?

Many thanks
Mauro
Re: Best practices: Where should I maintain my model status? [message #885350 is a reply to message #885283] Tue, 12 June 2012 21:17 Go to previous messageGo to next message
Sopot Cela is currently offline Sopot Cela
Messages: 597
Registered: December 2010
Senior Member

Mauro,

you are trying to do some really weird things.

First and foremost the MPart and MPerspective cannot be cast to each other. They are completely different interfaces. The method findPart will find a MPart for you and not a MPerspective and thus the p==null. I guess you can use the EModelService's find to find perspectives. p instanceof MPerspective will NEVER be true (will throw a CCE if you force the cast). Tell eclipse to do a type hierarchy on each of those (CTRL+T) and you will get the idea.

Also DON'T use internals like PerspectiveStackImpl. Stick to interfaces.

The menu items are kept in sync with their command. If you create your command on the fly with the command and handler service you should take care to also link the menu items with the newly created commands in order to keep things synced.
Re: Best practices: Where should I maintain my model status? [message #885364 is a reply to message #885350] Tue, 12 June 2012 21:55 Go to previous messageGo to next message
Mauro Condarelli is currently offline Mauro Condarelli
Messages: 417
Registered: September 2009
Senior Member
On 12/06/2012 23:17, Sopot Cela wrote:
> Mauro,
>
> you are trying to do some really weird things.
I know ;)
Truth is I am unable to find instructions on how to do several things
and thus I resort to experimenting.
Sometimes the experiments get a little wild ;)

> First and foremost the MPart and MPerspective cannot be cast to each
> other. They are completely different interfaces. The method findPart
> will find a MPart for you and not a MPerspective and thus the p==null. I
> guess you can use the EModelService's find to find perspectives. p
> instanceof MPerspective will NEVER be true (will throw a CCE if you
> force the cast). Tell eclipse to do a type hierarchy on each of those
> (CTRL+T) and you will get the idea.
I am still more than a little confused abiut exactly which service I
should use to get the right "piece" (Mpart, MPerspective or whatever).
I hoped there's a unified interface using the id's, but that doesn't
seem true.

> Also DON'T use internals like PerspectiveStackImpl. Stick to interfaces.
My bad.
I debugged and found out that's the actual type returned.
I should have used the Interface, instead.

> The menu items are kept in sync with their command. If you create your
> command on the fly with the command and handler service you should take
> care to also link the menu items with the newly created commands in
> order to keep things synced.
Ok.
What is the magic spell to get the Command already linked with the menu,
instead of creating a new one?
Use EModelService, I presume, but how do I add the parameter?

Can You suggest some specific documentation?
I am mainly using Lars's excellent site, but even that is rather terse
on many subjects.
Wiki seems to be lagging way behind, or I'm unable to navigate it properly.

Thanks for Your time
Mauro
Re: Best practices: Where should I maintain my model status? [message #885393 is a reply to message #885364] Tue, 12 June 2012 23:04 Go to previous message
Sopot Cela is currently offline Sopot Cela
Messages: 597
Registered: December 2010
Senior Member

I understand that at this point in time only the basics of using the new platform are documented online. If you want some thorough guide on how to do advanced stuff you won't find it yet. The resources you mentioned are as far as you get. When I looked for documentation some time ago I searched but ended up installing egit and cloning
http://git.eclipse.org/c/e4/org.eclipse.e4.tools.git/
http://git.eclipse.org/c/platform/eclipse.platform.ui.git/
http://git.eclipse.org/c/platform/eclipse.platform.runtime.git/
Also there is a demo project (Contacts demo) in one of the repositories. Seeing things working helps you see how they work.
Good luck.
Previous Topic:Migration from 3.x to Eclipse 4
Next Topic:Open Perspective Menu in RCP contains all installed perspectives
Goto Forum:
  


Current Time: Sun Sep 21 20:14:18 GMT 2014

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

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