Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » EMap<String, EList<MyObject>>
EMap<String, EList<MyObject>> [message #636483] Mon, 01 November 2010 14:40 Go to next message
J.-P. Pellet is currently offline J.-P. PelletFriend
Messages: 71
Registered: July 2009
Member
Hi,

I'm trying to emulate a multimap-like behavior with a feature of type
EMap<String, EList<MyObject>>. I've successfully defined a feature in
Java like this:

/**
* @model mapType="EStringToMyObjectListMapEntry"
*/
EMap<String, EList<MyObject>> getMyObjectsMap();

where EStringToMyObjectListMapEntry is defined in the package interface:

/**
* @model keyDataType="org.eclipse.emf.ecore.EString"
* valueType="org.mypackage.MyObject"
* valueContainment="true" valueMany="true"
*/
EClass getEStringToMyObjectListMapEntry();

Saving and loading from XML works great like this, but I'm puzzled
regarding how to populate this "multimap" in client code. Suppose I want
to add a value val to the list whose key is "a".

MyObject val = ...
String key = "a";
target.getMyObjectsMap().put(key, ...); // I need an EList here!

Here I'm stuck because I need an EList instance. I'd be happy (using
e.g. the Google collections) to write something like:

target.getMyObjectsMap().put(key, ImmutableList.of(val));

but ImmutableList.of(...) does not return an EList.

Alternatively, in my implementation class I can write something like

EStringToMyObjectListMapEntry entry =
new EStringToMyObjectListMapEntry();
entry.setKey(a);
entry.getValue().add(val);
getLinkedObjects().add(entry);

but this direct instantiation does not look like a good solution.

Any better idea?

J.-P.
Re: EMap<String, EList<MyObject>> [message #636499 is a reply to message #636483] Mon, 01 November 2010 15:18 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 30554
Registered: July 2009
Senior Member
J.-P.

Comments below.


J.-P. Pellet wrote:
> Hi,
>
> I'm trying to emulate a multimap-like behavior with a feature of type
> EMap<String, EList<MyObject>>. I've successfully defined a feature in
> Java like this:
>
> /**
> * @model mapType="EStringToMyObjectListMapEntry"
> */
> EMap<String, EList<MyObject>> getMyObjectsMap();
>
> where EStringToMyObjectListMapEntry is defined in the package interface:
>
> /**
> * @model keyDataType="org.eclipse.emf.ecore.EString"
> * valueType="org.mypackage.MyObject"
> * valueContainment="true" valueMany="true"
> */
> EClass getEStringToMyObjectListMapEntry();
>
> Saving and loading from XML works great like this, but I'm puzzled
> regarding how to populate this "multimap" in client code.
It's a little tricky...
> Suppose I want to add a value val to the list whose key is "a".
>
> MyObject val = ...
> String key = "a";
> target.getMyObjectsMap().put(key, ...); // I need an EList here!
>
> Here I'm stuck because I need an EList instance. I'd be happy (using
> e.g. the Google collections) to write something like:
>
> target.getMyObjectsMap().put(key, ImmutableList.of(val));
>
> but ImmutableList.of(...) does not return an EList.
>
> Alternatively, in my implementation class I can write something like
>
> EStringToMyObjectListMapEntry entry =
> new EStringToMyObjectListMapEntry();
> entry.setKey(a);
> entry.getValue().add(val);
> getLinkedObjects().add(entry);
>
> but this direct instantiation does not look like a good solution.
>
> Any better idea?
You can create a BasicEList. It makes me think that
ECollections.singletonEList would be a useful utility method. An
alternative would be to put an ECollections.emptyList() and then do a
get to fetch the entry's value's "real containment list".
>
> J.-P.
Re: EMap<String, EList<MyObject>> [message #636503 is a reply to message #636499] Mon, 01 November 2010 15:26 Go to previous messageGo to next message
Cyril Jaquier is currently offline Cyril JaquierFriend
Messages: 80
Registered: July 2009
Member
J.-P., Ed,

> You can create a BasicEList. It makes me think that
> ECollections.singletonEList would be a useful utility method. An
> alternative would be to put an ECollections.emptyList() and then do a
> get to fetch the entry's value's "real containment list".

From ECollections:

/**
* An unmodifiable empty list with an efficient reusable iterator.
*/
public static final EList<?> EMPTY_ELIST = new EmptyUnmodifiableEList();

@SuppressWarnings("unchecked")
public static <T> EList<T> emptyEList()
{
return (EList<T>)EMPTY_ELIST;
}

ECollections#emptyEList() returns an unmodifiable EList. So I'm not sure
this alternative would do it ;-)

Cheers,
Cyril
Re: EMap<String, EList<MyObject>> [message #636504 is a reply to message #636499] Mon, 01 November 2010 15:27 Go to previous messageGo to next message
J.-P. Pellet is currently offline J.-P. PelletFriend
Messages: 71
Registered: July 2009
Member
>> Any better idea?
> You can create a BasicEList. It makes me think that
> ECollections.singletonEList would be a useful utility method. An
> alternative would be to put an ECollections.emptyList() and then do a
> get to fetch the entry's value's "real containment list".

Thanks for the comments, Ed. I assume that I have to check for null list
values manually anyway before adding objects; i.e., no generated public
method out there will directly create the real containment list for me,
right? Other than the put-empty-list trick you've just described.

J.-P.
Re: EMap<String, EList<MyObject>> [message #636514 is a reply to message #636504] Mon, 01 November 2010 15:35 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 30554
Registered: July 2009
Senior Member
J.-P.,

Yes, that's the tricky part. A get on the map when there is no entry
will return null. Once there is an entry in the map, you'll always get
back a list you can edit directly...


J.-P. Pellet wrote:
>>> Any better idea?
>> You can create a BasicEList. It makes me think that
>> ECollections.singletonEList would be a useful utility method. An
>> alternative would be to put an ECollections.emptyList() and then do a
>> get to fetch the entry's value's "real containment list".
>
> Thanks for the comments, Ed. I assume that I have to check for null
> list values manually anyway before adding objects; i.e., no generated
> public method out there will directly create the real containment list
> for me, right? Other than the put-empty-list trick you've just described.
>
> J.-P.
Re: EMap<String, EList<MyObject>> [message #636620 is a reply to message #636503] Tue, 02 November 2010 08:49 Go to previous messageGo to next message
J.-P. Pellet is currently offline J.-P. PelletFriend
Messages: 71
Registered: July 2009
Member
> ECollections#emptyEList() returns an unmodifiable EList. So I'm not sure
> this alternative would do it ;-)

Cyril,

Yes, this would work, because the setValue() method of the generated
MapEntry is smart about keeping the real containment list correctly:

public EList<MyObject> setValue(EList<MyObject> value) {
EList<MyObject> oldValue = getValue();
getTypedValue().clear();
getTypedValue().addAll(value);
return oldValue;
}

Cheers,
J.-P.
Re: EMap<String, EList<MyObject>> [message #636621 is a reply to message #636514] Tue, 02 November 2010 08:49 Go to previous message
J.-P. Pellet is currently offline J.-P. PelletFriend
Messages: 71
Registered: July 2009
Member
> Yes, that's the tricky part. A get on the map when there is no entry
> will return null. Once there is an entry in the map, you'll always get
> back a list you can edit directly...

Ed,

Thanks for making it clear!

Cheers,
J.-P.
Previous Topic:Modelling XBRL Taxonomy
Next Topic:[CDO] bad performances for few objects
Goto Forum:
  


Current Time: Tue Oct 22 05:58:45 GMT 2019

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

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

Back to the top