Skip to content

Commit

Permalink
Fix Editor creating fields before client Grid can attach them (#16214)
Browse files Browse the repository at this point in the history
This patch includes some race condition handling.

Change-Id: I6ab3cf15a67de722181b2718ab85b6b4a6bcb997
  • Loading branch information
Teemu Suo-Anttila authored and Henrik Paul committed Jan 20, 2015
1 parent b9360a2 commit 74976a7
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 59 deletions.
27 changes: 15 additions & 12 deletions client/src/com/vaadin/client/connectors/GridConnector.java
Expand Up @@ -210,8 +210,13 @@ public CustomEditorHandler() {


@Override @Override
public void bind(final int rowIndex) { public void bind(final int rowIndex) {
serverInitiated = true; // call this finally to avoid issues with editing on init
GridConnector.this.getWidget().editRow(rowIndex); Scheduler.get().scheduleFinally(new ScheduledCommand() {
@Override
public void execute() {
GridConnector.this.getWidget().editRow(rowIndex);
}
});
} }


@Override @Override
Expand All @@ -223,7 +228,6 @@ public void cancel(int rowIndex) {
@Override @Override
public void confirmBind(final boolean bindSucceeded) { public void confirmBind(final boolean bindSucceeded) {
endRequest(bindSucceeded); endRequest(bindSucceeded);

} }


@Override @Override
Expand All @@ -235,18 +239,14 @@ public void confirmSave(boolean saveSucceeded) {


@Override @Override
public void bind(EditorRequest<JsonObject> request) { public void bind(EditorRequest<JsonObject> request) {
if (!handleServerInitiated(request)) { startRequest(request);
startRequest(request); rpc.bind(request.getRowIndex());
rpc.bind(request.getRowIndex());
}
} }


@Override @Override
public void save(EditorRequest<JsonObject> request) { public void save(EditorRequest<JsonObject> request) {
if (!handleServerInitiated(request)) { startRequest(request);
startRequest(request); rpc.save(request.getRowIndex());
rpc.save(request.getRowIndex());
}
} }


@Override @Override
Expand Down Expand Up @@ -296,11 +296,13 @@ private boolean handleServerInitiated(EditorRequest<?> request) {
} }


private void startRequest(EditorRequest<?> request) { private void startRequest(EditorRequest<?> request) {
assert currentRequest == null : "Earlier request not yet finished";

currentRequest = request; currentRequest = request;
} }


private void endRequest(boolean succeeded) { private void endRequest(boolean succeeded) {
assert currentRequest != null; assert currentRequest != null : "Current request was null";
/* /*
* Clear current request first to ensure the state is valid if * Clear current request first to ensure the state is valid if
* another request is made in the callback. * another request is made in the callback.
Expand Down Expand Up @@ -406,6 +408,7 @@ public GridState getState() {
protected void init() { protected void init() {
super.init(); super.init();


// All scroll RPC calls are executed finally to avoid issues on init
registerRpc(GridClientRpc.class, new GridClientRpc() { registerRpc(GridClientRpc.class, new GridClientRpc() {
@Override @Override
public void scrollToStart() { public void scrollToStart() {
Expand Down
7 changes: 4 additions & 3 deletions client/src/com/vaadin/client/widgets/Grid.java
Expand Up @@ -944,7 +944,7 @@ protected static class Editor<T> {
public static final int KEYCODE_HIDE = KeyCodes.KEY_ESCAPE; public static final int KEYCODE_HIDE = KeyCodes.KEY_ESCAPE;


protected enum State { protected enum State {
INACTIVE, ACTIVATING, ACTIVE, SAVING INACTIVE, ACTIVATING, BINDING, ACTIVE, SAVING
} }


private Grid<T> grid; private Grid<T> grid;
Expand Down Expand Up @@ -1018,7 +1018,7 @@ public void run() {
private final RequestCallback<T> bindRequestCallback = new RequestCallback<T>() { private final RequestCallback<T> bindRequestCallback = new RequestCallback<T>() {
@Override @Override
public void onSuccess(EditorRequest<T> request) { public void onSuccess(EditorRequest<T> request) {
if (state == State.ACTIVATING) { if (state == State.BINDING) {
state = State.ACTIVE; state = State.ACTIVE;
bindTimeout.cancel(); bindTimeout.cancel();


Expand All @@ -1029,7 +1029,7 @@ public void onSuccess(EditorRequest<T> request) {


@Override @Override
public void onError(EditorRequest<T> request) { public void onError(EditorRequest<T> request) {
if (state == State.ACTIVATING) { if (state == State.BINDING) {
state = State.INACTIVE; state = State.INACTIVE;
bindTimeout.cancel(); bindTimeout.cancel();


Expand Down Expand Up @@ -1188,6 +1188,7 @@ public void setEnabled(boolean enabled) {


protected void show() { protected void show() {
if (state == State.ACTIVATING) { if (state == State.ACTIVATING) {
state = State.BINDING;
bindTimeout.schedule(BIND_TIMEOUT_MS); bindTimeout.schedule(BIND_TIMEOUT_MS);
EditorRequest<T> request = new EditorRequest<T>(grid, rowIndex, EditorRequest<T> request = new EditorRequest<T>(grid, rowIndex,
bindRequestCallback); bindRequestCallback);
Expand Down
40 changes: 22 additions & 18 deletions server/src/com/vaadin/ui/Grid.java
Expand Up @@ -2740,14 +2740,19 @@ public void itemClick(String rowKey, String columnId,


@Override @Override
public void bind(int rowIndex) { public void bind(int rowIndex) {
boolean success; boolean success = false;
try { try {
Object id = getContainerDataSource().getIdByIndex(rowIndex); Object id = getContainerDataSource().getIdByIndex(rowIndex);
doEditItem(id); if (editedItemId == null) {
success = true; editedItemId = id;
}

if (editedItemId.equals(id)) {
success = true;
doEditItem();
}
} catch (Exception e) { } catch (Exception e) {
handleError(e); handleError(e);
success = false;
} }
getEditorRpc().confirmBind(success); getEditorRpc().confirmBind(success);
} }
Expand All @@ -2764,13 +2769,12 @@ public void cancel(int rowIndex) {


@Override @Override
public void save(int rowIndex) { public void save(int rowIndex) {
boolean success; boolean success = false;
try { try {
saveEditor(); saveEditor();
success = true; success = true;
} catch (Exception e) { } catch (Exception e) {
handleError(e); handleError(e);
success = false;
} }
getEditorRpc().confirmSave(success); getEditorRpc().confirmSave(success);
} }
Expand Down Expand Up @@ -4474,31 +4478,31 @@ public Field<?> getEditorField(Object propertyId) {
* @param itemId * @param itemId
* the id of the item to edit * the id of the item to edit
* @throws IllegalStateException * @throws IllegalStateException
* if the editor is not enabled * if the editor is not enabled or already editing an item
* @throws IllegalArgumentException * @throws IllegalArgumentException
* if the {@code itemId} is not in the backing container * if the {@code itemId} is not in the backing container
* @see #setEditorEnabled(boolean) * @see #setEditorEnabled(boolean)
*/ */
public void editItem(Object itemId) throws IllegalStateException, public void editItem(Object itemId) throws IllegalStateException,
IllegalArgumentException { IllegalArgumentException {
doEditItem(itemId);

getEditorRpc().bind(getContainerDataSource().indexOfId(itemId));
}

protected void doEditItem(Object itemId) {
if (!isEditorEnabled()) { if (!isEditorEnabled()) {
throw new IllegalStateException("Item editor is not enabled"); throw new IllegalStateException("Item editor is not enabled");
} } else if (editedItemId != null) {

throw new IllegalStateException("Editing item + " + itemId
Item item = getContainerDataSource().getItem(itemId); + " failed. Item editor is already editing item "
if (item == null) { + editedItemId);
} else if (!getContainerDataSource().containsId(itemId)) {
throw new IllegalArgumentException("Item with id " + itemId throw new IllegalArgumentException("Item with id " + itemId
+ " not found in current container"); + " not found in current container");
} }
editedItemId = itemId;
getEditorRpc().bind(getContainerDataSource().indexOfId(itemId));
}

protected void doEditItem() {
Item item = getContainerDataSource().getItem(editedItemId);


editorFieldGroup.setItemDataSource(item); editorFieldGroup.setItemDataSource(item);
editedItemId = itemId;


for (Column column : getColumns()) { for (Column column : getColumns()) {
Object propertyId = column.getPropertyId(); Object propertyId = column.getPropertyId();
Expand Down

0 comments on commit 74976a7

Please sign in to comment.