Conditional reference update [message #667676] |
Sun, 01 May 2011 07:53 |
Martin odloucký Messages: 49 Registered: July 2010 |
Member |
|
|
Hi,
another question from a newbie. In my EMF model I have a containment reference like this
Project ------------> Entity
0..*
I would like the Project to allow adding of a new Entity only when certain conditions are met. (Entities are supposed to have unique IDs in the Project, so if the Project already contains some Entity with specified ID it should reject addition of the new Entity).
The solution I came up with is to create two operations addEntity and removeEntity. But then I have tu suppress the possibility to add child Entities like this
myProject.getEntities().add(myEntity)
Since I want the accessor to be generated I would have to return unmodifiable EList implementation, which I can do of course, however, this seems little unclean to me. Is there a cleaner or more standard way of doing this? Many classes from my model should have this behavior of conditional child adding. I would still prefer to somehow use the standard EMF way of adding children via the getEntities method.
Thanks for help
[Updated on: Sun, 01 May 2011 07:56] Report message to a moderator
|
|
|
Re: Conditional reference update [message #667678 is a reply to message #667676] |
Sun, 01 May 2011 08:44 |
Ed Merks Messages: 33142 Registered: July 2009 |
Senior Member |
|
|
Martin,
Comments below.
Martin Podloucký wrote:
> Hi, another question from a newbie. In my EMF model I have a
> containment reference like this
>
> Project ------------> Entity
> 0..*
>
> I would like the Project to allow adding of a new Entity only when
> certain conditions are met.
Is that a statement about what the UI should allow or what the model allows?
> (Entities are supposed to have unique IDs in the Project, so if the
> Project already contains some Entity with specified ID it should
> reject addition of the new Entity).
Can the ID of an entity change? Is it a modeled feature of Entity?
> The solution I came up with is to create two operations addEntity and
> removeEntity.
Is there something that should prevent removal too?
> But then I have tu suppress the possibility to add child Entities like
> this
>
> myProject.getEntities().add(myEntity)
Fundamentally that always needs to be possible, at least reflectively...
>
> Since I want the accessor to be generated I would have to return
> unmodifiable EList implementation, which I can do of course, however,
> this seems little unclean to me.
Yes and is going to cause problems when reflective operations need to
operate directly on the EList, e.g., when you deserialize or use
EcoreUtil.copy...
> Is there a cleaner or more standard way of doing this? Many classes
> from my model should have this behavior of conditional child adding.
Probably you should rethink how you go about doing this. It's easy to
limit choices offered in the UI via specialized property descriptors.
It's extremely hard to absolutely prevent your model from being in a bad
state. After all, I assume an ID can be set/changed somehow, so what's
to prevent duplicates in that case? It seems better to me to define a
constraint that can be checked, rather than try to make the API bullet
proof...
Ed Merks
Professional Support: https://www.macromodeling.com/
|
|
|
|
Re: Conditional reference update [message #667686 is a reply to message #667676] |
Sun, 01 May 2011 10:22 |
Ed Willink Messages: 7655 Registered: July 2009 |
Senior Member |
|
|
Hi Martin
You provide a rather interesting use case.
OCL can be used to enrich models with programmatic constraints. See
http://help.eclipse.org/helios/index.jsp?topic=/org.eclipse. ocl.doc/tutorials/oclinecore/oclInEcoreTutorial.html
Normally you would define an invariant such as all IDs are unique that
would tell you that your model was broken after you broke it.
OCL also permits pre and post conditions to be defined for an operation.
You could therefore make the new-id-is-distinct a pre-condition of an
add operation, and the UI could evaluate the pre-condition. I've added
this use case to https://bugs.eclipse.org/bugs/show_bug.cgi?id=303686,
so that we provide a better API. However you should still be able to
navigate the operation to find the precondition and evaluate it anyway
using a mix of EMF navigation and OCL expression activation.
Without using OCL at all, you could just add a custom canAdd(...)
operation for your GUI to invoke.
Regards
Ed Willink
On 01/05/2011 08:53, Martin Podloucký wrote:
> Hi, another question from a newbie. In my EMF model I have a
> containment reference like this
>
> Project ------------> Entity
> 0..*
>
> I would like the Project to allow adding of a new Entity only when
> certain conditions are met. (Entities are supposed to have unique IDs
> in the Project, so if the Project already contains some Entity with
> specified ID it should reject addition of the new Entity). The
> solution I came up with is to create two operations addEntity and
> removeEntity. But then I have tu suppress the possibility to add child
> Entities like this
>
> myProject.getEntities().add(myEntity)
>
> Since I want the accessor to be generated I would have to return
> unmodifiable EList implementation, which I can do of course, however,
> this seems little unclean to me. Is there a cleaner or more standard
> way of doing this? Many classes from my model should have this
> behavior of conditional child adding.
|
|
|
Re: Conditional reference update [message #667709 is a reply to message #667678] |
Sun, 01 May 2011 15:05 |
Thomas Schindl Messages: 6651 Registered: July 2009 |
Senior Member |
|
|
In e4 we have specialized multi-valued feature list to check the value
before adding it.
What we do is to overload the EcoreList#validate and throw an
IllegalArgumentException if the conditions are not meet.
Tom
Am 01.05.11 10:44, schrieb Ed Merks:
> Martin,
>
> Comments below.
>
> Martin Podloucký wrote:
>> Hi, another question from a newbie. In my EMF model I have a
>> containment reference like this
>>
>> Project ------------> Entity
>> 0..*
>>
>> I would like the Project to allow adding of a new Entity only when
>> certain conditions are met.
> Is that a statement about what the UI should allow or what the model
> allows?
>> (Entities are supposed to have unique IDs in the Project, so if the
>> Project already contains some Entity with specified ID it should
>> reject addition of the new Entity).
> Can the ID of an entity change? Is it a modeled feature of Entity?
>> The solution I came up with is to create two operations addEntity and
>> removeEntity.
> Is there something that should prevent removal too?
>> But then I have tu suppress the possibility to add child Entities like
>> this
>>
>> myProject.getEntities().add(myEntity)
> Fundamentally that always needs to be possible, at least reflectively...
>>
>> Since I want the accessor to be generated I would have to return
>> unmodifiable EList implementation, which I can do of course, however,
>> this seems little unclean to me.
> Yes and is going to cause problems when reflective operations need to
> operate directly on the EList, e.g., when you deserialize or use
> EcoreUtil.copy...
>> Is there a cleaner or more standard way of doing this? Many classes
>> from my model should have this behavior of conditional child adding.
> Probably you should rethink how you go about doing this. It's easy to
> limit choices offered in the UI via specialized property descriptors.
> It's extremely hard to absolutely prevent your model from being in a bad
> state. After all, I assume an ID can be set/changed somehow, so what's
> to prevent duplicates in that case? It seems better to me to define a
> constraint that can be checked, rather than try to make the API bullet
> proof...
|
|
|
|
Powered by
FUDForum. Page generated in 0.03026 seconds