<commit_before>/*
 * UniTime 3.2 (University Timetabling Application)
 * Copyright (C) 2008 - 2010, 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.File;
import java.text.SimpleDateFormat;
import java.util.Enumeration;
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.unitime.commons.Debug;
import org.unitime.commons.web.Web;
import org.unitime.commons.web.WebTable;
import org.unitime.timetable.ApplicationProperties;
import org.unitime.timetable.form.AssignmentHistoryForm;
import org.unitime.timetable.solver.SolverProxy;
import org.unitime.timetable.solver.WebSolver;
import org.unitime.timetable.solver.TimetableSolver.AssignmentRecord;
import org.unitime.timetable.solver.TimetableSolver.RecordedAssignment;
import org.unitime.timetable.solver.interactive.ClassAssignmentDetails;
import org.unitime.timetable.solver.interactive.Suggestion;
import org.unitime.timetable.solver.interactive.SuggestionsModel;
import org.unitime.timetable.util.Constants;
import org.unitime.timetable.webutil.PdfWebTable;


/** 
 * @author <NAME>
 */
public class AssignmentHistoryAction extends Action {
	private static SimpleDateFormat sDF = new SimpleDateFormat("MM/dd hh:mma");

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

        // Check Access
        if (!Web.isLoggedIn( request.getSession() )) {
            throw new Exception ("Access Denied.");
        }

        String op = (myForm.getOp()!=null?myForm.getOp():request.getParameter("op"));
        
        SuggestionsModel model = (SuggestionsModel)request.getSession().getAttribute("Suggestions.model");
        if (model==null) {
        	model = new SuggestionsModel();
        	model.load(request.getSession());
        	request.getSession().setAttribute("Suggestions.model", model);
        }
        
        if ("Apply".equals(op) || "Export PDF".equals(op)) {
        	myForm.save(model);
        	model.save(request.getSession());
        }
        if ("Refresh".equals(op)) {
        	myForm.reset(mapping, request);
        }
        
        myForm.load(model);
        
        SolverProxy solver = WebSolver.getSolver(request.getSession());
        if (solver!=null) {
        	String historyTable = getHistoryTable(model.getSimpleMode(),request,"History",solver.getAssignmentRecords());
            if (historyTable!=null) {
            	request.setAttribute("AssignmentHistory.table",historyTable);
            	request.setAttribute("AssignmentHistory.table.colspan",new Integer(model.getSimpleMode()?7:17));
            } else
            	request.setAttribute("AssignmentHistory.message","No assignment history available at the moment."); 
        } else {
    		request.setAttribute("AssignmentHistory.message","No timetable is loaded. However, you can load one <a href=\"listSolutions.do\">here</a>.");
        }
		
        if ("Export PDF".equals(op)) {
        	File f = exportPdf(model.getSimpleMode(),request,"History",solver.getAssignmentRecords());
        	if (f!=null)
        		request.setAttribute(Constants.REQUEST_OPEN_URL, "temp/"+f.getName());
        		//response.sendRedirect("temp/"+f.getName());
        }

        return mapping.findForward("showAssignmentHistory");
	}
	
    public String getHistoryTable(boolean simple, HttpServletRequest request, String name, Vector history) {
    	if (history==null || history.isEmpty()) return null;
		WebTable.setOrder(request.getSession(),"assignmentHistory.ord",request.getParameter("ord"),1);
        WebTable webTable =
        	(simple?
       			new WebTable( 7,
       	        	name, "assignmentHistory.do?ord=%%",
       				new String[] {"Time", "Score", "Class", "Date", "Time", "Room", "Students"},
       				new String[] {"left", "left", "left", "left", "left", "left", "left"},
       				null )
        	:	new WebTable( 17,
        			name, "assignmentHistory.do?ord=%%",
        			new String[] {"Time", "Score", "Class", "Date", "Time", "Room", "Conf","Std","Tm","Rm","Gr","Ins","Usl","Big","Dept","Subp","Pert"},
        			new String[] {"left", "left", "left", "left", "left", "left","right","right","right","right","right","right","right","right","right","right","right"},
        			null ));
        webTable.setRowStyle("white-space:nowrap");
        try {
        	int idx = 0;
        	boolean hasBefore = false;
        	for (Enumeration e=history.elements();e.hasMoreElements();idx++) {
        		AssignmentRecord record = (AssignmentRecord)e.nextElement();
        		StringBuffer classes = new StringBuffer("<table colspan='0' rowspan='0' border='0'>");
        	    StringBuffer rooms = new StringBuffer("<table colspan='0' rowspan='0' border='0'>");
        	    StringBuffer times = new StringBuffer("<table colspan='0' rowspan='0' border='0'>");
        	    StringBuffer roomsSort = new StringBuffer();
        	    StringBuffer timesSort = new StringBuffer();
        	    StringBuffer dates = new StringBuffer("<table colspan='0' rowspan='0' border='0'>");
        	    StringBuffer datesSort = new StringBuffer();
        	    boolean first = true;
        	    for (Enumeration f=record.getAssignments().elements();f.hasMoreElements();) {
        	    	RecordedAssignment assignment = (RecordedAssignment)f.nextElement();
        	    	if (assignment.getBefore()!=null)
        	    		hasBefore=true;
        	    	ClassAssignmentDetails before = (assignment.getBefore()==null?null:assignment.getBefore().getDetails(request.getSession(),false));
        	    	ClassAssignmentDetails after = (assignment.getAfter()==null?null:assignment.getAfter().getDetails(request.getSession(),false));
        	    	if (!first) {
        	    		roomsSort.append(":");
        	    		timesSort.append(":");
        	    	}
        	    	classes.append("<tr valign='top' height='25'><td nowrap>");
        	        rooms.append("<tr valign='top' height='25'><td nowrap>");
        	        times.append("<tr valign='top' height='25'><td nowrap>");
        	        dates.append("<tr valign='top' height='25'><td nowrap>");
        	        classes.append((before==null?after.getClazz().toHtml(true,true):before.getClazz().toHtml(true,true)));
        	        times.append(ClassAssignmentDetails.dispTime2((before==null?null:before.getAssignedTime()),(after==null?null:after.getAssignedTime())));
        	        for (int i=0;i<(before==null?after.getAssignedRoom().length:before.getAssignedRoom().length);i++) {
        	        	if (i>0) rooms.append(", ");
        	        	rooms.append(ClassAssignmentDetails.dispRoom2((before==null?null:before.getAssignedRoom()[i]),(after==null?null:after.getAssignedRoom()[i])));
        	        }
        	        dates.append(before==null?after.getDaysHtml():before.getDaysHtml());
        	        timesSort.append(before==null?after.getTimeName():before.getTimeName());
        	        roomsSort.append(before==null?after.getRoomName():before.getRoomName());
        	        datesSort.append(before==null?after.getDaysName():before.getDaysName());
        	        classes.append("</td></tr>");<commit_msg>Assignment History  - avoid NullPointerException when a changed class disappears after reload of input data<commit_after>/*
 * UniTime 3.2 (University Timetabling Application)
 * Copyright (C) 2008 - 2010, 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.File;
import java.text.SimpleDateFormat;
import java.util.Enumeration;
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.unitime.commons.Debug;
import org.unitime.commons.web.Web;
import org.unitime.commons.web.WebTable;
import org.unitime.timetable.ApplicationProperties;
import org.unitime.timetable.form.AssignmentHistoryForm;
import org.unitime.timetable.solver.SolverProxy;
import org.unitime.timetable.solver.WebSolver;
import org.unitime.timetable.solver.TimetableSolver.AssignmentRecord;
import org.unitime.timetable.solver.TimetableSolver.RecordedAssignment;
import org.unitime.timetable.solver.interactive.ClassAssignmentDetails;
import org.unitime.timetable.solver.interactive.Suggestion;
import org.unitime.timetable.solver.interactive.SuggestionsModel;
import org.unitime.timetable.util.Constants;
import org.unitime.timetable.webutil.PdfWebTable;


/** 
 * @author <NAME>
 */
public class AssignmentHistoryAction extends Action {
	private static SimpleDateFormat sDF = new SimpleDateFormat("MM/dd hh:mma");

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

        // Check Access
        if (!Web.isLoggedIn( request.getSession() )) {
            throw new Exception ("Access Denied.");
        }

        String op = (myForm.getOp()!=null?myForm.getOp():request.getParameter("op"));
        
        SuggestionsModel model = (SuggestionsModel)request.getSession().getAttribute("Suggestions.model");
        if (model==null) {
        	model = new SuggestionsModel();
        	model.load(request.getSession());
        	request.getSession().setAttribute("Suggestions.model", model);
        }
        
        if ("Apply".equals(op) || "Export PDF".equals(op)) {
        	myForm.save(model);
        	model.save(request.getSession());
        }
        if ("Refresh".equals(op)) {
        	myForm.reset(mapping, request);
        }
        
        myForm.load(model);
        
        SolverProxy solver = WebSolver.getSolver(request.getSession());
        if (solver!=null) {
        	String historyTable = getHistoryTable(model.getSimpleMode(),request,"History",solver.getAssignmentRecords());
            if (historyTable!=null) {
            	request.setAttribute("AssignmentHistory.table",historyTable);
            	request.setAttribute("AssignmentHistory.table.colspan",new Integer(model.getSimpleMode()?7:17));
            } else
            	request.setAttribute("AssignmentHistory.message","No assignment history available at the moment."); 
        } else {
    		request.setAttribute("AssignmentHistory.message","No timetable is loaded. However, you can load one <a href=\"listSolutions.do\">here</a>.");
        }
		
        if ("Export PDF".equals(op)) {
        	File f = exportPdf(model.getSimpleMode(),request,"History",solver.getAssignmentRecords());
        	if (f!=null)
        		request.setAttribute(Constants.REQUEST_OPEN_URL, "temp/"+f.getName());
        		//response.sendRedirect("temp/"+f.getName());
        }

        return mapping.findForward("showAssignmentHistory");
	}
	
    public String getHistoryTable(boolean simple, HttpServletRequest request, String name, Vector history) {
    	if (history==null || history.isEmpty()) return null;
		WebTable.setOrder(request.getSession(),"assignmentHistory.ord",request.getParameter("ord"),1);
        WebTable webTable =
        	(simple?
       			new WebTable( 7,
       	        	name, "assignmentHistory.do?ord=%%",
       				new String[] {"Time", "Score", "Class", "Date", "Time", "Room", "Students"},
       				new String[] {"left", "left", "left", "left", "left", "left", "left"},
       				null )
        	:	new WebTable( 17,
        			name, "assignmentHistory.do?ord=%%",
        			new String[] {"Time", "Score", "Class", "Date", "Time", "Room", "Conf","Std","Tm","Rm","Gr","Ins","Usl","Big","Dept","Subp","Pert"},
        			new String[] {"left", "left", "left", "left", "left", "left","right","right","right","right","right","right","right","right","right","right","right"},
        			null ));
        webTable.setRowStyle("white-space:nowrap");
        try {
        	int idx = 0;
        	boolean hasBefore = false;
        	for (Enumeration e=history.elements();e.hasMoreElements();idx++) {
        		AssignmentRecord record = (AssignmentRecord)e.nextElement();
        		StringBuffer classes = new StringBuffer("<table colspan='0' rowspan='0' border='0'>");
        	    StringBuffer rooms = new StringBuffer("<table colspan='0' rowspan='0' border='0'>");
        	    StringBuffer times = new StringBuffer("<table colspan='0' rowspan='0' border='0'>");
        	    StringBuffer roomsSort = new StringBuffer();
        	    StringBuffer timesSort = new StringBuffer();
        	    StringBuffer dates = new StringBuffer("<table colspan='0' rowspan='0' border='0'>");
        	    StringBuffer datesSort = new StringBuffer();
        	    boolean first = true;
        	    for (Enumeration f=record.getAssignments().elements();f.hasMoreElements();) {
        	    	RecordedAssignment assignment = (RecordedAssignment)f.nextElement();
        	    	if (assignment.getBefore()!=null)
        	    		hasBefore=true;
        	    	ClassAssignmentDetails before = (assignment.getBefore()==null?null:assignment.getBefore().getDetails(request.getSession(),false));
        	    	ClassAssignmentDetails after = (assignment.getAfter()==null?null:assignment.getAfter().getDetails(request.getSession(),false));
        	    	if (before == null && after == null) continue;
        	    	if (!first) {
        	    		roomsSort.append(":");
        	    		timesSort.append(":");
        	    	}
        	    	classes.append("<tr valign='top' height='25'><td nowrap>");
        	        rooms.append("<tr valign='top' height='25'><td nowrap>");
        	        times.append("<tr valign='top' height='25'><td nowrap>");
        	        dates.append("<tr valign='top' height='25'><td nowrap>");
        	        classes.append((before==null?after.getClazz().toHtml(true,true):before.getClazz().toHtml(true,true)));
        	        times.append(ClassAssignmentDetails.dispTime2((before==null?null:before.getAssignedTime()),(after==null?null:after.getAssignedTime())));
        	        for (int i=0;i<(before==null?after.getAssignedRoom().length:before.getAssignedRoom().length);i++) {
        	        	if (i>0) rooms.append(", ");
        	        	rooms.append(ClassAssignmentDetails.dispRoom2((before==null?null:before.getAssignedRoom()[i]),(after==null?null:after.getAssignedRoom()[i])));
        	        }
        	        dates.append(before==null?after.getDaysHtml():before.getDaysHtml());
        	        timesSort.append(before==null?after.getTimeName():before.getTimeName());
        	        roomsSort.append(before==null?after.getRoomName():before.getRoomName());
        	        datesSort.append(before==null?after.getDaysName():before.getDaysName());
        	        classes.append("</td></tr>");
{'fraction_non_alphanumeric': 0.14125628445090557, 'fraction_numerical': 0.005209279786782967, 'mean_word_length': 3.3608029582673007, 'pattern_counts': {'":': 4, '<': 41, '<?xml version=': 0, '>': 41, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3956935', 'n_tokens_mistral': 4815, 'n_tokens_neox': 4707, 'n_words': 924}