Opened 8 years ago
Last modified 5 years ago
#13036 new enhancement
More validation for commands
Reported by: | michael2402 | Owned by: | team |
---|---|---|---|
Priority: | normal | Milestone: | |
Component: | Core | Version: | |
Keywords: | gsoc-core command | Cc: | Don-vip, bastiK, stoecker |
Description (last modified by )
Currently, the command class does only few validation of the layer the command works for.
I suggest:
Enforce thatlayer
may not be null. Make command construction fail if it is.- Always set the layer/dataset the command is working on.
- Check that all primitives of that command belong to the layer
layer
(for add/move/delete/... commands).- if plugins want to change this, we can provide them with the means to extend the commands. They have to take care of the problems that occur then, e.g. handle data integrity.
Attachments (2)
Change History (56)
comment:1 by , 8 years ago
Milestone: | 16.07 → 16.08 |
---|
comment:2 by , 8 years ago
Milestone: | 16.08 → 16.09 |
---|
comment:3 by , 8 years ago
Milestone: | 16.09 → 16.10 |
---|
comment:4 by , 8 years ago
Milestone: | 16.10 → 16.11 |
---|
comment:6 by , 8 years ago
Milestone: | 16.12 |
---|
comment:9 by , 7 years ago
Replying to michael2402:
- Enforce that
layer
may not be null. Make command construction fail if it is.
If I remember correctly I have put a great effort to make sure a null layer is allowed, in order to work only with a dataset. Plugins rely on it.
follow-up: 11 comment:10 by , 7 years ago
Milestone: | → 17.06 |
---|
If dataset is forced now, all command constructors must be checked/updated. I have fixed in r12386 the problem that caused opendata plugin unit test to fail, but I think all constructors from DeleteCommand that don't take a Layer or a DataSet as parameter will cause errors when executed.
comment:11 by , 7 years ago
Replying to Don-vip:
If dataset is forced now, all command constructors must be checked/updated. I have fixed in r12386 the problem that caused opendata plugin unit test to fail, but I think all constructors from DeleteCommand that don't take a Layer or a DataSet as parameter will cause errors when executed.
Not necessarily. All commands that modify the edit data set (the one while they are created) are fine. Undo/Redo respects the layer that was used during the command construction.
The problem with unit tests is that they do not correctly set the edit layer during the test - this is why they fail. If we get errors in plugins, the plugin is using commands to modify a layer that is not the edit layer.
... but I agree: We should try to always add dataset information to our utility functions - it will make them more universal and allow them to be used on a data set that is not in any layer. I fixed this for the right/left hand traffic computations.
comment:12 by , 7 years ago
Description: | modified (diff) |
---|
comment:15 by , 7 years ago
Milestone: | 17.07 → 17.08 |
---|
comment:16 by , 7 years ago
Milestone: | 17.08 → 17.09 |
---|
comment:17 by , 7 years ago
Keywords: | command added |
---|
comment:18 by , 7 years ago
In the course of #15182 it appears problematic to have commands depending on layers, because layers are GUI stuff, and commands should not depend on GUI. They should only affect a DataSet
, and I'd like to get rid of all layer references. This way we could move forward to have all commands, plus UndoRedoHandler
, to not depend on GUI.
follow-up: 20 comment:19 by , 7 years ago
+1
Should not be hard, since most of them only depend on the DataSet
internally. We only need to change most constructor calls.
We should also enforce that the data set needs to be set with the constructor.
You should never use the current edit layer during command execution/undo. I already fixed that, but it is not documented yet why this should not be the case.
by , 7 years ago
Attachment: | commands-layer.patch added |
---|
comment:20 by , 7 years ago
Replying to michael2402:
Should not be hard
Well it's quite a big patch, see attachment. Not tested a lot, and not completely finished, I have these warnings I don't know how to fix yet. Any idea?
[javac] org\openstreetmap\josm\data\UndoRedoHandler.java:100: warning: [deprecation] invalidateAffectedLayers() in Command has been deprecated [javac] c.invalidateAffectedLayers(); [javac] ^ [javac] org\openstreetmap\josm\data\UndoRedoHandler.java:133: warning: [deprecation] invalidateAffectedLayers() in Command has been deprecated [javac] c.invalidateAffectedLayers(); [javac] ^ [javac] org\openstreetmap\josm\data\UndoRedoHandler.java:169: warning: [deprecation] invalidateAffectedLayers() in Command has been deprecated [javac] c.invalidateAffectedLayers(); [javac] ^ [javac] org\openstreetmap\josm\command\SequenceCommand.java:139: warning: [deprecation] invalidateAffectedLayers() in Command has been deprecated [javac] public void invalidateAffectedLayers() { [javac] ^ [javac] org\openstreetmap\josm\command\SequenceCommand.java:140: warning: [deprecation] invalidateAffectedLayers() in Command has been deprecated [javac] super.invalidateAffectedLayers(); [javac] ^ [javac] org\openstreetmap\josm\command\SequenceCommand.java:142: warning: [deprecation] invalidateAffectedLayers() in Command has been deprecated [javac] c.invalidateAffectedLayers();
by , 7 years ago
Attachment: | commands-layerv2.patch added |
---|
comment:21 by , 7 years ago
Warnings fixed. I tested it quickly and it seems ready for integration in next release. Feedback welcome :)
follow-ups: 23 54 comment:22 by , 7 years ago
(1)
I'm no fan of invalidateDataSet()
. We don't want to tell components when they need to repaint data sets.
We have a change listener on the data set. We should fix those and see that they fire every time there was a change. Comonents can listen to those changes and repaint accordingly.
(2)
JoinAreasAction/SplitWayAction: There was a reason for the layer there. I don't exactly remember what, but I tried to remove it some time ago, too. Have you tested if re-creating the left/right traffic works?
(3)
While we are on it: Should we switch to a per-dataset command queue? It would make many things easier and Undo/Redo does not need to depend on the main layer manager any more. We should deprecate the Command()
constructor for the same reason.
We can simply bind the Undo/Redo manager to each layer. So you can do:
dataSet.getCommandManager().doCommand(new AddPrimitivesCommand(...))
Or we can simplify this for the caller:
addCommand.doCommand() -> call dataSet.getCommandManager().doCommand(this: AddPrimitivesCommand) -> call addCommand.run() throws CommandFailedException (good to make users aware that this method should not be called directly)
It might be a plus for users as well if we don't change things in hidden layers on undo but only in the active, visible layer.
While we are on it: Make that undo/redo queue implement an interface (e.g. UndoRedo
). then add a UndoRedo getUndoRedo()
to the Layer
class. It will make the code much more universal and we can add undo/redo to other layers later without changing the UI code.
(4)
Dataset names are a nice-to-have feature. So even if we change to DS command queues, we can keep them to make debugging easier.
follow-up: 24 comment:23 by , 7 years ago
Replying to michael2402:
(1)
I'm no fan of
invalidateDataSet()
. We don't want to tell components when they need to repaint data sets.
We have a change listener on the data set. We should fix those and see that they fire every time there was a change. Comonents can listen to those changes and repaint accordingly.
Yes, any change to the dataset should trigger OsmDataLayer.processDatasetEvent
, which invalidates the layer. So without testing, I would think the invalidation wasn't really necessary in the first place.
(2)
JoinAreasAction/SplitWayAction: There was a reason for the layer there. I don't exactly remember what, but I tried to remove it some time ago, too. Have you tested if re-creating the left/right traffic works?
If you don't remember, then there is no choice but to try and find out ... ;)
(3)
While we are on it: Should we switch to a per-dataset command queue?
Alright, but this is not really the scope of the patch.
comment:24 by , 7 years ago
(1)
Yes, any change to the dataset should trigger
OsmDataLayer.processDatasetEvent
, which invalidates the layer. So without testing, I would think the invalidation wasn't really necessary in the first place.
You're right, I don't see any problem after removing it :)
(2)
JoinAreasAction/SplitWayAction: There was a reason for the layer there. I don't exactly remember what, but I tried to remove it some time ago, too. Have you tested if re-creating the left/right traffic works?
If you don't remember, then there is no choice but to try and find out ... ;)
I tried and didn't see anything suspicious. the left/right traffic file is correctly recreated after cache cleanup, and the roundabout validator test works.
(3)
While we are on it: Should we switch to a per-dataset command queue?
Alright, but this is not really the scope of the patch.
I'll think about it when I'll work on UndoRedoHandler.
comment:46 by , 7 years ago
Milestone: | 17.09 → 17.10 |
---|
comment:48 by , 7 years ago
Milestone: | 17.10 → 17.11 |
---|
comment:49 by , 7 years ago
Milestone: | 17.11 → 17.12 |
---|
comment:50 by , 7 years ago
Milestone: | 17.12 → 18.01 |
---|
comment:51 by , 7 years ago
Milestone: | 18.01 → 18.02 |
---|
comment:52 by , 7 years ago
Milestone: | 18.02 → 18.03 |
---|
comment:53 by , 7 years ago
Milestone: | 18.03 |
---|
comment:54 by , 5 years ago
Replying to michael2402:
(3)
While we are on it: Should we switch to a per-dataset command queue?
See #6582.
Milestone renamed