org.unitime.timetable.action.ExamDistributionPrefsAction.java Source code

Java tutorial

Introduction

Here is the source code for org.unitime.timetable.action.ExamDistributionPrefsAction.java

Source

/*
 * UniTime 3.2 - 3.5 (University Timetabling Application)
 * Copyright (C) 2008 - 2013, UniTime LLC, and individual contributors
 * as indicated by the @authors tag.
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
 * 
*/
package org.unitime.timetable.action;

import java.io.OutputStream;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;
import java.util.Vector;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
import org.apache.struts.util.MessageResources;
import org.hibernate.Transaction;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.unitime.commons.Debug;
import org.unitime.timetable.defaults.SessionAttribute;
import org.unitime.timetable.form.DistributionPrefsForm;
import org.unitime.timetable.form.ExamDistributionPrefsForm;
import org.unitime.timetable.model.ChangeLog;
import org.unitime.timetable.model.CourseOffering;
import org.unitime.timetable.model.DistributionObject;
import org.unitime.timetable.model.DistributionPref;
import org.unitime.timetable.model.DistributionType;
import org.unitime.timetable.model.Exam;
import org.unitime.timetable.model.ExamType;
import org.unitime.timetable.model.Preference;
import org.unitime.timetable.model.PreferenceGroup;
import org.unitime.timetable.model.PreferenceLevel;
import org.unitime.timetable.model.SubjectArea;
import org.unitime.timetable.model.dao.CourseOfferingDAO;
import org.unitime.timetable.model.dao.DistributionPrefDAO;
import org.unitime.timetable.model.dao.DistributionTypeDAO;
import org.unitime.timetable.model.dao.ExamDAO;
import org.unitime.timetable.model.dao.SessionDAO;
import org.unitime.timetable.security.SessionContext;
import org.unitime.timetable.security.rights.Right;
import org.unitime.timetable.util.Constants;
import org.unitime.timetable.util.ExportUtils;
import org.unitime.timetable.util.LookupTables;
import org.unitime.timetable.webutil.BackTracker;
import org.unitime.timetable.webutil.ExamDistributionPrefsTableBuilder;

/**
 * @author Tomas Muller
 */
@Service("/examDistributionPrefs")
public class ExamDistributionPrefsAction extends Action {

    @Autowired
    SessionContext sessionContext;

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

        sessionContext.checkPermission(Right.ExaminationDistributionPreferences);

        MessageResources rsc = getResources(request);
        ActionMessages errors = new ActionMessages();
        ExamDistributionPrefsForm frm = (ExamDistributionPrefsForm) form;

        String deleteId = request.getParameter("deleteId");
        String deleteType = request.getParameter("deleteType");
        String distPrefId = request.getParameter("dp");
        String reloadCause = request.getParameter("reloadCause");
        String reloadId = request.getParameter("reloadId");

        String op = frm.getOp();
        if (op == null || op.trim().length() == 0) {
            op = "view";
            frm.setOp(op);
        }

        if (reloadCause != null && reloadCause.length() > 0)
            op = "reload";

        // Cancel - Display blank form
        if (op.equals(rsc.getMessage("button.cancel"))) {
            frm.reset(mapping, request);
            if (BackTracker.doBack(request, response))
                return null;
            op = "view"; //in case no back is available
        }

        // Set lookup tables lists
        //LookupTables.setupPrefLevels(request);    // Preference Levels
        LookupTables.setupExamDistribTypes(request, sessionContext); // Distribution Types
        LookupTables.setupExamTypes(request, sessionContext.getUser().getCurrentAcademicSessionId()); // Exam Types

        // Add / Update distribution pref
        if (op.equals(rsc.getMessage("button.save")) || op.equals(rsc.getMessage("button.update"))) {
            Debug.debug("Saving distribution pref ...");
            errors = frm.validate(mapping, request);
            if (errors.size() == 0) {
                try {
                    doAddOrUpdate(request, frm);
                    if (frm.getDistPrefId() != null) {
                        request.setAttribute("backType", "PreferenceGroup");
                        request.setAttribute("backId", frm.getDistPrefId());
                    }
                    frm.reset(mapping, request);
                    if (BackTracker.doBack(request, response))
                        return null;
                    op = "view"; //in case no back is available
                } catch (Exception e) {
                    Debug.error(e);
                    errors.add("classes", new ActionMessage("errors.generic", e.getMessage()));
                    saveErrors(request, errors);
                }
            } else
                saveErrors(request, errors);
        }

        // Delete distribution object / pref
        if (op.equals(rsc.getMessage("button.delete"))) {
            if (deleteType.equals("distObject")) {
                frm.deleteExam(Integer.parseInt(deleteId));
            }
            if (deleteType.equals("distPref")) {
                distPrefId = frm.getDistPrefId();
                doDelete(request, distPrefId);
                frm.reset(mapping, request);
                if (BackTracker.doBack(request, response))
                    return null;
                op = "view"; //in case no back is available
            }
        }

        // Add new class - redirect from SchedulingSubpartEdit / ClassEdit
        if (op.equals(rsc.getMessage("button.addDistPref"))) {
            Debug.debug("Adding new Class via redirect ...");
            frm.setDistType(Preference.BLANK_PREF_VALUE);
            if (request.getAttribute("subjectAreaId") != null) {
                frm.setSubjectArea(0, Long.valueOf(request.getAttribute("subjectAreaId").toString()));
            }
            if (request.getAttribute("courseOffrId") != null) {
                CourseOffering course = new CourseOfferingDAO()
                        .get(Long.valueOf(request.getAttribute("courseOffrId").toString()));
                frm.setSubjectArea(0, course.getSubjectArea().getUniqueId());
                frm.setCourseNbr(0, course.getUniqueId());
            }
            if (request.getAttribute("examId") != null) {
                Exam exam = new ExamDAO().get(Long.valueOf(request.getAttribute("examId").toString()));
                frm.setExam(0, exam.getUniqueId());
                frm.setSubjectArea(0, exam.firstSubjectArea().getUniqueId());
                frm.setCourseNbr(0, exam.firstCourseOffering().getUniqueId());
                frm.setExamType(exam.getExamType().getUniqueId());
            }
            frm.getSubjectArea().add(new Long(-1));
            frm.getCourseNbr().add(new Long(-1));
            frm.getExam().add(new Long(-1));
        }

        // Add new class
        if (op.equals(rsc.getMessage("button.addExam"))) {
            Debug.debug("Adding new Class ...");
            frm.getSubjectArea().add(new Long(-1));
            frm.getCourseNbr().add(new Long(-1));
            frm.getExam().add(new Long(-1));
        }

        if (op.equals(rsc.getMessage("button.search")) || op.equals(rsc.getMessage("button.exportPDF"))) {
            String subjectAreaId = frm.getFilterSubjectAreaId();
            String courseNbr = frm.getFilterCourseNbr();
            if (subjectAreaId != null && subjectAreaId.length() > 0)
                sessionContext.setAttribute(SessionAttribute.OfferingsSubjectArea, subjectAreaId);
            else
                sessionContext.removeAttribute(SessionAttribute.OfferingsSubjectArea);
            if (courseNbr != null && courseNbr.length() > 0)
                sessionContext.setAttribute(SessionAttribute.OfferingsCourseNumber, courseNbr);
            else
                sessionContext.removeAttribute(SessionAttribute.OfferingsCourseNumber);
            sessionContext.setAttribute(SessionAttribute.ExamType, frm.getExamType());
            if (op.equals(rsc.getMessage("button.exportPDF")))
                op = "export";
            else
                op = "view";
        }

        // Load Distribution Pref
        if (op != null && (op.equals("view") || op.equals("export")) && distPrefId != null
                && distPrefId.trim().length() > 0) {
            Debug.debug("Loading dist pref - " + distPrefId);

            frm.reset(mapping, request);

            doLoad(frm, distPrefId);
        }

        // Reload 
        if (op != null && op.equals("reload")) {
            // Move Distribution object up one level
            if (reloadCause != null && reloadCause.equals("moveUp")) {
                int index = Integer.parseInt(reloadId);
                Debug.debug("moving up ... " + reloadId);
                frm.swapExams(index, index - 1);
            }

            // Move Distribution object down one level
            if (reloadCause != null && reloadCause.equals("moveDown")) {
                int index = Integer.parseInt(reloadId);
                Debug.debug("moving down ... " + reloadId);
                frm.swapExams(index, index + 1);
            }
        }

        if (frm.getDistType() != null && !frm.getDistType().equals(Preference.BLANK_PREF_VALUE)) {
            Vector prefs = new Vector();
            DistributionType dist = (new DistributionTypeDAO().get(new Long(frm.getDistType())));
            frm.setDescription(dist.getDescr());
            boolean containsPref = false;
            for (PreferenceLevel pref : PreferenceLevel.getPreferenceLevelList()) {
                if (dist.isAllowed(pref)) {
                    prefs.addElement(pref);
                    if (frm.getPrefLevel() != null && !frm.getPrefLevel().equals(Preference.BLANK_PREF_VALUE)
                            && pref.getPrefId().equals(new Integer(frm.getPrefLevel())))
                        containsPref = true;
                }
            }
            if (!containsPref)
                frm.setPrefLevel(Preference.BLANK_PREF_VALUE);
            if (prefs.size() == 1)
                frm.setPrefLevel(((PreferenceLevel) prefs.firstElement()).getPrefId().toString());
            request.setAttribute(PreferenceLevel.PREF_LEVEL_ATTR_NAME, prefs);
        } else {
            request.setAttribute(PreferenceLevel.PREF_LEVEL_ATTR_NAME, new Vector(0));
            frm.setDescription("");
        }

        if ("export".equals(op) && (frm.getDistPrefId() == null || frm.getDistPrefId().length() == 0)) {
            OutputStream out = ExportUtils.getPdfOutputStream(response, "distpref");
            new ExamDistributionPrefsTableBuilder().getDistPrefsTableAsPdf(out, request, sessionContext,
                    (Constants.ALL_OPTION_VALUE.equals(frm.getFilterSubjectAreaId())
                            || frm.getFilterSubjectAreaId().isEmpty() ? null
                                    : Long.valueOf(frm.getFilterSubjectAreaId())),
                    frm.getFilterCourseNbr(), frm.getExamType());
            out.flush();
            out.close();
            return null;
        }

        request.setAttribute(DistributionPrefsForm.LIST_SIZE_ATTR, "" + (frm.getSubjectArea().size() - 1));

        if (sessionContext.getAttribute(SessionAttribute.ExamType) != null)
            frm.setExamType((Long) sessionContext.getAttribute(SessionAttribute.ExamType));
        if (frm.getExamType() == null) {
            TreeSet<ExamType> types = ExamType.findAllUsed(sessionContext.getUser().getCurrentAcademicSessionId());
            if (!types.isEmpty())
                frm.setExamType(types.first().getUniqueId());
        }

        frm.setFilterSubjectAreas(SubjectArea.getUserSubjectAreas(sessionContext.getUser(), false));
        if (frm.getFilterSubjectAreas().size() == 1) {
            SubjectArea firstSubjectArea = (SubjectArea) frm.getFilterSubjectAreas().iterator().next();
            frm.setFilterSubjectAreaId(firstSubjectArea.getUniqueId().toString());
        }

        if ("view".equals(op) && (frm.getDistPrefId() == null || frm.getDistPrefId().length() == 0)) {
            String subject = (String) sessionContext.getAttribute(SessionAttribute.OfferingsSubjectArea);
            if (subject != null && subject.indexOf(',') >= 0)
                subject = subject.substring(0, subject.indexOf(','));
            frm.setFilterSubjectAreaId(subject);
            frm.setFilterCourseNbr((String) sessionContext.getAttribute(SessionAttribute.OfferingsCourseNumber));

            ExamDistributionPrefsTableBuilder tbl = new ExamDistributionPrefsTableBuilder();
            if (frm.getFilterSubjectAreaId() == null) {
                if (sessionContext.getUser().getCurrentAuthority().hasRight(Right.DepartmentIndependent))
                    frm.setFilterSubjectAreaId(Constants.BLANK_OPTION_VALUE);
                else
                    frm.setFilterSubjectAreaId(Constants.ALL_OPTION_VALUE);
            }

            if (frm.getFilterSubjectAreaId() != null && frm.getFilterSubjectAreaId().length() > 0) {
                String html = tbl.getDistPrefsTable(request, sessionContext,
                        (Constants.ALL_OPTION_VALUE.equals(frm.getFilterSubjectAreaId()) ? null
                                : Long.valueOf(frm.getFilterSubjectAreaId())),
                        frm.getFilterCourseNbr(), frm.getExamType());
                if (html != null)
                    request.setAttribute(DistributionPref.DIST_PREF_REQUEST_ATTR, html);
            } else {
                request.setAttribute(DistributionPref.DIST_PREF_REQUEST_ATTR, "");
            }
            BackTracker.markForBack(request, "examDistributionPrefs.do", "Exam Distribution Prefs", true, true);
            return mapping.findForward("list");
        }

        return mapping
                .findForward(frm.getDistPrefId() == null || frm.getDistPrefId().length() == 0 ? "add" : "edit");
    }

    /**
     * Loads the form with the data for the distribution pref selected
     * @param frm
     * @param distPrefId
     */
    private void doLoad(ExamDistributionPrefsForm frm, String distPrefId) {

        sessionContext.checkPermission(distPrefId, "DistributionPref",
                Right.ExaminationDistributionPreferenceDetail);

        // Get distribution pref info
        DistributionPref dp = new DistributionPrefDAO().get(new Long(distPrefId));
        frm.setDistType(dp.getDistributionType().getUniqueId().toString());
        frm.setDescription(dp.getDistributionType().getDescr());
        frm.setPrefLevel(dp.getPrefLevel().getPrefId().toString());
        frm.setDistPrefId(distPrefId);

        for (Iterator i = new TreeSet(dp.getDistributionObjects()).iterator(); i.hasNext();) {
            DistributionObject distObj = (DistributionObject) i.next();
            Exam exam = (Exam) distObj.getPrefGroup();
            frm.getSubjectArea().add(exam.firstSubjectArea().getUniqueId());
            frm.getCourseNbr().add(exam.firstCourseOffering().getUniqueId());
            frm.getExam().add(exam.getUniqueId());
        }

    }

    /**
     * Add new distribution pref
     * @param httpSession
     * @param frm
     */
    private void doAddOrUpdate(HttpServletRequest request, ExamDistributionPrefsForm frm) throws Exception {

        String distPrefId = frm.getDistPrefId();

        if (distPrefId != null && !distPrefId.isEmpty()) {
            sessionContext.checkPermission(distPrefId, "DistributionPref",
                    Right.ExaminationDistributionPreferenceEdit);
        } else {
            sessionContext.checkPermission(Right.ExaminationDistributionPreferenceAdd);
        }

        // Create distribution preference
        DistributionPref dp = null;
        DistributionPrefDAO dpDao = new DistributionPrefDAO();
        Transaction tx = null;
        org.hibernate.Session hibSession = dpDao.getSession();
        HashSet relatedExams = new HashSet();

        try {
            tx = hibSession.beginTransaction();

            if (distPrefId != null && !distPrefId.isEmpty()) {
                dp = dpDao.get(Long.valueOf(distPrefId), hibSession);
                Set s = dp.getDistributionObjects();
                for (Iterator i = s.iterator(); i.hasNext();) {
                    DistributionObject dObj = (DistributionObject) i.next();
                    PreferenceGroup pg = dObj.getPrefGroup();
                    relatedExams.add(pg);
                    pg.getDistributionObjects().remove(dObj);
                    hibSession.saveOrUpdate(pg);
                }
                s.clear();
                dp.setDistributionObjects(s);
            } else
                dp = new DistributionPref();

            dp.setDistributionType(new DistributionTypeDAO().get(new Long(frm.getDistType()), hibSession));
            dp.setGrouping(-1);
            dp.setPrefLevel(PreferenceLevel.getPreferenceLevel(Integer.parseInt(frm.getPrefLevel())));

            dp.setOwner(SessionDAO.getInstance().get(sessionContext.getUser().getCurrentAcademicSessionId()));

            HashSet addedExams = new HashSet();
            int idx = 0;
            for (Iterator i = frm.getExam().iterator(); i.hasNext();) {
                Long examId = (Long) i.next();
                if (examId < 0)
                    continue;

                Exam exam = new ExamDAO().get(examId, hibSession);
                if (exam == null)
                    continue;
                if (!addedExams.add(exam))
                    continue;
                relatedExams.add(exam);

                DistributionObject dObj = new DistributionObject();
                dObj.setPrefGroup(exam);
                dObj.setDistributionPref(dp);
                dObj.setSequenceNumber(new Integer(++idx));
                exam.getDistributionObjects().add(dObj);
                dp.addTodistributionObjects(dObj);
            }

            // Save
            hibSession.saveOrUpdate(dp);

            for (Iterator i = relatedExams.iterator(); i.hasNext();) {
                Exam exam = (Exam) i.next();
                ChangeLog
                        .addChange(hibSession, sessionContext, exam, ChangeLog.Source.DIST_PREF_EDIT,
                                (distPrefId != null && distPrefId.trim().length() > 0 ? ChangeLog.Operation.UPDATE
                                        : ChangeLog.Operation.CREATE),
                                exam.firstSubjectArea(), exam.firstDepartment());
            }

            tx.commit();
            hibSession.flush();
            hibSession.refresh(dp.getOwner());
            frm.setDistPrefId(dp.getUniqueId().toString());
        } catch (Exception e) {
            if (tx != null)
                tx.rollback();
            hibSession.clear();
            throw e;
        }
    }

    /**
     * Delete distribution pref
     * @param distPrefId
     */
    private void doDelete(HttpServletRequest request, String distPrefId) {
        Transaction tx = null;

        sessionContext.checkPermission(distPrefId, "DistributionPref",
                Right.ExaminationDistributionPreferenceDelete);

        try {

            DistributionPrefDAO dpDao = new DistributionPrefDAO();
            org.hibernate.Session hibSession = dpDao.getSession();
            tx = hibSession.getTransaction();
            if (tx == null || !tx.isActive())
                tx = hibSession.beginTransaction();

            HashSet relatedExams = new HashSet();
            DistributionPref dp = dpDao.get(new Long(distPrefId));
            PreferenceGroup owner = (PreferenceGroup) dp.getOwner();
            owner.getPreferences().remove(dp);
            for (Iterator i = dp.getDistributionObjects().iterator(); i.hasNext();) {
                DistributionObject dObj = (DistributionObject) i.next();
                PreferenceGroup pg = dObj.getPrefGroup();
                relatedExams.add(pg);
                pg.getDistributionObjects().remove(dObj);
                hibSession.saveOrUpdate(pg);
            }

            hibSession.delete(dp);
            hibSession.saveOrUpdate(owner);

            for (Iterator i = relatedExams.iterator(); i.hasNext();) {
                Exam exam = (Exam) i.next();
                ChangeLog.addChange(hibSession, sessionContext, exam, ChangeLog.Source.DIST_PREF_EDIT,
                        ChangeLog.Operation.DELETE, exam.firstSubjectArea(), exam.firstDepartment());
            }

            if (tx != null && tx.isActive())
                tx.commit();

            hibSession.flush();
            hibSession.refresh(owner);
        } catch (Exception e) {
            Debug.error(e);
            if (tx != null && tx.isActive())
                tx.rollback();
        }
    }
}