public ActionForward execute(
      ActionMapping mapping,
      ActionForm form,
      HttpServletRequest request,
      HttpServletResponse response)
      throws Exception {
    ExamReportForm myForm = (ExamReportForm) form;

    // Check Access
    sessionContext.checkPermission(Right.NotAssignedExaminations);

    String op = (myForm.getOp() != null ? myForm.getOp() : request.getParameter("op"));

    if ("Export CSV".equals(op) || "Export PDF".equals(op) || "Apply".equals(op)) {
      myForm.save(sessionContext);
    } else if ("Refresh".equals(op)) {
      myForm.reset(mapping, request);
    }

    myForm.load(sessionContext);

    Session session =
        SessionDAO.getInstance().get(sessionContext.getUser().getCurrentAcademicSessionId());
    RoomAvailability.setAvailabilityWarning(request, session, myForm.getExamType(), true, false);

    ExamSolverProxy solver = WebSolver.getExamSolver(request.getSession());
    Collection<ExamInfo> unassignedExams = null;
    if (myForm.getSubjectArea() != null
        && myForm.getSubjectArea() != 0
        && myForm.getExamType() != null) {
      if (solver != null && solver.getExamTypeId().equals(myForm.getExamType()))
        unassignedExams = solver.getUnassignedExams(myForm.getSubjectArea());
      else
        unassignedExams =
            Exam.findUnassignedExams(
                sessionContext.getUser().getCurrentAcademicSessionId(),
                myForm.getSubjectArea(),
                myForm.getExamType());
    }

    WebTable.setOrder(sessionContext, "unassignedExams.ord", request.getParameter("ord"), 1);

    WebTable table = getTable(true, false, myForm, unassignedExams);

    if ("Export PDF".equals(op) && table != null) {
      ExportUtils.exportPDF(
          getTable(false, true, myForm, unassignedExams),
          WebTable.getOrder(sessionContext, "unassignedExams.ord"),
          response,
          "unassigned");
      return null;
    }

    if ("Export CSV".equals(op) && table != null) {
      ExportUtils.exportCSV(
          getTable(false, false, myForm, unassignedExams),
          WebTable.getOrder(sessionContext, "unassignedExams.ord"),
          response,
          "unassigned");
      return null;
    }

    if (table != null)
      myForm.setTable(
          table.printTable(WebTable.getOrder(sessionContext, "unassignedExams.ord")),
          9,
          unassignedExams.size());

    if (request.getParameter("backId") != null)
      request.setAttribute("hash", request.getParameter("backId"));

    LookupTables.setupExamTypes(
        request, sessionContext.getUser(), DepartmentStatusType.Status.ExamTimetable);

    return mapping.findForward("showReport");
  }
  /**
   * Build a html table with the list representing distribution prefs
   *
   * @param distPrefs
   * @param ordCol
   * @param editable
   * @return
   */
  public String toHtmlTable(
      HttpServletRequest request, SessionContext context, Collection distPrefs, String title)
      throws Exception {

    String backId =
        ("PreferenceGroup".equals(request.getParameter("backType"))
            ? request.getParameter("backId")
            : null);

    WebTable.setOrder(context, "examDistPrefsTable.ord", request.getParameter("order"), 4);

    WebTable tbl =
        new WebTable(
            3,
            title,
            "examDistributionPrefs.do?order=%%",
            new String[] {" Type ", " Exam ", " Class/Course "},
            new String[] {"left", "left", "left"},
            new boolean[] {true, true, true});

    int nrPrefs = 0;

    for (Iterator i1 = distPrefs.iterator(); i1.hasNext(); ) {
      DistributionPref dp = (DistributionPref) i1.next();

      if (!context.hasPermission(dp, Right.ExaminationDistributionPreferenceDetail)) continue;

      boolean prefEditable = context.hasPermission(dp, Right.ExaminationDistributionPreferenceEdit);

      nrPrefs++;

      String examStr = "";
      String objStr = "";

      for (Iterator i2 = dp.getOrderedSetOfDistributionObjects().iterator(); i2.hasNext(); ) {
        DistributionObject dO = (DistributionObject) i2.next();
        Exam exam = (Exam) dO.getPrefGroup();
        examStr += dO.preferenceText();
        for (Iterator i3 = exam.getOwners().iterator(); i3.hasNext(); ) {
          ExamOwner owner = (ExamOwner) i3.next();
          objStr += owner.getLabel();
          if (i3.hasNext()) {
            examStr += "<BR>";
            objStr += "<BR>";
          }
        }
        if (i2.hasNext()) {
          examStr += "<BR>";
          objStr += "<BR>";
        }
      }

      String distType = dp.getDistributionType().getLabel();
      String prefLevel = dp.getPrefLevel().getPrefName();
      String prefColor = dp.getPrefLevel().prefcolor();
      if (PreferenceLevel.sNeutral.equals(dp.getPrefLevel().getPrefProlog())) prefColor = "gray";
      String onClick = null;

      boolean gray = false;

      if (prefEditable) {
        onClick =
            "onClick=\"document.location='examDistributionPrefs.do"
                + "?dp="
                + dp.getUniqueId().toString()
                + "&op=view'\"";
      } // else gray = true;

      boolean back = dp.getUniqueId().toString().equals(backId);

      tbl.addLine(
          onClick,
          new String[] {
            (back ? "<A name=\"back\"</A>" : "")
                + (gray
                    ? "<span style='color:gray;'>"
                    : "<span style='color:"
                        + prefColor
                        + ";font-weight:bold;' title='"
                        + prefLevel
                        + " "
                        + distType
                        + "'>")
                + distType
                + "</span>",
            (gray ? "<span style='color:gray;'>" : "") + examStr + (gray ? "</span>" : ""),
            (gray ? "<span style='color:gray;'>" : "") + objStr + (gray ? "</span>" : "")
          },
          new Comparable[] {distType, examStr, objStr});
    }

    if (nrPrefs == 0) tbl.addLine(null, new String[] {"No preferences found", "", ""}, null);

    return tbl.printTable(WebTable.getOrder(context, "examDistPrefsTable.ord"));
  }
  public void toPdfTable(
      OutputStream out,
      HttpServletRequest request,
      SessionContext context,
      Collection distPrefs,
      Long examTypeId)
      throws Exception {
    WebTable.setOrder(context, "examDistPrefsTable.ord", request.getParameter("order"), 4);

    PdfWebTable tbl =
        new PdfWebTable(
            4,
            ExamTypeDAO.getInstance().get(examTypeId).getLabel()
                + " Examination Distribution Preferences",
            null,
            new String[] {" Preference ", " Type ", " Exam ", " Class/Course "},
            new String[] {"left", "left", "left", "left"},
            new boolean[] {true, true, true, true});

    int nrPrefs = 0;

    for (Iterator i1 = distPrefs.iterator(); i1.hasNext(); ) {
      DistributionPref dp = (DistributionPref) i1.next();

      if (!context.hasPermission(dp, Right.ExaminationDistributionPreferenceDetail)) continue;

      nrPrefs++;

      String examStr = "";
      String objStr = "";

      for (Iterator i2 = dp.getOrderedSetOfDistributionObjects().iterator(); i2.hasNext(); ) {
        DistributionObject dO = (DistributionObject) i2.next();
        Exam exam = (Exam) dO.getPrefGroup();
        examStr += dO.preferenceText();
        for (Iterator i3 = exam.getOwners().iterator(); i3.hasNext(); ) {
          ExamOwner owner = (ExamOwner) i3.next();
          objStr += owner.getLabel();
          if (i3.hasNext()) {
            examStr += "\n";
            objStr += "\n";
          }
        }
        if (i2.hasNext()) {
          examStr += "\n";
          objStr += "\n";
        }
      }

      String distType = dp.getDistributionType().getLabel();
      String prefLevel = dp.getPrefLevel().getPrefName();

      tbl.addLine(
          null,
          new String[] {prefLevel, distType, examStr, objStr},
          new Comparable[] {null, distType, examStr, objStr});
    }

    if (nrPrefs == 0) tbl.addLine(null, new String[] {"No preferences found", "", "", ""}, null);

    int ord = WebTable.getOrder(context, "examDistPrefsTable.ord");
    ord = (ord > 0 ? 1 : -1) * (1 + Math.abs(ord));

    PdfPTable table = tbl.printPdfTable(ord);

    float width = tbl.getWidth();

    Document doc = new Document(new Rectangle(60f + width, 60f + 1.30f * width), 30, 30, 30, 30);

    PdfWriter iWriter = PdfWriter.getInstance(doc, out);
    iWriter.setPageEvent(new PdfEventHandler());
    doc.open();

    if (tbl.getName() != null) doc.add(new Paragraph(tbl.getName(), PdfFont.getBigFont(true)));

    doc.add(table);

    doc.close();
  }
  private void getSolverParameterDefs(HttpServletRequest request, Long uniqueId) throws Exception {
    Transaction tx = null;

    WebTable.setOrder(sessionContext, "solverParamDef.ord", request.getParameter("ord"), 1);

    StringBuffer tables = new StringBuffer();
    try {
      SolverParameterGroupDAO dao = new SolverParameterGroupDAO();
      org.hibernate.Session hibSession = dao.getSession();
      if (hibSession.getTransaction() == null || !hibSession.getTransaction().isActive())
        tx = hibSession.beginTransaction();

      List groups = dao.findAll(hibSession, Order.asc("order"));

      if (groups.isEmpty()) {
        // Create web table instance
        WebTable webTable =
            new WebTable(
                5,
                "Solver Parameters",
                "solverParamDef.do?ord=%%",
                new String[] {"Order", "Name", "Description", "Type", "Default"},
                new String[] {"left", "left", "left", "left", "left"},
                null);
        webTable.addLine(null, new String[] {"No solver parameter group defined."}, null, null);
        tables.append(webTable.printTable(WebTable.getOrder(sessionContext, "solverParamDef.ord")));
      }

      for (Iterator i = groups.iterator(); i.hasNext(); ) {
        SolverParameterGroup group = (SolverParameterGroup) i.next();
        if (tables.length() > 0) tables.append("<TR><TD colspan='5'>&nbsp;</TD></TR>");
        List parameters =
            hibSession
                .createCriteria(SolverParameterDef.class)
                .add(Restrictions.eq("group", group))
                .addOrder(Order.asc("order"))
                .list();
        if (parameters.isEmpty()) continue;
        String name =
            "<table class='BottomBorder' width='100%'><tr><td width='100%' nowrap>"
                + "<a name='"
                + group.getName()
                + "'>"
                + "<DIV class='WelcomeRowHeadNoLine'>"
                + group.getDescription()
                + "</DIV>"
                + "</a>"
                + "</td><td style='padding-bottom: 3px' nowrap>"
                + "<input type=\"submit\" name=\"op\" accesskey=\"A\" value=\"Add Solver Parameter\" title=\"Create New Solver Parameter (Alt+A)\""
                + "onclick=\"solverParamDefForm.group.value='"
                + group.getName()
                + "';\">"
                + "</td></tr></table>";
        WebTable webTable =
            new WebTable(
                5,
                name,
                "solverParamDef.do?ord=%%",
                new String[] {"Order", "Name", "Description", "Type", "Default"},
                new String[] {"left", "left", "left", "left", "left"},
                null);
        if (parameters.isEmpty()) {
          webTable.addLine(
              null,
              new String[] {"No parameter defined in group <i>" + group.getDescription() + "</i>."},
              null,
              null);
        }
        for (Iterator j = parameters.iterator(); j.hasNext(); ) {
          SolverParameterDef def = (SolverParameterDef) j.next();
          String ops = "";
          if (def.getOrder().intValue() > 0) {
            ops +=
                "<img src='images/arrow_up.png' border='0' align='absmiddle' title='Move Up' "
                    + "onclick=\"solverParamDefForm.op2.value='Move Up';solverParamDefForm.uniqueId.value='"
                    + def.getUniqueId()
                    + "';solverParamDefForm.submit(); event.cancelBubble=true;\">";
          } else ops += "<img src='images/blank.png' border='0' align='absmiddle'>";
          if (j.hasNext()) {
            ops +=
                "<img src='images/arrow_down.png' border='0' align='absmiddle' title='Move Down' "
                    + "onclick=\"solverParamDefForm.op2.value='Move Down';solverParamDefForm.uniqueId.value='"
                    + def.getUniqueId()
                    + "';solverParamDefForm.submit(); event.cancelBubble=true;\">";
          } else ops += "<img src='images/blank.png' border='0' align='absmiddle'>";
          String onClick =
              "onClick=\"document.location='solverParamDef.do?op=Edit&id="
                  + def.getUniqueId()
                  + "';\"";
          webTable.addLine(
              onClick,
              new String[] {
                ops,
                (def.isVisible() ? "" : "<font color='gray'>")
                    + "<a name='"
                    + def.getUniqueId()
                    + "'>"
                    + def.getName()
                    + "</a>"
                    + (def.isVisible() ? "" : "</font>"),
                (def.isVisible() ? "" : "<font color='gray'>")
                    + def.getDescription()
                    + (def.isVisible() ? "" : "</font>"),
                (def.isVisible() ? "" : "<font color='gray'>")
                    + def.getType().replaceAll(",", ", ")
                    + (def.isVisible() ? "" : "</font>"),
                (def.isVisible() ? "" : "<font color='gray'>")
                    + (def.getDefault() == null
                        ? ""
                        : def.getDefault().length() > 50
                            ? "<span title='"
                                + def.getDefault()
                                + "'>"
                                + def.getDefault().substring(0, 50)
                                + "...</span>"
                            : def.getDefault())
                    + (def.isVisible() ? "" : "</font>")
              },
              new Comparable[] {
                def.getOrder(), def.getName(), def.getDescription(), def.getType(), def.getDefault()
              });
          if (def.getUniqueId().equals(uniqueId))
            request.setAttribute("SolverParameterDef.last", new Integer(parameters.size() - 1));
        }
        tables.append(webTable.printTable(WebTable.getOrder(sessionContext, "solverParamDef.ord")));
      }

      if (!groups.isEmpty()) {
        tables.append(
            "\n<TR><TD colspan='5'><DIV class='WelcomeRowHeadBlank'>&nbsp;</DIV></TD></TR>");
        tables.append(
            "\n<TR><TD colspan='5' align='right'>"
                + "<input type=\"submit\" name=\"op\" accesskey=\"A\" value=\"Add Solver Parameter\" title=\"Create New Solver Parameter (Alt+A)\">"
                + "</TD></TR>");
      }

      if (tx != null) tx.commit();
    } catch (Exception e) {
      if (tx != null) tx.rollback();
      throw e;
    }
    request.setAttribute("SolverParameterDef.table", tables.toString());
  }