Bug 118323 - [DataBinding] Need editing life cycle events on the data binding framework
Summary: [DataBinding] Need editing life cycle events on the data binding framework
Status: RESOLVED WORKSFORME
Alias: None
Product: Platform
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 3.1   Edit
Hardware: PC All
: P2 normal (vote)
Target Milestone: ---   Edit
Assignee: Dave Orme CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 120582
  Show dependency tree
 
Reported: 2005-11-28 17:39 EST by Dave Orme CLA
Modified: 2007-11-16 08:43 EST (History)
9 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Dave Orme CLA 2005-11-28 17:39:11 EST
(16:05:12) David: I think "Michel" in the Undo/Redo bug (bug #116465) might have identified a deficiency that we have right now.
(16:05:51) Boris: Yes.
(16:05:56) David: Do we currently have a way to ask an IUpdatableValue that wraps an editor of some sort if it is dirty--that is, if it has unsaved changes?
(16:06:04) Boris: No/
(16:06:47) Boris: I think there should be some kind of event that we can rely on to be fired when an updatable objects gets dirty.
(16:07:19) Boris: Without an event, you can never solve the problem of displaying a "*" in the editor tab when you start typing.
(16:07:31) David: Good point.
(16:07:46) David: You also want to be able to ask isDirty()
(16:07:51) Boris: I just checked the PDE manifest editor.
(16:08:05) Boris: It marks the editor as dirty on the first keypress.
(16:08:14) David: Yes.
(16:08:55) Boris: So I think we need the event (or could we rely on an existing event like VERIFY?) and isDirty() on IUpdatable.
(16:09:08) David: Yes.
(16:09:21) David: Plus at least save() and possibly canSave().
(16:09:30) Boris: Why?
(16:09:56) David: Let there be table A and table B in a 1:M relationship.
(16:10:00) Boris: Can't you just call getValue() for the current value?
(16:10:41) David: The user has left an editor dirty inside table B and clicks on a different row than the current master row in table A.
(16:11:05) David: table A has to ask table B if it is dirty, and if it is, to save itself before permitting the row change.
(16:12:43) Boris: I am not sure anymore about the isDirty(). Isn't this something that should be tracked by the edge instead of the nodes?
(16:13:19) David: Yes; so the way the use-case above would be implemented is:
(16:14:04) David: there would be a validator on the edge between the selection listener and the proxy for table B's input
(16:14:52) David: this validator would have to ask table B if it can change its input, which is the algorithm I detailed above (if (b.isDirty()) return b.save())
(16:15:05) David: or
(16:15:28) David: return b.save ? null : "Validation error saving table B";
(16:15:42) David: something like that.
(16:16:16) Boris: or
(16:16:40) Boris: create a sub data binding context for B
(16:17:40) Boris: We add methods IDataBindingContext.hasUncommittedChanges() and IDataBindingContext.commitChanges().
(16:17:54) Boris: Those would flush all "dirty" bindings./
(16:18:29) Boris: The reason for my suggestion is that we already have a scenario that we don't cover:
(16:18:49) Boris: Don't update the model updatables at all until the user clicks "Save" or "OK" in a dialog.
(16:19:21) Boris: Something like this is already in the scenarios document.
(16:19:45) David: TIME_GLACIAL
(16:20:04) Boris: yes.
(16:20:13) David: ;-)
(16:20:20) David: Hmmmm...
(16:20:32) David: I think we might need both, because
(16:21:04) David: 1) In a database application, there are 3 places data can be: the SWT control; the business object; the database.
(16:21:14) David: 2) That implies two save semantics:
(16:21:23) David: a) between the SWT control and the business object
(16:21:34) David: b) between the business object and the dbms
(16:22:15) Boris: Isn't b) out of scope for us?
(16:22:16) David: 3) To be precise, I refer to "saving" as moving data from the SWT control to the business object and "committing" as moving data all the way to the DBMS
(16:22:37) David: just a sec--I'll answer that in a moment
(16:23:27) David: 4) I think that dbc.save() really implies "commit" semantics, but that updatable.save() implies "save" semantics.
(16:23:33) David: Now for your question
(16:23:54) David: When I wrote ED, I took exactly the same attitude:
(16:24:27) David: "Everyone knows how to persist objects and has their favorite religion about how to do it.  ED is agnostic about that religion.  If you can persist your objects, ED can edit them for you."
(16:25:05) David: The trouble is that real applications need some support from the data binding framework in order to know when is the appropriate time to commit those objects back to the dbms.
(16:25:59) Boris: Yes, you need hooks.
(16:26:19) David: At the layer below the data binding framework, there aren't enough events to know when the user just left a row in a table, for example, without going around the data binders and adding event handlers directly on the table.  And since the data binders are putting events on the table, you never know what side-effects your event handlers might cause.
(16:27:03) David: So I agree you need hooks.
(16:27:18) David: Probably a strategy pattern object that does the commit.
(16:28:13) David: Something like the SWT selectionEvent that has different methods it calls at different points in the editing life cycle, so each commit policy object can decide the appropriate time to commit changes to the database.
(16:28:33) David: widgetSelected() versus
(16:28:37) David: widgetDefaultSelected()
(16:30:40) Boris: I'm running out of time for today, could you put this into bugzilla, either in the undo/redo bug, or a separate new one?
(16:30:47) David: Maybe event methods like: keystrokeSaveOccured(), fieldSaveOccured(), objectSaveOccured(), explicitSaveOccurred()
(16:30:52) David: I am too.
(16:30:57) David: Gladly.
(16:31:08) David: With your permission, I'll just copy our transcript...
(16:31:14) Boris: sure
(16:31:17) David: Okay.
Comment 1 Dave Orme CLA 2005-11-28 17:41:34 EST
> (16:30:47) David: Maybe event methods like: keystrokeSaveOccured(),
> fieldSaveOccured(), objectSaveOccured(), explicitSaveOccurred()

Also updatableBecameDirty(), per the early part of our discussion.

Comment 2 Dave Orme CLA 2006-01-23 14:42:31 EST
This is also important for adding logging or other debug listeners to a data binding connection for tracking when things go wrong.

We believe that this is also the proper way to add a master validator for hooking up business logic validation.

Here is what we see right now:

Vetoable life cycle events at every edge in the following graphs:

target2model copy
  get -> Validate -> convert -> businessValidate -> set

model2target copy
  get -> convert -> set

isDirtyChanged
Comment 3 Dave Orme CLA 2006-01-24 15:16:33 EST
Released to HEAD -> 20060124

If the events provided prove inadaqute for someone's needs, please reopen and add a comment.
Comment 4 Dave Orme CLA 2006-02-08 00:02:53 EST
Several have asked for an event that is fired whenever any of the validation events fail.  Reopening until that is solved.
Comment 5 Dave Orme CLA 2006-03-29 00:42:06 EST
from https://bugs.eclipse.org/bugs/show_bug.cgi?id=119791#c11 :

very nice would be an active Information, if the validation (and also
business-validation) has failed in the ValueBinding:
eg:
public void updateModelFromTarget(...) {
...
  validationError = doValidate(e.originalValue);
  if (validationError != null) {
    e.pipelinePosition = BindingEvent.PIPELINE_AFTER_VALIDATION_FAILED;
    fireBindingEvent(e);
    context.updatePartialValidationError(targetChangeListener,
validationError);
    return;
  }
...
}

Is there any other possibility to recognize, that a validation has failed?
Comment 6 Boris Bokowski CLA 2006-05-10 23:21:12 EDT
Changing priority to P2.
Comment 7 Dave Orme CLA 2006-05-10 23:24:35 EDT
BOOKMARK.

This is a bookmark comment so I can find this bug again easily.  :-)
Comment 8 Matthew Hall CLA 2007-11-16 00:15:29 EST
This bug appears obsolete:

"Dirty" events mentioned in comment #0 are covered by IStaleListener and IChangeListener.

Delaying copy-target-to-model bindings as discussed in comment #0 is possible using POLICY_NEVER update strategies.

It is possible to observe validation events mentioned in comment #4 by observing either DBC.getValidationStatusMap() or Binding.getValidationStatus().

Did I miss any aspects of this bug that are still outstanding?
Comment 9 Boris Bokowski CLA 2007-11-16 08:43:29 EST
See also Snippet 14 (the one with a wizard dialog) and the wizard support class it references. To find out whether the user has started changing values in the wizard page, a change listener is added to all target (UI) observables by iterating over all bindings and retrieving each binding's target observable.