Home » Modeling » EMF » Overriding ItemPropertyDescriptor.setPropertyValue
| Overriding ItemPropertyDescriptor.setPropertyValue [message #398550] |
Tue, 14 February 2006 16:47  |
Eclipse User |
|
|
|
Hello,
I am trying to set property values for model objects by delegating to the
auto-generated EMF ItemPropertyDescriptors from my own subclass of the
Eclipse PropertySheetEntry. My property sheet entry uses the EMFT
CompositeTransactionalOperation to support changing the same property value
on many model objects in a single undoable operation.
The difficulty is that the generated ItemPropertyDescriptor executes its
SetCommand through the editing domain's command stack. I do not want this
behaviour because my property sheet entry is already taking care of this by
executing its CompositeTransactionOperation through the Eclipse operation
history.
So far I have succeeded in overriding this behaviour by wrapping the
ItemPropertyDescriptor in the ItemPropertyDescriptionDecorator which
overrides setPropertyValue() and does not execute commands through the
command stack. Unfortunately, to do this I have to repeat a lot of code
that is already in ItemPropertyDescriptor.setPropertyValue(). Would it be
possible to refactor ItemPropertyDescriptor.setPropertyValue() to provide a
reusable getter for the SetCommand? This would make my override simpler and
less prone to future obsolescence.
Is there a better way for me to solve this problem? Any suggestions would
be most appreciated.
Thanks,
Linda
|
|
| |
| Re: Overriding ItemPropertyDescriptor.setPropertyValue [message #398555 is a reply to message #398553] |
Tue, 14 February 2006 17:57   |
Eclipse User |
|
|
|
This is a multi-part message in MIME format.
------=_NextPart_000_004A_01C63190.1925FF10
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
Hi Ed,
If I don't have an editing domain, then won't I miss the command =
overrides that may be contributed to the editing domain?
In any case, I'm not able to subclass ItemPropertyDescriptor, because I =
am working with descriptors from client metamodels.
Thanks,
Linda
"Ed Merks" <merks@ca.ibm.com> wrote in message =
news:dstl3u$tc2$1@utils.eclipse.org...
Linda,
Maybe you could just override ItemPropertyDescriptor.getEditingDomain =
to return null? In that case no commands will be used.
But looking at the code I think that =
https://bugs.eclipse.org/bugs/show_bug.cgi?id=3D119797 introduced a bug =
since this will now return false if there is no editing domain.
public boolean canSetProperty(Object object)
{
if (isSettable)
{
EditingDomain editingDomain =3D getEditingDomain(object);
if (editingDomain !=3D null)
{
Resource resource =3D object instanceof EObject ?
((EObject)object).eResource() :
object instanceof Resource ?
(Resource)object :
null;
=20
return resource =3D=3D null || =
!editingDomain.isReadOnly(resource);
}
}
return false;
}
We should fix that. Please open a bugzilla if this approach works but =
this bug causes problems...
Linda Damus wrote:=20
Hello,
I am trying to set property values for model objects by delegating to =
the
auto-generated EMF ItemPropertyDescriptors from my own subclass of the
Eclipse PropertySheetEntry. My property sheet entry uses the EMFT
CompositeTransactionalOperation to support changing the same property =
value
on many model objects in a single undoable operation.
The difficulty is that the generated ItemPropertyDescriptor executes its
SetCommand through the editing domain's command stack. I do not want =
this
behaviour because my property sheet entry is already taking care of this =
by
executing its CompositeTransactionOperation through the Eclipse =
operation
history.
So far I have succeeded in overriding this behaviour by wrapping the
ItemPropertyDescriptor in the ItemPropertyDescriptionDecorator which
overrides setPropertyValue() and does not execute commands through the
command stack. Unfortunately, to do this I have to repeat a lot of code
that is already in ItemPropertyDescriptor.setPropertyValue(). Would it =
be
possible to refactor ItemPropertyDescriptor.setPropertyValue() to =
provide a
reusable getter for the SetCommand? This would make my override simpler =
and
less prone to future obsolescence.
Is there a better way for me to solve this problem? Any suggestions =
would
be most appreciated.
Thanks,
Linda
=20
------=_NextPart_000_004A_01C63190.1925FF10
Content-Type: text/html;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=3DContent-Type =
content=3Dtext/html;charset=3DISO-8859-1>
<META content=3D"MSHTML 6.00.2800.1505" name=3DGENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY text=3D#000000 bgColor=3D#ffffff>
<DIV><FONT face=3DArial size=3D2>Hi Ed,</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>If I don't have an editing domain, then =
won't I=20
miss the command overrides that may be contributed to the editing=20
domain?</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>In any case, I'm not able to subclass=20
ItemPropertyDescriptor, because I am working with descriptors from =
client=20
metamodels.</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>Thanks,</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>Linda</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV>"Ed Merks" <<A =
href=3D"mailto:merks@ca.ibm.com">merks@ca.ibm.com</A>>=20
wrote in message <A=20
href=3D"news:dstl3u$tc2$1@utils.eclipse.org">news:dstl3u$tc2$1@utils.ecli=
pse.org</A>...</DIV>
<BLOCKQUOTE=20
style=3D"PADDING-RIGHT: 0px; PADDING-LEFT: 5px; MARGIN-LEFT: 5px; =
BORDER-LEFT: #000000 2px solid; MARGIN-RIGHT: 0px">Linda,<BR><BR>Maybe=20
you could just override ItemPropertyDescriptor.getEditingDomain to =
return=20
null? In that case no commands will be used.<BR><BR>But looking =
at the=20
code I think that <A=20
=
href=3D"https://bugs.eclipse.org/bugs/show_bug.cgi?id=3D119797">https://b=
ugs.eclipse.org/bugs/show_bug.cgi?id=3D119797</A>=20
introduced a bug since this will now return false if there is no =
editing=20
domain.<BR>
<BLOCKQUOTE><SMALL> public boolean canSetProperty(Object=20
object)</SMALL><BR><SMALL> =
{</SMALL><BR><SMALL> if=20
(isSettable)</SMALL><BR><SMALL> =20
{</SMALL><BR><SMALL> EditingDomain=20
editingDomain =3D=20
=
getEditingDomain(object);</SMALL><BR><SMALL>  =
;=20
if (editingDomain !=3D =
null)</SMALL><BR><SMALL> =20
{</SMALL><BR><SMALL> =
Resource=20
resource =3D object instanceof EObject=20
=
?</SMALL><BR><SMALL>  =
;=20
((EObject)object).eResource()=20
=
:</SMALL><BR><SMALL>  =
; =20
object instanceof Resource=20
=
?</SMALL><BR><SMALL>  =
; =20
(Resource)object=20
=
:</SMALL><BR><SMALL>  =
; =20
null;</SMALL><BR><SMALL> =20
</SMALL><BR><SMALL> return =
resource =3D=3D null ||=20
=
!editingDomain.isReadOnly(resource);</SMALL><BR><SMALL> =
=20
}</SMALL><BR><SMALL> =20
}</SMALL><BR><SMALL> return=20
false;</SMALL><BR><SMALL> }</SMALL><BR></BLOCKQUOTE>We should =
fix=20
that. Please open a bugzilla if this approach works but this bug =
causes=20
problems...<BR><BR><BR>Linda Damus wrote:=20
<BLOCKQUOTE cite=3Dmiddstj7k$q9c$1@utils.eclipse.org =
type=3D"cite"><PRE wrap=3D"">Hello,
I am trying to set property values for model objects by delegating to =
the
auto-generated EMF ItemPropertyDescriptors from my own subclass of the
Eclipse PropertySheetEntry. My property sheet entry uses the EMFT
CompositeTransactionalOperation to support changing the same property =
value
on many model objects in a single undoable operation.
The difficulty is that the generated ItemPropertyDescriptor executes its
SetCommand through the editing domain's command stack. I do not want =
this
behaviour because my property sheet entry is already taking care of this =
by
executing its CompositeTransactionOperation through the Eclipse =
operation
history.
So far I have succeeded in overriding this behaviour by wrapping the
ItemPropertyDescriptor in the ItemPropertyDescriptionDecorator which
overrides setPropertyValue() and does not execute commands through the
command stack. Unfortunately, to do this I have to repeat a lot of code
that is already in ItemPropertyDescriptor.setPropertyValue(). Would it =
be
possible to refactor ItemPropertyDescriptor.setPropertyValue() to =
provide a
reusable getter for the SetCommand? This would make my override simpler =
and
less prone to future obsolescence.
Is there a better way for me to solve this problem? Any suggestions =
would
be most appreciated.
Thanks,
Linda
</PRE></BLOCKQUOTE><BR></BLOCKQUOTE></BODY></HTML>
------=_NextPart_000_004A_01C63190.1925FF10--
|
|
|
| Re: Overriding ItemPropertyDescriptor.setPropertyValue [message #398558 is a reply to message #398555] |
Wed, 15 February 2006 07:00   |
Eclipse User |
|
|
|
This is a multi-part message in MIME format.
--------------020905060403010606070205
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
Linda,
Yes, but is not avoiding executing commands exactly what you are asking
for? And if you cannot subclass ItemPropertyDescriptor, then how will
refactoring it help you?
I'm quite confused now about what exactly you are wanting...
Linda Damus wrote:
> Hi Ed,
>
> If I don't have an editing domain, then won't I miss the command
> overrides that may be contributed to the editing domain?
>
> In any case, I'm not able to subclass ItemPropertyDescriptor, because
> I am working with descriptors from client metamodels.
>
> Thanks,
>
> Linda
>
>
> "Ed Merks" <merks@ca.ibm.com <mailto:merks@ca.ibm.com>> wrote in
> message news:dstl3u$tc2$1@utils.eclipse.org...
>
> Linda,
>
> Maybe you could just override
> ItemPropertyDescriptor.getEditingDomain to return null? In that
> case no commands will be used.
>
> But looking at the code I think that
> https://bugs.eclipse.org/bugs/show_bug.cgi?id=119797 introduced a
> bug since this will now return false if there is no editing domain.
>
> public boolean canSetProperty(Object object)
> {
> if (isSettable)
> {
> EditingDomain editingDomain = getEditingDomain(object);
> if (editingDomain != null)
> {
> Resource resource = object instanceof EObject ?
> ((EObject)object).eResource() :
> object instanceof Resource ?
> (Resource)object :
> null;
>
> return resource == null ||
> !editingDomain.isReadOnly(resource);
> }
> }
> return false;
> }
>
> We should fix that. Please open a bugzilla if this approach works
> but this bug causes problems...
>
>
> Linda Damus wrote:
>> Hello,
>>
>> I am trying to set property values for model objects by delegating to the
>> auto-generated EMF ItemPropertyDescriptors from my own subclass of the
>> Eclipse PropertySheetEntry. My property sheet entry uses the EMFT
>> CompositeTransactionalOperation to support changing the same property value
>> on many model objects in a single undoable operation.
>>
>> The difficulty is that the generated ItemPropertyDescriptor executes its
>> SetCommand through the editing domain's command stack. I do not want this
>> behaviour because my property sheet entry is already taking care of this by
>> executing its CompositeTransactionOperation through the Eclipse operation
>> history.
>>
>> So far I have succeeded in overriding this behaviour by wrapping the
>> ItemPropertyDescriptor in the ItemPropertyDescriptionDecorator which
>> overrides setPropertyValue() and does not execute commands through the
>> command stack. Unfortunately, to do this I have to repeat a lot of code
>> that is already in ItemPropertyDescriptor.setPropertyValue(). Would it be
>> possible to refactor ItemPropertyDescriptor.setPropertyValue() to provide a
>> reusable getter for the SetCommand? This would make my override simpler and
>> less prone to future obsolescence.
>>
>> Is there a better way for me to solve this problem? Any suggestions would
>> be most appreciated.
>>
>> Thanks,
>>
>> Linda
>>
>>
>>
>
--------------020905060403010606070205
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
Linda,<br>
<br>
Yes, but is not avoiding executing commands exactly what you are asking
for? And if you cannot subclass ItemPropertyDescriptor, then how will
refactoring it help you? <br>
<br>
I'm quite confused now about what exactly you are wanting...<br>
<br>
<br>
Linda Damus wrote:
<blockquote cite="middstn8k$321$1@utils.eclipse.org" type="cite">
<meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1">
<meta content="MSHTML 6.00.2800.1505" name="GENERATOR">
<style></style>
<div><font face="Arial" size="2">Hi Ed,</font></div>
<div> </div>
<div><font face="Arial" size="2">If I don't have an editing domain,
then won't I miss the command overrides that may be contributed to the
editing domain?</font></div>
<div> </div>
<div><font face="Arial" size="2">In any case, I'm not able to
subclass ItemPropertyDescriptor, because I am working with descriptors
from client metamodels.</font></div>
<div> </div>
<div><font face="Arial" size="2">Thanks,</font></div>
<div> </div>
<div><font face="Arial" size="2">Linda</font></div>
<div> </div>
<div> </div>
<div>"Ed Merks" <<a href="mailto:merks@ca.ibm.com">merks@ca.ibm.com</a>>
wrote in message <a href="news:dstl3u$tc2$1@utils.eclipse.org">news:dstl3u$tc2$1@utils.eclipse.org</a>...</div>
<blockquote
style="border-left: 2px solid rgb(0, 0, 0); padding-right: 0px; padding-left: 5px; margin-left: 5px; margin-right: 0px;">Linda,<br>
<br>
Maybe you could just override ItemPropertyDescriptor.getEditingDomain
to return null? In that case no commands will be used.<br>
<br>
But looking at the code I think that <a
href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=119797">https://bugs.eclipse.org/bugs/show_bug.cgi?id=119797</a>
introduced a bug since this will now return false if there is no
editing domain.<br>
<blockquote><small> public boolean canSetProperty(Object object)</small><br>
<small> {</small><br>
<small> if (isSettable)</small><br>
<small> {</small><br>
<small> EditingDomain editingDomain =
getEditingDomain(object);</small><br>
<small> if (editingDomain != null)</small><br>
<small> {</small><br>
<small> Resource resource = object instanceof EObject ?</small><br>
<small> ((EObject)object).eResource() :</small><br>
<small> object instanceof Resource ?</small><br>
<small> (Resource)object :</small><br>
<small> null;</small><br>
<small> </small><br>
<small> return resource == null ||
!editingDomain.isReadOnly(resource);</small><br>
<small> }</small><br>
<small> }</small><br>
<small> return false;</small><br>
<small> }</small><br>
</blockquote>
We should fix that. Please open a bugzilla if this approach works but
this bug causes problems...<br>
<br>
<br>
Linda Damus wrote:
<blockquote cite="middstj7k$q9c$1@utils.eclipse.org" type="cite">
<pre wrap="">Hello,
I am trying to set property values for model objects by delegating to the
auto-generated EMF ItemPropertyDescriptors from my own subclass of the
Eclipse PropertySheetEntry. My property sheet entry uses the EMFT
CompositeTransactionalOperation to support changing the same property value
on many model objects in a single undoable operation.
The difficulty is that the generated ItemPropertyDescriptor executes its
SetCommand through the editing domain's command stack. I do not want this
behaviour because my property sheet entry is already taking care of this by
executing its CompositeTransactionOperation through the Eclipse operation
history.
So far I have succeeded in overriding this behaviour by wrapping the
ItemPropertyDescriptor in the ItemPropertyDescriptionDecorator which
overrides setPropertyValue() and does not execute commands through the
command stack. Unfortunately, to do this I have to repeat a lot of code
that is already in ItemPropertyDescriptor.setPropertyValue(). Would it be
possible to refactor ItemPropertyDescriptor.setPropertyValue() to provide a
reusable getter for the SetCommand? This would make my override simpler and
less prone to future obsolescence.
Is there a better way for me to solve this problem? Any suggestions would
be most appreciated.
Thanks,
Linda
</pre>
</blockquote>
<br>
</blockquote>
</blockquote>
<br>
</body>
</html>
--------------020905060403010606070205--
|
|
|
| Re: Overriding ItemPropertyDescriptor.setPropertyValue [message #398564 is a reply to message #398558] |
Wed, 15 February 2006 08:42   |
Eclipse User |
|
|
|
This is a multi-part message in MIME format.
------=_NextPart_000_008C_01C6320B.C452D630
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
Hello Ed,
Thank you for your prompt reply. Let me try to clarify my request... =20
I want to avoid executing the commands through the editing domain's =
command stack, and instead execute them directly by using their =
execute() method.
My current solution is to wrap the generated ItemPropertyDescriptor in =
an ItemPropertyDescriptorDecorator, and set the property value through =
my decorator. It looks like this:
/**
* Property descriptor decorator that overrides
* {@link #setPropertyValue(Object, Object)} to execute the EMF =
commands
* directly, rather than through the EMF command stack.
* <P>
* This decorator should only be used when the properties are being =
changed
* through an {@link AbstractTransactionalCommand}.
*=20
* @author ldamus
*/
protected class TransactionalOperationItemPropertyDescriptor
extends ItemPropertyDescriptorDecorator {
private final EditingDomain editingDomain;
/**
* Initializes me with my editing domain, the object whose =
properties I
* describe and my item property descriptor delegate.
*=20
* @param editingDomain
* the editing domain
* @param object
* the object whose properties I describe
* @param itemPropertyDescriptor
* the delegate
*/
public TransactionalOperationItemPropertyDescriptor(
EditingDomain editingDomain, Object object,
IItemPropertyDescriptor itemPropertyDescriptor) {
super(object, itemPropertyDescriptor);
this.editingDomain =3D editingDomain;
}
/**
* Sets the property value without executing commands on the =
editing
* domain command stack.
*/
public void setPropertyValue(Object thisObject, Object newValue) =
{
if (editingDomain =3D=3D null) {
// no editing domain, so no my delegate will not execute =
a
// command through the command stack
itemPropertyDescriptor.setPropertyValue(thisObject, =
newValue);
return;
}
EObject eObject =3D (EObject) this.object;
Object owner =3D null;
if (getItemDescriptor() instanceof ItemPropertyDescriptor) {
owner =3D ((ItemPropertyDescriptor) getItemDescriptor())
.getCommandOwner();
}
Object commandOwner =3D (owner !=3D null) ? owner
: eObject;
Object featureObject =3D getFeature(eObject);
if (featureObject instanceof EReference[]) {
EReference[] parentReferences =3D (EReference[]) =
featureObject;
Command removeCommand =3D null;
for (int i =3D 0; i < parentReferences.length; ++i) {
Object formerValue =3D =
eObject.eGet(parentReferences[i]);
if (formerValue !=3D null) {
final EReference parentReference =3D =
parentReferences[i];
if (formerValue =3D=3D newValue) {
return;
} else if =
(parentReference.getEType().isInstance(
newValue)) {
SetCommand.create(editingDomain, =
commandOwner,
parentReference, newValue).execute();
return;
} else {
removeCommand =3D =
SetCommand.create(editingDomain,
commandOwner, parentReference, null);
break;
}
}
}
for (int i =3D 0; i < parentReferences.length; ++i) {
final EReference parentReference =3D =
parentReferences[i];
if (parentReference.getEType().isInstance(newValue)) =
{
if (removeCommand !=3D null) {
final CompoundCommand compoundCommand =3D =
new CompoundCommand(
CompoundCommand.LAST_COMMAND_ALL);
compoundCommand.append(removeCommand);
compoundCommand.append(SetCommand.create(
editingDomain, commandOwner, =
parentReference,
newValue));
compoundCommand.execute();
} else {
SetCommand.create(editingDomain, =
commandOwner,
parentReference, newValue).execute();
}
break;
}
}
} else {
SetCommand.create(editingDomain, commandOwner, =
featureObject,
newValue).execute();
}
}
}
I was thinking that it would be better if I could implement my =
setPropertyValue() method with something like this:
/**
* Sets the property value without executing commands on the =
editing
* domain command stack.
*/
public void setPropertyValue(Object thisObject, Object newValue) =
{
=20
if (editingDomain =3D=3D null) {
// no editing domain, so no my delegate will not execute =
a
// command through the command stack
itemPropertyDescriptor.setPropertyValue(thisObject, =
newValue);
return;
}
Command setCommand =3D itemPropertyDescriptor
.getSetPropertyValueCommand(thisObject, newValue);
if (setCommand !=3D null && setCommand.canExecute()) {
setCommand.execute();
}
}
Thanks,
Linda
"Ed Merks" <merks@ca.ibm.com> wrote in message =
news:dsv555$fr7$1@utils.eclipse.org...
Linda,
Yes, but is not avoiding executing commands exactly what you are =
asking for? And if you cannot subclass ItemPropertyDescriptor, then how =
will refactoring it help you? =20
I'm quite confused now about what exactly you are wanting...
Linda Damus wrote:=20
Hi Ed,
If I don't have an editing domain, then won't I miss the command =
overrides that may be contributed to the editing domain?
In any case, I'm not able to subclass ItemPropertyDescriptor, =
because I am working with descriptors from client metamodels.
Thanks,
Linda
"Ed Merks" <merks@ca.ibm.com> wrote in message =
news:dstl3u$tc2$1@utils.eclipse.org...
Linda,
Maybe you could just override =
ItemPropertyDescriptor.getEditingDomain to return null? In that case no =
commands will be used.
But looking at the code I think that =
https://bugs.eclipse.org/bugs/show_bug.cgi?id=3D119797 introduced a bug =
since this will now return false if there is no editing domain.
public boolean canSetProperty(Object object)
{
if (isSettable)
{
EditingDomain editingDomain =3D getEditingDomain(object);
if (editingDomain !=3D null)
{
Resource resource =3D object instanceof EObject ?
((EObject)object).eResource() :
object instanceof Resource ?
(Resource)object :
null;
=20
return resource =3D=3D null || =
!editingDomain.isReadOnly(resource);
}
}
return false;
}
We should fix that. Please open a bugzilla if this approach works =
but this bug causes problems...
Linda Damus wrote:=20
Hello,
I am trying to set property values for model objects by delegating to =
the
auto-generated EMF ItemPropertyDescriptors from my own subclass of the
Eclipse PropertySheetEntry. My property sheet entry uses the EMFT
CompositeTransactionalOperation to support changing the same property =
value
on many model objects in a single undoable operation.
The difficulty is that the generated ItemPropertyDescriptor executes its
SetCommand through the editing domain's command stack. I do not want =
this
behaviour because my property sheet entry is already taking care of this =
by
executing its CompositeTransactionOperation through the Eclipse =
operation
history.
So far I have succeeded in overriding this behaviour by wrapping the
ItemPropertyDescriptor in the ItemPropertyDescriptionDecorator which
overrides setPropertyValue() and does not execute commands through the
command stack. Unfortunately, to do this I have to repeat a lot of code
that is already in ItemPropertyDescriptor.setPropertyValue(). Would it =
be
possible to refactor ItemPropertyDescriptor.setPropertyValue() to =
provide a
reusable getter for the SetCommand? This would make my override simpler =
and
less prone to future obsolescence.
Is there a better way for me to solve this problem? Any suggestions =
would
be most appreciated.
Thanks,
Linda
=20
------=_NextPart_000_008C_01C6320B.C452D630
Content-Type: text/html;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=3DContent-Type =
content=3Dtext/html;charset=3DISO-8859-1>
<META content=3D"MSHTML 6.00.2800.1505" name=3DGENERATOR></HEAD>
<BODY text=3D#000000 bgColor=3D#ffffff>
<DIV><FONT face=3DArial size=3D2>Hello Ed,</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>Thank you for your prompt reply. =
Let me try=20
to clarify my request... </FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>I want to avoid executing the commands =
through the=20
editing domain's command stack, and instead execute them directly by =
using their=20
execute() method.</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>My current solution is to wrap the =
generated=20
ItemPropertyDescriptor in an ItemPropertyDescriptorDecorator, and set =
the=20
property value through my decorator. It looks like =
this:</FONT></DIV>
<DIV><FONT size=3D2>
<P align=3Dleft><FONT face=3DCourier> =20
/**<BR> * Property descriptor decorator that=20
overrides<BR> * <A =
href=3D"mailto:{@link">{@link</A>=20
#setPropertyValue(Object, Object)} to execute the EMF=20
commands<BR> * directly, rather than through the =
EMF=20
command stack.<BR> *=20
<P><BR> * This decorator should only be =
used when=20
the properties are being changed<BR> * through =
an <A=20
href=3D"mailto:{@link">{@link</A>=20
AbstractTransactionalCommand}.<BR> *=20
<BR> * @author =
ldamus<BR> =20
*/<BR> protected class=20
TransactionalOperationItemPropertyDescriptor<BR> &=
nbsp; =20
extends ItemPropertyDescriptorDecorator {</FONT></P>
<P align=3Dleft><FONT =
face=3DCourier> =20
private final EditingDomain editingDomain;</FONT></P>
<P align=3Dleft><FONT =
face=3DCourier> =20
/**<BR> * Initializes me =
with my=20
editing domain, the object whose properties=20
I<BR> * describe and my =
item=20
property descriptor=20
delegate.<BR> *=20
<BR> * @param=20
editingDomain<BR> =20
*   ; the =
editing=20
domain<BR> * @param=20
object<BR> =20
*   ; the =
object=20
whose properties I =
describe<BR> =20
* @param=20
itemPropertyDescriptor<BR>  =
;=20
*   ; the=20
delegate<BR> =20
*/<BR> public=20
TransactionalOperationItemPropertyDescriptor(<BR> =
=20
EditingDomain editingDomain, Object=20
object,<BR> &n=
bsp; =20
IItemPropertyDescriptor itemPropertyDescriptor) {</FONT></P>
<P align=3Dleft><FONT=20
face=3DCourier> &nbs=
p; =20
super(object,=20
itemPropertyDescriptor);<BR> &nb=
sp; =20
this.editingDomain =3D=20
editingDomain;<BR> =
}</FONT></P>
<P align=3Dleft><FONT =
face=3DCourier> =20
/**<BR> * Sets the =
property=20
value without executing commands on the=20
editing<BR> * domain =
command=20
stack.<BR> =20
*/<BR> public void=20
setPropertyValue(Object thisObject, Object newValue) {</FONT></P>
<P align=3Dleft><FONT=20
face=3DCourier> &nbs=
p; =20
if (editingDomain =3D=3D null)=20
{<BR> &n=
bsp; =20
// no editing domain, so no my delegate will not execute=20
a<BR> &n=
bsp; =20
// command through the command=20
stack<BR> &nbs=
p; =20
itemPropertyDescriptor.setPropertyValue(thisObject,=20
newValue);<BR>  =
; =20
return;<BR> &n=
bsp;=20
}</FONT></P>
<P align=3Dleft><FONT=20
face=3DCourier> &nbs=
p; =20
EObject eObject =3D (EObject) this.object;</FONT></P>
<P align=3Dleft><FONT=20
face=3DCourier> &nbs=
p; =20
Object owner =3D null;</FONT></P>
<P align=3Dleft><FONT=20
face=3DCourier> &nbs=
p; =20
if (getItemDescriptor() instanceof ItemPropertyDescriptor)=20
{<BR> &n=
bsp; =20
owner =3D ((ItemPropertyDescriptor)=20
getItemDescriptor())<BR> &=
nbsp; & nbsp; =20
..getCommandOwner();<BR> &n=
bsp; =20
}</FONT></P>
<P align=3Dleft><FONT=20
face=3DCourier> &nbs=
p; =20
Object commandOwner =3D (owner !=3D null) ?=20
owner<BR> &nbs=
p; =20
: eObject;</FONT></P>
<P align=3Dleft><FONT=20
face=3DCourier> &nbs=
p; =20
Object featureObject =3D getFeature(eObject);</FONT></P>
<P align=3Dleft><FONT=20
face=3DCourier> &nbs=
p; =20
if (featureObject instanceof EReference[])=20
{<BR> &n=
bsp; =20
EReference[] parentReferences =3D (EReference[])=20
featureObject;<BR> &=
nbsp; =20
Command removeCommand =3D null;</FONT></P>
<P align=3Dleft><FONT=20
face=3DCourier> &nbs=
p; =20
for (int i =3D 0; i < parentReferences.length; ++i)=20
{<BR> &n=
bsp; &n bsp; =20
Object formerValue =3D eObject.eGet(parentReferences[i]);</FONT></P>
<P align=3Dleft><FONT=20
face=3DCourier> &nbs=
p; &nbs p; =20
if (formerValue !=3D null)=20
{<BR> &n=
bsp; &n bsp; =20
final EReference parentReference =3D parentReferences[i];</FONT></P>
<P align=3Dleft><FONT=20
face=3DCourier> &nbs=
p; &nbs p; &nbs p=
; =20
if (formerValue =3D=3D newValue)=20
{<BR> &n=
bsp; &n bsp; &n b=
sp; =20
return;</FONT></P>
<P align=3Dleft><FONT=20
face=3DCourier> &nbs=
p; &nbs p; &nbs p=
; =20
} else if=20
(parentReference.getEType().isInstance(<BR> =
&=
nbsp; & nbsp; =20
newValue)) {</FONT></P>
<P align=3Dleft><FONT=20
face=3DCourier> &nbs=
p; &nbs p; &nbs p=
; =20
SetCommand.create(editingDomain,=20
commandOwner,<BR> &n=
bsp; &n bsp; &n b=
sp; &nb sp; =20
parentReference,=20
newValue).execute();<BR> &=
nbsp; & nbsp; & n=
bsp; &n bsp;=20
return;</FONT></P>
<P align=3Dleft><FONT=20
face=3DCourier> &nbs=
p; &nbs p; &nbs p=
; =20
} else=20
{<BR> &n=
bsp; &n bsp; &n b=
sp; =20
removeCommand =3D=20
SetCommand.create(editingDomain,<BR> &=
nbsp; & nbsp; & n=
bsp; &n bsp; &n b=
sp;=20
commandOwner, parentReference,=20
null);<BR> &nb=
sp; &nb sp; &nb s=
p; =20
break;<BR> &nb=
sp; &nb sp; &nb s=
p;=20
}<BR> &n=
bsp; &n bsp; =20
}<BR> &n=
bsp; =20
}</FONT></P>
<P align=3Dleft><FONT=20
face=3DCourier> &nbs=
p; =20
for (int i =3D 0; i < parentReferences.length; ++i)=20
{<BR> &n=
bsp; &n bsp; =20
final EReference parentReference =3D parentReferences[i];</FONT></P>
<P align=3Dleft><FONT=20
face=3DCourier> &nbs=
p; &nbs p; =20
if (parentReference.getEType().isInstance(newValue))=20
{<BR> &n=
bsp; &n bsp; =20
if (removeCommand !=3D null)=20
{<BR> &n=
bsp; &n bsp; &n b=
sp; =20
final CompoundCommand compoundCommand =3D new=20
CompoundCommand(<BR>  =
;   ;   ;=
=20
CompoundCommand.LAST_COMMAND_ALL);<BR>  =
;   ;   ;=
=20
compoundCommand.append(removeCommand);<BR> &=
nbsp; & nbsp; & n=
bsp; &n bsp; =20
compoundCommand.append(SetCommand.create(<BR> &nbs=
p; &nbs p; &nbs p=
;   ;   ;=
=20
editingDomain, commandOwner,=20
parentReference,<BR>  =
;   ;   ;=
=20
newValue));<BR> &nbs=
p; &nbs p; &nbs p=
; =20
compoundCommand.execute();</FONT></P>
<P align=3Dleft><FONT=20
face=3DCourier> &nbs=
p; &nbs p; &nbs p=
; =20
} else=20
{<BR> &n=
bsp; &n bsp; &n b=
sp; =20
SetCommand.create(editingDomain,=20
commandOwner,<BR> &n=
bsp; &n bsp; &n b=
sp; &nb sp; =20
parentReference,=20
newValue).execute();<BR> &=
nbsp; & nbsp; & n=
bsp; =20
}<BR> &n=
bsp; &n bsp; =20
break;<BR> &nb=
sp; &nb sp; =20
}<BR> &n=
bsp; =20
}<BR> =
} else=20
{<BR> &n=
bsp; =20
SetCommand.create(editingDomain, commandOwner,=20
featureObject,<BR> &=
nbsp; & nbsp; =20
newValue).execute();<BR> &=
nbsp; =20
}<BR> }<BR> =20
}</FONT></P></FONT><FONT size=3D2></FONT></DIV>
<DIV><FONT face=3DArial size=3D2>I was thinking that it would be better =
if I could=20
implement my setPropertyValue() method with something like=20
this:</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DCourier=20
size=3D2> /** <BR> &nb=
sp; &nb sp;=20
* Sets the property value without executing commands on the=20
editing<BR> * domain =
command=20
stack.<BR> =20
*/<BR> public void=20
setPropertyValue(Object thisObject, Object newValue)=20
{<BR> =20
<BR> =
if=20
(editingDomain =3D=3D null)=20
{<BR> &n=
bsp; =20
// no editing domain, so no my delegate will not execute=20
a<BR> &n=
bsp; =20
// command through the command=20
stack<BR> &nbs=
p; =20
itemPropertyDescriptor.setPropertyValue(thisObject,=20
newValue);<BR>  =
; =20
return;<BR> &n=
bsp;=20
}</FONT></DIV>
<DIV><FONT face=3DCourier></FONT> </DIV>
<DIV><FONT face=3DCourier=20
size=3D2> &nbs=
p;=20
Command setCommand =3D=20
itemPropertyDescriptor<BR>  =
;   ; =20
..<STRONG>getSetPropertyValueCommand</STRONG>(thisObject, =
newValue);</FONT></DIV>
<DIV><FONT face=3DCourier></FONT> </DIV>
<DIV><FONT face=3DCourier=20
size=3D2> &nbs=
p; if=20
(setCommand !=3D null && setCommand.canExecute())=20
{<BR> &n=
bsp; =20
setCommand.execute();<BR> =
=20
}<BR> }</FONT></DIV>
<DIV><FONT face=3DCourier size=3D2></FONT> </DIV>
<DIV><FONT face=3DCourier size=3D2></FONT> </DIV>
<DIV><FONT face=3DCourier size=3D2></FONT> </DIV>
<DIV>Thanks,</DIV>
<DIV> </DIV>
<DIV>Linda</DIV>
<DIV> </DIV>
<BLOCKQUOTE=20
style=3D"PADDING-RIGHT: 0px; PADDING-LEFT: 5px; MARGIN-LEFT: 5px; =
BORDER-LEFT: #000000 2px solid; MARGIN-RIGHT: 0px">
<DIV>"Ed Merks" <<A =
href=3D"mailto:merks@ca.ibm.com">merks@ca.ibm.com</A>>=20
wrote in message <A=20
=
href=3D"news:dsv555$fr7$1@utils.eclipse.org">news:dsv555$fr7$1@utils.ecli=
pse.org</A>...</DIV>Linda,<BR><BR>Yes,=20
but is not avoiding executing commands exactly what you are asking =
for? =20
And if you cannot subclass ItemPropertyDescriptor, then how will =
refactoring=20
it help you? <BR><BR>I'm quite confused now about what exactly =
you are=20
wanting...<BR><BR><BR>Linda Damus wrote:=20
<BLOCKQUOTE cite=3Dmiddstn8k$321$1@utils.eclipse.org type=3D"cite">
<META content=3D"MSHTML 6.00.2800.1505" name=3DGENERATOR>
<STYLE></STYLE>
<DIV><FONT face=3DArial size=3D2>Hi Ed,</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>If I don't have an editing domain, =
then won't I=20
miss the command overrides that may be contributed to the editing=20
domain?</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=3DArial size=3D2>In any case, I'm not able to =
subclass=20
ItemPropertyDescriptor, because I am working with descriptors from =
client=20
metamodels.</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=3DArial size=3D2>Thanks,</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=3DArial size=3D2>Linda</FONT></DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV>"Ed Merks" <<A=20
href=3D"mailto:merks@ca.ibm.com">merks@ca.ibm.com</A>> wrote in =
message <A=20
=
href=3D"news:dstl3u$tc2$1@utils.eclipse.org">news:dstl3u$tc2$1@utils.ecli=
pse.org</A>...</DIV>
<BLOCKQUOTE=20
style=3D"PADDING-RIGHT: 0px; PADDING-LEFT: 5px; MARGIN-LEFT: 5px; =
BORDER-LEFT: rgb(0,0,0) 2px solid; MARGIN-RIGHT: =
0px">Linda,<BR><BR>Maybe=20
you could just override ItemPropertyDescriptor.getEditingDomain to =
return=20
null? In that case no commands will be used.<BR><BR>But =
looking at=20
the code I think that <A=20
=
href=3D"https://bugs.eclipse.org/bugs/show_bug.cgi?id=3D119797">https://b=
ugs.eclipse.org/bugs/show_bug.cgi?id=3D119797</A>=20
introduced a bug since this will now return false if there is no =
editing=20
domain.<BR>
<BLOCKQUOTE><SMALL> public boolean canSetProperty(Object=20
object)</SMALL><BR><SMALL> =
{</SMALL><BR><SMALL> =20
if (isSettable)</SMALL><BR><SMALL> =20
{</SMALL><BR><SMALL> EditingDomain =
editingDomain =3D=20
=
getEditingDomain(object);</SMALL><BR><SMALL>  =
;=20
if (editingDomain !=3D=20
null)</SMALL><BR><SMALL> =20
{</SMALL><BR><SMALL> =
Resource=20
resource =3D object instanceof EObject=20
=
?</SMALL><BR><SMALL>  =
;=20
((EObject)object).eResource()=20
=
:</SMALL><BR><SMALL>  =
; =20
object instanceof Resource=20
=
?</SMALL><BR><SMALL>  =
; =20
(Resource)object=20
=
:</SMALL><BR><SMALL>  =
; =20
null;</SMALL><BR><SMALL> =20
</SMALL><BR><SMALL> =
return=20
resource =3D=3D null ||=20
=
!editingDomain.isReadOnly(resource);</SMALL><BR><SMALL> =
=20
}</SMALL><BR><SMALL> =20
}</SMALL><BR><SMALL> return=20
false;</SMALL><BR><SMALL> }</SMALL><BR></BLOCKQUOTE>We =
should fix=20
that. Please open a bugzilla if this approach works but this =
bug=20
causes problems...<BR><BR><BR>Linda Damus wrote:=20
<BLOCKQUOTE cite=3Dmiddstj7k$q9c$1@utils.eclipse.org =
type=3D"cite"><PRE wrap=3D"">Hello,
I am trying to set property values for model objects by delegating to =
the
auto-generated EMF ItemPropertyDescriptors from my own subclass of the
Eclipse PropertySheetEntry. My property sheet entry uses the EMFT
CompositeTransactionalOperation to support changing the same property =
value
on many model objects in a single undoable operation.
The difficulty is that the generated ItemPropertyDescriptor executes its
SetCommand through the editing domain's command stack. I do not want =
this
behaviour because my property sheet entry is already taking care of this =
by
executing its CompositeTransactionOperation through the Eclipse =
operation
history.
So far I have succeeded in overriding this behaviour by wrapping the
ItemPropertyDescriptor in the ItemPropertyDescriptionDecorator which
overrides setPropertyValue() and does not execute commands through the
command stack. Unfortunately, to do this I have to repeat a lot of code
that is already in ItemPropertyDescriptor.setPropertyValue(). Would it =
be
possible to refactor ItemPropertyDescriptor.setPropertyValue() to =
provide a
reusable getter for the SetCommand? This would make my override simpler =
and
less prone to future obsolescence.
Is there a better way for me to solve this problem? Any suggestions =
would
be most appreciated.
Thanks,
Linda
=
</PRE></BLOCKQUOTE><BR></BLOCKQUOTE></BLOCKQUOTE><BR></BLOCKQUOTE ></BODY>=
</HTML>
------=_NextPart_000_008C_01C6320B.C452D630--
|
|
|
| Re: Overriding ItemPropertyDescriptor.setPropertyValue [message #398565 is a reply to message #398564] |
Wed, 15 February 2006 08:57  |
Eclipse User |
|
|
|
This is a multi-part message in MIME format.
--------------090901090305020008070703
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
Linda,
This isn't just refactoring, this is changing the API itself, so I'm not
keen on so that idea, since clients specializing the API would now have
to worry about two override points, not just one. Given that there is
an editing domain with a command stack, could you structure that editing
domain's stack so that it knows that commands are being executed while
you are in a state where you really don't want to record them on the
command stack itself? I.e., override BasicCommandStack.execute to
behave differently depending on the current state/expectations.
Linda Damus wrote:
> Hello Ed,
>
> Thank you for your prompt reply. Let me try to clarify my request...
>
> I want to avoid executing the commands through the editing domain's
> command stack, and instead execute them directly by using their
> execute() method.
>
> My current solution is to wrap the generated ItemPropertyDescriptor in
> an ItemPropertyDescriptorDecorator, and set the property value through
> my decorator. It looks like this:
>
> /**
> * Property descriptor decorator that overrides
> * {@link <mailto:%7B@link> #setPropertyValue(Object, Object)} to
> execute the EMF commands
> * directly, rather than through the EMF command stack.
> * <P>
> * This decorator should only be used when the properties are
> being changed
> * through an {@link <mailto:%7B@link> AbstractTransactionalCommand}.
> *
> * @author ldamus
> */
> protected class TransactionalOperationItemPropertyDescriptor
> extends ItemPropertyDescriptorDecorator {
>
> private final EditingDomain editingDomain;
>
> /**
> * Initializes me with my editing domain, the object whose
> properties I
> * describe and my item property descriptor delegate.
> *
> * @param editingDomain
> * the editing domain
> * @param object
> * the object whose properties I describe
> * @param itemPropertyDescriptor
> * the delegate
> */
> public TransactionalOperationItemPropertyDescriptor(
> EditingDomain editingDomain, Object object,
> IItemPropertyDescriptor itemPropertyDescriptor) {
>
> super(object, itemPropertyDescriptor);
> this.editingDomain = editingDomain;
> }
>
> /**
> * Sets the property value without executing commands on the
> editing
> * domain command stack.
> */
> public void setPropertyValue(Object thisObject, Object newValue) {
>
> if (editingDomain == null) {
> // no editing domain, so no my delegate will not execute a
> // command through the command stack
> itemPropertyDescriptor.setPropertyValue(thisObject,
> newValue);
> return;
> }
>
> EObject eObject = (EObject) this.object;
>
> Object owner = null;
>
> if (getItemDescriptor() instanceof ItemPropertyDescriptor) {
> owner = ((ItemPropertyDescriptor) getItemDescriptor())
> ..getCommandOwner();
> }
>
> Object commandOwner = (owner != null) ? owner
> : eObject;
>
> Object featureObject = getFeature(eObject);
>
> if (featureObject instanceof EReference[]) {
> EReference[] parentReferences = (EReference[])
> featureObject;
> Command removeCommand = null;
>
> for (int i = 0; i < parentReferences.length; ++i) {
> Object formerValue =
> eObject.eGet(parentReferences[i]);
>
> if (formerValue != null) {
> final EReference parentReference =
> parentReferences[i];
>
> if (formerValue == newValue) {
> return;
>
> } else if (parentReference.getEType().isInstance(
> newValue)) {
>
> SetCommand.create(editingDomain, commandOwner,
> parentReference, newValue).execute();
> return;
>
> } else {
> removeCommand =
> SetCommand.create(editingDomain,
> commandOwner, parentReference, null);
> break;
> }
> }
> }
>
> for (int i = 0; i < parentReferences.length; ++i) {
> final EReference parentReference =
> parentReferences[i];
>
> if (parentReference.getEType().isInstance(newValue)) {
> if (removeCommand != null) {
> final CompoundCommand compoundCommand =
> new CompoundCommand(
> CompoundCommand.LAST_COMMAND_ALL);
> compoundCommand.append(removeCommand);
> compoundCommand.append(SetCommand.create(
> editingDomain, commandOwner,
> parentReference,
> newValue));
> compoundCommand.execute();
>
> } else {
> SetCommand.create(editingDomain, commandOwner,
> parentReference, newValue).execute();
> }
> break;
> }
> }
> } else {
> SetCommand.create(editingDomain, commandOwner,
> featureObject,
> newValue).execute();
> }
> }
> }
>
> I was thinking that it would be better if I could implement my
> setPropertyValue() method with something like this:
>
> /**
> * Sets the property value without executing commands on the
> editing
> * domain command stack.
> */
> public void setPropertyValue(Object thisObject, Object newValue) {
>
> if (editingDomain == null) {
> // no editing domain, so no my delegate will not execute a
> // command through the command stack
> itemPropertyDescriptor.setPropertyValue(thisObject,
> newValue);
> return;
> }
>
> Command setCommand = itemPropertyDescriptor
> ..*getSetPropertyValueCommand*(thisObject, newValue);
>
> if (setCommand != null && setCommand.canExecute()) {
> setCommand.execute();
> }
> }
>
>
>
> Thanks,
>
> Linda
>
>
> "Ed Merks" <merks@ca.ibm.com <mailto:merks@ca.ibm.com>> wrote in
> message news:dsv555$fr7$1@utils.eclipse.org...
> Linda,
>
> Yes, but is not avoiding executing commands exactly what you are
> asking for? And if you cannot subclass ItemPropertyDescriptor,
> then how will refactoring it help you?
>
> I'm quite confused now about what exactly you are wanting...
>
>
> Linda Damus wrote:
>> Hi Ed,
>>
>> If I don't have an editing domain, then won't I miss the command
>> overrides that may be contributed to the editing domain?
>>
>> In any case, I'm not able to subclass ItemPropertyDescriptor,
>> because I am working with descriptors from client metamodels.
>>
>> Thanks,
>>
>> Linda
>>
>>
>> "Ed Merks" <merks@ca.ibm.com <mailto:merks@ca.ibm.com>> wrote in
>> message news:dstl3u$tc2$1@utils.eclipse.org...
>>
>> Linda,
>>
>> Maybe you could just override
>> ItemPropertyDescriptor.getEditingDomain to return null? In
>> that case no commands will be used.
>>
>> But looking at the code I think that
>> https://bugs.eclipse.org/bugs/show_bug.cgi?id=119797
>> introduced a bug since this will now return false if there is
>> no editing domain.
>>
>> public boolean canSetProperty(Object object)
>> {
>> if (isSettable)
>> {
>> EditingDomain editingDomain = getEditingDomain(object);
>> if (editingDomain != null)
>> {
>> Resource resource = object instanceof EObject ?
>> ((EObject)object).eResource() :
>> object instanceof Resource ?
>> (Resource)object :
>> null;
>>
>> return resource == null ||
>> !editingDomain.isReadOnly(resource);
>> }
>> }
>> return false;
>> }
>>
>> We should fix that. Please open a bugzilla if this approach
>> works but this bug causes problems...
>>
>>
>> Linda Damus wrote:
>>> Hello,
>>>
>>> I am trying to set property values for model objects by delegating to the
>>> auto-generated EMF ItemPropertyDescriptors from my own subclass of the
>>> Eclipse PropertySheetEntry. My property sheet entry uses the EMFT
>>> CompositeTransactionalOperation to support changing the same property value
>>> on many model objects in a single undoable operation.
>>>
>>> The difficulty is that the generated ItemPropertyDescriptor executes its
>>> SetCommand through the editing domain's command stack. I do not want this
>>> behaviour because my property sheet entry is already taking care of this by
>>> executing its CompositeTransactionOperation through the Eclipse operation
>>> history.
>>>
>>> So far I have succeeded in overriding this behaviour by wrapping the
>>> ItemPropertyDescriptor in the ItemPropertyDescriptionDecorator which
>>> overrides setPropertyValue() and does not execute commands through the
>>> command stack. Unfortunately, to do this I have to repeat a lot of code
>>> that is already in ItemPropertyDescriptor.setPropertyValue(). Would it be
>>> possible to refactor ItemPropertyDescriptor.setPropertyValue() to provide a
>>> reusable getter for the SetCommand? This would make my override simpler and
>>> less prone to future obsolescence.
>>>
>>> Is there a better way for me to solve this problem? Any suggestions would
>>> be most appreciated.
>>>
>>> Thanks,
>>>
>>> Linda
>>>
>>>
>>>
>>
>
--------------090901090305020008070703
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
Linda,<br>
<br>
This isn't just refactoring, this is changing the API itself, so I'm
not keen on so that idea, since clients specializing the API would now
have to worry about two override points, not just one. Given that
there is an editing domain with a command stack, could you structure
that editing domain's stack so that it knows that commands are being
executed while you are in a state where you really don't want to record
them on the command stack itself? I.e., override
BasicCommandStack.execute to behave differently depending on the
current state/expectations. <br>
<br>
<br>
Linda Damus wrote:
<blockquote cite="middsvb4c$qpo$1@utils.eclipse.org" type="cite">
<meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1">
<meta content="MSHTML 6.00.2800.1505" name="GENERATOR">
<div><font face="Arial" size="2">Hello Ed,</font></div>
<div> </div>
<div><font face="Arial" size="2">Thank you for your prompt reply.
Let me try to clarify my request... </font></div>
<div> </div>
<div><font face="Arial" size="2">I want to avoid executing the
commands through the editing domain's command stack, and instead
execute them directly by using their execute() method.</font></div>
<div> </div>
<div><font face="Arial" size="2">My current solution is to wrap the
generated ItemPropertyDescriptor in an ItemPropertyDescriptorDecorator,
and set the property value through my decorator. It looks like this:</font></div>
<div><font size="2">
<p align="left"><font face="Courier"> /**<br>
* Property descriptor decorator that overrides<br>
* <a href="mailto:%7B@link">{@link</a> #setPropertyValue(Object,
Object)} to execute the EMF commands<br>
* directly, rather than through the EMF command stack.<br>
* <P><br>
* This decorator should only be used when the properties are being
changed<br>
* through an <a href="mailto:%7B@link">{@link</a>
AbstractTransactionalCommand}.<br>
* <br>
* @author ldamus<br>
*/<br>
protected class TransactionalOperationItemPropertyDescriptor<br>
extends ItemPropertyDescriptorDecorator {</font></p>
<p align="left"><font face="Courier"> private final
EditingDomain editingDomain;</font></p>
<p align="left"><font face="Courier"> /**<br>
* Initializes me with my editing domain, the object whose
properties I<br>
* describe and my item property descriptor delegate.<br>
* <br>
* @param editingDomain<br>
*   ; the editing domain<br>
* @param object<br>
*   ; the object whose properties I describe<br>
* @param itemPropertyDescriptor<br>
*   ; the delegate<br>
*/<br>
public TransactionalOperationItemPropertyDescriptor(<br>
EditingDomain editingDomain, Object object,<br>
IItemPropertyDescriptor itemPropertyDescriptor) {</font></p>
<p align="left"><font face="Courier"> super(object,
itemPropertyDescriptor);<br>
this.editingDomain = editingDomain;<br>
}</font></p>
<p align="left"><font face="Courier"> /**<br>
* Sets the property value without executing commands on the
editing<br>
* domain command stack.<br>
*/<br>
public void setPropertyValue(Object thisObject, Object
newValue) {</font></p>
<p align="left"><font face="Courier"> if (editingDomain ==
null) {<br>
// no editing domain, so no my delegate will not
execute a<br>
// command through the command stack<br>
itemPropertyDescriptor.setPropertyValue(thisObject,
newValue);<br>
return;<br>
}</font></p>
<p align="left"><font face="Courier"> EObject eObject =
(EObject) this.object;</font></p>
<p align="left"><font face="Courier"> Object owner = null;</font></p>
<p align="left"><font face="Courier"> if
(getItemDescriptor() instanceof ItemPropertyDescriptor) {<br>
owner = ((ItemPropertyDescriptor) getItemDescriptor())<br>
..getCommandOwner();<br>
}</font></p>
<p align="left"><font face="Courier"> Object commandOwner
= (owner != null) ? owner<br>
: eObject;</font></p>
<p align="left"><font face="Courier"> Object featureObject
= getFeature(eObject);</font></p>
<p align="left"><font face="Courier"> if (featureObject
instanceof EReference[]) {<br>
EReference[] parentReferences = (EReference[])
featureObject;<br>
Command removeCommand = null;</font></p>
<p align="left"><font face="Courier"> for (int i = 0;
i < parentReferences.length; ++i) {<br>
Object formerValue =
eObject.eGet(parentReferences[i]);</font></p>
<p align="left"><font face="Courier"> if
(formerValue != null) {<br>
final EReference parentReference =
parentReferences[i];</font></p>
<p align="left"><font face="Courier"> if
(formerValue == newValue) {<br>
return;</font></p>
<p align="left"><font face="Courier"> } else
if (parentReference.getEType().isInstance(<br>
newValue)) {</font></p>
<p align="left"><font face="Courier">
SetCommand.create(editingDomain, commandOwner,<br>
parentReference, newValue).execute();<br>
return;</font></p>
<p align="left"><font face="Courier"> } else {<br>
removeCommand =
SetCommand.create(editingDomain,<br>
commandOwner, parentReference, null);<br>
break;<br>
}<br>
}<br>
}</font></p>
<p align="left"><font face="Courier"> for (int i = 0;
i < parentReferences.length; ++i) {<br>
final EReference parentReference =
parentReferences[i];</font></p>
<p align="left"><font face="Courier"> if
(parentReference.getEType().isInstance(newValue)) {<br>
if (removeCommand != null) {<br>
final CompoundCommand compoundCommand = new
CompoundCommand(<br>
CompoundCommand.LAST_COMMAND_ALL);<br>
compoundCommand.append(removeCommand);<br>
compoundCommand.append(SetCommand.create(<br>
editingDomain, commandOwner,
parentReference,<br>
newValue));<br>
compoundCommand.execute();</font></p>
<p align="left"><font face="Courier"> } else {<br>
SetCommand.create(editingDomain,
commandOwner,<br>
parentReference, newValue).execute();<br>
}<br>
break;<br>
}<br>
}<br>
} else {<br>
SetCommand.create(editingDomain, commandOwner,
featureObject,<br>
newValue).execute();<br>
}<br>
}<br>
}</font></p>
</font></div>
<div><font face="Arial" size="2">I was thinking that it would be
better if I could implement my setPropertyValue() method with something
like this:</font></div>
<div> </div>
<div><font face="Courier" size="2"> /** <br>
* Sets the property value without executing commands on the
editing<br>
* domain command stack.<br>
*/<br>
public void setPropertyValue(Object thisObject, Object
newValue) {<br>
<br>
if (editingDomain == null) {<br>
// no editing domain, so no my delegate will not
execute a<br>
// command through the command stack<br>
itemPropertyDescriptor.setPropertyValue(thisObject,
newValue);<br>
return;<br>
}</font></div>
<div> </div>
<div><font face="Courier" size="2"> Command setCommand =
itemPropertyDescriptor<br>
..<strong>getSetPropertyValueCommand</strong>(thisObject,
newValue);</font></div>
<div> </div>
<div><font face="Courier" size="2"> if (setCommand != null
&& setCommand.canExecute()) {<br>
setCommand.execute();<br>
}<br>
}</font></div>
<div> </div>
<div> </div>
<div> </div>
<div>Thanks,</div>
<div> </div>
<div>Linda</div>
<div> </div>
<blockquote
style="border-left: 2px solid rgb(0, 0, 0); padding-right: 0px; padding-left: 5px; margin-left: 5px; margin-right: 0px;">
<div>"Ed Merks" <<a href="mailto:merks@ca.ibm.com">merks@ca.ibm.com</a>>
wrote in message <a href="news:dsv555$fr7$1@utils.eclipse.org">news:dsv555$fr7$1@utils.eclipse.org</a>...</div>
Linda,<br>
<br>
Yes, but is not avoiding executing commands exactly what you are asking
for? And if you cannot subclass ItemPropertyDescriptor, then how will
refactoring it help you? <br>
<br>
I'm quite confused now about what exactly you are wanting...<br>
<br>
<br>
Linda Damus wrote:
<blockquote cite="middstn8k$321$1@utils.eclipse.org" type="cite">
<meta content="MSHTML 6.00.2800.1505" name="GENERATOR">
<style></style>
<div><font face="Arial" size="2">Hi Ed,</font></div>
<div> </div>
<div><font face="Arial" size="2">If I don't have an editing
domain, then won't I miss the command overrides that may be contributed
to the editing domain?</font></div>
<div> </div>
<div><font face="Arial" size="2">In any case, I'm not able to
subclass ItemPropertyDescriptor, because I am working with descriptors
from client metamodels.</font></div>
<div> </div>
<div><font face="Arial" size="2">Thanks,</font></div>
<div> </div>
<div><font face="Arial" size="2">Linda</font></div>
<div> </div>
<div> </div>
<div>"Ed Merks" <<a href="mailto:merks@ca.ibm.com">merks@ca.ibm.com</a>>
wrote in message <a href="news:dstl3u$tc2$1@utils.eclipse.org">news:dstl3u$tc2$1@utils.eclipse.org</a>...</div>
<blockquote
style="border-left: 2px solid rgb(0, 0, 0); padding-right: 0px; padding-left: 5px; margin-left: 5px; margin-right: 0px;">Linda,<br>
<br>
Maybe you could just override ItemPropertyDescriptor.getEditingDomain
to return null? In that case no commands will be used.<br>
<br>
But looking at the code I think that <a
href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=119797">https://bugs.eclipse.org/bugs/show_bug.cgi?id=119797</a>
introduced a bug since this will now return false if there is no
editing domain.<br>
<blockquote><small> public boolean canSetProperty(Object
object)</small><br>
<small> {</small><br>
<small> if (isSettable)</small><br>
<small> {</small><br>
<small> EditingDomain editingDomain =
getEditingDomain(object);</small><br>
<small> if (editingDomain != null)</small><br>
<small> {</small><br>
<small> Resource resource = object instanceof EObject ?</small><br>
<small> ((EObject)object).eResource() :</small><br>
<small> object instanceof Resource ?</small><br>
<small> (Resource)object :</small><br>
<small> null;</small><br>
<small> </small><br>
<small> return resource == null ||
!editingDomain.isReadOnly(resource);</small><br>
<small> }</small><br>
<small> }</small><br>
<small> return false;</small><br>
<small> }</small><br>
</blockquote>
We should fix that. Please open a bugzilla if this approach works but
this bug causes problems...<br>
<br>
<br>
Linda Damus wrote:
<blockquote cite="middstj7k$q9c$1@utils.eclipse.org" type="cite">
<pre wrap="">Hello,
I am trying to set property values for model objects by delegating to the
auto-generated EMF ItemPropertyDescriptors from my own subclass of the
Eclipse PropertySheetEntry. My property sheet entry uses the EMFT
CompositeTransactionalOperation to support changing the same property value
on many model objects in a single undoable operation.
The difficulty is that the generated ItemPropertyDescriptor executes its
SetCommand through the editing domain's command stack. I do not want this
behaviour because my property sheet entry is already taking care of this by
executing its CompositeTransactionOperation through the Eclipse operation
history.
So far I have succeeded in overriding this behaviour by wrapping the
ItemPropertyDescriptor in the ItemPropertyDescriptionDecorator which
overrides setPropertyValue() and does not execute commands through the
command stack. Unfortunately, to do this I have to repeat a lot of code
that is already in ItemPropertyDescriptor.setPropertyValue(). Would it be
possible to refactor ItemPropertyDescriptor.setPropertyValue() to provide a
reusable getter for the SetCommand? This would make my override simpler and
less prone to future obsolescence.
Is there a better way for me to solve this problem? Any suggestions would
be most appreciated.
Thanks,
Linda
</pre>
</blockquote>
<br>
</blockquote>
</blockquote>
<br>
</blockquote>
</blockquote>
<br>
</body>
</html>
--------------090901090305020008070703--
|
|
|
Goto Forum:
Current Time: Wed Nov 05 13:47:23 EST 2025
Powered by FUDForum. Page generated in 0.05366 seconds
|