示例#1
0
 /**
  * Prepare Page. - Set Header
  *
  * @param loginInfo
  * @return WReportEngine page
  */
 private MobileDoc preparePage(String loginInfo) {
   MobileDoc doc = MobileDoc.create("Workflow");
   head header = doc.getHead();
   body b = doc.getBody();
   //  add window.js & .css
   header.addElement(new script("", MobileEnv.getBaseDirectory("/js/window.js")));
   header.addElement(
       new link().setRel("stylesheet").setHref(MobileEnv.getBaseDirectory("/css/window.css")));
   //
   //
   String title = "Workflow" + " - " + loginInfo;
   b.addElement(new script("top.document.title='" + title + "';"));
   return doc;
 } //  preparePage
示例#2
0
  /**
   * Create Image with name, id of button_name and set M_Command onClick
   *
   * @param name Name of the Image used also for Name24.gif
   * @param js_command Java script command, null results in 'submit();', an empty string disables
   *     OnClick
   * @param enabled Enable the immage button, if not uses the "D" image
   * @return Image
   */
  private static img createControlButtonImage(String name, String js_command, boolean enabled) {
    StringBuffer imgName = new StringBuffer("wf" + name);

    if (!enabled) imgName.append("D");

    imgName.append("24.gif");
    //
    img img = new img(MobileEnv.getImageDirectory(imgName.toString()), name);
    if (enabled) img.setAlt(Msg.getMsg(AD_Language, name)); //  Translate ToolTip

    img.setID("imgButton"); //  css

    // append js command only to enabled image
    if (js_command != null && js_command.length() > 0 && enabled) {
      img.setOnClick(
          "document." + FORM_NAME + "." + M_Command + ".value='" + name + "';" + js_command);
    }
    //
    return img;
  } //  createImage
示例#3
0
  /**
   * Create Image with name, id of button_name and set M_Command onClick
   *
   * @param name Name of the Image used also for Name24.gif
   * @param js_command Java script command, null results in 'submit();', an empty string disables
   *     OnClick
   * @param enabled Enable the immage button, if not uses the "D" image
   * @return Image
   */
  private static img createWorkflowImage(
      String name, int activeNode, String js_command, boolean pressed) {
    StringBuffer imgName = new StringBuffer(name);
    imgName.append("WF");

    imgName.append(".gif");
    //
    img img = new img(MobileEnv.getImageDirectory(imgName.toString()), name);

    if (!(imgName.toString()).startsWith("Spacer") && !(imgName.toString()).startsWith("Arrow")) {
      if (!pressed) img.setID("imgButton"); //  css
      else img.setID("imgButtonPressed");
    }

    // append js command only to enabled image
    if (js_command != null && js_command.length() > 0 && activeNode != 0) {
      String js_command_front =
          "document." + FORM_NAME + "." + J_Command + ".value='" + activeNode + "'; ";
      js_command_front = js_command_front + "document." + FORM_NAME + ".submit();";
      img.setOnClick(js_command_front + js_command);
    }
    //
    return img;
  } //  createImage
示例#4
0
 public void init(ServletConfig config) throws ServletException {
   super.init(config);
   if (!MobileEnv.initWeb(config)) throw new ServletException("WWorkflow.init");
 } //  init
示例#5
0
/**
 * @author Jack Lam
 * @version $Id: WWorkflow.java,v 1.1 2009/04/15 11:27:15 vinhpt Exp $
 */
public class WWorkflow extends HttpServlet {
  /** */
  private static final long serialVersionUID = 7220553249782175533L;

  /** Initialize global variables */
  public static final int SIZE = 3;

  public static final int SPACE = 0;
  public static final int ARROW_FORWARD = -1;
  public static final int ARROW_BACKWARD = -3;
  public static final int ARROW_DOWN = -2;

  public static final String WORKFLOW = "Workflow";
  public static final String NODES = "Nodes";
  public static final String NODES_ID = "Nodes_ID";
  public static final String IMAGE_MAP = "Image_Map";
  public static final String ACTIVE_NODE = "Active_Node";

  public static final String M_Command = "MCommand"; // move command
  public static final String J_Command = "JCommand"; // jump command

  public static final String FIRST = "Start";
  public static final String NEXT = "Next";
  public static final String BACK = "Back";
  public static final String LAST = "End";

  private static final String FORM_NAME = "MForm";
  private static final String TARGET_WINDOW = "WWindow";
  private static final String FORM_ACTION = MobileEnv.getBaseDirectory("/WWorkflow");

  private static String AD_Language = null;
  Properties ctx = null;

  /** Window Number Counter */
  private static int s_WindowNo = 1;

  public void init(ServletConfig config) throws ServletException {
    super.init(config);
    if (!MobileEnv.initWeb(config)) throw new ServletException("WWorkflow.init");
  } //  init

  /**
   * Process the HTTP Get request - Initial Call. <br>
   * http://localhost/adempiere/WWorkflow?AD_Menu_ID=123 <br>
   * Find the AD_Workflow_ID Load workflow and initial session atribute Create output
   *
   * @param request
   * @param response
   * @throws ServletException
   * @throws IOException
   */
  public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    // Log.trace(Log.l1_User, "WWorkflow.doGet");
    // WUtil.debug(new String("In do get"),"");

    //  Get Session attributes
    HttpSession sess = request.getSession();
    MobileSessionCtx wsc = MobileSessionCtx.get(request);
    ctx = wsc.ctx;
    // String loginInfo = (String)sess.getAttribute(WebEnv.SA_LOGININFO);
    if (ctx == null) {
      MobileUtil.createTimeoutPage(request, response, this, null);
      return;
    }

    //  Get Parameter: Menu_ID
    int AD_Menu_ID = MobileUtil.getParameterAsInt(request, "AD_Menu_ID");

    //  Get Parameter: Menu_ID
    int AD_Window_ID = MobileUtil.getParameterAsInt(request, "AD_Window_ID");

    // set language
    AD_Language = Env.getAD_Language(ctx);

    // load AD_Workflow_ID
    int AD_Workflow_ID = getAD_Workflow_ID(AD_Menu_ID);

    // load workflow
    loadWorkflow(ctx, AD_Workflow_ID, sess);

    // get session attributes
    MWorkflow wf = (MWorkflow) sess.getAttribute(WORKFLOW);
    MWFNode[] nodes = (MWFNode[]) sess.getAttribute(NODES);
    ArrayList nodes_ID = (ArrayList) sess.getAttribute(NODES_ID);
    int[][] imageMap = (int[][]) sess.getAttribute(IMAGE_MAP);
    int activeNode = ((Integer) sess.getAttribute(ACTIVE_NODE)).intValue();

    // create output
    MobileDoc doc = preparePage("loginInfo");
    doc = createLayout(doc, wf, activeNode, nodes, nodes_ID, imageMap);
    MobileUtil.createResponse(request, response, this, null, doc, false);
  } //  doGet

  /**
   * Process the HTTP Post request - Initial Call.
   *
   * <p>Execute the received command Update session attributes Create output
   *
   * @param request
   * @param response
   * @throws ServletException
   * @throws IOException
   */
  public void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    // WUtil.debug(new String("In do Post"),"");
    HttpSession sess = request.getSession();

    MobileSessionCtx wsc = MobileSessionCtx.get(request);
    Properties ctx = wsc.ctx;
    if (ctx == null) {
      MobileUtil.createTimeoutPage(request, response, this, null);

      return;
    }
    // String loginInfo = (String)sess.getAttribute(WEnv.SA_LOGININFO);

    // get session attributes
    MWorkflow wf = (MWorkflow) sess.getAttribute(WORKFLOW);
    MWFNode[] nodes = (MWFNode[]) sess.getAttribute(NODES);
    ArrayList nodes_ID = (ArrayList) sess.getAttribute(NODES_ID);
    int[][] imageMap = (int[][]) sess.getAttribute(IMAGE_MAP);
    int activeNode = ((Integer) sess.getAttribute(ACTIVE_NODE)).intValue();

    // execute commnad
    String m_command = request.getParameter(M_Command);
    int j_command = MobileUtil.getParameterAsInt(request, J_Command);
    // WUtil.debug(m_command,"m_command");
    // WUtil.debug(""+j_command,"j_command");

    executeCommand(m_command, j_command, wf, activeNode, nodes, nodes_ID, sess);

    // get updated session attributes
    wf = (MWorkflow) sess.getAttribute(WORKFLOW);
    nodes = (MWFNode[]) sess.getAttribute(NODES);
    nodes_ID = (ArrayList) sess.getAttribute(NODES_ID);
    imageMap = (int[][]) sess.getAttribute(IMAGE_MAP);
    activeNode = ((Integer) sess.getAttribute(ACTIVE_NODE)).intValue();

    // create layout
    MobileDoc doc = preparePage("loginInfo");
    doc = createLayout(doc, wf, activeNode, nodes, nodes_ID, imageMap);
    MobileUtil.createResponse(request, response, this, null, doc, false);
  } //  doPost

  /** ******************************************************************************************* */

  /**
   * Generate image map array. - Generate the orientation of workflow automatically
   *
   * @param nodes
   * @return int [][]
   */
  private int[][] generateImageMap(ArrayList nodes_ID) {

    // number of nodes
    int numOfNode = nodes_ID.size();

    int rowNode_count = (int) Math.ceil((float) numOfNode / SIZE);

    int rowTotal_count = 2 * rowNode_count - 1;

    int ROW = rowTotal_count;
    int COL = 2 * SIZE - 1;

    int[][] imageMap = new int[ROW][COL];
    //
    boolean isEmptyRow_Right = true;
    boolean isForwardRow = true;
    int row_Last = ROW - 1;
    // indexs
    int index_Row = 0;
    int index_Node = 0;
    int i, j;

    // operate on every row
    for (index_Row = 0; index_Row < ROW; index_Row++) {
      // odd row
      if ((index_Row % 2) != 0) {
        if (isEmptyRow_Right) {
          imageMap[index_Row][COL - 1] = ARROW_DOWN;
          isEmptyRow_Right = false;
        } else {
          imageMap[index_Row][0] = ARROW_DOWN;
          isEmptyRow_Right = true;
        }
      } // odd row

      // even row
      if ((index_Row % 2) == 0) {
        if (isForwardRow) {
          isForwardRow = false;

          // Last row
          if (index_Row == row_Last) {
            j = 0;
            for (i = index_Node; i < numOfNode; i++) {
              imageMap[index_Row][j++] = ((Integer) nodes_ID.get(i)).intValue();
              if (i != numOfNode - 1) imageMap[index_Row][j++] = ARROW_FORWARD;
            }

          } // Last row-end

          // not last row
          else {

            for (i = 0; i < COL; i++)
              imageMap[index_Row][i] =
                  ((i % 2 == 0)
                      ? ((Integer) nodes_ID.get(index_Node++)).intValue()
                      : ARROW_FORWARD);
          } // not last row
        } // Forward row - end
        else {

          isForwardRow = true;

          // Backward-Last row
          if (index_Row == row_Last) {
            j = 0;
            for (i = index_Node; i < numOfNode; i++) {
              imageMap[index_Row][COL - 1 - j++] = ((Integer) nodes_ID.get(i)).intValue();
              if (i != numOfNode - 1) imageMap[index_Row][COL - 1 - j++] = ARROW_BACKWARD;
            }

          } // Backward-Last row -end

          // Backward-Not last row
          else {
            j = 0;
            for (i = 0; i < COL; i++) {
              imageMap[index_Row][COL - 1 - i] =
                  (i % 2 == 0) ? ((Integer) nodes_ID.get(index_Node++)).intValue() : ARROW_BACKWARD;
            }
          } // Backward-Not last row- end
        } // Backward row
      } // even row
    } // for every row

    return imageMap;
  } // generateImageMap

  /**
   * Print the workflow. - Use the image map array to create the visual layout of workflow
   *
   * @param activeNode
   * @param wf
   * @param nodes
   * @param nodes_ID
   * @param imageMap
   * @return table
   */
  private table printWorkflow(
      int activeNode, MWorkflow wf, MWFNode[] nodes, ArrayList nodes_ID, int[][] imageMap) {

    // create a new table
    table imageTable = new table();
    // find the dimension for the table
    final int ROW = imageMap.length;
    final int COL = imageMap[0].length;

    // process every row
    for (int i = 0; i < ROW; i++) {
      // create a new row
      tr aRow = new tr();

      for (int j = 0; j < COL; j++) {
        // create a new grid
        td grid = new td();
        grid.setAlign("center");
        // not node images
        img spaceImage = createWorkflowImage("Spacer", 0, null, true);
        img arrowForwardImage = createWorkflowImage("ArrowFW_", 0, null, true);
        img arrowBackwardImage = createWorkflowImage("ArrowBW_", 0, null, true);
        img arrowDownImage = createWorkflowImage("ArrowDown_", 0, null, true);
        // node images

        img normalNodeImage = null;
        img activeNodeImage = null;

        // not node images
        if (imageMap[i][j] <= 0) {

          if (imageMap[i][j] == ARROW_FORWARD) grid.addElement(arrowForwardImage);

          if (imageMap[i][j] == ARROW_BACKWARD) grid.addElement(arrowBackwardImage);

          if (imageMap[i][j] == ARROW_DOWN) grid.addElement(arrowDownImage);

          if (imageMap[i][j] == SPACE) grid.addElement(spaceImage);

        } // not node images
        else {

          // Initialize variable
          int AD_Window_ID = 0;
          String url = "";
          String Target_Window = "";
          String parameters = "";
          String js_command = "";

          if (imageMap[i][j] == activeNode) {
            // Create image

            AD_Window_ID = nodes[getIndex(imageMap[i][j], nodes_ID)].getAD_Window_ID();
            //  url = "'WWindow?AD_Window_ID="+AD_Window_ID+"&Target_Window=win_"+AD_Window_ID+"'";
            url = "'WWindow?AD_Window_ID=" + AD_Window_ID;
            Target_Window = "'WWindow" + AD_Window_ID + "'";
            /// url=WebEnv.getBaseDirectory("WWindow")+
            //	"?AD_Window_ID="+AD_Window_ID+"&Target_Window=win_"+AD_Window_ID+"'";
            //	Target_Window = "'win_"+AD_Window_ID+"'";
            System.out.println("WorkFlow if(true)======" + url);

            parameters = url + "'," + Target_Window;
            js_command = "popUp(" + parameters + ");submit()";
            activeNodeImage = createWorkflowImage("mWorkFlow_", imageMap[i][j], js_command, true);

            grid.addElement(activeNodeImage);
            grid.addElement(new br());
            grid.addElement("" + imageMap[i][j]);
            grid.addElement(new br());
            grid.addElement(
                "<font color=blue>"
                    + nodes[getIndex(imageMap[i][j], nodes_ID)].getName()
                    + "</font>");
          } // active node
          else {
            // Create image
            AD_Window_ID = nodes[getIndex(imageMap[i][j], nodes_ID)].getAD_Window_ID();
            // url = "'WWindow?AD_Window_ID="+AD_Window_ID+"&Target_Window=win_"+AD_Window_ID+"'";
            url = "'WWindow?AD_Window_ID=" + AD_Window_ID;

            // url=WebEnv.getBaseDirectory("WWindow")+"?AD_Window_ID="+AD_Window_ID+"&Target_Window=win_"+AD_Window_ID+"'";
            Target_Window = "'WWindow" + AD_Window_ID + "'";

            System.out.println("WorkFlow else======" + url);
            parameters = url + "'," + Target_Window;
            js_command = "popUp(" + parameters + ");submit()";
            normalNodeImage = createWorkflowImage("mWorkFlow_", imageMap[i][j], js_command, false);

            grid.addElement(normalNodeImage);
            grid.addElement(new br());
            grid.addElement("" + imageMap[i][j]);
            grid.addElement(new br());
            grid.addElement(nodes[getIndex(imageMap[i][j], nodes_ID)].getName());
          } // inactive node
        }
        aRow.addElement(grid);
      } // process every gird

      imageTable.addElement(aRow);
    } // every row

    return imageTable;
  } // printWorkflow

  /**
   * Print the description for a workflow or a node.
   *
   * @param activeNode
   * @param wf
   * @param nodes
   * @param nodes_ID
   * @return table
   */
  private table printDescription(
      int activeNode, MWorkflow wf, MWFNode[] nodes, ArrayList nodes_ID) {
    // create new table
    table desTable = new table();

    String WFName = "";
    String WFDescription = "";

    // not started yet
    if (activeNode < 0) {
      WFName = wf.getName();
      WFDescription = wf.getHelp();
    }

    // started
    else {
      WFName = nodes[getIndex(activeNode, nodes_ID)].getName();
      WFDescription = nodes[getIndex(activeNode, nodes_ID)].getHelp();
    }

    // add info to the desciption table
    tr aRow = new tr();
    td aGrid = new td();
    aGrid.addElement(new h6(WFName));
    aGrid.addElement(new br());
    aGrid.addElement(WFDescription);
    desTable.addElement(aRow.addElement(aGrid));

    return desTable;
  } // printDescription

  /**
   * Find the index at which the WFNode ID is positioned.
   *
   * @param node_ID
   * @param nodes_ID
   * @return int
   */
  private int getIndex(int node_ID, ArrayList nodes_ID) {

    int index = 0;

    for (int i = 0; i < nodes_ID.size(); i++) {
      int element_ID = ((Integer) nodes_ID.get(i)).intValue();
      if (element_ID == node_ID) index = i;
    } // for

    return index;
  } // getIndex

  /**
   * Print the control panel.
   *
   * @param activeNode
   * @param wf
   * @param nodes
   * @param nodes_ID
   * @return form
   */
  private form printControlPanel(
      int activeNode, MWorkflow wf, MWFNode[] nodes, ArrayList nodes_ID) {
    // create a new form
    form myForm = new form(FORM_ACTION, form.METHOD_POST, form.ENC_DEFAULT);
    myForm.addElement(new input("hidden", M_Command, ""));
    myForm.addElement(new input("hidden", J_Command, ""));
    myForm.setTarget(TARGET_WINDOW);
    myForm.setName(FORM_NAME);

    // test fist or last node

    boolean isFirst = wf.isFirst(activeNode, Env.getContextAsInt(ctx, "#AD_Client_ID"));
    boolean isLast = wf.isLast(activeNode, Env.getContextAsInt(ctx, "#AD_Client_ID"));

    // get AD_Window_ID for the first and last node
    int First_Window_ID = wf.getFirstNode().getAD_Window_ID();
    int Last_Window_ID = nodes[nodes.length - 1].getAD_Window_ID();

    int Back_Window_ID = 0;
    int Next_Window_ID = 0;
    int index = 0;

    // WUtil.debug(""+activeNode,"activeNode");
    if (!isFirst) {
      index = activeNode >= 0 ? getIndex(activeNode, nodes_ID) - 1 : 0;
      // WUtil.debug(""+index,"index");
      Back_Window_ID = nodes[index].getAD_Window_ID();
    }
    if (!isLast) {
      index = activeNode >= 0 ? getIndex(activeNode, nodes_ID) + 1 : 0;
      Next_Window_ID = nodes[index].getAD_Window_ID();
    }
    boolean enableFirst = true;
    boolean enableBack = true;
    boolean enableNext = true;
    boolean enableLast = true;

    if (isFirst) {
      enableBack = false;
      enableFirst = false;
    }
    if (isLast) {
      enableNext = false;
      enableLast = false;
    }

    td firstImage = new td();
    td backImage = new td();
    td nextImage = new td();
    td lastImage = new td();

    // first
    String url = "'WWindow?AD_Window_ID=" + First_Window_ID + "'";
    // String
    // url=WebEnv.getBaseDirectory("WWindow")+"?AD_Window_ID="+First_Window_ID+"&Target_Window=win_"+First_Window_ID+"'";
    String Target_Window = "'WWindow" + First_Window_ID + "'";
    String parameters = url + "," + Target_Window;
    String js_command = "popUp(" + parameters + ");submit()";
    firstImage.addElement(createControlButtonImage("Start", js_command, enableFirst));
    // back
    url = "'WWindow?AD_Window_ID=" + Back_Window_ID + "'";
    //
    // url=WebEnv.getBaseDirectory("WWindow")+"?AD_Window_ID="+Back_Window_ID+"&Target_Window=win_"+Back_Window_ID+"'";
    Target_Window = "'WWindow" + Back_Window_ID + "'";
    parameters = url + "," + Target_Window;
    js_command = "popUp(" + parameters + ");submit()";
    backImage.addElement(createControlButtonImage("Back", js_command, enableBack));

    // next
    url = "'WWindow?AD_Window_ID=" + Next_Window_ID + "'";
    // url=WebEnv.getBaseDirectory("WWindow")+"?AD_Window_ID="+Next_Window_ID+"&Target_Window=win_"+Next_Window_ID+"'";
    Target_Window = "'WWindow" + Next_Window_ID + "'";
    parameters = url + "," + Target_Window;
    js_command = "popUp(" + parameters + ");submit()";
    nextImage.addElement(createControlButtonImage("Next", js_command, enableNext));

    // last
    url = "'WWindow?AD_Window_ID=" + Last_Window_ID + "'";
    // url=WebEnv.getBaseDirectory("WWindow")+"?AD_Window_ID="+Last_Window_ID+"&Target_Window=win_"+Last_Window_ID+"'";
    Target_Window = "'WWindow" + Last_Window_ID + "'";
    parameters = url + "," + Target_Window;
    js_command = "popUp(" + parameters + ");submit()";
    lastImage.addElement(createControlButtonImage("End", js_command, enableLast));

    tr aRow = new tr();
    aRow.addElement(firstImage);
    aRow.addElement(backImage);
    aRow.addElement(nextImage);
    aRow.addElement(lastImage);

    // add the table to the form
    myForm.addElement(new table().addElement(aRow));

    return myForm;
  } // printControlPanel

  /**
   * Create Image with name, id of button_name and set M_Command onClick
   *
   * @param name Name of the Image used also for Name24.gif
   * @param js_command Java script command, null results in 'submit();', an empty string disables
   *     OnClick
   * @param enabled Enable the immage button, if not uses the "D" image
   * @return Image
   */
  private static img createControlButtonImage(String name, String js_command, boolean enabled) {
    StringBuffer imgName = new StringBuffer("wf" + name);

    if (!enabled) imgName.append("D");

    imgName.append("24.gif");
    //
    img img = new img(MobileEnv.getImageDirectory(imgName.toString()), name);
    if (enabled) img.setAlt(Msg.getMsg(AD_Language, name)); //  Translate ToolTip

    img.setID("imgButton"); //  css

    // append js command only to enabled image
    if (js_command != null && js_command.length() > 0 && enabled) {
      img.setOnClick(
          "document." + FORM_NAME + "." + M_Command + ".value='" + name + "';" + js_command);
    }
    //
    return img;
  } //  createImage

  /**
   * Create Image with name, id of button_name and set M_Command onClick
   *
   * @param name Name of the Image used also for Name24.gif
   * @param js_command Java script command, null results in 'submit();', an empty string disables
   *     OnClick
   * @param enabled Enable the immage button, if not uses the "D" image
   * @return Image
   */
  private static img createWorkflowImage(
      String name, int activeNode, String js_command, boolean pressed) {
    StringBuffer imgName = new StringBuffer(name);
    imgName.append("WF");

    imgName.append(".gif");
    //
    img img = new img(MobileEnv.getImageDirectory(imgName.toString()), name);

    if (!(imgName.toString()).startsWith("Spacer") && !(imgName.toString()).startsWith("Arrow")) {
      if (!pressed) img.setID("imgButton"); //  css
      else img.setID("imgButtonPressed");
    }

    // append js command only to enabled image
    if (js_command != null && js_command.length() > 0 && activeNode != 0) {
      String js_command_front =
          "document." + FORM_NAME + "." + J_Command + ".value='" + activeNode + "'; ";
      js_command_front = js_command_front + "document." + FORM_NAME + ".submit();";
      img.setOnClick(js_command_front + js_command);
    }
    //
    return img;
  } //  createImage

  /**
   * Print the entire layout .
   *
   * @param activeNode
   * @param wf
   * @param nodes
   * @param nodes_ID
   * @param imageMap
   * @return WReportEngine
   */
  private MobileDoc createLayout(
      MobileDoc doc,
      MWorkflow wf,
      int activeNode,
      MWFNode[] nodes,
      ArrayList nodes_ID,
      int[][] imageMap) {
    body b = doc.getBody();

    b.addElement(printWorkflow(activeNode, wf, nodes, nodes_ID, imageMap));
    b.addElement(new hr());
    b.addElement(printDescription(activeNode, wf, nodes, nodes_ID));
    b.addElement(new br());
    b.addElement(printControlPanel(activeNode, wf, nodes, nodes_ID));

    return doc;
  } // createLayout

  /**
   * Load workflw and initialize the session attributes.
   *
   * @param ctx
   * @param AD_Workflow_ID
   * @param sess
   */
  private void loadWorkflow(Properties ctx, int AD_Workflow_ID, HttpSession sess) {

    MWorkflow wf = new MWorkflow(ctx, AD_Workflow_ID, null);
    // get the MWFNode in order
    MWFNode[] nodes = wf.getNodes(true, Env.getContextAsInt(ctx, "#AD_Client_ID"));
    MWFNode wfn = null;
    ArrayList nodes_ID = new ArrayList();
    for (int i = 0; i < nodes.length; i++) {
      wfn = nodes[i];
      nodes_ID.add(new Integer(wfn.getAD_WF_Node_ID()));
    } // for
    int imageMap[][] = generateImageMap(nodes_ID);
    // printMap(imageMap);
    // set session attribtes
    sess.setAttribute(WORKFLOW, wf);
    sess.setAttribute(NODES, nodes);
    sess.setAttribute(NODES_ID, nodes_ID);
    sess.setAttribute(IMAGE_MAP, imageMap);
    sess.setAttribute(ACTIVE_NODE, new Integer(-999));
  } // loadWorkflow

  /**
   * Execute the M_Command and update the .
   *
   * @param m_command
   * @param wf
   * @param activeNode
   * @param nodes
   * @param nodes_ID
   * @param sess
   */
  private void executeCommand(
      String m_command,
      int j_command,
      MWorkflow wf,
      int activeNode,
      MWFNode[] nodes,
      ArrayList nodes_ID,
      HttpSession sess) {
    if (j_command != 0) {
      sess.setAttribute(ACTIVE_NODE, new Integer(j_command));
      return;
    }

    debug(m_command, "m_command in executeCommand");
    // check first or last node
    boolean isFirst = wf.isFirst(activeNode, Env.getContextAsInt(ctx, "#AD_Client_ID"));
    boolean isLast = wf.isLast(activeNode, Env.getContextAsInt(ctx, "#AD_Client_ID"));

    boolean notReady = false;
    int updatedActiveNode = activeNode;

    if (activeNode < 0) notReady = true;

    if (notReady) {
      updatedActiveNode = ((Integer) nodes_ID.get(0)).intValue();

    } else {
      if (m_command.equals(NEXT)) {
        if (notReady) updatedActiveNode = ((Integer) nodes_ID.get(0)).intValue();
        else updatedActiveNode = wf.getNext(activeNode, Env.getContextAsInt(ctx, "#AD_Client_ID"));
      } // next
      if (m_command.equals(BACK)) {
        if (notReady) updatedActiveNode = ((Integer) nodes_ID.get(0)).intValue();
        else
          updatedActiveNode = wf.getPrevious(activeNode, Env.getContextAsInt(ctx, "#AD_Client_ID"));
      } // back
      if (m_command.equals(FIRST)) updatedActiveNode = ((Integer) nodes_ID.get(0)).intValue();

      if (m_command.equals(LAST))
        updatedActiveNode = wf.getLast(0, Env.getContextAsInt(ctx, "#AD_Client_ID"));
    } // ready

    // update
    sess.setAttribute(ACTIVE_NODE, new Integer(updatedActiveNode));
  } // executeCommand

  /**
   * Retrieve the AD_Workflow_ID from database using AD_Menu_ID.
   *
   * @param AD_Menu_ID
   * @return int
   */
  private int getAD_Workflow_ID(int AD_Menu_ID) {

    int AD_Workflow_ID = 0;
    String sql = "SELECT AD_Workflow_ID FROM AD_Menu " + "WHERE AD_Menu_ID=? AND Action='F'";
    try {
      PreparedStatement pstmt = DB.prepareStatement(sql);
      pstmt.setInt(1, AD_Menu_ID);
      ResultSet rs = pstmt.executeQuery();
      while (rs.next()) AD_Workflow_ID = rs.getInt(1);
      rs.close();
      pstmt.close();
    } catch (SQLException e) {

      e.printStackTrace();
    }
    return AD_Workflow_ID;
  } // getAD_Workflow_ID

  /**
   * Prepare Page. - Set Header
   *
   * @param loginInfo
   * @return WReportEngine page
   */
  private MobileDoc preparePage(String loginInfo) {
    MobileDoc doc = MobileDoc.create("Workflow");
    head header = doc.getHead();
    body b = doc.getBody();
    //  add window.js & .css
    header.addElement(new script("", MobileEnv.getBaseDirectory("/js/window.js")));
    header.addElement(
        new link().setRel("stylesheet").setHref(MobileEnv.getBaseDirectory("/css/window.css")));
    //
    //
    String title = "Workflow" + " - " + loginInfo;
    b.addElement(new script("top.document.title='" + title + "';"));
    return doc;
  } //  preparePage

  /**
   * Debugger. - Display the name and value set
   *
   * @param variable
   * @param name
   * @return WReportEngine page
   */
  private void debug(Object variable, String name) {
    if (variable != null) {
      System.out.println("*************" + name + "=" + variable);
    } else System.out.println("*************" + name + " is null");
  } // debug

  private void printMap(int[][] map) {
    final int ROW = map.length;
    final int COL = map[0].length;

    for (int row = 0; row < ROW; row++) {
      for (int col = 0; col < COL; col++) {
        System.out.print(" " + map[row][col] + " ");
      }
      System.out.println(" ");
    }
  } // printMap
} //  WWorkflow