Skip to main content



      Home
Home » Modeling » EMF » How to automatically create an additional entry?
How to automatically create an additional entry? [message #377552] Mon, 19 May 2003 02:45 Go to next message
Eclipse UserFriend
Hi,

I have a model with a containment class A where I put instances of
class B. When I create A using the context menu of the editor I want
automatically get one instance of B created within containment A.

How can I do that? I cannot find the right place: the constructor is
called much to often.
Re: How to automatically create an additional entry? [message #377570 is a reply to message #377552] Mon, 19 May 2003 18:56 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: shu.us.ibm.com

Daniel,

It requires user modification on genmodel codes.

Using EMF tutorial library model as an example, I add a class CD which is
containee of Book.

After genmodel, I modify createBook function in LibraryFactoryImpl class
like:
public Book createBook()
{
BookImpl book = new BookImpl();
CDImpl cd = new CDImpl();
book.getBookCD().add(cd);
return book;
}

Then in EMF editor, after I create a Book instance, a CD instance is added
to tree under Book instance.

Regards,
Shu

Daniel Hirscher wrote:

> Hi,

> I have a model with a containment class A where I put instances of
> class B. When I create A using the context menu of the editor I want
> automatically get one instance of B created within containment A.

> How can I do that? I cannot find the right place: the constructor is
> called much to often.
Re: How to automatically create an additional entry? [message #377572 is a reply to message #377570] Tue, 20 May 2003 02:25 Go to previous messageGo to next message
Eclipse UserFriend
Shu Wang,

this is not the right place either.

- If I create a new Book (using the popup menu), I get
automatically one CD added. This is ok.

- But, if I save and reopen the File, I get one more CD for
every Book automatically added! This is not what I want.

I only want an entry added if I create the entry, not if I open
a file.

So, I'm still searching for the right place...


> It requires user modification on genmodel codes.
>
> Using EMF tutorial library model as an example, I add a class CD which is
> containee of Book.
>
> After genmodel, I modify createBook function in LibraryFactoryImpl class
> like:
> public Book createBook()
> {
> BookImpl book = new BookImpl();
> CDImpl cd = new CDImpl();
> book.getBookCD().add(cd);
> return book;
> }
>
> Then in EMF editor, after I create a Book instance, a CD instance is added
> to tree under Book instance.
>
> Regards,
> Shu
>
> Daniel Hirscher wrote:
>
>
>>Hi,
>
>
>>I have a model with a containment class A where I put instances of
>>class B. When I create A using the context menu of the editor I want
>>automatically get one instance of B created within containment A.
>
>
>>How can I do that? I cannot find the right place: the constructor is
>>called much to often.

Daniel
Re: How to automatically create an additional entry? [message #377578 is a reply to message #377552] Tue, 20 May 2003 09:57 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: richkulp.NOSPAM.us.ibm.com

Typically you add to your factory (both the interface and
implementation) a method to do this. Then your action can call this
method. The method would call the standard create method within the
factory, and then do any manipulations it likes.

If you are going to be serializing this resource out to an XMI file, it
is important that anything you do in this method uses standard feature
API. This is so that the new object can be correctly serialized. If you
do other things to it that aren't done through features, then the
changes will probably get lost and won't get reconstructed when the XMI
file is read back in.

Note: You yourself should never call the default constructor of an EMF
class. You should always call the standard create method in the factory.
Even in the special create method in the factory as I described above.
This is so that if in the future anything special is required to
construct such an object, you will be using the official way to
construct it and not get caught with bad code.

Rich
Re: How to automatically create an additional entry? [message #377582 is a reply to message #377552] Tue, 20 May 2003 10:46 Go to previous messageGo to next message
Eclipse UserFriend
Daniel,

The XSD model's item providers do stuff like this to create fully
initialized instances in the editor. You should create a derived
version of a create command that will do the additional initialization
when needed...


Daniel Hirscher wrote:

> Hi,
>
> I have a model with a containment class A where I put instances of
> class B. When I create A using the context menu of the editor I want
> automatically get one instance of B created within containment A.
>
> How can I do that? I cannot find the right place: the constructor is
> called much to often.
Re: How to automatically create an additional entry? [message #377583 is a reply to message #377572] Tue, 20 May 2003 10:47 Go to previous message
Eclipse UserFriend
Hi Daniel,

Daniel Hirscher wrote:
> this is not the right place either.
> - If I create a new Book (using the popup menu), I get
> automatically one CD added. This is ok.
> - But, if I save and reopen the File, I get one more CD for
> every Book automatically added! This is not what I want.
> I only want an entry added if I create the entry, not if I open
> a file.

You were on the right track: it sounds like you don't want to make a
change to the behaviour of the model, but rather add a convenience to
the editor. In other words, the change you want to make doesn't belong
in the generated model code, but in the generated EMF.Edit code.

I made a similar modification to the library model as Shu (actually, I
assumed that the bookCD reference was multiplicity-1), and generated
with the normal three plug-in pattern. Now I've got three projects:
library, library.edit, and library.editor.

The change we need to make is in the UI-independent library.edit
project. We're going to modify the item provider for the Library class.
In EMF.Edit, item providers provide class-specific support for the
viewer widget (the content model and labels), the property sheet,
command creation, and change notification in the editor. Here, we're
interested in command creation, specifically, the CreateChildCommand
that adds an object under this class.

Here's the method you need to change in LibraryItemProvider:

protected void collectNewChildDescriptors(
Collection newChildDescriptors, Object object)
{
super.collectNewChildDescriptors(newChildDescriptors, object);
newChildDescriptors.add(createChildParameter(
LibraryPackage.eINSTANCE.getLibrary_Writers(),
LibraryFactory.eINSTANCE.createWriter()));
newChildDescriptors.add(createChildParameter(
LibraryPackage.eINSTANCE.getLibrary_Books(),
LibraryFactory.eINSTANCE.createBook()));
}

You should replace the last statement with something like this:

Book book = LibraryFactory.eINSTANCE.createBook();
CD cd = LibraryFactory.eINSTANCE.createCD();
book.setBookCD(cd);
newChildDescriptors.add(createChildParameter(
LibraryPackage.eINSTANCE.getLibrary_Books(), book));

Since EMF.Edit isn't exactly trivial and its documentation isn't exactly
complete <grin>, here's an overview of what's happening. In the
library.editor plug-in, there's a generated class called
LibraryActionBarContributor, which adds actions to the pull-down and
pop-up menus for the editor. When the selection changes, its
selectionChanged() method is called and it queries the EditingDomain
(all command-based editing is done through the editing domain) to find
out how to create the actions for child and sibling creation, given that
selection:

newChildDescriptors = domain.getNewChildDescriptors(object, null);
newSiblingDescriptors = domain.getNewChildDescriptors(null, object);

The editing domain delegates this call to the item provider, via the
correct adapter factory for the model, in this case
LibraryItemProviderAdapterFactory, which is generated in the
library.edit plug-in. So, getNewChildDescriptors() gets called on the
item provider. This method is actually implemented in the base class
for EMF model object item providers, ItemProviderAdapter, which can be
found in the org.eclipse.emf.edit plug-in. It has to return the
information that will be used later on by createCommand() to actually
create the command. This result is also used by the action bar
contributor to key the action (either a CreateChildAction or a
CreateSiblingAction) that it creates as a wrapper for this command.

So, what information does getNewChildDescriptors() return? It actually
creates the object that will be added, and it also includes the
EReference where it will be added, and the index at which it will be
added (if the reference is multiplicity-many). It calls
collectNewChildDescriptors(), which is overridden in any of the
generated item providers that correspond to classes with containment
references. As generated, the method adds a CommandParameter containing
the new object and the reference. (The base implementation of
getNewChildDescriptors() may then play around with the index to make new
siblings appear close to the selection.)

Our modification to this method in the Library item provider just added
some initialization of the new Book object. This is the correct spot to
add any initialization that you just want to occur in the editor's
object creation, but not in the model.

As Rich just suggested, you could certainly add a method to the factory
that creates the Book and CD objects together, and just call this one
from collectNewChildDescriptors(). It would probably make sense to do
this if you're creating Book objects in this way from several different
places.

Hope that helps,
Dave
Previous Topic:Bug with Inverse References & Containment?
Next Topic:One EditingDomain per Project
Goto Forum:
  


Current Time: Thu Nov 06 18:31:00 EST 2025

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

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

Back to the top