Esempio n. 1
0
  protected void storeToForm(WorkflowAssignment wfAssignment, Map properties, Map object) {
    String formDefId = (String) properties.get("formDefId");
    if (formDefId != null && formDefId.trim().length() > 0) {
      ApplicationContext ac = AppUtil.getApplicationContext();
      AppService appService = (AppService) ac.getBean("appService");
      AppDefinition appDef = (AppDefinition) properties.get("appDef");

      Object[] fieldMapping = (Object[]) properties.get("fieldMapping");
      String multirowBaseObjectName = (String) properties.get("multirowBaseObject");

      FormRowSet rowSet = new FormRowSet();

      if (multirowBaseObjectName != null && multirowBaseObjectName.trim().length() > 0) {
        Object[] baseObjectArray = (Object[]) getObjectFromMap(multirowBaseObjectName, object);
        if (baseObjectArray != null && baseObjectArray.length > 0) {
          rowSet.setMultiRow(true);
          for (int i = 0; i < baseObjectArray.length; i++) {
            rowSet.add(getRow(wfAssignment, multirowBaseObjectName, i, fieldMapping, object));
          }
        }
      } else {
        rowSet.add(getRow(wfAssignment, null, null, fieldMapping, object));
      }

      if (rowSet.size() > 0) {
        appService.storeFormData(
            appDef.getId(), appDef.getVersion().toString(), formDefId, rowSet, null);
      }
    }
  }
Esempio n. 2
0
  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;
  }
Esempio n. 3
0
  @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("/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("/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("/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("/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("/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);
  }
  @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;
  }
Esempio n. 11
0
  /**
   * 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);
  }
Esempio n. 13
0
  @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";
  }
Esempio n. 14
0
  @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";
      }
    }
  }
Esempio n. 15
0
  @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("/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);
  }