Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » GEF » Checking constraints on a model wich rises Exceptions ?
Checking constraints on a model wich rises Exceptions ? [message #133934] Mon, 24 May 2004 22:40 Go to next message
Eclipse UserFriend
Originally posted by: rlemaigr.ulb.ac.be

Hello,

I have to build a GEF editor on top of a model I have not written myself=
=

and I can't modify because it is used in other applications. This model =
=

have a lot of constraints associated. There is only one way to check a =

constraint: trying to execute the operation and seeing what happens. If =
an =

Exception occures, then the operation was illegal and it is not performe=
d. =

If no exception occure then the operation was legal and is executed.

This way of checking constraints confuses me. I don't know how to =

integrate that to gef.

If I put my operations in a Commands,
1) I have no way to check a constaint in the canExecute method without =

trying to execute the command, so the mouse pointer will never show the =
=

symbol for unexecutable command (but this is not a big problem I could =

live with it),
2) when the command is executed, if an Exception occures, I will have to=
=

deal with it in the execute method of the command. I don't know how to d=
o =

that. The problem is my command will still be in the CommandStack, even =
if =

it failed to execute. Can I safely remove a command from the command sta=
ck =

as I am still in the execute() method ?

There are other problems. Like: if a command fails to execute, I will mo=
re =

likely want to show some kind of dialog informing the user that the =

command has failed to execute, and maybe ask him if I can perform some =

action in order to make the command executable and retry to execute it. =
I =

don't know where and how to do that.

That's annoying.

Any ideas ?

Thank you !

r=E9gis


-- =

Using Opera's revolutionary e-mail client: http://www.opera.com/m2/
Re: Checking constraints on a model wich rises Exceptions ? [message #134273 is a reply to message #133934] Tue, 25 May 2004 21:09 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: none.us.ibm.com

It sounds like your model stinks :-)

It sounds like you need to write a special commandstack which overrides
execute() to reset a boolean flag, then your commands can set that flag to
true if an exception occured. Then, before returning from execute you can
check the flag, and if it is true, undo the command and reset the flag. The
commands undo should be a no-op at this point, but you need to call undo in
order to take it off the stack.


<rlemaigr@ulb.ac.be> wrote in message
news:opr8izyjrmxn9g2u@xn--pcrgis-dva.mshome.net...
Hello,

I have to build a GEF editor on top of a model I have not written myself
and I can't modify because it is used in other applications. This model
have a lot of constraints associated. There is only one way to check a
constraint: trying to execute the operation and seeing what happens. If an
Exception occures, then the operation was illegal and it is not performed.
If no exception occure then the operation was legal and is executed.

This way of checking constraints confuses me. I don't know how to
integrate that to gef.

If I put my operations in a Commands,
1) I have no way to check a constaint in the canExecute method without
trying to execute the command, so the mouse pointer will never show the
symbol for unexecutable command (but this is not a big problem I could
live with it),
2) when the command is executed, if an Exception occures, I will have to
deal with it in the execute method of the command. I don't know how to do
that. The problem is my command will still be in the CommandStack, even if
it failed to execute. Can I safely remove a command from the command stack
as I am still in the execute() method ?

There are other problems. Like: if a command fails to execute, I will more
likely want to show some kind of dialog informing the user that the
command has failed to execute, and maybe ask him if I can perform some
action in order to make the command executable and retry to execute it. I
don't know where and how to do that.

That's annoying.

Any ideas ?

Thank you !

r
Re: Checking constraints on a model wich rises Exceptions ? [message #134312 is a reply to message #134273] Wed, 26 May 2004 00:10 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: rlemaigr.ulb.ac.be

Thank you for your very helpful advice !
This put me on the good way to the solution I think.

Yep the model stinks. But I think this problem could happen even with a =
=

gef editor with a well built model.

Please consider this two situations:

- the model is quite large and complex, so checking a constraint takes a=
=

lot of time, too much time to allow checking it in the canExecute method=
=

because this method must be very responsive (if I am not wrong it is =

called almost every time the mouse moves),
- some operations on the model involve things that can fire Exceptions i=
n =

an non-predictable way (maybe an acces to a file or to an url).

In this two cases, an Exception could occur in the execute method of a =

Command. I think that GEF should allow the programmer to properly react =
to =

this case by treating the Exception in some way and remove the bad Comma=
nd =

from the command stack.

What do you think about it ? Couldn't it be a useful feature ?

By thinking to your advice, I think I've find a good way to implement it=
:

I will subclass the CommandStack class like you said, and put the =

Command.execute() method in a try & catch block. So if an exception occu=
rs =

in the execute method, I will catch it and react to it by removing the b=
ad =

Command from the command stack as you said.

But then I want to allow myself to do some action with this Exception. =

Maybe displaying an error message, some dialog to the user, and then ret=
ry =

to execute the modified command for example, wich may in turn rise an =

exception too, etc... I think the object the more able to know what to d=
o =

with the Exception is the bad Command wich made it occur because it know=
s =

all the details of the context wich causes this Exception to occur. So I=
=

will subclass the Command class too and add a method like that:

class FallibleCommand extends Command
{
....
public void exceptionOccured(CommandStack stack, Exception e)
{ =

//does nothing by default
}
....
}


And the CommandStack will call it like that:

class FallibleCommandStack extends CommandStack
{
....
public void execute(Command c)
{
...
try
{
c.execute();
}
catch(Exception e)
{
//here c gets removed from the command stack
c.exceptionOccured(this, e);
}
...
}
....
}

What do you think about it ? Couldn't this system be included in gef in =
=

some way in a later version ?
There are really not a lot of things to add and it could fix this kind o=
f =

problems...

Thanks for your help,

r=E9gis



On Tue, 25 May 2004 17:09:18 -0400, Randy Hudson <none@us.ibm.com> wrote=
:

> It sounds like your model stinks :-)
>
> It sounds like you need to write a special commandstack which override=
s
> execute() to reset a boolean flag, then your commands can set that fla=
g =

> to
> true if an exception occured. Then, before returning from execute you=
=

> can
> check the flag, and if it is true, undo the command and reset the flag=
.. =

> The
> commands undo should be a no-op at this point, but you need to call un=
do =

> in
> order to take it off the stack.
Re: Checking constraints on a model wich rises Exceptions ? [message #134512 is a reply to message #134312] Wed, 26 May 2004 18:02 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: rlemaigr.ulb.ac.be

My solution is not correct because the execute() method in Command shoul=
d =

throws Exception and that's impossible because the super implementation =
=

don't...I didn't think about that...
Maybe that's for that reason you were talking about a boolean flag inste=
ad =

of doing things like this...
Too bad...

So I will do like you said.
thx

r=E9gis

On Wed, 26 May 2004 02:10:14 +0200, <rlemaigr@ulb.ac.be> wrote:

> Thank you for your very helpful advice !
> This put me on the good way to the solution I think.
>
> Yep the model stinks. But I think this problem could happen even with =
a =

> gef editor with a well built model.
>
> Please consider this two situations:
>
> - the model is quite large and complex, so checking a constraint takes=
a =

> lot of time, too much time to allow checking it in the canExecute meth=
od =

> because this method must be very responsive (if I am not wrong it is =

> called almost every time the mouse moves),
> - some operations on the model involve things that can fire Exceptions=
=

> in an non-predictable way (maybe an acces to a file or to an url).
>
> In this two cases, an Exception could occur in the execute method of a=
=

> Command. I think that GEF should allow the programmer to properly reac=
t =

> to this case by treating the Exception in some way and remove the bad =
=

> Command from the command stack.
>
> What do you think about it ? Couldn't it be a useful feature ?
>
> By thinking to your advice, I think I've find a good way to implement =
it:
>
> I will subclass the CommandStack class like you said, and put the =

> Command.execute() method in a try & catch block. So if an exception =

> occurs in the execute method, I will catch it and react to it by =

> removing the bad Command from the command stack as you said.
>
> But then I want to allow myself to do some action with this Exception.=
=

> Maybe displaying an error message, some dialog to the user, and then =

> retry to execute the modified command for example, wich may in turn ri=
se =

> an exception too, etc... I think the object the more able to know what=
=

> to do with the Exception is the bad Command wich made it occur because=
=

> it knows all the details of the context wich causes this Exception to =
=

> occur. So I will subclass the Command class too and add a method like =
=

> that:
>
> class FallibleCommand extends Command
> {
> ...
> public void exceptionOccured(CommandStack stack, Exception e)
> { =

> //does nothing by default
> }
> ...
> }
>
>
> And the CommandStack will call it like that:
>
> class FallibleCommandStack extends CommandStack
> {
> ...
> public void execute(Command c)
> {
> ...
> try
> {
> c.execute();
> }
> catch(Exception e)
> {
> //here c gets removed from the command stack
> c.exceptionOccured(this, e);
> }
> ...
> }
> ...
> }
>
> What do you think about it ? Couldn't this system be included in gef i=
n =

> some way in a later version ?
> There are really not a lot of things to add and it could fix this kind=
=

> of problems...
>
> Thanks for your help,
>
> r=E9gis
>
>
>
> On Tue, 25 May 2004 17:09:18 -0400, Randy Hudson <none@us.ibm.com> wro=
te:
>
>> It sounds like your model stinks :-)
>>
>> It sounds like you need to write a special commandstack which overrid=
es
>> execute() to reset a boolean flag, then your commands can set that fl=
ag =

>> to
>> true if an exception occured. Then, before returning from execute yo=
u =

>> can
>> check the flag, and if it is true, undo the command and reset the =

>> flag. The
>> commands undo should be a no-op at this point, but you need to call =

>> undo in
>> order to take it off the stack.



-- =

Using Opera's revolutionary e-mail client: http://www.opera.com/m2/
Re: Checking constraints on a model wich rises Exceptions ? [message #134525 is a reply to message #134512] Wed, 26 May 2004 23:28 Go to previous messageGo to next message
Pratik Shah is currently offline Pratik ShahFriend
Messages: 1077
Registered: July 2009
Senior Member
You can always throw RuntimeExceptions. Maybe you can nest the actual
exception in a RuntimeException. However, I am not sure of the
repercussions of catching all RuntimeExceptions.

<rlemaigr@ulb.ac.be> wrote in message
news:opr8mcdt0rxn9g2u@xn--pcrgis-dva.mshome.net...
My solution is not correct because the execute() method in Command should
throws Exception and that's impossible because the super implementation
don't...I didn't think about that...
Maybe that's for that reason you were talking about a boolean flag instead
of doing things like this...
Too bad...

So I will do like you said.
thx

r
Re: Checking constraints on a model wich rises Exceptions ? [message #134585 is a reply to message #134525] Thu, 27 May 2004 11:34 Go to previous message
Eclipse UserFriend
Originally posted by: rlemaigr.ulb.ac.be

Thanks everybody for your help, the problem seems solved and that works =
=

very well.

(RuntimeException are a good idea too I will think about it the next tim=
e =

I cross the problem, thx patrik)

I describe the final solution I've chosen here because I think this coul=
d =

help other people to solve similar problems.

They are two classes, FallibleCommand extending Command and =

FallibleCommandStack extending CommandStack. Their codes and explanation=
s =

are copy-pasted and the end of my message (maybe they are still errors o=
r =

things that are not well done I don't know).

The purpose of the FallibleCommand.handleException(CommandStack) is to =

allow to implement some default behaviour on Exceptions that will be =

inherited by subclasses. Currently, in my editor, it is just displaying =
=

the Exception.getMessage() in a popup message. The command stack is pass=
ed =

to that method because it could be useful to put there a dialog with the=
=

user, with some suggestions of things to do to make the operation he =

wanted to perform valid and that could require some action on the model,=
=

and after that retry to execute the command.

Thanks everybody for your help.

r=E9gis



here are the codes:

//-------------------------------FallibleCommand------------ ------------=
--------------

import org.eclipse.gef.commands.*;

/**
* A Command class to use with the FallibleCommandStack to handle the f=
act =

that
* an Exception could occur during the execution of the execute() metho=
d =

of the
* command. In this case the Command will be removed of the command sta=
ck, =

and
* after that, get a chance to do some job to handle the exception trou=
gh =

a call
* to its handleException method.
* <br>
* <br>
* To use, just call the setException method in the catch block of the =
=

execute method,
* passing it the Exception that has occured.
* <br>
* <br>
* Each time a Command is executed by the command stack, just after it =
has =

been
* executed, the command stack will check the return of the method =

getException().
* <br>
* If it is null, nothing special occur.
* <br>
* If it is non-null, then the command stack will remove the command fr=
om =

the top
* of the stack, and after that call the method handleException on the =
=

Command which
* has been removed.
*/

public abstract class FallibleCommand extends Command
{
private Exception exception =3D null;
=

/**
* Must be called in the catch block of the execute method.
* @param e the exception that has occured
*/
public void setException(Exception e)
{
exception =3D e;
}
=

/**
* Returns the exception that has occured during the execution of the =

command.
* @return the exception that has occurd during the execution of the =

command.
*/
public Exception getException()
{
return exception;
}
=

/**
* Will be called by the FallibleCommandStack if an exception has occur=
ed =

during
* the execution of the command.
* @param stack the CommandStack
*/
public abstract void handleException(CommandStack stack);
}






//-------------------------------FallibleCommandStack------- ------------=
-------------------

//this is almost completly a copy-paste of the CommandStack =

implementation, exept the execute method,
//and all the listeners things left in the super class.

import org.eclipse.gef.commands.*;
import java.util.*;

/**
* A CommandStack class to use with the FallibleCommand class to handle=
=

the fact that
* an Exception could occur during the execution of the execute() metho=
d =

of the
* command. In this case the Command will be removed of the command sta=
ck, =

and
* after that, get a chance to do some job to handle the exception trou=
gh =

a call
* to its handleException method.
* <br>
* @see FallibleCommand
*/

public class FallibleCommandStack extends CommandStack
{

private int undoLimit =3D 0;
private int saveLocation =3D 0;
private Stack undo =3D new Stack();
private Stack redo =3D new Stack();

/**
* the list of {@link CommandStackListener}s
*/
protected List listeners =3D new ArrayList();

/**
* Constructs a command stack. By default, there is no undo limit.
*/
public FallibleCommandStack() { }

/**
* @return <code>true</code> if it is appropriate to call {@link #redo(=
)}.
*/
public boolean canRedo() {
return !redo.isEmpty();
}

/**
* @return <code>true</code> if {@link #undo()} can be called
*/
public boolean canUndo() {
if (undo.size() =3D=3D 0)
return false;
return ((Command)undo.lastElement()).canUndo();
}

/**
* Executes the specified Command if it is executable. Flushes the redo=
=

stack.
* <br>
* Modified to do the job described in the description of this class.
* @param command the Command to execute
*/
public void execute(Command command) {
if (command =3D=3D null || !command.canExecute())
return;
command.execute();

if(command instanceof FallibleCommand)
{
FallibleCommand com =3D (FallibleCommand) command;
Exception ex =3D com.getException();
if(ex !=3D null)
{
com.handleException(this); =

return;
}
}
flushRedo();//this line was before the command.execute but I put it he=
re
//because when a command fails to execute, the redo stack has not to b=
e =

flushed.

if (getUndoLimit() > 0) {
while (undo.size() >=3D getUndoLimit()) {
undo.remove(0);
if (saveLocation > -1)
saveLocation--;
}
}
if (saveLocation > undo.size())
saveLocation =3D -1; //The save point was somewhere in the redo stack=

undo.push(command);
notifyListeners();
}

/**
* This will <code>dispose()</code> all the commands in both the undo a=
nd =

redo stack. Both
* stacks will be empty afterwards.
*/
public void dispose() {
flushUndo();
flushRedo();
}

/**
* Flushes the entire stack and resets the save location to zero. This =
=

method might be
* called when performing "revert to saved".
*/
public void flush() {
flushRedo();
flushUndo();
saveLocation =3D 0;
notifyListeners();
}

private void flushRedo() {
while (!redo.isEmpty())
((Command)redo.pop()).dispose();
}

private void flushUndo() {
while (!undo.isEmpty())
((Command)undo.pop()).dispose();
}

/**
* @return an array containing all commands in the order they were =

executed
*/
public Object[] getCommands() {
List commands =3D new ArrayList(undo);
for (int i =3D redo.size() - 1; i >=3D 0; i--) {
commands.add(redo.get(i));
}
return commands.toArray();
}

/**
* Peeks at the top of the <i>redo</i> stack. This is useful for =

describing to the User
* what will be redone. The returned <code>Command</code> has a label =

describing it.
* @return the top of the <i>redo</i> stack, which may be =

<code>null</code>
*/
public Command getRedoCommand() {
return redo.isEmpty() ? null : (Command)redo.peek();
}

/**
* Peeks at the top of the <i>undo</i> stack. This is useful for =

describing to the User
* what will be undone. The returned <code>Command</code> has a label =

describing it.
* @return the top of the <i>undo</i> stack, which may be =

<code>null</code>
*/
public Command getUndoCommand() {
return undo.isEmpty() ? null : (Command)undo.peek();
}

/**
* Returns the undo limit. The undo limit is the maximum number of atom=
ic =

operations that
* the User can undo. <code>-1</code> is used to indicate no limit.
* @return the undo limit
*/
public int getUndoLimit() {
return undoLimit;
}

/**
* Returns true if the stack is dirty. The stack is dirty whenever the =
=

last executed or
* redone command is different than the command that was at the top of =
=

the undo stack when
* {@link #markSaveLocation()} was last called.
* @return <code>true</code> if the stack is dirty
*/
public boolean isDirty() {
return undo.size() !=3D saveLocation;
}

/**
* Marks the last executed or redone Command as the point at which the =
=

changes were saved.
* Calculation of {@link #isDirty()} will be based on this checkpoint.
*/
public void markSaveLocation() {
saveLocation =3D undo.size();
notifyListeners();
}

/**
* Calls redo on the Command at the top of the <i>redo</i> stack, and =

pushes that Command
* onto the <i>undo</i> stack. This method should only be called when =

{@link #canUndo()}
* returns <code>true</code>.
*/
public void redo() {
//Assert.isTrue(canRedo())
if (!canRedo())
return;
Command command =3D (Command)redo.pop();
command.redo();
undo.push(command);
notifyListeners();
}

/**
* Sets the undo limit. The undo limit is the maximum number of atomic =
=

operations that the
* User can undo. <code>-1</code> is used to indicate no limit.
* @param undoLimit the undo limit
*/
public void setUndoLimit(int undoLimit) {
this.undoLimit =3D undoLimit;
}

/**
* Undoes the most recently executed (or redone) Command. The Command i=
s =

popped from the
* undo stack to and pushed onto the redo stack. This method should onl=
y =

be called when
* {@link #canUndo()} returns <code>true</code>.
*/
public void undo() {
//Assert.isTrue(canUndo());
Command command =3D (Command)undo.pop();
command.undo();
redo.push(command);
notifyListeners();
}

}
Previous Topic:HelloGef example
Next Topic:Newbie: GEF standalone
Goto Forum:
  


Current Time: Thu Apr 25 21:25:43 GMT 2024

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

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

Back to the top