/** * Widget allowing to display the current state of a Case in a recap.<br> * Corresponds to the URL ?instance=&lgt;ProcessInstanceUUID>&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(); } } }
/** * 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(); } }