@RequestMapping("/app/(*:appId)/(~:appVersion)/form/embed") public String appEmbedForm( ModelMap model, HttpServletRequest request, HttpServletResponse response, @RequestParam("appId") String appId, @RequestParam(value = "appVersion", required = false) String appVersion, @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 { AppDefinition appDef = appService.getAppDefinition(appId, appVersion); if (appDef == null) { response.setStatus(HttpServletResponse.SC_NOT_FOUND); return null; } AppUtil.setCurrentAppDefinition(appDef); return embedForm( model, request, response, buttonLabel, json, callback, callbackSetting, id, action); }
@RequestMapping("/json/app/(*:appId)/(~:appVersion)/form/options") public void formAjaxOptions( Writer writer, @RequestParam("appId") String appId, @RequestParam(value = "appVersion", required = false) String appVersion, @RequestParam("_dv") String dependencyValue, @RequestParam("_n") String nonce, @RequestParam("_bd") String binderData) throws JSONException { AppDefinition appDef = appService.getAppDefinition(appId, appVersion); FormRowSet rowSet = FormUtil.getAjaxOptionsBinderData(dependencyValue, appDef, nonce, binderData); JSONArray jsonArray = new JSONArray(); if (rowSet != null) { for (Map row : rowSet) { Map<String, String> data = new HashMap<String, String>(); data.put(FormUtil.PROPERTY_LABEL, (String) row.get(FormUtil.PROPERTY_LABEL)); data.put(FormUtil.PROPERTY_VALUE, (String) row.get(FormUtil.PROPERTY_VALUE)); jsonArray.put(data); } } jsonArray.write(writer); }
protected DataList getDataList() throws BeansException { if (cacheDataList == null) { // get datalist ApplicationContext ac = AppUtil.getApplicationContext(); AppService appService = (AppService) ac.getBean("appService"); DataListService dataListService = (DataListService) ac.getBean("dataListService"); DatalistDefinitionDao datalistDefinitionDao = (DatalistDefinitionDao) ac.getBean("datalistDefinitionDao"); String id = getPropertyString("datalistId"); AppDefinition appDef = appService.getAppDefinition( getRequestParameterString("appId"), getRequestParameterString("appVersion")); DatalistDefinition datalistDefinition = datalistDefinitionDao.loadById(id, appDef); if (datalistDefinition != null) { cacheDataList = dataListService.fromJson(datalistDefinition.getJson()); if (getPropertyString(Userview.USERVIEW_KEY_NAME) != null && getPropertyString(Userview.USERVIEW_KEY_NAME).trim().length() > 0) { cacheDataList.addBinderProperty( Userview.USERVIEW_KEY_NAME, getPropertyString(Userview.USERVIEW_KEY_NAME)); } if (getKey() != null && getKey().trim().length() > 0) { cacheDataList.addBinderProperty(Userview.USERVIEW_KEY_VALUE, getKey()); } cacheDataList.setActionPosition(getPropertyString("buttonPosition")); cacheDataList.setSelectionType(getPropertyString("selectionType")); cacheDataList.setCheckboxPosition(getPropertyString("checkboxPosition")); } } return cacheDataList; }
@RequestMapping("/fbuilder/app/(*:appId)/(~:appVersion)/form/(*:formId)/element/preview") public String previewElement( ModelMap model, @RequestParam("appId") String appId, @RequestParam(value = "appVersion", required = false) String appVersion, @RequestParam("formId") String formId, @RequestParam("json") String json) { try { FormUtil.setProcessedFormJson(json); model.addAttribute("appId", appId); model.addAttribute("appVersion", appVersion); AppDefinition appDef = appService.getAppDefinition(appId, appVersion); String tempJson = json; if (tempJson.contains(SecurityUtil.ENVELOPE) || tempJson.contains(PropertyUtil.PASSWORD_PROTECTED_VALUE)) { FormDefinition formDef = formDefinitionDao.loadById(formId, appDef); if (formDef != null) { tempJson = PropertyUtil.propertiesJsonStoreProcessing(formDef.getJson(), tempJson); } } String elementHtml = formService.previewElement(tempJson); model.addAttribute("elementTemplate", elementHtml); model.addAttribute("elementJson", json); } finally { FormUtil.clearProcessedFormJson(); } return "fbuilder/previewElement"; }
@RequestMapping("/console/app/(*:appId)/(~:version)/datalist/builder/(*:id)") public String builder( ModelMap map, @RequestParam("appId") String appId, @RequestParam(value = "version", required = false) String version, @RequestParam("id") String id, @RequestParam(required = false) String json) throws Exception { AppDefinition appDef = appService.getAppDefinition(appId, version); map.addAttribute("appId", appId); map.addAttribute("appVersion", appDef.getVersion()); map.addAttribute("appDefinition", appDef); DatalistDefinition datalist = datalistDefinitionDao.loadById(id, appDef); String listJson = null; if (json != null && !json.trim().isEmpty()) { // read custom JSON from request listJson = json; } else { // get JSON from form definition listJson = datalist.getJson(); } map.addAttribute("id", id); map.addAttribute("datalist", datalist); map.addAttribute("json", PropertyUtil.propertiesJsonLoadProcessing(listJson)); return "dbuilder/builder"; }
@RequestMapping("/json/console/app/(*:appId)/(~:appVersion)/builder/actions") public void getBuilderDataActionList( ModelMap map, Writer writer, @RequestParam("appId") String appId, @RequestParam(required = false) String appVersion, HttpServletRequest request) throws Exception { appService.getAppDefinition(appId, appVersion); JSONObject jsonObject = new JSONObject(); // get available binders DataListAction[] actions = dataListService.getAvailableActions(); Collection<Object> collection = new ArrayList<Object>(); for (DataListAction action : actions) { Plugin p = (Plugin) action; HashMap hm = new HashMap(); hm.put("name", p.getName()); hm.put("label", action.getLinkLabel()); hm.put("className", action.getClassName()); if (action instanceof PropertyEditable) { String propertyOptions = ((PropertyEditable) action).getPropertyOptions(); if (propertyOptions != null && !propertyOptions.isEmpty()) { hm.put("propertyOptions", propertyOptions); } } hm.put("type", "text"); collection.add(hm); } jsonObject.accumulate("actions", collection); jsonObject.write(writer); }
@RequestMapping("/app/(*:appId)/(~:appVersion)/datalist/embed") public String embedDatalist( ModelMap model, @RequestParam("appId") String appId, @RequestParam(value = "version", required = false) String version, HttpServletRequest request, @RequestParam("_submitButtonLabel") String buttonLabel, @RequestParam("_callback") String callback, @RequestParam("_setting") String callbackSetting, @RequestParam(required = false) String id, @RequestParam(value = "_listId", required = false) String listId, @RequestParam(value = "_type", required = false) String selectionType) throws JSONException { AppDefinition appDef = appService.getAppDefinition(appId, version); DatalistDefinition datalistDefinition = datalistDefinitionDao.loadById(listId, appDef); String json = datalistDefinition.getJson(); DataList dataList = dataListService.fromJson(json); dataList.setSelectionType(selectionType); model.addAttribute("id", id); model.addAttribute("json", json); model.addAttribute("buttonLabel", buttonLabel); model.addAttribute("dataList", dataList); model.addAttribute("setting", callbackSetting); model.addAttribute("callback", callback); return "dbuilder/embedDatalist"; }
@RequestMapping("/client/app/(~:appId)/(~:version)/assignment/(*:activityId)") public String clientAssignmentView( HttpServletRequest request, ModelMap model, @RequestParam(required = false) String appId, @RequestParam(required = false) String version, @RequestParam("activityId") String activityId) { // check assignment WorkflowAssignment assignment = workflowManager.getAssignment(activityId); if (assignment == null) { return "client/app/assignmentUnavailable"; } try { // get app AppDefinition appDef = null; if (appId != null && !appId.isEmpty()) { appDef = appService.getAppDefinition(appId, version); } else { appDef = appService.getAppDefinitionForWorkflowActivity(activityId); if (appDef != null) { appId = appDef.getId(); } } FormData formData = new FormData(); formData = formService.retrieveFormDataFromRequest(formData, request); // get form Long appVersion = (appDef != null) ? appDef.getVersion() : null; String formUrl = AppUtil.getRequestContextPath() + "/web/client/app/" + appId + "/" + appVersion + "/assignment/" + activityId + "/submit"; PackageActivityForm activityForm = appService.viewAssignmentForm(appId, version, activityId, formData, formUrl); Form form = activityForm.getForm(); // generate form HTML String formHtml = formService.retrieveFormHtml(form, formData); String formJson = formService.generateElementJson(form); model.addAttribute("appDef", appDef); model.addAttribute("assignment", assignment); model.addAttribute("activityForm", activityForm); model.addAttribute("form", form); model.addAttribute("formHtml", formHtml); model.addAttribute("formJson", formJson); } catch (Exception e) { Logger.getLogger(AppWebController.class.getName()).log(Level.SEVERE, null, e); } return "client/app/assignmentView"; }
@RequestMapping( value = { "/console/app/(*:appId)/(~:appVersion)/datalist/builderPreview/(*:id)", "/client/app/(*:appId)/(*:appVersion)/datalist/(*:id)" }) public String preview( ModelMap map, HttpServletRequest request, @RequestParam("appId") String appId, @RequestParam(value = "appVersion", required = false) String appVersion, @RequestParam("id") String id, @RequestParam(required = false) String json) throws Exception { String view = "dbuilder/view"; // get current app to set into thread AppDefinition appDef = appService.getAppDefinition(appId, appVersion); try { // get data list DataList dataList = new DataList(); if (json != null && !json.trim().isEmpty()) { String tempJson = json; if (tempJson.contains(SecurityUtil.ENVELOPE) || tempJson.contains(PropertyUtil.PASSWORD_PROTECTED_VALUE)) { DatalistDefinition datalistDef = datalistDefinitionDao.loadById(id, appDef); if (datalistDef != null) { tempJson = PropertyUtil.propertiesJsonStoreProcessing(datalistDef.getJson(), tempJson); } } dataList = dataListService.fromJson(AppUtil.processHashVariable(tempJson, null, null, null)); map.addAttribute("json", json); } else { dataList = parseFromJsonParameter(map, dataList, id, request); } map.addAttribute("dataList", dataList); } catch (Exception ex) { StringWriter out = new StringWriter(); ex.printStackTrace(new PrintWriter(out)); String message = ex.toString(); message += "\r\n<pre class=\"stacktrace\">" + out.getBuffer() + "</pre>"; map.addAttribute("error", message); } // set map into model to be used in the JSP template map.addAttribute("properties", new HashMap(map)); return view; }
/** * Download uploaded files. * * @param response * @param fileName * @param processInstanceId * @throws IOException */ @RequestMapping( "/client/app/(*:appId)/(~:version)/form/download/(*:formDefId)/(*:primaryKeyValue)/(*:fileName)") public void downloadUploadedFile( HttpServletResponse response, @RequestParam("formDefId") String formDefId, @RequestParam(value = "appId") String appId, @RequestParam(value = "version", required = false) String version, @RequestParam("primaryKeyValue") String primaryKeyValue, @RequestParam("fileName") String fileName, @RequestParam(required = false) String attachment) throws IOException { ServletOutputStream stream = response.getOutputStream(); Form form = null; AppDefinition appDef = appService.getAppDefinition(appId, version); FormDefinition formDef = formDefinitionDao.loadById(formDefId, appDef); if (formDef != null) { String json = formDef.getJson(); form = (Form) formService.createElementFromJson(json); } String decodedFileName = fileName; try { decodedFileName = URLDecoder.decode(fileName, "UTF8"); } catch (UnsupportedEncodingException e) { // ignore } File file = FileUtil.getFile(decodedFileName, form, primaryKeyValue); if (file.isDirectory() || !file.exists()) { response.sendError(HttpServletResponse.SC_NOT_FOUND); return; } DataInputStream in = new DataInputStream(new FileInputStream(file)); byte[] bbuf = new byte[65536]; try { // set attachment filename if (Boolean.valueOf(attachment).booleanValue()) { response.addHeader("Content-Disposition", "attachment; filename=" + fileName); } // set expires header for caching long expires = 300000; // 5 minutes response.setDateHeader("Expires", System.currentTimeMillis() + expires); // send output int length = 0; while ((in != null) && ((length = in.read(bbuf)) != -1)) { stream.write(bbuf, 0, length); } } finally { in.close(); stream.flush(); stream.close(); } }
@RequestMapping( value = "/console/app/(*:appId)/(~:version)/datalist/builderSave/(*:id)", method = RequestMethod.POST) public void save( Writer writer, @RequestParam("appId") String appId, @RequestParam(value = "version", required = false) String version, @RequestParam("id") String id, @RequestParam("json") String json) throws Exception { AppDefinition appDef = appService.getAppDefinition(appId, version); DatalistDefinition datalist = datalistDefinitionDao.loadById(id, appDef); DataList dlist = dataListService.fromJson(json); datalist.setName(dlist.getName()); datalist.setDescription(dlist.getName()); datalist.setJson(PropertyUtil.propertiesJsonStoreProcessing(datalist.getJson(), json)); boolean success = datalistDefinitionDao.update(datalist); JSONObject jsonObject = new JSONObject(); jsonObject.accumulate("success", success); jsonObject.write(writer); }
@RequestMapping("/console/app/(*:appId)/(~:version)/form/builder/(*:formId)") public String formBuilder( ModelMap model, @RequestParam("appId") String appId, @RequestParam(value = "version", required = false) String version, @RequestParam("formId") String formId, @RequestParam(required = false) String json) { // verify app version ConsoleWebPlugin consoleWebPlugin = (ConsoleWebPlugin) pluginManager.getPlugin(ConsoleWebPlugin.class.getName()); String page = consoleWebPlugin.verifyAppVersion(appId, version); if (page != null) { return page; } // set flag in request FormUtil.setFormBuilderActive(true); // load form definition model.addAttribute("appId", appId); AppDefinition appDef = appService.getAppDefinition(appId, version); FormDefinition formDef = null; if (appDef == null) { // TODO: handle invalid app } else { model.addAttribute("appDefinition", appDef); formDef = formDefinitionDao.loadById(formId, appDef); } if (formDef != null) { String formJson = null; if (json != null && !json.trim().isEmpty()) { // read custom JSON from request formJson = json; } else { // get JSON from form definition formJson = formDef.getJson(); } if (formJson != null && formJson.trim().length() > 0) { String processedformJson = PropertyUtil.propertiesJsonLoadProcessing(formJson); try { FormUtil.setProcessedFormJson(processedformJson); String elementHtml = formService.previewElement(formJson); model.addAttribute("elementHtml", elementHtml); model.addAttribute("elementJson", processedformJson); } finally { FormUtil.clearProcessedFormJson(); } } else { // default empty form String tableName = formDef.getTableName(); if (tableName == null || tableName.isEmpty()) { tableName = formDef.getId(); } String escapedFormName = StringEscapeUtils.escapeJavaScript(formDef.getName()); String defaultJson = "{className: 'org.joget.apps.form.model.Form', \"properties\":{ \"id\":\"" + formId + "\", \"name\":\"" + escapedFormName + "\", \"tableName\":\"" + tableName + "\", \"loadBinder\":{ \"className\":\"org.joget.apps.form.lib.WorkflowFormBinder\" }, \"storeBinder\":{ \"className\":\"org.joget.apps.form.lib.WorkflowFormBinder\" } }}"; String formHtml = formService.previewElement(defaultJson); model.addAttribute("elementHtml", formHtml); } } else { // default empty form String formJson = "{className: 'org.joget.apps.form.model.Form', \"properties\":{ \"id\":\"" + formId + "\", \"name\":\"\" \"loadBinder\":{ \"className\":\"org.joget.apps.form.lib.WorkflowFormBinder\" }, \"storeBinder\":{ \"className\":\"org.joget.apps.form.lib.WorkflowFormBinder\" } }}"; String formHtml = formService.previewElement(formJson); model.addAttribute("elementHtml", formHtml); } // add palette model.addAttribute("palette", formBuilderPalette); // add form def id model.addAttribute("formId", formId); model.addAttribute("formDef", formDef); return "fbuilder/formBuilder"; }
@RequestMapping( value = "/json/console/app/(*:appId)/(~:appVersion)/builder/binder/columns", method = RequestMethod.POST) public void getBuilderDataColumnList( ModelMap map, Writer writer, @RequestParam("appId") String appId, @RequestParam(required = false) String appVersion, @RequestParam String id, @RequestParam String binderId, HttpServletRequest request) throws Exception { AppDefinition appDef = appService.getAppDefinition(appId, appVersion); JSONObject jsonObject = new JSONObject(); // get data list DataList dataList = new DataList(); // parse JSON from request if available dataList = parseFromJsonParameter(map, dataList, id, request); // get binder from request DataListBinder binder = createDataListBinderFromRequestInternal(appDef, id, binderId, request); if (binder != null) { dataList.setBinder(binder); } DataListColumn[] sourceColumns = (binder != null) ? binder.getColumns() : new DataListColumn[0]; // sort columns by label List<DataListColumn> binderColumnList = Arrays.asList(sourceColumns); Collections.sort( binderColumnList, new Comparator<DataListColumn>() { public int compare(DataListColumn o1, DataListColumn o2) { return o1.getLabel().toLowerCase().compareTo(o2.getLabel().toLowerCase()); } }); Collection<String> columnNameList = new HashSet<String>(); DataListColumn[] targetColumns = dataList.getColumns(); if (targetColumns != null) { for (DataListColumn selectedColumn : targetColumns) { columnNameList.add(selectedColumn.getName()); } } for (Iterator i = binderColumnList.iterator(); i.hasNext(); ) { DataListColumn column = (DataListColumn) i.next(); if (columnNameList.contains(column.getName())) { i.remove(); } } sourceColumns = (DataListColumn[]) binderColumnList.toArray(new DataListColumn[0]); DataList sourceDataList = new DataList(); sourceDataList.setColumns(sourceColumns); Collection<Object> collection = new ArrayList<Object>(); for (DataListColumn sourceColumn : sourceColumns) { HashMap hm = new HashMap(); hm.put("name", sourceColumn.getName()); hm.put("label", sourceColumn.getLabel()); hm.put("sortable", true); hm.put("filterable", true); hm.put("type", sourceColumn.getType()); collection.add(hm); } jsonObject.accumulate("columns", collection); jsonObject.write(writer); }
@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("/client/app/(~:appId)/(~:version)/assignment/(*:activityId)/submit") public String clientAssignmentSubmit( HttpServletRequest request, ModelMap model, @RequestParam(required = false) String appId, @RequestParam(required = false) String version, @RequestParam("activityId") String activityId) { // check assignment WorkflowAssignment assignment = workflowManager.getAssignment(activityId); if (assignment == null) { return "client/app/assignmentUnavailable"; } // get app AppDefinition appDef = null; if (appId != null && !appId.isEmpty()) { appDef = appService.getAppDefinition(appId, version); } else { appDef = appService.getAppDefinitionForWorkflowActivity(activityId); } // extract form values from request FormData formData = new FormData(); formData = formService.retrieveFormDataFromRequest(formData, request); // set process instance ID as primary key String processId = assignment.getProcessId(); // load form Long appVersion = (appDef != null) ? appDef.getVersion() : null; String formUrl = AppUtil.getRequestContextPath() + "/web/client/app/" + appId + "/" + appVersion + "/assignment/" + activityId + "/submit"; PackageActivityForm activityForm = appService.viewAssignmentForm(appId, version, activityId, formData, formUrl); Form form = activityForm.getForm(); // submit form FormData formResult = formService.executeFormActions(form, formData); if (formResult.getFormResult(AssignmentWithdrawButton.DEFAULT_ID) != null) { // withdraw assignment workflowManager.assignmentWithdraw(activityId); return "client/app/dialogClose"; } else if (formResult.getFormResult(AssignmentCompleteButton.DEFAULT_ID) != null) { // complete assignment Map<String, String> variableMap = AppUtil.retrieveVariableDataFromRequest(request); formResult = appService.completeAssignmentForm(appId, version, activityId, formData, variableMap); Map<String, String> errors = formResult.getFormErrors(); if (errors.isEmpty() && activityForm.isAutoContinue()) { // redirect to next activity if available WorkflowAssignment nextActivity = workflowManager.getAssignmentByProcess(processId); if (nextActivity != null) { String assignmentUrl = "/web/client/app/" + appId + "/" + appVersion + "/assignment/" + nextActivity.getActivityId(); return "redirect:" + assignmentUrl; } } } String html = null; // check for validation errors Map<String, String> errors = formResult.getFormErrors(); int errorCount = 0; if (errors == null || errors.isEmpty()) { // render normal template html = formService.generateElementHtml(form, formResult); } else { // render error template html = formService.generateElementErrorHtml(form, formResult); errorCount = errors.size(); } String formJson = formService.generateElementJson(form); model.addAttribute("assignment", assignment); model.addAttribute("form", form); model.addAttribute("formHtml", html); model.addAttribute("formJson", formJson); model.addAttribute("formResult", formResult); model.addAttribute("errorCount", errorCount); model.addAttribute("submitted", Boolean.TRUE); model.addAttribute("closeDialog", Boolean.TRUE); return "client/app/assignmentView"; }
@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"; }