@RequestMapping("/client/app/(*:appId)/(~:version)/process/(*:processDefId)") public String clientProcessView( HttpServletRequest request, ModelMap model, @RequestParam("appId") String appId, @RequestParam(required = false) String version, @RequestParam String processDefId, @RequestParam(required = false) String recordId, @RequestParam(required = false) String start) { // clean process def processDefId = WorkflowUtil.getProcessDefIdWithoutVersion(processDefId); AppDefinition appDef = appService.getAppDefinition(appId, version); WorkflowProcess processDef = appService.getWorkflowProcessForApp(appId, appDef.getVersion().toString(), processDefId); // check for permission if (!workflowManager.isUserInWhiteList(processDef.getId())) { return "client/app/processUnauthorized"; } // set app and process details model.addAttribute("appId", appId); model.addAttribute("appVersion", appDef.getVersion()); model.addAttribute("appDefinition", appDef); model.addAttribute("process", processDef); model.addAttribute("queryString", request.getQueryString()); // check for start mapped form FormData formData = new FormData(); formData.setPrimaryKeyValue(recordId); String formUrl = "/web/client/app/" + appId + "/" + appDef.getVersion() + "/process/" + processDefId + "/start"; if (recordId != null) { formUrl += "?recordId=" + recordId; } String formUrlWithContextPath = AppUtil.getRequestContextPath() + formUrl; PackageActivityForm startFormDef = appService.viewStartProcessForm( appId, appDef.getVersion().toString(), processDefId, formData, formUrlWithContextPath); if (startFormDef != null && startFormDef.getForm() != null) { Form startForm = startFormDef.getForm(); // generate form HTML String formHtml = formService.retrieveFormHtml(startForm, formData); String formJson = formService.generateElementJson(startForm); // show form model.addAttribute("form", startForm); model.addAttribute("formJson", formJson); model.addAttribute("formHtml", formHtml); return "client/app/processFormStart"; } else { if (Boolean.valueOf(start).booleanValue()) { // redirect to start URL return "redirect:" + formUrl; } else { // empty start page return "client/app/processStart"; } } }
@RequestMapping("/form/embed") public String embedForm( ModelMap model, HttpServletRequest request, HttpServletResponse response, @RequestParam("_submitButtonLabel") String buttonLabel, @RequestParam("_json") String json, @RequestParam("_callback") String callback, @RequestParam("_setting") String callbackSetting, @RequestParam(required = false) String id, @RequestParam(value = "_a", required = false) String action) throws JSONException, UnsupportedEncodingException { FormData formData = new FormData(); if (id != null && !id.isEmpty()) { formData.setPrimaryKeyValue(id); } Form form = formService.loadFormFromJson(json, formData); AppDefinition appDef = AppUtil.getCurrentAppDefinition(); String appId = ""; String appVersion = ""; if (appDef != null) { appId = appDef.getAppId(); appVersion = appDef.getVersion().toString(); } String nonce = request.getParameter("_nonce"); if (form == null || !SecurityUtil.verifyNonce( nonce, new String[] {"EmbedForm", appId, appVersion, form.getPropertyString("id"), nonce})) { response.setStatus(HttpServletResponse.SC_FORBIDDEN); return null; } if (callbackSetting == null || (callbackSetting != null && callbackSetting.isEmpty())) { callbackSetting = "{}"; } form.setProperty( "url", "?_nonce=" + URLEncoder.encode(nonce, "UTF-8") + "&_a=submit&_callback=" + callback + "&_setting=" + StringEscapeUtils.escapeHtml(callbackSetting) + "&_submitButtonLabel=" + StringEscapeUtils.escapeHtml(buttonLabel)); if (form != null) { // if id field not exist, automatically add an id hidden field Element idElement = FormUtil.findElement(FormUtil.PROPERTY_ID, form, formData); if (idElement == null) { Collection<Element> formElements = form.getChildren(); idElement = new HiddenField(); idElement.setProperty(FormUtil.PROPERTY_ID, FormUtil.PROPERTY_ID); idElement.setParent(form); formElements.add(idElement); } // create new section for buttons Section section = new Section(); section.setProperty(FormUtil.PROPERTY_ID, "section-actions"); Collection<Element> sectionChildren = new ArrayList<Element>(); section.setChildren(sectionChildren); Collection<Element> formChildren = form.getChildren(formData); if (formChildren == null) { formChildren = new ArrayList<Element>(); } formChildren.add(section); // add new horizontal column to section Column column = new Column(); column.setProperty("horizontal", "true"); Collection<Element> columnChildren = new ArrayList<Element>(); column.setChildren(columnChildren); sectionChildren.add(column); Element hiddenField = (Element) pluginManager.getPlugin(HiddenField.class.getName()); hiddenField.setProperty(FormUtil.PROPERTY_ID, "_json"); hiddenField.setProperty(FormUtil.PROPERTY_VALUE, json); columnChildren.add((Element) hiddenField); Element submitButton = (Element) pluginManager.getPlugin(SubmitButton.class.getName()); submitButton.setProperty(FormUtil.PROPERTY_ID, "submit"); submitButton.setProperty("label", buttonLabel); columnChildren.add((Element) submitButton); } // generate form HTML String formHtml = null; if ("submit".equals(action)) { formData = formService.retrieveFormDataFromRequest(formData, request); formData = formService.executeFormActions(form, formData); // check for validation errors Map<String, String> errors = formData.getFormErrors(); int errorCount = 0; if (!formData.getStay() && (errors == null || errors.isEmpty())) { // render normal template formHtml = formService.generateElementHtml(form, formData); // convert submitted JSONObject jsonResult = new JSONObject(); // get binder of main form FormStoreBinder mainBinder = form.getStoreBinder(); FormRowSet rows = formData.getStoreBinderData(mainBinder); for (FormRow row : rows) { for (Object o : row.keySet()) { jsonResult.accumulate(o.toString(), row.get(o)); } Map<String, String> tempFilePathMap = row.getTempFilePathMap(); if (tempFilePathMap != null && !tempFilePathMap.isEmpty()) { jsonResult.put(FormUtil.PROPERTY_TEMP_FILE_PATH, tempFilePathMap); } } model.addAttribute("jsonResult", StringEscapeUtils.escapeJavaScript(jsonResult.toString())); } else { // render error template formHtml = formService.generateElementErrorHtml(form, formData); errorCount = errors.size(); } model.addAttribute("setting", callbackSetting); model.addAttribute("callback", callback); model.addAttribute("submitted", Boolean.TRUE); model.addAttribute("errorCount", errorCount); model.addAttribute("stay", formData.getStay()); } else { formHtml = formService.retrieveFormHtml(form, formData); } model.addAttribute("formHtml", formHtml); if (request.getParameter("_mapp") != null) { response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin")); response.setHeader("Access-Control-Allow-Credentials", "true"); response.setHeader("Content-type", "application/xml"); return "mapp/embedForm"; } else { return "fbuilder/embedForm"; } }
@RequestMapping("/client/app/(*:appId)/(~:version)/process/(*:processDefId)/start") public String clientProcessStart( HttpServletRequest request, ModelMap model, @RequestParam("appId") String appId, @RequestParam(required = false) String version, @RequestParam(required = false) String recordId, @RequestParam String processDefId) { // clean process def processDefId = WorkflowUtil.getProcessDefIdWithoutVersion(processDefId); // set app and process details AppDefinition appDef = appService.getAppDefinition(appId, version); WorkflowProcess processDef = appService.getWorkflowProcessForApp(appId, appDef.getVersion().toString(), processDefId); String processDefIdWithVersion = processDef.getId(); model.addAttribute("appId", appId); model.addAttribute("appVersion", appDef.getVersion()); model.addAttribute("appDefinition", appDef); model.addAttribute("process", processDef); // check for permission if (!workflowManager.isUserInWhiteList(processDef.getId())) { return "client/app/processUnauthorized"; } // extract form values from request FormData formData = new FormData(); formData.setPrimaryKeyValue(recordId); formData = formService.retrieveFormDataFromRequest(formData, request); // get workflow variables Map<String, String> variableMap = AppUtil.retrieveVariableDataFromRequest(request); String formUrl = AppUtil.getRequestContextPath() + "/web/client/app/" + appId + "/" + appDef.getVersion() + "/process/" + processDefId + "/start"; if (recordId != null) { formUrl += "?recordId=" + recordId; } PackageActivityForm startFormDef = appService.viewStartProcessForm( appId, appDef.getVersion().toString(), processDefId, formData, formUrl); WorkflowProcessResult result = appService.submitFormToStartProcess( appId, version, processDefId, formData, variableMap, recordId, formUrl); if (startFormDef != null && (startFormDef.getForm() != null || PackageActivityForm.ACTIVITY_FORM_TYPE_EXTERNAL.equals(startFormDef.getType()))) { if (result == null) { // validation error, get form Form startForm = startFormDef.getForm(); // generate form HTML String formHtml = formService.retrieveFormErrorHtml(startForm, formData); String formJson = formService.generateElementJson(startForm); // show form model.addAttribute("form", startForm); model.addAttribute("formJson", formJson); model.addAttribute("formHtml", formHtml); model.addAttribute("activityForm", startFormDef); return "client/app/processFormStart"; } } else { // start process - TODO: handle process linking result = workflowManager.processStart( processDefIdWithVersion, null, variableMap, null, recordId, false); } // set result if (result != null) { WorkflowProcess process = result.getProcess(); model.addAttribute("process", process); // redirect to next activity if available Collection<WorkflowActivity> activities = result.getActivities(); if (activities != null && !activities.isEmpty()) { WorkflowActivity nextActivity = activities.iterator().next(); String assignmentUrl = "/web/client/app/" + appId + "/" + appDef.getVersion() + "/assignment/" + nextActivity.getId() + "?" + request.getQueryString(); return "redirect:" + assignmentUrl; } } return "client/app/processStarted"; }