public SeatInfo() {
    File file = new File(".", "data");
    file.mkdir();
    File f = new File(file, "SeatInfo.txt");

    try {
      raf = new RandomAccessFile(f, "rw");

      if (raf.length() == 0) {
        raf.setLength(31 * 4 * FLIGHT_PER_DAY);
        for (int i = 0; i < 31 * FLIGHT_PER_DAY; i++) raf.writeInt(0);
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
 private File getEventLogFile(File userMailDir, int id) {
   File logDir = new File(userMailDir, "logs");
   logDir.mkdir();
   return new File(logDir, id + ".log");
 }
  /**
   * Add a student to a course if not already so. If student not registered in the student table
   * yet, the user are required to enter the student information so that the student can be added.
   * Throws InvalidDBRequestException if user name belongs to an instructor, student already
   * registered in the course, student information differs than the one in the database, student
   * information not available when needed, error occured during insertion, or if other exception
   * occured Throws FileFailureException if fail to create folder for the student.
   *
   * @param username student's user name
   * @param courseID course id (course number + instructor name)
   * @param lastname student's last name
   * @param firstname student's first name
   * @param initPass initial password for the student
   * @throws InvalidDBRequestException
   */
  public void addStudent(
      String courseID, String username, String lastName, String firstName, String initPass)
      throws InvalidDBRequestException, FileFailureException {
    try {
      Class.forName(GaigsServer.DBDRIVER);
      db =
          DriverManager.getConnection(GaigsServer.DBURL, GaigsServer.DBLOGIN, GaigsServer.DBPASSWD);

      Statement stmt = db.createStatement();
      ResultSet rs;

      int count = 0;

      // check if user name belongs to an instructor
      rs = stmt.executeQuery("select login from instructor where login = '******'");
      if (rs.next()) throw new InvalidDBRequestException("User name is reserved by an instructor");

      // check if student in the database or not
      rs =
          stmt.executeQuery(
              "select last_name, first_name from student where login = '******'");
      if (rs.next()) {
        // check if user name belongs to another student
        if (!lastName.equals("")
            && (!lastName.equalsIgnoreCase(rs.getString(1).trim())
                || !firstName.equalsIgnoreCase(rs.getString(2).trim())))
          throw new InvalidDBRequestException(
              "User name is used by: " + rs.getString(2).trim() + " " + rs.getString(1).trim());
      } else {
        // check if student's information is given
        if (lastName.equals(""))
          throw new InvalidDBRequestException(
              "Student is not registered in the database. Please enter the student's name");

        // insert student into hte database
        count =
            stmt.executeUpdate(
                "insert into student values ('"
                    + username
                    + "', '"
                    + lastName
                    + "', '"
                    + firstName
                    + "', '"
                    + initPass
                    + "', now())");
        if (count != 1) throw new InvalidDBRequestException("Error occured during insertion!");

        // create student's folder
        File newStudentDir = new File("./StudentQuizzes/" + username);
        if (!(newStudentDir.mkdir())) {
          System.err.println("Error in creating new folder for student: " + username);
          throw new FileFailureException("huh");
        }
      }

      // check if student is registered in the course
      rs =
          stmt.executeQuery(
              "select * from courseRoster where course_id = '"
                  + courseID
                  + "' and user_login = '******'");
      if (rs.next())
        throw new InvalidDBRequestException("Student is already registered to the course");

      // register student to the course
      count =
          stmt.executeUpdate(
              "insert into courseRoster values ('" + courseID + "', '" + username + "')");
      if (count != 1) throw new InvalidDBRequestException("Error occured during insertion!");

      rs.close();
      stmt.close();
      db.close();
    } catch (SQLException e) {
      System.err.println("Invalid SQL in addstudent: " + e.getMessage());
      throw new InvalidDBRequestException("???");
    } catch (ClassNotFoundException e) {
      System.err.println("Driver Not Loaded");
      throw new InvalidDBRequestException("Internal Server Error");
    }
  }
  public boolean parserCpYieldTxt(File txtFile) throws Exception {
    FileInputStream fIn = null;
    String fileNameUid = "";
    try {
      Calendar calendar = Calendar.getInstance();
      SimpleDateFormat df2 = new SimpleDateFormat("yyyyMM");

      // Using Find Target "|=124" or ",=44" Count
      DateFormat df = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH);

      logger.debug(
          "File "
              + txtFile.getAbsolutePath()
              + "  "
              + txtFile.getName()
              + "  "
              + new MimetypesFileTypeMap().getContentType(txtFile));

      // 1.0 讀入檔案, 建立資料流
      fIn = new FileInputStream(txtFile);
      // FileInputStream fIn2 = new FileInputStream(csvFile);
      InputStreamReader isr = null;
      BufferedReader br = null;
      isr = new InputStreamReader(fIn, "UTF-8");
      br = new BufferedReader(isr);

      // byte[] byteArray = new byte[new Long(csvFile.length()).intValue()];
      // 讀入File Data Byte.....
      // fIn2.read(byteArray);
      logger.debug(txtFile.getName() + "<--讀入資料檔...成功");
      // Using get sign  "\n" 抓行數...

      // 1.1 讀入行數資料, 略過行數
      int l = -1;
      List<String> lineDataList = new ArrayList<String>();
      for (int i = 0; i <= l; i++) {
        br.readLine();
      }
      while (br.ready()) {
        String line = br.readLine();
        line = null != line ? line : "";
        // logger.debug(line);
        if (!line.trim().equals("")) {
          lineDataList.add(line);
        }
      }

      // 1.2 確認有資料開使處理
      if (lineDataList != null) {
        CpYieldParserDao cpYieldParserDao = new CpYieldParserDao();

        CpYieldLotTo cpYieldLotTo = new CpYieldLotTo();

        String cpYieldUuid = UUID.randomUUID().toString().toUpperCase();
        logger.debug("lineDataList.size() " + lineDataList.size());

        fileNameUid =
            FilenameUtils.getBaseName(txtFile.getName())
                + "_"
                + cpYieldUuid
                + "."
                + FilenameUtils.getExtension(txtFile.getName());

        File bkFolder =
            new File(fileOutUrl + File.separator + df2.format(calendar.getTime()).toString());

        bkFolder.mkdir();

        File bkFile = new File(bkFolder.getPath().toString() + File.separator + fileNameUid);
        // 1.2.1 處理每行資料
        String tmpWaferID = lineDataList.get(1);
        String arrayWafer[] = tmpWaferID.split("=")[1].trim().split("-");

        // logger.debug("arrayWafer[] " + arrayWafer.length);

        // 1.3 Prepare Data
        String cpLot = arrayWafer[0].trim();
        String waferId = arrayWafer[1].trim();
        String machineId = arrayWafer[2].trim();
        Integer cpTestTimes = cpYieldParserDao.getMaxCpTestTimes(cpLot, waferId);

        String xMaxCoor = lineDataList.get(2).split("=")[1].trim();
        String yMaxCoor = lineDataList.get(3).split("=")[1].trim();
        String flat = lineDataList.get(4).split("=")[1].trim();

        logger.debug("xMaxCoor " + xMaxCoor);
        logger.debug("yMaxCoor " + yMaxCoor);
        logger.debug("flat " + flat);

        // 1.3 Find Bin Data
        int sb = 0, eb = 0;
        for (int i = 0; i < lineDataList.size(); i++) {
          if (lineDataList.get(i).indexOf("Wafer Bin Summary") >= 0) {
            sb = i + 1;
            break;
          }
        }
        for (int i = sb; i < lineDataList.size(); i++) {
          if (lineDataList.get(i).indexOf("bin") < 0) {
            eb = i - 1;
            break;
          }
        }

        logger.debug("sb " + sb);
        logger.debug(lineDataList.get(sb).trim());
        logger.debug("eb " + eb);
        logger.debug(lineDataList.get(eb).trim());
        // 1.3.1 Get Bin Data
        List<CpYieldLotBinTo> cpYieldLotBins = new ArrayList<CpYieldLotBinTo>();
        String cpYieldBinUuid;

        String bin;
        Integer die;
        String percentage;
        String binString;

        for (int j = sb; j <= eb; j++) {
          cpYieldBinUuid = UUID.randomUUID().toString().toUpperCase();
          CpYieldLotBinTo cpYieldLotBinTo = new CpYieldLotBinTo();

          cpYieldLotBinTo.setCpYieldBinUuid(cpYieldBinUuid);
          cpYieldLotBinTo.setCpYieldUuid(cpYieldUuid);

          binString = lineDataList.get(j).trim();
          binString = binString.replaceAll("bin", "").trim();
          // Get Bin
          bin = binString.substring(0, binString.indexOf(" "));
          logger.debug("bin " + bin);
          // Get Die
          bin = binString.substring(0, binString.indexOf(" "));
          binString = binString.replaceAll(bin, "").trim();
          die = Integer.parseInt(binString.substring(0, binString.indexOf(" ")));
          logger.debug("die " + die);
          // Get Percentage
          binString = binString.replaceAll(die.toString(), "").trim();
          percentage = binString.substring(0, binString.length() - 1);
          logger.debug("percentage " + percentage);

          cpYieldLotBinTo.setBin(bin);
          cpYieldLotBinTo.setDie(die);
          cpYieldLotBinTo.setPercentage(percentage);

          cpYieldLotBins.add(cpYieldLotBinTo);
        }

        // 1.4 Die Data
        Integer passDie;
        Integer failDie;
        Integer totelDie;
        for (int i = eb + 1; i < lineDataList.size(); i++) {
          // pass die
          if (lineDataList.get(i).trim().indexOf("pass die") >= 0) {
            passDie = Integer.parseInt(lineDataList.get(i).trim().split(":")[1].trim());
            logger.debug("passDie " + passDie);
            cpYieldLotTo.setPassDie(passDie);
            continue;
          }
          // fail die
          if (lineDataList.get(i).trim().indexOf("fail die") >= 0) {
            failDie = Integer.parseInt(lineDataList.get(i).trim().split(":")[1].trim());
            logger.debug("failDie " + failDie);
            cpYieldLotTo.setFailDie(failDie);
            continue;
          }
          // totel die
          if (lineDataList.get(i).trim().indexOf("totel die") >= 0) {
            totelDie = Integer.parseInt(lineDataList.get(i).trim().split(":")[1].trim());
            logger.debug("totelDie " + totelDie);
            cpYieldLotTo.setTotelDie(totelDie);
            continue;
          }
        }

        // 1.5 Set data in To
        cpYieldLotTo.setCpYieldUuid(cpYieldUuid);
        cpYieldLotTo.setCpTestTimes(cpTestTimes);
        cpYieldLotTo.setCpLot(cpLot);
        cpYieldLotTo.setWaferId(waferId);
        cpYieldLotTo.setMachineId(machineId);
        cpYieldLotTo.setxMaxCoor(xMaxCoor);
        cpYieldLotTo.setyMaxCoor(yMaxCoor);
        cpYieldLotTo.setFlat(flat);

        String fileMimeType = new MimetypesFileTypeMap().getContentType(txtFile);
        cpYieldLotTo.setFileName(
            df2.format(calendar.getTime()).toString() + File.separator + fileNameUid);
        cpYieldLotTo.setFileMimeType(fileMimeType);
        cpYieldLotTo.setFtpFlag("N");

        fIn.close();
        br.close();

        Methods.copyFile(txtFile, bkFile);
        txtFile.delete();
        // 1.6 DataBasse
        // 1.6.1 Insert CP Lot Table
        cpYieldParserDao.insertCpYieldLot(cpYieldLotTo);
        cpYieldParserDao.insertCpYieldLotBin(cpYieldLotBins);
      }

      fIn.close();
      br.close();

      logger.info(txtFile.getName() + " is Parser complete");
      logger.info(fileNameUid + " is Parser complete");

      // logger.debug(tapeList.size());
      logger.info("---------------------------------");
    } catch (Exception e) {
      if (fIn != null) {
        fIn.close();
      }
      logger.info("ERROR MOVE FILE");
      Methods.copyFile(txtFile, new File(fileErrorUrl + "\\" + txtFile.getName()));
      txtFile.delete();

      StackTraceElement[] messages = e.getStackTrace();
      Exception ex = new Exception(txtFile.getName());
      ex.setStackTrace(messages);
      ex.printStackTrace();
      throw ex;
    } finally {
      try {
        if (fIn != null) {
          fIn.close();
        }
      } catch (IOException ie) {
        StackTraceElement[] messages = ie.getStackTrace();
        int length = messages.length;
        String error = "";
        for (int i = 0; i < length; i++) {
          error = error + "toString:" + messages[i].toString() + "\r\n";
        }
        ie.printStackTrace();
        logger.error(error);
        return false;
      }
    }
    return true;
  }
  public static void main(String arg[]) {
    Hashtable ignoreList = new Hashtable();
    Class cl = null;
    Model model = null;
    System.out.println("Synchronizing forms with database...");
    Db.init();

    try {
      DatabaseMetaData meta = Db.getCon().getMetaData();
      String[] types = {"TABLE"};
      ResultSet rs = meta.getTables(null, null, "%", types);

      // read ignore.list
      ignoreList = AutogenerateUtil.readIgnoreList();
      // prepare directory
      File fDir = new File("../../web/WEB-INF/views/crud_form");
      if (!fDir.exists()) fDir.mkdir();
      while (rs.next()) {
        // proper file name generationm
        String className = "";
        String tableName = rs.getString("TABLE_NAME");
        className = StringUtil.toProperClassName(tableName); // space allowed...
        // tableName = tableName.toUpperCase(); //If Oracle that need uppercase tablename. In MySQL
        // in Mac OS X (and probably Linux), it mustbe case sensitive
        // open table
        String sql = "select * from " + tableName;
        PreparedStatement pstmt =
            Db.getCon()
                .prepareStatement(sql, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
        ResultSet resultSet = pstmt.executeQuery();
        ResultSetMetaData metaColumn = resultSet.getMetaData();
        int nColoumn = metaColumn.getColumnCount();

        // get foreign keys,and stored it in hashtable
        ResultSet rsFk = meta.getImportedKeys(Db.getCon().getCatalog(), null, tableName);
        Hashtable hashFk = new Hashtable();
        System.out.println("FK Infos for table " + tableName);
        while (rsFk.next()) {
          String pkTableName = rsFk.getString("PKTABLE_NAME");
          String pkColumnName = rsFk.getString("PKCOLUMN_NAME");
          String fkColumnName = rsFk.getString("FKCOLUMN_NAME");

          int fkSequence = rsFk.getInt("KEY_SEQ");
          System.out.println(
              tableName + "." + fkColumnName + " => " + pkTableName + "." + pkColumnName);
          hashFk.put(fkColumnName, pkColumnName);
          hashFk.put(fkColumnName + "_table", pkTableName);
        }
        rsFk.close();

        // create form page
        System.out.println(
            "Creating form page for "
                + tableName
                + " from table + "
                + application.config.Database.DB
                + "."
                + tableName);
        fDir = new File("../../web/WEB-INF/views/" + tableName);
        if (!fDir.exists()) fDir.mkdir();
        File f = new File("../../web/WEB-INF/views/" + tableName + "/form_" + tableName + ".jsp");
        if (ignoreList.get("form_" + tableName + ".jsp") != null) {
          Logger.getLogger(GenerateForm.class.getName())
              .log(Level.INFO, "Ignoring creation of form_" + tableName + ".jsp");
        } else {
          Writer out = new FileWriter(f);
          out.write(
              "<%@ page contentType=\"text/html; charset=UTF-8\" language=\"java\" import=\"java.sql.*,recite18th.library.Db,application.config.Config,recite18th.library.Pagination\" %>");
          out.write("<%@ taglib uri=\"http://java.sun.com/jsp/jstl/core\" prefix=\"c\" %>\n");
          out.write("<%@ taglib uri=\"http://java.sun.com/jsp/jstl/functions\" prefix=\"fn\" %>\n");

          // create model for this class, use in detecting its PK Field
          cl = Class.forName("application.models." + className + "Model");
          model = (Model) cl.newInstance();

          // iterate all columns
          resultSet.beforeFirst();
          resultSet.next();
          out.write(
              "<table border=\"1\" align=\"center\" cellpadding=\"0\" cellspacing=\"0\" bordercolor=\"#E8EDFF\">\n");
          out.write("<tr>\n");
          out.write("<td>\n");
          out.write(
              "<form action=\"<%=Config.base_url%>index/"
                  + className
                  + "/save\" method=\"post\" enctype=\"multipart/form-data\">\n"); // I hope it's
          // okay to
          // default it to
          // multipart data
          out.write("<table id=\"hor-zebra\" summary=\"Form " + className + "\">\n");
          out.write("<thead>\n");
          out.write("<tr>\n");
          out.write("<th colspan=\"2\" class=\"odd\" scope=\"col\">Form " + className + " </th>\n");
          out.write("</tr>\n");
          out.write("</thead>\n");
          out.write("<tbody>\n");

          for (int i = 1; i <= nColoumn; i++) {
            String columnName = metaColumn.getColumnName(i);
            String dataType = metaColumn.getColumnClassName(i);
            out.write("<tr>\n");

            // if(!columnName.equals(model.getPkFieldName())) // implementing the case of PK not
            // AutoIncrement
            // if(!metaColumn.isAutoIncrement(i))
            // {
            // varying field input for type

            // foreign field, as chooser page view
            if (hashFk.get(columnName)
                != null) // TODO: what if PK is chooser also?? :) CUrrently I add it manually the
            // hidden_*Pk_nama* field
            {
              String fkTableName = hashFk.get(columnName + "_table") + "";
              String fkColumnName = hashFk.get(columnName) + "";
              String fkController = StringUtil.toProperClassName(fkTableName);

              out.write("<td>" + columnName + "</td>\n");
              out.write("<td>\n");
              out.write(
                  "<input name=\""
                      + columnName
                      + "\" type=\"hidden\" id=\""
                      + columnName
                      + "\" value=\"${model."
                      + columnName
                      + "}\"/>\n");
              out.write(
                  "<input name=\"label_"
                      + columnName
                      + "\" readonly=\"true\" type=\"text\" id=\"label_"
                      + columnName
                      + "\" value=\"${model."
                      + columnName
                      + "}\"/>\n"); // TODO : translate I
              out.write(
                  "<a href=\"<%=Config.base_url%>index/"
                      + fkController
                      + "/chooseView?height=220&width=700\" class=\"thickbox\">Pilih</a>");
              out.write("</td>\n");
            } else {

              // regular field input, not foreign key case
              if (!columnName.equals(model.getPkFieldName())) {
                out.write("<td>" + columnName + "</td>\n");
                out.write("<td>\n");

                // ENUM Column, displayed as HTML SELECT. May will only work for mysql only...
                Logger.getLogger(GenerateForm.class.getName())
                    .log(Level.INFO, columnName + " type is " + metaColumn.getColumnType(i));
                if (metaColumn.getColumnType(i) == 1) {
                  String enum_content[][] =
                      Db.getDataSet(
                          "SELECT SUBSTRING(COLUMN_TYPE,6,length(SUBSTRING(COLUMN_TYPE,6))-1) as enum_content "
                              + " FROM information_schema.COLUMNS "
                              + " WHERE TABLE_NAME='"
                              + tableName
                              + "' "
                              + " AND COLUMN_NAME='"
                              + columnName
                              + "'");
                  if (enum_content.length > 0) {
                    // Logger.getLogger(Model.class.getName()).log(Level.INFO, "Enum Content = " +
                    // enum_content[0][0]);
                    String enum_list[] = enum_content[0][0].split(",");
                    out.write("<select name=\"" + columnName + "\" id=\"" + columnName + "\">\n");
                    for (int ienum_list = 0; ienum_list < enum_list.length; ienum_list++)
                      out.write(
                          "\t<option <c:if test=\"${model."
                              + columnName
                              + "=='"
                              + enum_list[ienum_list].substring(
                                  1, enum_list[ienum_list].length() - 1)
                              + "'}\"> selected=\"selected\" </c:if> value=\""
                              + enum_list[ienum_list].substring(
                                  1, enum_list[ienum_list].length() - 1)
                              + "\">"
                              + enum_list[ienum_list].substring(
                                  1, enum_list[ienum_list].length() - 1)
                              + "</option>\n");
                    out.write("</select>\n\n");

                  } else {
                    // no enum content detected.. :)
                    out.write(
                        "<input name=\""
                            + columnName
                            + "\" type=\"text\" id=\""
                            + columnName
                            + "\" value=\"${model."
                            + columnName
                            + "}\"/>\n");
                  }
                } else if (metaColumn.getColumnType(i) == 91) {
                  out.write(
                      "<input name=\""
                          + columnName
                          + "\" type=\"text\" id=\""
                          + columnName
                          + "\" value=\"${model."
                          + columnName
                          + "}\"/>\n");
                  out.write("<script>\n");
                  out.write(
                      " if(!isValidDate($('#"
                          + columnName
                          + "').val())) $('#"
                          + columnName
                          + "').val('1980-1-1');\n"); // TODO: default value
                  out.write("  (function($){\n");

                  out.write("  $('#" + columnName + "').click(function() {\n");
                  out.write("    $('#" + columnName + "').DatePickerShow();\n");
                  out.write("  });\n");

                  out.write("  $('#" + columnName + "').DatePicker({\n");
                  out.write("    format:'Y-m-d',\n");
                  out.write("    date: $('#" + columnName + "').val(),\n");
                  out.write("    current: $('#" + columnName + "').val(),\n");
                  out.write("    starts: 1,\n");
                  out.write("    position: 'r',\n");

                  out.write("    onBeforeShow: function(){\n");
                  out.write(
                      "      $('#"
                          + columnName
                          + "').DatePickerSetDate($('#"
                          + columnName
                          + "').val(), true);\n");
                  out.write("    },\n");

                  out.write("    onChange: function(formated, dates){\n");
                  out.write("      $('#" + columnName + "').DatePickerHide();\n");
                  out.write("      $('#" + columnName + "').val(formated);\n");
                  out.write("    }\n");
                  out.write("  });\n");
                  out.write("  })(jQuery)\n");
                  out.write(" </script>\n");
                } else {
                  out.write(
                      "<input name=\""
                          + columnName
                          + "\" type=\"text\" id=\""
                          + columnName
                          + "\" value=\"${model."
                          + columnName
                          + "}\"/>\n");
                  out.write("${" + columnName + "_error}\n"); // regular input field
                }
              } else { // PK case
                if (metaColumn.isAutoIncrement(i)) {
                  out.write(
                      "<input name=\"hidden_"
                          + columnName
                          + "\" type=\"hidden\" id=\"hidden_"
                          + columnName
                          + "\" value=\"${model."
                          + columnName
                          + "}\"/>\n");
                } else {
                  out.write("<td>" + columnName + "</td>\n");
                  out.write("<td>\n");

                  out.write(
                      "<input name=\""
                          + columnName
                          + "\" type=\"text\" id=\""
                          + columnName
                          + "\" value=\"${model."
                          + columnName
                          + "}\"/>\n");
                  out.write("${" + columnName + "_error}\n");
                  out.write(
                      "<input name=\"hidden_"
                          + columnName
                          + "\" type=\"hidden\" id=\"hidden_"
                          + columnName
                          + "\" value=\"${model."
                          + columnName
                          + "}\"/>\n");
                }
              }
              out.write("</td>\n");
            }
            out.write("</tr>\n");
          }
          out.write("<tr class=\"odd\">\n");
          out.write("<td>&nbsp;</td>\n");
          out.write("<td><input type=\"submit\" name=\"Submit\" value=\"Simpan\">");
          out.write(
              "<input name=\"Button\" type=\"button\" id=\"Submit\" value=\"Batal\" onClick=\"javascript:history.back(-1);\"></td>\n");
          out.write("</tr>\n");
          out.write("</tbody>\n");
          out.write("</table>\n");
          out.write("</form></td>\n");
          out.write("</tr>\n");
          out.write("</table>\n");
          out.flush();
          out.close();
        }

        // create viewPage
        if (ignoreList.get("view_" + tableName + ".jsp") != null) {
          Logger.getLogger(GenerateForm.class.getName())
              .log(Level.INFO, "Ignoring creation of view_" + tableName + ".jsp");
        } else {
          System.out.println("Creating view page " + tableName);

          fDir = new File("../../web/WEB-INF/views/" + tableName);
          if (!fDir.exists()) fDir.mkdir();
          File fView =
              new File("../../web/WEB-INF/views/" + tableName + "/view_" + tableName + ".jsp");
          Writer outView = new FileWriter(fView);
          outView.write(
              "<%@ page contentType=\"text/html; charset=UTF-8\" language=\"java\" import=\"java.sql.*,recite18th.library.Db,application.config.Config,recite18th.library.Pagination\" %>");
          outView.write("<%@ taglib uri=\"http://java.sun.com/jsp/jstl/core\" prefix=\"c\" %>\n");
          outView.write(
              "<%@ taglib uri=\"http://java.sun.com/jsp/jstl/functions\" prefix=\"fn\" %>\n");
          outView.write("<% int pagenum = 0; %>\n");
          // outView.write("<%@ include file=\"/WEB-INF/views/header.jsp\" %>");
          outView.write(
              "<a href=\"<%=Config.base_url%>index/" + className + "/input/-1\">Tambah Data</a>\n");
          outView.write(
              "|| <a href=\"<%=Config.base_url%>index/" + className + "/print\">Cetak</a>\n");
          outView.write("<table width=\"100%\" id=\"rounded-corner\">\n");
          outView.write("<thead>\n");
          // iterate all columns : table header
          outView.write("  <tr>\n");
          outView.write("  <th scope=\"col\" class=\"rounded-company\">No.</th>\n");
          resultSet.beforeFirst();
          resultSet.next();

          // get Primary Key Field Name : often use
          String pkFieldName = "";
          try {
            Class params[] = null;
            Method objMethod = cl.getMethod("getPkFieldName", params);
            pkFieldName = "" + objMethod.invoke(model);
          } catch (Exception ex) {
            Logger.getLogger(Model.class.getName()).log(Level.SEVERE, null, ex);
          }

          // ALL Lower Case
          pkFieldName = pkFieldName.toLowerCase();

          // customize column view page
          for (int i = 1; i <= nColoumn; i++) {
            String columnName =
                metaColumn.getColumnName(i).toLowerCase(); // Caution : ALL LowerCase
            String dataType = metaColumn.getColumnClassName(i);
            String thClass = "rounded-q1";
            String thTitle = StringUtil.toProperFieldTitle(columnName);

            if (TableCustomization.getTable(tableName)
                != null) // there is customization for this table
            {
              if (TableCustomization.getTable(tableName).get(columnName) != null) {
                thTitle = TableCustomization.getTable(tableName).get(columnName) + "";
                outView.write(
                    "  <th scope=\"col\" class=\"" + thClass + "\">" + thTitle + "</th>\n");
              }
            } else { // standard view for this table : hide PK, because mostly is auto increment
              if (!metaColumn.isAutoIncrement(i))
                outView.write(
                    "  <th scope=\"col\" class=\"" + thClass + "\">" + thTitle + "</th>\n");
            }
          }

          outView.write("  <th scope=\"col\" class=\"rounded-q4\">Aksi</th>\n");
          outView.write("  </tr>\n");
          outView.write("</thead>\n");
          outView.write("<tfoot>\n");
          outView.write("  <tr>\n");
          outView.write(
              "    <td colspan=\""
                  + (nColoumn + 1)
                  + "\" class=\"rounded-foot-left\"><%=Pagination.createLinks(pagenum)%></td>\n");
          outView.write("    <td class=\"rounded-foot-right\">&nbsp;</td>\n");
          outView.write("  </tr>\n");
          outView.write("</tfoot>\n");

          outView.write("<tbody>\n");
          outView.write("  <c:forEach items=\"${row}\" var=\"item\" varStatus=\"status\" >\n");
          outView.write("    <tr>\n");
          outView.write("      <td>${status.count}</td>\n");

          // iterate all columns : table data
          resultSet.beforeFirst();
          resultSet.next();
          for (int i = 1; i <= nColoumn; i++) {
            String columnName = metaColumn.getColumnName(i);
            // if(!columnName.equals(pkFieldName)) //TOFIX : currently, PK Field is not shown
            if (TableCustomization.getTable(tableName) != null) {
              if (TableCustomization.getTable(tableName).get(columnName) != null) {
                outView.write("      <td>${item." + columnName + "}</td>\n");
              }
            } else {
              if (!metaColumn.isAutoIncrement(i))
                outView.write("      <td>${item." + columnName + "}</td>\n");
            }
          }

          outView.write("      <td>\n");
          outView.write(
              "         <a href=\"<%=Config.base_url%>index/"
                  + className
                  + "/input/${item."
                  + pkFieldName
                  + "}\">Ubah</a>\n");
          outView.write(
              "         <a href=\"<%=Config.base_url%>index/"
                  + className
                  + "/delete/${item."
                  + pkFieldName
                  + "}\" onClick=\"return confirm('Apakah Anda yakin?');\">Hapus</a>\n");
          outView.write("      </td>\n");

          outView.write("    </tr>\n");
          outView.write("  </c:forEach>\n");
          outView.write("</tbody>\n");
          outView.write("</table>\n");
          // outView.write("<%@ include file=\"/WEB-INF/views/footer.jsp\" %>");
          outView.flush();
          outView.close();
        }
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }