Example #1
0
/**
 * Widget allowing to display the current state of a Case in a recap.<br>
 * Corresponds to the URL ?instance=&lgt;ProcessInstanceUUID&gt;&recap=true
 *
 * @author Nicolas Chabanoles
 */
public class CaseRecapViewerWidget extends BonitaPanel implements ModelChangeListener {

  protected final ProcessDataSource myProcessDataSource;
  protected final CaseDataSource myCaseDataSource;
  protected final StepItemDataSource myStepDataSource;

  protected final DecoratorPanel myOuterPanel = new DecoratorPanel();
  protected final FlowPanel myInnerPanel = new FlowPanel();
  protected final FlowPanel myFirstRowPanel = new FlowPanel();
  protected final FlowPanel mySecondRowPanel = new FlowPanel();
  protected final FlowPanel myThirdRowPanel = new FlowPanel();

  protected Frame myIFrame;

  protected CaseItem myCase;
  protected BonitaProcess myProcess;

  protected boolean isOverviewVisible = true;
  protected boolean mustRefresh;

  protected URLUtils urlUtils = URLUtilsFactory.getInstance();
  protected String formId;

  /**
   * Default constructor.
   *
   * @param aDataSource
   * @param aStep
   * @param mustBeVisible
   */
  public CaseRecapViewerWidget(
      StepItemDataSource aDataSource,
      CaseItem aCase,
      CaseDataSource aCaseDataSource,
      ProcessDataSource aProcessDataSource) {
    super();
    myStepDataSource = aDataSource;
    myCaseDataSource = aCaseDataSource;
    myProcessDataSource = aProcessDataSource;
    myCase = aCase;
    formId = myCase.getProcessUUID().getValue() + "$recap";
    myInnerPanel.add(myFirstRowPanel);
    myInnerPanel.add(mySecondRowPanel);
    myInnerPanel.add(myThirdRowPanel);
    myOuterPanel.add(myInnerPanel);

    myFirstRowPanel.setStylePrimaryName("bos_first_row");
    mySecondRowPanel.setStylePrimaryName("bos_second_row");
    myThirdRowPanel.setStylePrimaryName("bos_third_row");
    myInnerPanel.setStylePrimaryName("bos_case_recap_viewer_inner");
    myOuterPanel.setStylePrimaryName("bos_case_recap_viewer");
    myOuterPanel.addStyleName(CSSClassManager.ROUNDED_PANEL);
    this.initWidget(myOuterPanel);

    myProcessDataSource.getItem(
        myCase.getProcessUUID(),
        new AsyncHandler<BonitaProcess>() {
          public void handleFailure(Throwable aT) {
            // Do nothing.
            GWT.log("Unable to get the process definition:", aT);
          }

          public void handleSuccess(BonitaProcess aResult) {
            myProcess = aResult;
            initContent();
            update();
          }
        });
  }

  /** Build the static part of the UI. */
  protected void initContent() {

    // Case initiator will not change.
    final String theCaseInitiator = constants.caseStartedBy() + myCase.getStartedBy().getValue();
    final String theProcessDescription = myProcess.getProcessDescription();
    final String theShortDesc;
    if (theProcessDescription.length() > 50) {
      theShortDesc = theProcessDescription.substring(0, 47) + "...";
    } else {
      theShortDesc = theProcessDescription;
    }

    final Grid theWrapper = new Grid(1, 3);
    theWrapper.setHTML(0, 0, theCaseInitiator);
    theWrapper.setHTML(
        0,
        1,
        DateTimeFormat.getFormat(constants.dateShortFormat()).format(myCase.getLastUpdateDate()));
    theWrapper.setHTML(0, 2, theShortDesc);
    myFirstRowPanel.add(theWrapper);
    theWrapper.addStyleName("bos_step_descriptor");

    // Create click handler for user interaction.
    theWrapper.addClickHandler(
        new ClickHandler() {
          public void onClick(ClickEvent anEvent) {
            final Cell theCell = theWrapper.getCellForEvent(anEvent);
            if (theCell != null) {
              toggleOverviewVisibility();
            }
          }
        });
  }

  public void refresh() {
    if (isOverviewVisible) {
      try {
        if (DOMUtils.getInstance().isInternetExplorer()) {
          update();
        } else {
          if (myIFrame != null) {
            myIFrame.setUrl(cleanURL(myIFrame.getUrl()));
          }
        }

      } catch (Exception e) {
        Window.alert("Unable to refresh the Case recap! " + e.getMessage());
      }
    }
    mustRefresh = false;
  }

  /**
   * @param aUrl
   * @return
   */
  protected String cleanURL(String anUrl) {
    final ArrayList<String> paramsToRemove = new ArrayList<String>();
    paramsToRemove.add(URLUtils.USER_CREDENTIALS_PARAM);
    final ArrayList<String> hashToRemove = new ArrayList<String>();
    hashToRemove.add(URLUtils.USER_CREDENTIALS_PARAM);
    return URLUtils.getInstance().rebuildUrl(anUrl, paramsToRemove, null, hashToRemove, null);
  }

  /** Update the UI. */
  protected void update() {
    // Either the form content is available or it will be computed
    // asynchronously.
    if (isOverviewVisible) {
      // We already have the content to display.
      buildIframeAndInsertIt(myProcess.getApplicationUrl());
    } else {
      mySecondRowPanel.clear();
    }
  }

  protected void buildIframeAndInsertIt(final String anApplicationURL) {

    String theApplicationURL = anApplicationURL;
    if (theApplicationURL == null) {
      theApplicationURL = "";
    }
    if (BonitaConsole.userProfile.useCredentialTransmission()) {
      RpcConsoleServices.getLoginService()
          .generateTemporaryToken(new GetTokenAsyncCallback(theApplicationURL));
    } else {
      insertFormIFrame(buildProcessFormIFrame(theApplicationURL, ""));
    }
  }

  public void insertFormIFrame(final String aFormIFrame) {
    myIFrame = new FormPageFrame();
    myIFrame.setStyleName("form_view_frame");
    final Element theElement = myIFrame.getElement();
    theElement.setId(formId);
    theElement.setAttribute("frameBorder", "0");
    theElement.setAttribute("allowTransparency", "true");
    myIFrame.setUrl(aFormIFrame);
    mySecondRowPanel.add(myIFrame);
  }

  protected class GetTokenAsyncCallback implements AsyncCallback<String> {

    protected String myApplicationURL;

    public GetTokenAsyncCallback(String anApplicationURL) {
      this.myApplicationURL = anApplicationURL;
    }

    public void onSuccess(String temporaryToken) {
      String theCredentialsParam = "&" + URLUtils.USER_CREDENTIALS_PARAM + "=" + temporaryToken;
      insertFormIFrame(buildProcessFormIFrame(myApplicationURL, theCredentialsParam));
    }

    public void onFailure(Throwable t) {
      insertFormIFrame(buildProcessFormIFrame(myApplicationURL, ""));
    }
  }

  protected String buildProcessFormIFrame(String anApplicationURL, String aCredentialsParam) {
    final Map<String, List<String>> parametersMap = urlUtils.getURLParametersMap(anApplicationURL);
    final String url = urlUtils.removeURLparameters(anApplicationURL);

    StringBuilder processFormIFrame = new StringBuilder();
    processFormIFrame.append(url);
    processFormIFrame.append("?");
    processFormIFrame.append(URLUtils.LOCALE_PARAM);
    processFormIFrame.append("=");
    if (parametersMap.containsKey(URLUtils.LOCALE_PARAM)) {
      processFormIFrame.append(parametersMap.get(URLUtils.LOCALE_PARAM).get(0));
      parametersMap.remove(URLUtils.LOCALE_PARAM);
    } else {
      processFormIFrame.append(LocaleInfo.getCurrentLocale().getLocaleName());
    }
    if (BonitaConsole.userProfile.getDomain() != null) {
      processFormIFrame.append("&");
      processFormIFrame.append(URLUtils.DOMAIN_PARAM);
      processFormIFrame.append("=");
      if (parametersMap.containsKey(URLUtils.DOMAIN_PARAM)) {
        processFormIFrame.append(parametersMap.get(URLUtils.DOMAIN_PARAM).get(0));
        parametersMap.remove(URLUtils.DOMAIN_PARAM);
      } else {
        processFormIFrame.append(BonitaConsole.userProfile.getDomain());
      }
    }
    for (Entry<String, List<String>> parametersEntry : parametersMap.entrySet()) {
      processFormIFrame.append("&");
      processFormIFrame.append(parametersEntry.getKey());
      processFormIFrame.append("=");
      List<String> entryValues = parametersEntry.getValue();
      for (String value : entryValues) {
        processFormIFrame.append(value);
        processFormIFrame.append(",");
      }
      processFormIFrame.deleteCharAt(processFormIFrame.length() - 1);
    }

    processFormIFrame.append("#");
    processFormIFrame.append(URLUtils.FORM_ID);
    processFormIFrame.append("=");
    processFormIFrame.append(formId);
    processFormIFrame.append("&");
    processFormIFrame.append(URLUtils.VIEW_MODE_PARAM);
    processFormIFrame.append("=");
    processFormIFrame.append(URLUtils.FORM_ONLY_APPLICATION_MODE);
    processFormIFrame.append("&");
    processFormIFrame.append(URLUtils.INSTANCE_ID_PARAM);
    processFormIFrame.append("=");
    processFormIFrame.append(myCase.getUUID());
    processFormIFrame.append("&");
    processFormIFrame.append(URLUtils.RECAP_PARAM);
    processFormIFrame.append("=");
    processFormIFrame.append("true");
    processFormIFrame.append(aCredentialsParam);

    return processFormIFrame.toString();
  }

  /*
   * Switch visibility of the overview.
   */
  void toggleOverviewVisibility() {
    isOverviewVisible = !isOverviewVisible;
    update();
  }

  /*
   * (non-Javadoc)
   *
   * @seejava.beans.ModelChangeListener#propertyChange(java.beans. PropertyChangeEvent)
   */
  public void modelChange(ModelChangeEvent anEvt) {
    update();
  }

  /*
   * (non-Javadoc)
   *
   * @see com.google.gwt.user.client.ui.Composite#onDetach()
   */
  @Override
  protected void onDetach() {
    super.onDetach();
    mustRefresh = true;
  }

  /*
   * (non-Javadoc)
   *
   * @see com.google.gwt.user.client.ui.Composite#onAttach()
   */
  @Override
  protected void onAttach() {
    super.onAttach();
    if (mustRefresh) {
      refresh();
    }
  }
}
Example #2
0
  /**
   * Build the widget
   *
   * @param user the logged in user
   * @return the {@link Widget}
   */
  protected Widget buildUserIdentityCard() {

    final FlowPanel theIDWidget = new FlowPanel();
    theIDWidget.setStylePrimaryName("bonita_identification");

    final FlowPanel theLeftAlignedBox = new FlowPanel();
    theLeftAlignedBox.setStylePrimaryName("bonita_identified-left");

    theIDWidget.add(theLeftAlignedBox);

    final Image theAvatar = new Image("images/avatar-default.gif");
    theAvatar.setStyleName("bonita_avatar");

    theLeftAlignedBox.add(theAvatar);

    final FlowPanel theRightAlignedBox = new FlowPanel();
    theRightAlignedBox.setStylePrimaryName("bonita_identified-right");

    theLeftAlignedBox.add(theRightAlignedBox);

    HTML theUserIdentity = null;
    if (user.isAnonymous()) {
      theUserIdentity = new HTML(FormsResourceBundle.getMessages().anonymousLabel());
    } else {
      theUserIdentity = new HTML(user.getUsername());
    }
    theUserIdentity.setStylePrimaryName("bonita_identif-1");

    theRightAlignedBox.add(theUserIdentity);

    Anchor theLogoutLink = null;
    if (user.isAnonymous()) {
      theLogoutLink = new Anchor(FormsResourceBundle.getMessages().loginButtonLabel());
    } else {
      theLogoutLink = new Anchor(FormsResourceBundle.getMessages().logoutButtonLabel());
    }
    theLogoutLink.setStylePrimaryName("bonita_identif-2");

    final URLUtils urlUtils = URLUtilsFactory.getInstance();
    final List<String> paramsToRemove = new ArrayList<String>();
    paramsToRemove.add(URLUtils.LOCALE_PARAM);
    final List<String> hashParamsToRemove = new ArrayList<String>();
    if (user.isAutoLogin()) {
      hashParamsToRemove.add(URLUtils.AUTO_LOGIN_PARAM);
    } else {
      hashParamsToRemove.add(URLUtils.USER_CREDENTIALS_PARAM);
    }
    if (!user.isAnonymous()) {
      for (final Entry<String, Object> hashParamEntry : context.entrySet()) {
        hashParamsToRemove.add(hashParamEntry.getKey());
      }
    }
    Map<String, String> hashParamsToAdd = new HashMap<String, String>();
    hashParamsToAdd.put(URLUtils.TODOLIST_PARAM, "true");
    hashParamsToAdd.put(URLUtils.VIEW_MODE_PARAM, "app");
    final String theRedirectURL =
        urlUtils.rebuildUrl(paramsToRemove, null, hashParamsToRemove, hashParamsToAdd);
    String theURL = "?" + URLUtils.REDIRECT_URL_PARAM + "=";
    try {
      theURL += URL.encodeQueryString(theRedirectURL);
    } catch (final Exception e) {
      Window.alert("Unable to redirect to login page: Invalid URL");
      theURL += GWT.getModuleBaseURL();
    }
    theLogoutLink.setHref(theURL);

    theRightAlignedBox.add(theLogoutLink);

    return theIDWidget;
  }
/**
 * Controller dealing with Task form controls before display
 *
 * @author Ruiheng Fan
 */
public class PageflowViewController {

  /** forms RPC service */
  protected FormsServiceAsync formsServiceAsync;

  /** Pages view controller (handles the page flow) */
  protected FormPagesViewController formPagesViewController;

  /** Utility Class form DOM manipulation */
  protected DOMUtils domUtils = DOMUtils.getInstance();

  /** Utility Class form URL manipulation */
  protected URLUtils urlUtils = URLUtilsFactory.getInstance();

  /** mandatory form field symbol */
  protected String mandatoryFieldSymbol;

  /** mandatory form field label */
  protected String mandatoryFieldLabel;

  /** mandatory form field symbol classes */
  protected String mandatoryFieldClasses;

  /** The formID UUID retrieved from the request as a String */
  protected String formID;

  /** Application template panel (can be null in form only mode) */
  protected HTMLPanel applicationHTMLPanel;

  /** The logged in user */
  protected User user;

  /** Handler allowing to retrieve the first page */
  protected FirstPageHandler firstPageHandler = new FirstPageHandler();

  /** The context of URL parameters */
  protected Map<String, Object> urlContext;

  /** Id of the element in which to insert the page */
  protected String elementId;

  /**
   * Constructor
   *
   * @param formID
   * @param urlContext
   * @param user
   * @param applicationHTMLPanel
   */
  public PageflowViewController(
      final String formID,
      final Map<String, Object> urlContext,
      final User user,
      final String elementId,
      final HTMLPanel applicationHTMLPanel) {
    this.formID = formID;
    this.urlContext = urlContext;
    this.user = user;
    this.elementId = elementId;
    this.applicationHTMLPanel = applicationHTMLPanel;

    formsServiceAsync = RpcFormsServices.getFormsService();
  }

  /** create the view for the form */
  public void createForm() {
    formsServiceAsync.getFormFirstPage(formID, urlContext, firstPageHandler);
  }

  /** Handler allowing to retrieve the page list */
  protected class FirstPageHandler extends FormsAsyncCallback<ReducedFormPage> {

    /** {@inheritDoc} */
    @Override
    public void onSuccess(final ReducedFormPage firstPage) {

      if (firstPage != null) {
        try {
          RequestBuilder theRequestBuilder;
          final String theURL =
              urlUtils.buildLayoutURL(
                  firstPage.getPageTemplate().getBodyContentId(),
                  (String) urlContext.get(URLUtils.FORM_ID),
                  (String) urlContext.get(URLUtils.TASK_ID_PARAM),
                  true);
          GWT.log("Calling the Form Layout Download Servlet with query: " + theURL);
          theRequestBuilder = new RequestBuilder(RequestBuilder.GET, theURL);
          theRequestBuilder.setCallback(
              new RequestCallback() {

                @Override
                public void onError(final Request aRequest, final Throwable anException) {
                  final String errorMessage =
                      FormsResourceBundle.getErrors().applicationConfigRetrievalError();
                  formsServiceAsync.getApplicationErrorTemplate(
                      firstPage.getPageId(),
                      urlContext,
                      new ErrorPageHandler(
                          null, firstPage.getPageId(), errorMessage, anException, elementId));
                }

                @Override
                public void onResponseReceived(final Request request, final Response response) {

                  firstPage.getPageTemplate().setBodyContent(response.getText());
                  formPagesViewController =
                      FormViewControllerFactory.getFormPagesViewController(
                          formID, urlContext, firstPage, applicationHTMLPanel, user, elementId);
                  formPagesViewController.setMandatoryFieldSymbol(mandatoryFieldSymbol);
                  formPagesViewController.setMandatoryFieldLabel(mandatoryFieldLabel);
                  formPagesViewController.setMandatoryFieldClasses(mandatoryFieldClasses);
                  formPagesViewController.displayPage(0);
                }
              });
          theRequestBuilder.send();
        } catch (final Exception e) {
          Window.alert("Error while trying to query the form layout :" + e.getMessage());
        }
      } else {
        final String processUUIDStr = (String) urlContext.get(URLUtils.PROCESS_ID_PARAM);
        final String instanceUUIDStr = (String) urlContext.get(URLUtils.INSTANCE_ID_PARAM);
        if (processUUIDStr != null) {
          final String autoInstantiate = (String) urlContext.get(URLUtils.AUTO_INSTANTIATE);
          final ConfirmationPageHandler confirmationPageHandler = createConfirmationPageHandler();
          final FormTerminationHandler formTerminationHandler =
              new FormTerminationHandler(confirmationPageHandler);
          // if the parameter autoInstanciate is set explicitly to false, the we skip the form
          if (!Boolean.FALSE.toString().equals(autoInstantiate)) {
            formsServiceAsync.skipForm(formID, urlContext, formTerminationHandler);
          } else {
            final FlowPanel buttonContainer = new FlowPanel();
            confirmationPageHandler.setCurrentPageHTMLPanel(buttonContainer);
            buttonContainer.setStyleName("bonita_form_button_container");
            buttonContainer.add(createStartProcessInstanceButton(formTerminationHandler));
            addStartProcessInstanceContainer(buttonContainer);
          }
        } else if (instanceUUIDStr != null) {
          final String errorMessage = FormsResourceBundle.getErrors().nothingToDisplay();
          formsServiceAsync.getApplicationErrorTemplate(
              formID,
              urlContext,
              new ErrorPageHandler(applicationHTMLPanel, formID, errorMessage, elementId));
        } else {
          formsServiceAsync.skipForm(
              formID, urlContext, new FormTerminationHandler(createConfirmationPageHandler()));
        }
      }
    }

    @Override
    public void onUnhandledFailure(final Throwable caught) {

      try {
        throw caught;
      } catch (final ForbiddenFormAccessException e) {
        String errorMessage;
        if (urlContext.containsKey(URLUtils.PROCESS_ID_PARAM)) {
          errorMessage = FormsResourceBundle.getMessages().forbiddenProcessStartMessage();
        } else {
          errorMessage = FormsResourceBundle.getMessages().forbiddenStepReadMessage();
        }
        formsServiceAsync.getApplicationErrorTemplate(
            formID,
            urlContext,
            new ErrorPageHandler(applicationHTMLPanel, formID, errorMessage, elementId));
      } catch (final MigrationProductVersionNotIdenticalException e) {
        final String errorMessage =
            FormsResourceBundle.getMessages().migrationProductVersionMessage();
        formsServiceAsync.getApplicationErrorTemplate(
            formID,
            urlContext,
            new ErrorPageHandler(applicationHTMLPanel, formID, errorMessage, elementId));
      } catch (final CanceledFormException e) {
        final String errorMessage = FormsResourceBundle.getMessages().cancelledTaskMessage();
        formsServiceAsync.getApplicationErrorTemplate(
            formID,
            urlContext,
            new ErrorPageHandler(applicationHTMLPanel, formID, errorMessage, elementId));
        // } catch (SuspendedFormException e) {
        // final String errorMessage = FormsResourceBundle.getMessages().suspendedTaskMessage();
        // formsServiceAsync.getApplicationErrorTemplate(formID, urlContext, new
        // ErrorPageHandler(applicationHTMLPanel, formID, errorMessage,
        // elementId));
      } catch (final AbortedFormException e) {
        final String errorMessage = FormsResourceBundle.getMessages().abortedFormMessage();
        formsServiceAsync.getApplicationErrorTemplate(
            formID,
            urlContext,
            new ErrorPageHandler(applicationHTMLPanel, formID, errorMessage, elementId));
      } catch (final FormInErrorException e) {
        final String errorMessage = FormsResourceBundle.getMessages().errorTaskMessage();
        formsServiceAsync.getApplicationErrorTemplate(
            formID,
            urlContext,
            new ErrorPageHandler(applicationHTMLPanel, formID, errorMessage, elementId));
      } catch (final SkippedFormException e) {
        final String errorMessage = FormsResourceBundle.getMessages().skippedFormMessage();
        formsServiceAsync.getApplicationErrorTemplate(
            formID,
            urlContext,
            new ErrorPageHandler(applicationHTMLPanel, formID, errorMessage, elementId));
      } catch (final FormAlreadySubmittedException e) {
        final String errorMessage = FormsResourceBundle.getErrors().formAlreadySubmittedError();
        formsServiceAsync.getApplicationErrorTemplate(
            formID,
            urlContext,
            new ErrorPageHandler(applicationHTMLPanel, formID, errorMessage, elementId));
      } catch (final Throwable t) {
        final String errorMessage = FormsResourceBundle.getErrors().pageListRetrievalError();
        formsServiceAsync.getApplicationErrorTemplate(
            formID,
            urlContext,
            new ErrorPageHandler(applicationHTMLPanel, formID, errorMessage, elementId));
      }
    }
  }

  protected Button createStartProcessInstanceButton(
      final FormTerminationHandler formTerminationHandler) {
    final Button startInstanceButton =
        new Button(FormsResourceBundle.getMessages().caseStartButtonLabel());
    startInstanceButton.setStyleName("bonita_form_button");
    startInstanceButton.addClickHandler(
        new ClickHandler() {

          @Override
          public void onClick(final ClickEvent event) {
            startInstanceButton.setEnabled(false);
            formsServiceAsync.skipForm(formID, urlContext, formTerminationHandler);
          }
        });
    return startInstanceButton;
  }

  protected void addStartProcessInstanceContainer(final FlowPanel buttonContainer) {
    domUtils.hideLoading();
    if (applicationHTMLPanel != null) {
      applicationHTMLPanel.add(buttonContainer, DOMUtils.DEFAULT_FORM_ELEMENT_ID);
    } else {
      RootPanel.get(DOMUtils.STATIC_CONTENT_ELEMENT_ID).add(buttonContainer);
    }
  }

  /** Handler to deal with what happens after a form has been submitted or skipped */
  protected class FormTerminationHandler extends FormsAsyncCallback<Map<String, Object>> {

    private ConfirmationPageHandler confirmationPageHandler;

    public FormTerminationHandler(final ConfirmationPageHandler confirmationPageHandler) {
      setConfirmationPageHandler(confirmationPageHandler);
    }

    /** {@inheritDoc} */
    @Override
    public void onSuccess(final Map<String, Object> newContext) {
      urlContext.putAll(newContext);
      redirectToConfirmationPage(getConfirmationPageHandler());
    }

    /** @return the confirmationPageHandler */
    public ConfirmationPageHandler getConfirmationPageHandler() {
      return confirmationPageHandler;
    }

    /** @param confirmationPageHandler the confirmationPageHandler to set */
    public void setConfirmationPageHandler(final ConfirmationPageHandler confirmationPageHandler) {
      this.confirmationPageHandler = confirmationPageHandler;
    }

    @Override
    public void onUnhandledFailure(final Throwable caught) {
      try {
        throw caught;
      } catch (final IllegalActivityTypeException t) {
        final String errorMessage = FormsResourceBundle.getErrors().taskFormSkippedError();
        formsServiceAsync.getApplicationErrorTemplate(
            formID,
            urlContext,
            new ErrorPageHandler(applicationHTMLPanel, formID, errorMessage, elementId));
      } catch (final FormAlreadySubmittedException t) {
        final String errorMessage =
            FormsResourceBundle.getErrors().formAlreadySubmittedOrCancelledError();
        formsServiceAsync.getApplicationErrorTemplate(
            formID,
            urlContext,
            new ErrorPageHandler(applicationHTMLPanel, formID, errorMessage, elementId));
      } catch (final Throwable t) {
        final String errorMessage = FormsResourceBundle.getErrors().taskExecutionError();
        formsServiceAsync.getApplicationErrorTemplate(
            formID,
            urlContext,
            new ErrorPageHandler(applicationHTMLPanel, formID, errorMessage, t, elementId));
      }
    }
  }

  protected class GetTokenAsyncCallback implements AsyncCallback<String> {

    protected String applicationURL;

    protected Map<String, Object> urlContext;

    public GetTokenAsyncCallback(
        final String applicationURL, final Map<String, Object> urlContext) {
      this.applicationURL = applicationURL;
      this.urlContext = urlContext;
    }

    @Override
    public void onSuccess(final String temporaryToken) {
      urlContext.put(URLUtils.USER_CREDENTIALS_PARAM, temporaryToken);
      final String url = urlUtils.getFormRedirectionUrl(applicationURL, urlContext);
      if (domUtils.isPageInFrame()) {
        urlUtils.frameRedirect(DOMUtils.DEFAULT_FORM_ELEMENT_ID, url);
      } else {
        urlUtils.windowRedirect(url);
      }
    }

    @Override
    public void onFailure(final Throwable t) {
      final String url = urlUtils.getFormRedirectionUrl(applicationURL, urlContext);
      if (domUtils.isPageInFrame()) {
        urlUtils.frameRedirect(DOMUtils.DEFAULT_FORM_ELEMENT_ID, url);
      } else {
        urlUtils.windowRedirect(url);
      }
    }
  }

  public void setMandatoryFieldSymbol(final String mandatoryFieldSymbol) {
    this.mandatoryFieldSymbol = mandatoryFieldSymbol;
  }

  public void setMandatoryFieldClasses(final String mandatoryFieldClasses) {
    this.mandatoryFieldClasses = mandatoryFieldClasses;
  }

  public void setMandatoryFieldLabel(final String mandatoryFieldLabel) {
    this.mandatoryFieldLabel = mandatoryFieldLabel;
  }

  protected void redirectToConfirmationPage(final ConfirmationPageHandler confirmationPageHandler) {
    formsServiceAsync.getFormConfirmationTemplate(formID, urlContext, confirmationPageHandler);
  }

  protected ConfirmationPageHandler createConfirmationPageHandler() {
    return new ConfirmationPageHandler(
        applicationHTMLPanel, elementId, getDefaultConfirmationMessage(), formID, urlContext);
  }

  private String getDefaultConfirmationMessage() {
    return FormsResourceBundle.getMessages().submissionConfirmationMessage();
  }
}