JBoss Community Archive (Read Only)

RHQ 4.9

GwtAsyncTips

Here's an example of making three simultaneous async calls and reporting combined results only after all three have completed. Notice an instance of an inner class is used to keep track of the results as each call completes.

    @Override
    protected void executeUpdate(Record updatedUserRecord, Record oldUserRecord, final DSRequest request,
                                 final DSResponse response) {
        Subject updatedSubject = copyValues(updatedUserRecord);

        final int subjectId = updatedSubject.getId();
        final AddOrUpdateResults results = new AddOrUpdateResults();
        results.subjectId = subjectId;

        final String updatedPassword = updatedUserRecord.getAttributeAsString(Field.PASSWORD);
        boolean passwordWasUpdated = !MASKED_PASSWORD_VALUE.equals(updatedPassword);
        if (!passwordWasUpdated) {
            results.passwordProcessed = true;
        }

        Record[] oldRoleRecords = oldUserRecord.getAttributeAsRecordArray(Field.ROLES);
        Set<Role> oldRoles = RolesDataSource.getInstance().buildDataObjects(oldRoleRecords);
        Record[] updatedRoleRecords = updatedUserRecord.getAttributeAsRecordArray(Field.ROLES);
        Set<Role> updatedRoles = RolesDataSource.getInstance().buildDataObjects(updatedRoleRecords);
        boolean rolesWereUpdated = (oldRoles != null && !oldRoles.equals(updatedRoles)) ||
            (oldRoles == null && updatedRoles != null);
        if (!rolesWereUpdated) {
            results.rolesProcessed = true;
        }

        subjectService.updateSubject(updatedSubject, new AsyncCallback<Subject>() {
            public void onFailure(Throwable caught) {
                results.subjectProcessed = true;
                results.subjectError = caught;
                populateAndProcessResponseIfComplete(results, request, response);
            }

            public void onSuccess(final Subject updatedSubject) {
                results.subjectProcessed = true;
                results.updatedSubject = updatedSubject;
                populateAndProcessResponseIfComplete(results, request, response);
            }
        });

        if (passwordWasUpdated) {
            subjectService.changePassword(updatedSubject.getName(), updatedPassword, new AsyncCallback<Void>() {
                public void onFailure(Throwable caught) {
                    results.passwordProcessed = true;
                    results.passwordError = caught;
                    populateAndProcessResponseIfComplete(results, request, response);
                }

                public void onSuccess(Void nothing) {
                    results.passwordProcessed = true;
                    results.updatedPassword = updatedPassword;
                    populateAndProcessResponseIfComplete(results, request, response);
                }
            });
        }

        if (rolesWereUpdated) {
            if (updatedRoles == null) {
                updatedRoles = Collections.emptySet();
            }
            int[] updatedRoleIds = new int[updatedRoles.size()];
            int index = 0;
            for (Role updatedRole : updatedRoles) {
                updatedRoleIds[index++] = updatedRole.getId();
            }
            final Set<Role> finalUpdatedRoles = updatedRoles;
            GWTServiceLookup.getRoleService().setAssignedRolesForSubject(subjectId, updatedRoleIds,
                new AsyncCallback<Void>() {
                    public void onFailure(Throwable caught) {
                        results.rolesProcessed = true;
                        results.rolesError = caught;
                        populateAndProcessResponseIfComplete(results, request, response);
                    }

                    public void onSuccess(Void result) {
                        results.rolesProcessed = true;
                        results.updatedRoles = finalUpdatedRoles;
                        populateAndProcessResponseIfComplete(results, request, response);
                    }
                });
        }
    }

    private void populateAndProcessResponseIfComplete(AddOrUpdateResults results, DSRequest request, DSResponse response) {
        if (results.isComplete()) {
            Record updatedRecord = null;
            if (results.updatedSubject != null) {
                updatedRecord = copyValues(results.updatedSubject);
            } else {
                if (results.updatedPassword != null || results.updatedRoles != null) {
                    RecordList recordList = response.getDataAsRecordList();
                    updatedRecord = recordList.find(Field.ID, results.subjectId);
                }
                if (results.subjectError != null) {
                    CoreGUI.getErrorHandler().handleError("Failed to update subject for user with id ["
                        + results.subjectId + "]." , results.subjectError);
                }
            }

            if (results.updatedPassword != null) {
                updatedRecord.setAttribute(Field.PASSWORD, results.updatedPassword);
            } else if (results.passwordError != null) {
                CoreGUI.getErrorHandler().handleError("Failed to update password for user with id [" + results.subjectId
                    + "]." , results.passwordError);
            }

            if (results.updatedRoles != null) {
                updatedRecord.setAttribute(Field.ROLES, results.updatedRoles);
            } else if (results.rolesError != null) {
                CoreGUI.getErrorHandler().handleError("Failed to update assigned roles for user with id ["
                    + results.subjectId + "].", results.rolesError);
            }

            if (updatedRecord != null) {
                String username = updatedRecord.getAttribute(Field.NAME);
                UsersView.setMessage(new Message("User updated.", "User [" + username + "] updated.",
                    Message.Severity.Info));
                response.setData(new Record[] {updatedRecord});
                processResponse(request.getRequestId(), response);
            }

            CoreGUI.goToView(UsersView.VIEW_PATH);
        }
    }

    class AddOrUpdateResults {
        int subjectId;

        boolean subjectProcessed;
        boolean passwordProcessed;
        boolean rolesProcessed;

        Subject updatedSubject;
        String updatedPassword;
        Set<Role> updatedRoles;

        Throwable subjectError;
        Throwable passwordError;
        Throwable rolesError;

        boolean isComplete() {
            return (subjectProcessed && passwordProcessed && rolesProcessed);
        }
    }
JBoss.org Content Archive (Read Only), exported from JBoss Community Documentation Editor at 2020-03-13 08:20:18 UTC, last content change 2013-09-18 19:40:42 UTC.