Java tutorial
/* * Licensed to The Apereo Foundation under one or more contributor license * agreements. See the NOTICE file distributed with this work for * additional information regarding copyright ownership. * * The Apereo Foundation licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * limitations under the License. * */ package org.unitime.timetable.model; import java.text.DecimalFormat; import java.util.Calendar; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.Enumeration; import java.util.HashSet; import java.util.Hashtable; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.Queue; import java.util.Set; import java.util.TreeSet; import java.util.Vector; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.cpsolver.coursett.model.Placement; import org.cpsolver.ifs.util.CSVFile; import org.cpsolver.ifs.util.DataProperties; import org.cpsolver.ifs.util.CSVFile.CSVField; import org.hibernate.SessionFactory; import org.hibernate.criterion.Restrictions; import org.unitime.commons.Debug; import org.unitime.commons.Email; import org.unitime.localization.impl.Localization; import org.unitime.timetable.defaults.ApplicationProperty; import org.unitime.timetable.form.ListSolutionsForm.InfoComparator; import org.unitime.timetable.gwt.resources.GwtConstants; import org.unitime.timetable.interfaces.RoomAvailabilityInterface.TimeBlock; import org.unitime.timetable.model.base.BaseSolution; import org.unitime.timetable.model.comparators.ClassComparator; import org.unitime.timetable.model.comparators.DivSecAssignmentComparator; import org.unitime.timetable.model.dao.Class_DAO; import org.unitime.timetable.model.dao.InstructionalOfferingDAO; import org.unitime.timetable.model.dao.SolutionDAO; import org.unitime.timetable.model.dao.SolutionInfoDAO; import org.unitime.timetable.solver.ClassAssignmentProxy; import org.unitime.timetable.solver.ui.AssignmentPreferenceInfo; import org.unitime.timetable.solver.ui.PropertiesInfo; import org.unitime.timetable.solver.ui.TimetableInfo; import org.unitime.timetable.solver.ui.TimetableInfoFileProxy; import org.unitime.timetable.util.Constants; import org.unitime.timetable.util.Formats; /** * @author Tomas Muller, Stephanie Schluttenhofer */ public class Solution extends BaseSolution implements ClassAssignmentProxy { protected static GwtConstants CONSTANTS = Localization.create(GwtConstants.class); private static final long serialVersionUID = 1L; private static Log sLog = LogFactory.getLog(Solution.class); public static DecimalFormat sSufixFormat = new DecimalFormat("000"); public static boolean DEBUG = false; /*[CONSTRUCTOR MARKER BEGIN]*/ public Solution() { super(); } /** * Constructor for primary key */ public Solution(java.lang.Long uniqueId) { super(uniqueId); } /*[CONSTRUCTOR MARKER END]*/ public SolutionInfo getSolutionInfo(String name) throws Exception { if ("GlobalInfo".equals(name)) return getGlobalInfo(); return (SolutionInfo) (new SolutionInfoDAO()).getSession().createQuery( "select si from SolutionInfo si where si.definition.name=:name and si.solution.uniqueId=:solutionId") .setString("name", name).setLong("solutionId", getUniqueId()).uniqueResult(); /* org.hibernate.Session session = (new SolutionInfoDAO()).getSession(); SolverInfoDef def = SolverInfoDef.findByName(session,name); if (def==null) return null; return (SolutionInfo)session.createCriteria(SolutionInfo.class).add(Restrictions.eq("definition",def)).add(Restrictions.eq("solution",this)).setCacheable(true).uniqueResult(); */ } public TimetableInfo getInfo(String name) throws Exception { SolutionInfo sinfo = getSolutionInfo(name); if (sinfo == null) return null; return sinfo.getInfo(); } public void uncommitSolution(org.hibernate.Session hibSession) throws Exception { uncommitSolution(hibSession, null); } public void uncommitSolution(org.hibernate.Session hibSession, String sendNotificationPuid) throws Exception { if (DEBUG) sLog.debug("uncommit[" + getUniqueId() + "," + getOwner().getName() + "] -------------------------------------------------------"); setCommitDate(null); setCommited(Boolean.FALSE); hibSession.update(this); if (ApplicationProperty.ClassAssignmentChangePastMeetings.isTrue()) { deleteObjects(hibSession, "ClassEvent", "select e.uniqueId from Solution s inner join s.assignments a, ClassEvent e where e.clazz=a.clazz and s.uniqueId=:solutionId"); } else { EventContact contact = (sendNotificationPuid == null ? null : EventContact.findByExternalUniqueId(sendNotificationPuid)); if (contact == null && sendNotificationPuid != null) { TimetableManager manager = TimetableManager.findByExternalId(sendNotificationPuid); if (manager != null) { contact = new EventContact(); contact.setFirstName(manager.getFirstName()); contact.setMiddleName(manager.getMiddleName()); contact.setLastName(manager.getLastName()); contact.setExternalUniqueId(manager.getExternalUniqueId()); contact.setEmailAddress(manager.getEmailAddress()); hibSession.save(contact); } } Calendar cal = Calendar.getInstance(Locale.US); cal.set(Calendar.HOUR_OF_DAY, 0); cal.set(Calendar.MINUTE, 0); cal.set(Calendar.SECOND, 0); cal.set(Calendar.MILLISECOND, 0); Date today = cal.getTime(); List<ClassEvent> events = (List<ClassEvent>) hibSession.createQuery( "select e from Solution s inner join s.assignments a, ClassEvent e where e.clazz=a.clazz and s.uniqueId=:solutionId") .setLong("solutionId", getUniqueId()).list(); for (ClassEvent event : events) { for (Iterator<Meeting> i = event.getMeetings().iterator(); i.hasNext();) if (!i.next().getMeetingDate().before(today)) i.remove(); if (event.getMeetings().isEmpty()) { hibSession.delete(event); } else { if (event.getNotes() == null) event.setNotes(new HashSet<EventNote>()); EventNote note = new EventNote(); note.setEvent(event); note.setNoteType(EventNote.sEventNoteTypeDeletion); note.setTimeStamp(new Date()); note.setUser(contact == null ? "System" : contact.getName()); note.setUserId(sendNotificationPuid); note.setTextNote(getOwner().getName() + " uncommitted"); note.setMeetings("N/A"); event.getNotes().add(note); hibSession.saveOrUpdate(event); } } } // removeDivSecNumbers(hibSession); if (sendNotificationPuid != null) sendNotification(this, null, sendNotificationPuid, true, null); // Manually fix the Clazz_.committedAssignment cache. for (Assignment a : getAssignments()) a.getClazz().setCommittedAssignment(null); } public boolean commitSolution(Vector messages, org.hibernate.Session hibSession) throws Exception { return commitSolution(messages, hibSession, null); } public static boolean shareRooms(Assignment a1, Assignment a2) { if (!a1.getPlacement().sameRooms(a2.getPlacement())) return false; for (Iterator i = a1.getClazz().getDistributionObjects().iterator(); i.hasNext();) { DistributionObject distObj = (DistributionObject) i.next(); DistributionPref dp = distObj.getDistributionPref(); String ref = dp.getDistributionType().getReference(); if (!"MEET_WITH".equals(ref) && !"CAN_SHARE_ROOM".equals(ref)) continue; if (!PreferenceLevel.sRequired.equals(dp.getPrefLevel().getPrefProlog())) continue; for (Iterator j = dp.getDistributionObjects().iterator(); j.hasNext();) { DistributionObject distObj2 = (DistributionObject) j.next(); if (distObj2.getPrefGroup().equals(a2.getClazz()) || distObj2.getPrefGroup().equals(a2.getClazz().getSchedulingSubpart())) return true; } } for (Iterator i = a1.getClazz().getSchedulingSubpart().getDistributionObjects().iterator(); i.hasNext();) { DistributionObject distObj = (DistributionObject) i.next(); DistributionPref dp = distObj.getDistributionPref(); String ref = dp.getDistributionType().getReference(); if (!"MEET_WITH".equals(ref) && !"CAN_SHARE_ROOM".equals(ref)) continue; if (!PreferenceLevel.sRequired.equals(dp.getPrefLevel().getPrefProlog())) continue; for (Iterator j = dp.getDistributionObjects().iterator(); j.hasNext();) { DistributionObject distObj2 = (DistributionObject) j.next(); if (distObj2.getPrefGroup().equals(a2.getClazz()) || distObj2.getPrefGroup().equals(a2.getClazz().getSchedulingSubpart())) return true; } } for (Iterator i = a1.getInstructors().iterator(); i.hasNext();) { DepartmentalInstructor instr = (DepartmentalInstructor) i.next(); for (Iterator j = instr.getDistributionPreferences().iterator(); j.hasNext();) { DistributionPref dp = (DistributionPref) j.next(); String ref = dp.getDistributionType().getReference(); if (!"MEET_WITH".equals(ref) && !"CAN_SHARE_ROOM".equals(ref)) continue; if (!PreferenceLevel.sRequired.equals(dp.getPrefLevel().getPrefProlog())) continue; for (Iterator k = DepartmentalInstructor .getAllForInstructor(instr, instr.getDepartment().getSession().getUniqueId()).iterator(); k .hasNext();) { DepartmentalInstructor inst2 = (DepartmentalInstructor) k.next(); for (Iterator l = inst2.getClasses().iterator(); l.hasNext();) { ClassInstructor ci = (ClassInstructor) l.next(); if (ci.getClassInstructing().equals(a2.getClazz())) return true; } } } } return false; } public boolean commitSolution(List<String> messages, org.hibernate.Session hibSession, String sendNotificationPuid) throws Exception { List solutions = hibSession.createCriteria(Solution.class).add(Restrictions.eq("owner", getOwner())).list(); Solution uncommittedSolution = null; for (Iterator i = solutions.iterator(); i.hasNext();) { Solution s = (Solution) i.next(); if (s.equals(this)) continue; if (s.isCommited().booleanValue()) { uncommittedSolution = s; s.uncommitSolution(hibSession, null); } } if (DEBUG) sLog.debug("commit[" + getUniqueId() + "," + getOwner().getName() + "] -------------------------------------------------------"); boolean isOK = true; for (Object[] o : (List<Object[]>) hibSession.createQuery( "select r, a1, a2 from Location r inner join r.assignments a1 inner join r.assignments a2 " + "where a1.solution.uniqueId = :solutionId and a2.solution.commited = true and a2.solution.owner.uniqueId != :ownerId and " + "bit_and(a1.days, a2.days) > 0 and (a1.timePattern.type = :exactType or a2.timePattern.type = :exactType or " + "(a1.startSlot < a2.startSlot + a2.timePattern.slotsPerMtg and a2.startSlot < a1.startSlot + a1.timePattern.slotsPerMtg))") .setLong("ownerId", getOwner().getUniqueId()).setLong("solutionId", getUniqueId()) .setInteger("exactType", TimePattern.sTypeExactTime).list()) { Location room = (Location) o[0]; Assignment a = (Assignment) o[1]; Assignment b = (Assignment) o[2]; if (!room.isIgnoreRoomCheck() && a.getTimeLocation().hasIntersection(b.getTimeLocation()) && !shareRooms(a, b)) { messages.add("Class " + a.getClassName() + " " + a.getTimeLocation().getName(CONSTANTS.useAmPm()) + " overlaps with " + b.getClassName() + " " + b.getTimeLocation().getName(CONSTANTS.useAmPm()) + " (room " + room.getLabel() + ")"); isOK = false; } } for (Object[] o : (List<Object[]>) hibSession.createQuery( "select i1, a1, a2 from ClassInstructor c1 inner join c1.instructor i1 inner join c1.classInstructing.assignments a1, " + "ClassInstructor c2 inner join c2.instructor i2 inner join c2.classInstructing.assignments a2 where c1.lead = true and c2.lead = true and " + "i1.department.solverGroup.uniqueId = :ownerId and i2.department.solverGroup.uniqueId != :ownerId and i2.department.session = :sessionId and " + "i1.externalUniqueId is not null and i1.externalUniqueId = i2.externalUniqueId and " + "a1.solution.uniqueId = :solutionId and a2.solution.commited = true and a2.solution.owner.uniqueId != :ownerId and " + "bit_and(a1.days, a2.days) > 0 and (a1.timePattern.type = :exactType or a2.timePattern.type = :exactType or " + "(a1.startSlot < a2.startSlot + a2.timePattern.slotsPerMtg and a2.startSlot < a1.startSlot + a1.timePattern.slotsPerMtg))") .setLong("ownerId", getOwner().getUniqueId()).setLong("solutionId", getUniqueId()) .setLong("sessionId", getOwner().getSession().getUniqueId()) .setInteger("exactType", TimePattern.sTypeExactTime).list()) { DepartmentalInstructor instructor = (DepartmentalInstructor) o[0]; Assignment a = (Assignment) o[1]; Assignment b = (Assignment) o[2]; if (a.getTimeLocation().hasIntersection(b.getTimeLocation()) && !shareRooms(a, b)) { messages.add("Class " + a.getClassName() + " " + a.getTimeLocation().getName(CONSTANTS.useAmPm()) + " overlaps with " + b.getClassName() + " " + b.getTimeLocation().getName(CONSTANTS.useAmPm()) + " (instructor " + instructor.nameLastNameFirst() + ")"); isOK = false; } } if (!isOK) { if (sendNotificationPuid != null) sendNotification(uncommittedSolution, this, sendNotificationPuid, false, messages); return false; } // NOTE: In order to decrease the amount of interaction between solutions persistance of committed student conflicts was disabled /* SolverInfoDef defJenrlInfo = SolverInfoDef.findByName(hibSession,"JenrlInfo"); Hashtable solverInfos = new Hashtable(); AssignmentDAO adao = new AssignmentDAO(); q = hibSession.createQuery( "select a.uniqueId, oa.uniqueId, count(*) from "+ "Solution s inner join s.assignments a inner join s.studentEnrollments as e, "+ "Solution os inner join os.assignments oa inner join os.studentEnrollments as oe "+ "where "+ "s.uniqueId=:solutionId and os.owner.session.uniqueId=:sessionId and os.owner.uniqueId!=:ownerId and "+ "a.clazz=e.clazz and oa.clazz=oe.clazz and a.clazz.schedulingSubpart!=oa.clazz.schedulingSubpart and e.studentId=oe.studentId "+ "group by a.uniqueId, oa.uniqueId"); q.setLong("ownerId",getOwner().getUniqueId().longValue()); q.setLong("solutionId",getUniqueId()); q.setLong("sessionId",getOwner().getSession().getUniqueId().longValue()); Iterator otherAssignments = q.iterate(); while (otherAssignments.hasNext()) { Object[] result = (Object[])otherAssignments.next(); Assignment assignment = adao.get((Integer)result[0],hibSession); Assignment otherAssignment = adao.get((Integer)result[1],hibSession); int jenrl = ((Number)result[2]).intValue(); if (assignment==null || otherAssignment==null || jenrl==0 || !assignment.isInConflict(otherAssignment)) continue; addCommitJenrl(hibSession, assignment, otherAssignment, jenrl, defJenrlInfo, solverInfos); } for (Iterator i=solverInfos.values().iterator();i.hasNext();) { SolverInfo sInfo = (SolverInfo)i.next(); hibSession.saveOrUpdate(sInfo); } */ setCommitDate(new Date()); setCommited(Boolean.TRUE); // createDivSecNumbers(hibSession, messages); EventContact contact = null; if (sendNotificationPuid != null) { contact = EventContact.findByExternalUniqueId(sendNotificationPuid); if (contact == null) { TimetableManager manager = TimetableManager.findByExternalId(sendNotificationPuid); if (manager != null) { contact = new EventContact(); contact.setFirstName(manager.getFirstName()); contact.setMiddleName(manager.getMiddleName()); contact.setLastName(manager.getLastName()); contact.setExternalUniqueId(manager.getExternalUniqueId()); contact.setEmailAddress(manager.getEmailAddress()); hibSession.save(contact); } } } Hashtable<Long, ClassEvent> classEvents = new Hashtable(); for (Iterator i = hibSession.createQuery( "select e from Solution s inner join s.assignments a, ClassEvent e where e.clazz=a.clazz and s.uniqueId=:solutionId") .setLong("solutionId", getUniqueId()).iterate(); i.hasNext();) { ClassEvent e = (ClassEvent) i.next(); classEvents.put(e.getClazz().getUniqueId(), e); } for (Iterator i = getAssignments().iterator(); i.hasNext();) { Assignment a = (Assignment) i.next(); ClassEvent event = a.generateCommittedEvent(classEvents.get(a.getClassId()), true); classEvents.remove(a.getClassId()); if (event != null && !event.getMeetings().isEmpty()) { event.setMainContact(contact); if (event.getNotes() == null) event.setNotes(new HashSet<EventNote>()); EventNote note = new EventNote(); note.setEvent(event); note.setNoteType(event.getUniqueId() == null ? EventNote.sEventNoteTypeCreateEvent : EventNote.sEventNoteTypeEditEvent); note.setTimeStamp(new Date()); note.setUser(contact == null ? "System" : contact.getName()); note.setUserId(sendNotificationPuid); note.setTextNote(getOwner().getName() + " committed"); note.setMeetings(a.getPlacement().getLongName(CONSTANTS.useAmPm())); event.getNotes().add(note); hibSession.saveOrUpdate(event); } if (event != null && event.getMeetings().isEmpty() && event.getUniqueId() != null) hibSession.delete(event); } if (ApplicationProperty.ClassAssignmentChangePastMeetings.isTrue()) { for (Enumeration e = classEvents.elements(); e.hasMoreElements();) { ClassEvent event = (ClassEvent) e.nextElement(); hibSession.delete(event); } } else { Calendar cal = Calendar.getInstance(Locale.US); cal.set(Calendar.HOUR_OF_DAY, 0); cal.set(Calendar.MINUTE, 0); cal.set(Calendar.SECOND, 0); cal.set(Calendar.MILLISECOND, 0); Date today = cal.getTime(); for (Enumeration e = classEvents.elements(); e.hasMoreElements();) { ClassEvent event = (ClassEvent) e.nextElement(); for (Iterator<Meeting> i = event.getMeetings().iterator(); i.hasNext();) if (!i.next().getMeetingDate().before(today)) i.remove(); if (event.getMeetings().isEmpty()) { hibSession.delete(event); } else { if (event.getNotes() == null) event.setNotes(new HashSet<EventNote>()); EventNote note = new EventNote(); note.setEvent(event); note.setNoteType(EventNote.sEventNoteTypeDeletion); note.setTimeStamp(new Date()); note.setUser(contact == null ? "System" : contact.getName()); note.setUserId(sendNotificationPuid); note.setTextNote(getOwner().getName() + " committed, class was removed or unassigned"); note.setMeetings("N/A"); event.getNotes().add(note); hibSession.saveOrUpdate(event); } } } if (sendNotificationPuid != null) sendNotification(uncommittedSolution, this, sendNotificationPuid, true, messages); // Manually fix the Clazz_.committedAssignment cache. for (Assignment a : getAssignments()) a.getClazz().setCommittedAssignment(a); return true; } public static void sendNotification(Solution uncommittedSolution, Solution committedSolution, String puid, boolean success, List<String> messages) { try { if (ApplicationProperty.EmailNotificationSolutionCommits.isFalse()) return; //email notification disabled Formats.Format<Date> sdf = Formats.getDateFormat(Formats.Pattern.DATE_TIME_STAMP); SolverGroup owner = (uncommittedSolution == null ? committedSolution : uncommittedSolution).getOwner(); String subject = "Solution " + (committedSolution != null ? uncommittedSolution != null ? "recommitted" : "committed" : "uncommitted") + " for " + owner.getName(); if (!success) { subject = "Failed to " + (committedSolution != null ? uncommittedSolution != null ? "recommit" : "commit" : "uncommit") + " a solution for " + owner.getName(); } String mail = subject; mail += "\r\n"; mail += "\r\n"; if (messages != null && !messages.isEmpty()) { mail += "Message(s): ----------------- \r\n"; for (String m : messages) { mail += m + "\r\n"; } mail += "\r\n"; mail += "\r\n"; } if (committedSolution != null) { mail += "Committed solution info: -------------- \r\n"; mail += "Created: " + sdf.format(committedSolution.getCreated()) + "\r\n"; mail += "Owner: " + committedSolution.getOwner().getName() + "\r\n"; if (committedSolution.getCommitDate() != null) mail += "Commited: " + sdf.format(committedSolution.getCommitDate()) + "\r\n"; if (committedSolution.getNote() != null && committedSolution.getNote().trim().length() > 0) mail += "Note: " + committedSolution.getNote() + "\r\n"; PropertiesInfo globalInfo = (PropertiesInfo) committedSolution.getInfo("GlobalInfo"); Vector infos = new Vector(globalInfo.keySet()); Collections.sort(infos, new InfoComparator()); for (Enumeration e = infos.elements(); e.hasMoreElements();) { String key = (String) e.nextElement(); String value = (String) globalInfo.getProperty(key); mail += key + ": " + value + "\r\n"; } mail += "\r\n"; mail += "\r\n"; } if (uncommittedSolution != null) { mail += "Uncommitted solution info: -------------- \r\n"; mail += "Created: " + sdf.format(uncommittedSolution.getCreated()) + "\r\n"; mail += "Owner: " + uncommittedSolution.getOwner().getName() + "\r\n"; if (uncommittedSolution.getNote() != null && uncommittedSolution.getNote().trim().length() > 0) mail += "Note: " + uncommittedSolution.getNote() + "\r\n"; PropertiesInfo globalInfo = (PropertiesInfo) uncommittedSolution.getInfo("GlobalInfo"); Vector infos = new Vector(globalInfo.keySet()); Collections.sort(infos, new InfoComparator()); for (Enumeration e = infos.elements(); e.hasMoreElements();) { String key = (String) e.nextElement(); String value = (String) globalInfo.getProperty(key); mail += key + ": " + value + "\r\n"; } mail += "\r\n"; mail += "\r\n"; } TimetableManager mgr = TimetableManager.findByExternalId(puid); mail += "Manager info -------------- \r\n"; mail += "Name: " + mgr.getName() + "\r\n"; //mail += "PUID: "+mgr.getPuid()+"\r\n"; mail += "Email: " + mgr.getEmailAddress() + "\r\n"; mail += "\r\n"; mail += "Session info -------------- \r\n"; mail += "Session Term: " + owner.getSession().getAcademicYearTerm() + "\r\n"; mail += "Session Initiative: " + owner.getSession().getAcademicInitiative() + "\r\n"; mail += "Departments (from solver group): \r\n"; for (Iterator i = owner.getDepartments().iterator(); i.hasNext();) { Department d = (Department) i.next(); mail += " " + d.getLabel() + "\r\n"; } mail += "\r\n"; mail += "Application info -------------- \r\n"; mail += "Version: " + Constants.getVersion() + " (" + Constants.getReleaseDate() + ")\r\n"; mail += "TimeStamp: " + (new Date()); Email email = Email.createEmail(); email.addRecipient(mgr.getEmailAddress(), mgr.getName()); email.addNotifyCC(); email.setSubject("UniTime (Solution Commit): " + subject); email.setText(mail); email.send(); } catch (Exception e) { sLog.error("Unable to send solution commit/uncommit notification, reason: " + e.getMessage(), e); } } public void export(CSVFile file, String instructorFormat) { file.setSeparator(","); file.setQuotationMark("\""); if (isCommited().booleanValue()) { file.setHeader(new CSVField[] { new CSVField("COURSE"), new CSVField("ITYPE"), new CSVField("SECTION"), new CSVField("SUFFIX"), new CSVField("EXTERNAL_ID"), new CSVField("DATE_PATTERN"), new CSVField("DAY"), new CSVField("START_TIME"), new CSVField("END_TIME"), new CSVField("ROOM"), new CSVField("INSTRUCTOR"), new CSVField("SCHEDULE_NOTE") }); } else { file.setHeader(new CSVField[] { new CSVField("COURSE"), new CSVField("ITYPE"), new CSVField("SECTION"), new CSVField("SUFFIX"), new CSVField("DATE_PATTERN"), new CSVField("DAY"), new CSVField("START_TIME"), new CSVField("END_TIME"), new CSVField("ROOM"), new CSVField("INSTRUCTOR"), new CSVField("SCHEDULE_NOTE") }); } Vector assignments = new Vector(getAssignments()); assignments.addAll(getOwner().getNotAssignedClasses(this)); Collections.sort(assignments, new ClassOrAssignmentComparator()); for (Iterator i = assignments.iterator(); i.hasNext();) { Object o = i.next(); if (o instanceof Assignment) { Assignment assignment = (Assignment) o; Class_ clazz = assignment.getClazz(); List<DepartmentalInstructor> leads = clazz.getLeadInstructors(); StringBuffer leadsSb = new StringBuffer(); for (Iterator<DepartmentalInstructor> e = leads.iterator(); e.hasNext();) { DepartmentalInstructor instructor = (DepartmentalInstructor) e.next(); leadsSb.append(instructor.getName(instructorFormat)); if (e.hasNext()) leadsSb.append(";"); } Placement placement = assignment.getPlacement(); if (isCommited().booleanValue()) { file.addLine(new CSVField[] { new CSVField(clazz.getCourseName()), new CSVField(clazz.getItypeDesc()), new CSVField(clazz.getSectionNumber()), new CSVField(clazz.getSchedulingSubpart().getSchedulingSubpartSuffix()), new CSVField(clazz.getDivSecNumber()), new CSVField(clazz.effectiveDatePattern().getName()), new CSVField(placement.getTimeLocation().getDayHeader()), new CSVField(placement.getTimeLocation().getStartTimeHeader(CONSTANTS.useAmPm())), new CSVField(placement.getTimeLocation().getEndTimeHeader(CONSTANTS.useAmPm())), new CSVField(placement.getRoomName(",")), new CSVField(leadsSb), new CSVField( clazz.getSchedulePrintNote() == null ? "" : clazz.getSchedulePrintNote()) }); } else { file.addLine(new CSVField[] { new CSVField(clazz.getCourseName()), new CSVField(clazz.getItypeDesc()), new CSVField(clazz.getSectionNumber()), new CSVField(clazz.getSchedulingSubpart().getSchedulingSubpartSuffix()), new CSVField(clazz.effectiveDatePattern().getName()), new CSVField(placement.getTimeLocation().getDayHeader()), new CSVField(placement.getTimeLocation().getStartTimeHeader(CONSTANTS.useAmPm())), new CSVField(placement.getTimeLocation().getEndTimeHeader(CONSTANTS.useAmPm())), new CSVField(placement.getRoomName(",")), new CSVField(leadsSb), new CSVField( clazz.getSchedulePrintNote() == null ? "" : clazz.getSchedulePrintNote()) }); } } else { Class_ clazz = (Class_) o; List<DepartmentalInstructor> leads = clazz.getLeadInstructors(); StringBuffer leadsSb = new StringBuffer(); for (Iterator<DepartmentalInstructor> e = leads.iterator(); e.hasNext();) { DepartmentalInstructor instructor = (DepartmentalInstructor) e.next(); leadsSb.append(instructor.getName(instructorFormat)); if (e.hasNext()) leadsSb.append(";"); } if (isCommited().booleanValue()) { file.addLine(new CSVField[] { new CSVField(clazz.getCourseName()), new CSVField(clazz.getItypeDesc()), new CSVField(clazz.getSectionNumber()), new CSVField(clazz.getSchedulingSubpart().getSchedulingSubpartSuffix()), new CSVField(clazz.getDivSecNumber()), new CSVField(clazz.effectiveDatePattern().getName()), new CSVField(""), new CSVField(""), new CSVField(""), new CSVField(""), new CSVField(leadsSb), new CSVField( clazz.getSchedulePrintNote() == null ? "" : clazz.getSchedulePrintNote()) }); } else { file.addLine(new CSVField[] { new CSVField(clazz.getCourseName()), new CSVField(clazz.getItypeDesc()), new CSVField(clazz.getSectionNumber()), new CSVField(clazz.getSchedulingSubpart().getSchedulingSubpartSuffix()), new CSVField(clazz.effectiveDatePattern().getName()), new CSVField(""), new CSVField(""), new CSVField(""), new CSVField(""), new CSVField(leadsSb), new CSVField( clazz.getSchedulePrintNote() == null ? "" : clazz.getSchedulePrintNote()) }); } } } } private static class ClassOrAssignmentComparator implements Comparator { ClassComparator cc = new ClassComparator(ClassComparator.COMPARE_BY_HIERARCHY); public int compare(Object o1, Object o2) { if (o1 == null || o2 == null) return 0; Class_ c1 = (o1 instanceof Class_ ? (Class_) o1 : ((Assignment) o1).getClazz()); Class_ c2 = (o2 instanceof Class_ ? (Class_) o2 : ((Assignment) o2).getClazz()); return cc.compare(c1, c2); } } private void deleteObjects(org.hibernate.Session hibSession, String objectName, String idQuery) { Iterator idIterator = hibSession.createQuery(idQuery).setLong("solutionId", getUniqueId()).iterate(); StringBuffer ids = new StringBuffer(); int idx = 0; while (idIterator.hasNext()) { ids.append(idIterator.next()); idx++; if (idx == 100) { hibSession.createQuery("delete " + objectName + " as x where x.uniqueId in (" + ids + ")") .executeUpdate(); ids = new StringBuffer(); idx = 0; } else if (idIterator.hasNext()) { ids.append(","); } } if (idx > 0) hibSession.createQuery("delete " + objectName + " as x where x.uniqueId in (" + ids + ")") .executeUpdate(); } public void delete(org.hibernate.Session hibSession) { // NOTE: In order to decrease the amount of interaction between solutions persistance of committed student conflicts was disabled /* Iterator i = hibSession.createQuery( "select distinct c, oa from "+ "ConstraintInfo c inner join c.assignments a, Assignment oa "+ "where "+ "a.solution.uniqueId=:solutionId and oa.solution.uniqueId!=:solutionId and oa in elements ( c.assignments) ") .setLong("solutionId",getUniqueId()) .iterate(); while (i.hasNext()) { Object[] next = (Object[])i.next(); ConstraintInfo c = (ConstraintInfo)next[0]; Assignment oa = (Assignment)next[1]; oa.getConstraintInfo().remove(c); hibSession.saveOrUpdate(oa); } */ try { SolutionInfo solutionInfo = getSolutionInfo("CBSInfo"); if (solutionInfo != null) solutionInfo.delete(hibSession); } catch (Exception e) { Debug.error(e); } hibSession.createQuery("delete StudentEnrollment x where x.solution.uniqueId=:solutionId ") .setLong("solutionId", getUniqueId().longValue()).executeUpdate(); hibSession.createQuery("delete JointEnrollment x where x.solution.uniqueId=:solutionId ") .setLong("solutionId", getUniqueId().longValue()).executeUpdate(); deleteObjects(hibSession, "SolverInfo", "select a.uniqueId from AssignmentInfo a where a.assignment.solution.uniqueId=:solutionId"); deleteObjects(hibSession, "SolverInfo", "select s.uniqueId from SolutionInfo s where s.solution.uniqueId=:solutionId"); deleteObjects(hibSession, "SolverInfo", "select c.uniqueId from ConstraintInfo c inner join c.assignments a where a.solution.uniqueId=:solutionId"); hibSession.createQuery("delete Assignment x where x.solution.uniqueId=:solutionId ") .setLong("solutionId", getUniqueId()).executeUpdate(); deleteObjects(hibSession, "SolverParameter", "select p.uniqueId from Solution s inner join s.parameters p where s.uniqueId=:solutionId"); getOwner().getSolutions().remove(this); hibSession.delete(this); } public void empty(org.hibernate.Session hibSession, TimetableInfoFileProxy proxy) { // NOTE: In order to decrease the amount of interaction between solutions persistance of committed student conflicts was disabled /* Iterator i = hibSession.createQuery( "select distinct c, oa from "+ "ConstraintInfo c inner join c.assignments a, Assignment oa "+ "where "+ "a.solution.uniqueId=:solutionId and oa.solution.uniqueId!=:solutionId and oa in elements ( c.assignments) ") .setLong("solutionId",getUniqueId()) .iterate(); while (i.hasNext()) { Object[] next = (Object[])i.next(); ConstraintInfo c = (ConstraintInfo)next[0]; Assignment oa = (Assignment)next[1]; oa.getConstraintInfo().remove(c); hibSession.saveOrUpdate(oa); } */ try { SolutionInfo solutionInfo = getSolutionInfo("CBSInfo"); if (solutionInfo != null) solutionInfo.delete(hibSession, proxy); } catch (Exception e) { Debug.error(e); } hibSession.flush(); hibSession.createQuery("delete StudentEnrollment x where x.solution.uniqueId=:solutionId ") .setLong("solutionId", getUniqueId()).executeUpdate(); hibSession.createQuery("delete JointEnrollment x where x.solution.uniqueId=:solutionId ) ") .setLong("solutionId", getUniqueId()).executeUpdate(); deleteObjects(hibSession, "SolverInfo", "select a.uniqueId from AssignmentInfo a where a.assignment.solution.uniqueId=:solutionId"); deleteObjects(hibSession, "SolverInfo", "select s.uniqueId from SolutionInfo s where s.solution.uniqueId=:solutionId"); deleteObjects(hibSession, "SolverInfo", "select c.uniqueId from ConstraintInfo c inner join c.assignments a where a.solution.uniqueId=:solutionId"); hibSession.createQuery("delete Assignment x where x.solution.uniqueId=:solutionId ) ") .setLong("solutionId", getUniqueId()).executeUpdate(); deleteObjects(hibSession, "SolverParameter", "select p.uniqueId from Solution s inner join s.parameters p where s.uniqueId=:solutionId"); setAssignments(null); setSolutionInfo(null); setJointEnrollments(null); setStudentEnrollments(null); setParameters(null); hibSession.saveOrUpdate(this); hibSession.flush(); } public void updateCommittedStudentEnrollmentInfos(org.hibernate.Session hibSession) throws Exception { SolutionInfo sInfo = getSolutionInfo("GlobalInfo"); if (sInfo != null) { PropertiesInfo propInfo = (PropertiesInfo) sInfo.getInfo(); String conf = propInfo.getProperty("Student conflicts"); int studentConf = Integer.parseInt(conf.substring(0, conf.indexOf(' '))); if (conf.indexOf("committed:") >= 0) { int commitedStart = conf.indexOf("committed:") + "committed:".length(); int commitedEnd = conf.indexOf(',', commitedStart); int commitedConf = Integer.parseInt(conf.substring(commitedStart, commitedEnd)); //String newConf = (studentConf-commitedConf)+" [committed:"+0+conf.substring(commitedEnd); String newConf = (studentConf - commitedConf) + " [" + conf.substring(commitedEnd + 2); propInfo.setProperty("Student conflicts", newConf); } sInfo.setInfo(propInfo); hibSession.saveOrUpdate(sInfo); } //NOTE: In order to decrease the amount of interaction between solutions persistance of committed student conflicts was disabled /* if (getAssignments()!=null) { for (Iterator i=getAssignments().iterator();i.hasNext();) { Assignment a = (Assignment)i.next(); for (Iterator j=a.getAssignmentInfo().iterator();j.hasNext();) { AssignmentInfo aInfo = (AssignmentInfo)j.next(); if (!"AssignmentInfo".equals(aInfo.getDefinition().getName())) continue; AssignmentPreferenceInfo assignmentInfo = (AssignmentPreferenceInfo)aInfo.getInfo(); assignmentInfo.setNrStudentConflicts(assignmentInfo.getNrStudentConflicts()-assignmentInfo.getNrCommitedStudentConflicts()); assignmentInfo.setNrCommitedStudentConflicts(0); aInfo.setInfo(assignmentInfo); hibSession.saveOrUpdate(aInfo); } for (Iterator j=a.getConstraintInfos("JenrlInfo").iterator();j.hasNext();) { ConstraintInfo c = (ConstraintInfo)j.next(); boolean isCommittedInfo = false; for (Iterator k=c.getAssignments().iterator();k.hasNext();) { Assignment oa = (Assignment)k.next(); if (!oa.getSolution().equals(this)) { oa.getConstraintInfo().remove(c); hibSession.saveOrUpdate(oa); isCommittedInfo = true; } } if (isCommittedInfo) { a.getConstraintInfo().remove(c); hibSession.saveOrUpdate(a); hibSession.delete(c); } } } } SolverInfoDef defJenrlInfo = SolverInfoDef.findByName(hibSession,"JenrlInfo"); Hashtable solverInfos = new Hashtable(); AssignmentDAO adao = new AssignmentDAO(); Query q = hibSession.createQuery( "select a.uniqueId, oa.uniqueId, count(*) from "+ "Solution s inner join s.assignments a inner join s.studentEnrollments as e, "+ "Solution os inner join os.assignments oa inner join os.studentEnrollments as oe "+ "where "+ "s.uniqueId=:solutionId and os.owner.session.uniqueId=:sessionId and os.owner.uniqueId!=:ownerId and os.commited=true and "+ "a.clazz=e.clazz and oa.clazz=oe.clazz and a.clazz.schedulingSubpart!=oa.clazz.schedulingSubpart and e.studentId=oe.studentId "+ "group by a.uniqueId, oa.uniqueId"); q.setLong("ownerId",getOwner().getUniqueId().longValue()); q.setLong("solutionId",getUniqueId()); q.setLong("sessionId",getOwner().getSession().getUniqueId().longValue()); Iterator otherAssignments = q.iterate(); while (otherAssignments.hasNext()) { Object[] result = (Object[])otherAssignments.next(); Assignment assignment = adao.get((Integer)result[0],hibSession); Assignment otherAssignment = adao.get((Integer)result[1],hibSession); int jenrl = ((Number)result[2]).intValue(); if (assignment==null || otherAssignment==null || jenrl==0 || !assignment.isInConflict(otherAssignment)) continue; addCommitJenrl(hibSession, otherAssignment, assignment, jenrl, defJenrlInfo, solverInfos); } for (Iterator i=solverInfos.values().iterator();i.hasNext();) { SolverInfo solverInfo = (SolverInfo)i.next(); hibSession.saveOrUpdate(solverInfo); } */ } public Session getSession() { return getOwner().getSession(); } public static Collection findBySessionId(Long sessionId) { return (new SolutionDAO()).getSession() .createQuery("select s from Solution s where s.owner.session.uniqueId=:sessionId") .setLong("sessionId", sessionId.longValue()). //setCacheable(true). list(); } private HashSet takenDivisionNumbers(SchedulingSubpart subpart) { HashSet divNums = new HashSet(); InstructionalOffering offering = subpart.getInstrOfferingConfig().getInstructionalOffering(); ItypeDesc itype = subpart.getItype(); for (Iterator i = offering.getInstrOfferingConfigs().iterator(); i.hasNext();) { InstrOfferingConfig cfg = (InstrOfferingConfig) i.next(); for (Iterator j = cfg.getSchedulingSubparts().iterator(); j.hasNext();) { SchedulingSubpart s = (SchedulingSubpart) j.next(); if (!s.getItype().equals(itype)) continue; for (Iterator k = s.getClasses().iterator(); k.hasNext();) { Class_ clazz = (Class_) k.next(); if (clazz.getClassSuffix() == null) continue; Integer divNum = Integer.valueOf(clazz.getClassSuffix().substring(0, 3)); divNums.add(divNum); } } } return divNums; } public void createDivSecNumbers(org.hibernate.Session hibSession, Vector messages) { Vector assignments = new Vector(getAssignments()); assignments.addAll(new SolutionDAO().getSession() .createQuery("select distinct c from Class_ c, Solution s inner join s.owner.departments d " + "where s.uniqueId = :solutionId and c.managingDept=d and " + "c.uniqueId not in (select a.clazz.uniqueId from s.assignments a)") .setLong("solutionId", getUniqueId().longValue()).list()); HashSet relatedOfferings = new HashSet(); for (Enumeration e = assignments.elements(); e.hasMoreElements();) { Object o = e.nextElement(); Assignment assignment = (o instanceof Assignment ? (Assignment) o : null); Class_ clazz = (assignment == null ? (Class_) o : assignment.getClazz()); relatedOfferings.add(clazz.getSchedulingSubpart().getInstrOfferingConfig().getInstructionalOffering()); } for (Iterator i = relatedOfferings.iterator(); i.hasNext();) { InstructionalOffering io = (InstructionalOffering) i.next(); for (Iterator j = io.getInstrOfferingConfigs().iterator(); j.hasNext();) { InstrOfferingConfig ioc = (InstrOfferingConfig) j.next(); for (Iterator k = ioc.getSchedulingSubparts().iterator(); k.hasNext();) { SchedulingSubpart subpart = (SchedulingSubpart) k.next(); for (Iterator l = subpart.getClasses().iterator(); l.hasNext();) { Class_ clazz = (Class_) l.next(); if (clazz.getClassSuffix() != null && !getOwner().getDepartments().contains(clazz.getManagingDept())) { Assignment assignment = clazz.getCommittedAssignment(); assignments.add(assignment == null ? (Object) clazz : (Object) assignment); clazz.setClassSuffix(null); } } } } } DivSecAssignmentComparator cmp = new DivSecAssignmentComparator(this, true, false); Collections.sort(assignments, cmp); Assignment lastAssignment = null; SchedulingSubpart lastSubpart = null; Class_ lastClazz = null; int divNum = 1, secNum = 0; HashSet takenDivNums = null; HashSet recompute = new HashSet(); for (Enumeration e = assignments.elements(); e.hasMoreElements();) { Object o = e.nextElement(); Assignment assignment = (o instanceof Assignment ? (Assignment) o : null); Class_ clazz = (assignment == null ? (Class_) o : assignment.getClazz()); if (clazz.getParentClass() != null && clazz.getSchedulingSubpart().getItype() .equals(clazz.getParentClass().getSchedulingSubpart().getItype())) continue; if (lastSubpart == null || !lastSubpart.equals(clazz.getSchedulingSubpart())) { takenDivNums = takenDivisionNumbers(clazz.getSchedulingSubpart()); lastAssignment = null; lastSubpart = null; lastClazz = null; } int nrClasses = clazz.getSchedulingSubpart().getInstrOfferingConfig().getInstructionalOffering() .getNrClasses(clazz.getSchedulingSubpart().getItype()); if (lastAssignment != null && assignment != null) { if (nrClasses >= 100 && cmp.compareTimeLocations(lastAssignment.getClazz(), assignment.getClazz(), lastAssignment.getTimeLocation(), assignment.getTimeLocation()) == 0) { if (lastClazz != null && clazz.getParentClass() != null && !clazz.getParentClass().equals(lastClazz.getParentClass()) && clazz.getParentClass().getDivSecNumber() != null && lastClazz.getParentClass().getDivSecNumber() != null) { if (cmp.compareTimeLocations(lastAssignment.getClazz(), assignment.getClazz(), lastAssignment.getTimeLocation(), assignment.getTimeLocation()) == 0 && clazz.getParentClass().getDivSecNumber().substring(0, 3) .equals(lastClazz.getParentClass().getDivSecNumber().substring(0, 3))) { secNum++; } else { divNum++; secNum = 1; while (takenDivNums.contains(new Integer(divNum))) divNum++; } } else { secNum++; } } else { divNum++; secNum = 1; while (takenDivNums.contains(new Integer(divNum))) divNum++; } } else if (lastClazz != null) { divNum++; secNum = 1; while (takenDivNums.contains(new Integer(divNum))) divNum++; } else { divNum = 1; secNum = 1; while (takenDivNums.contains(new Integer(divNum))) divNum++; } if (divNum == 100 && secNum == 1) { sLog.warn("Division number exceeded 99 for scheduling subpart " + clazz.getSchedulingSubpart().getSchedulingSubpartLabel() + "."); for (Iterator i = clazz.getSchedulingSubpart().getInstrOfferingConfig().getInstructionalOffering() .getInstrOfferingConfigs().iterator(); i.hasNext();) { InstrOfferingConfig cfg = (InstrOfferingConfig) i.next(); for (Iterator j = cfg.getSchedulingSubparts().iterator(); j.hasNext();) { SchedulingSubpart subpart = (SchedulingSubpart) j.next(); if (subpart.getItype().equals(clazz.getSchedulingSubpart().getItype())) recompute.add(subpart); } } } clazz.setClassSuffix(sSufixFormat.format(divNum) + sSufixFormat.format(secNum)); hibSession.update(clazz); lastAssignment = assignment; lastSubpart = clazz.getSchedulingSubpart(); lastClazz = clazz; } if (!recompute.isEmpty()) { HashSet recompute2 = new HashSet(); for (Iterator i = assignments.iterator(); i.hasNext();) { Object o = i.next(); Assignment assignment = (o instanceof Assignment ? (Assignment) o : null); Class_ clazz = (assignment == null ? (Class_) o : assignment.getClazz()); if (recompute.contains(clazz.getSchedulingSubpart())) { clazz.setClassSuffix(null); hibSession.update(clazz); } else { i.remove(); } } cmp = new DivSecAssignmentComparator(this, false, false); Collections.sort(assignments, cmp); lastAssignment = null; lastSubpart = null; lastClazz = null; for (Enumeration e = assignments.elements(); e.hasMoreElements();) { Object o = e.nextElement(); Assignment assignment = (o instanceof Assignment ? (Assignment) o : null); Class_ clazz = (assignment == null ? (Class_) o : assignment.getClazz()); if (lastSubpart == null || !lastSubpart.equals(clazz.getSchedulingSubpart())) { takenDivNums = takenDivisionNumbers(clazz.getSchedulingSubpart()); lastAssignment = null; lastSubpart = null; lastClazz = null; } if (lastAssignment != null && assignment != null) { if (cmp.compareTimeLocations(lastAssignment.getClazz(), assignment.getClazz(), lastAssignment.getTimeLocation(), assignment.getTimeLocation()) == 0) { secNum++; } else { divNum++; secNum = 1; while (takenDivNums.contains(new Integer(divNum))) divNum++; } } else if (lastClazz != null) { divNum++; secNum = 1; while (takenDivNums.contains(new Integer(divNum))) divNum++; } else { divNum = 1; secNum = 1; while (takenDivNums.contains(new Integer(divNum))) divNum++; } if (divNum == 100 && secNum == 1) { sLog.warn("Division number still (fallback) exceeded 99 for scheduling subpart " + clazz.getSchedulingSubpart().getSchedulingSubpartLabel() + "."); for (Iterator i = clazz.getSchedulingSubpart().getInstrOfferingConfig() .getInstructionalOffering().getInstrOfferingConfigs().iterator(); i.hasNext();) { InstrOfferingConfig cfg = (InstrOfferingConfig) i.next(); for (Iterator j = cfg.getSchedulingSubparts().iterator(); j.hasNext();) { SchedulingSubpart subpart = (SchedulingSubpart) j.next(); if (subpart.getItype().equals(clazz.getSchedulingSubpart().getItype())) recompute2.add(subpart); } } } clazz.setClassSuffix(sSufixFormat.format(divNum) + sSufixFormat.format(secNum)); hibSession.update(clazz); lastAssignment = assignment; lastSubpart = clazz.getSchedulingSubpart(); lastClazz = clazz; } if (!recompute2.isEmpty()) { for (Iterator i = assignments.iterator(); i.hasNext();) { Object o = i.next(); Assignment assignment = (o instanceof Assignment ? (Assignment) o : null); Class_ clazz = (assignment == null ? (Class_) o : assignment.getClazz()); if (recompute2.contains(clazz.getSchedulingSubpart())) { clazz.setClassSuffix(null); hibSession.update(clazz); } else { i.remove(); } } cmp = new DivSecAssignmentComparator(this, false, true); Collections.sort(assignments, cmp); lastAssignment = null; lastSubpart = null; lastClazz = null; for (Enumeration e = assignments.elements(); e.hasMoreElements();) { Object o = e.nextElement(); Assignment assignment = (o instanceof Assignment ? (Assignment) o : null); Class_ clazz = (assignment == null ? (Class_) o : assignment.getClazz()); if (lastSubpart == null || cmp.compareSchedulingSubparts(lastSubpart, clazz.getSchedulingSubpart()) != 0) { takenDivNums = takenDivisionNumbers(clazz.getSchedulingSubpart()); lastAssignment = null; lastSubpart = null; lastClazz = null; } if (lastAssignment != null && assignment != null) { if (cmp.compareTimeLocations(lastAssignment.getClazz(), assignment.getClazz(), lastAssignment.getTimeLocation(), assignment.getTimeLocation()) == 0) { secNum++; } else { divNum++; secNum = 1; while (takenDivNums.contains(new Integer(divNum))) divNum++; } } else if (lastClazz != null) { divNum++; secNum = 1; while (takenDivNums.contains(new Integer(divNum))) divNum++; } else { divNum = 1; secNum = 1; while (takenDivNums.contains(new Integer(divNum))) divNum++; } if (divNum == 100 && secNum == 1) { messages.add("Division number exceeded 99 for scheduling subpart " + clazz.getSchedulingSubpart().getSchedulingSubpartLabel() + "."); sLog.warn("Division number still (fallback2) exceeded 99 for scheduling subpart " + clazz.getSchedulingSubpart().getSchedulingSubpartLabel() + "."); } clazz.setClassSuffix(sSufixFormat.format(divNum) + sSufixFormat.format(secNum)); hibSession.update(clazz); lastAssignment = assignment; lastSubpart = clazz.getSchedulingSubpart(); lastClazz = clazz; } } } /* lastSubpart = null; TreeSet otherClasses = new TreeSet(new ClassComparator(ClassComparator.COMPARE_BY_HIERARCHY)); otherClasses.addAll(new SolutionDAO().getSession().createQuery( "select distinct c from Class_ c, Solution s inner join s.owner.departments d "+ "where s.uniqueId = :solutionId and c.managingDept=d and "+ "c.uniqueId not in (select a.clazz.uniqueId from s.assignments a) order by c.schedulingSubpart.uniqueId, c.sectionNumberCache"). setLong("solutionId", getUniqueId().longValue()). list()); for (Iterator i=otherClasses.iterator();i.hasNext();) { Class_ clazz = (Class_)i.next(); if (clazz.getParentClass()!=null && clazz.getSchedulingSubpart().getItype().equals(clazz.getParentClass().getSchedulingSubpart().getItype())) continue; if (clazz.getClassSuffix()!=null) { sLog.warn("This is odd, class "+clazz.getClassLabel()+" already has a div-sec number "+clazz.getClassSuffix()+"."); continue; } if (lastSubpart==null || !lastSubpart.equals(clazz.getSchedulingSubpart())) { takenDivNums = takenDivisionNumbers(clazz.getSchedulingSubpart()); } divNum = 1; while (takenDivNums.contains(new Integer(divNum))) divNum++; if (divNum==100) { messages.add("Division number exceeded 99 for scheduling subpart "+clazz.getSchedulingSubpart().getSchedulingSubpartLabel()+"."); } clazz.setClassSuffix(sSufixFormat.format(divNum)+sSufixFormat.format(1)); takenDivNums.add(new Integer(divNum)); lastSubpart = clazz.getSchedulingSubpart(); hibSession.update(clazz); } */ } public void removeDivSecNumbers(org.hibernate.Session hibSession) { HashSet classes = new HashSet(); for (Iterator i = getAssignments().iterator(); i.hasNext();) { Assignment assignment = (Assignment) i.next(); Class_ clazz = assignment.getClazz(); if (clazz == null || clazz.getClassSuffix() == null) continue; classes.add(clazz); } HashSet subparts2fix = new HashSet(); for (Iterator i = classes.iterator(); i.hasNext();) { Class_ clazz = (Class_) i.next(); clazz.setClassSuffix(null); subparts2fix.add(clazz.getSchedulingSubpart()); hibSession.update(clazz); } List otherClasses = new SolutionDAO().getSession() .createQuery("select distinct c from Class_ c, Solution s inner join s.owner.departments d " + "where s.uniqueId = :solutionId and c.managingDept=d and " + "c.uniqueId not in (select a.clazz.uniqueId from s.assignments a)") .setLong("solutionId", getUniqueId().longValue()).list(); for (Iterator i = otherClasses.iterator(); i.hasNext();) { Class_ clazz = (Class_) i.next(); if (clazz.getClassSuffix() == null) continue; clazz.setClassSuffix(null); subparts2fix.add(clazz.getSchedulingSubpart()); hibSession.update(clazz); } for (Iterator i = subparts2fix.iterator(); i.hasNext();) { SchedulingSubpart subpart = (SchedulingSubpart) i.next(); TreeSet takenDivNums = new TreeSet(takenDivisionNumbers(subpart)); int dec = 0, lastDiv = 0; for (Iterator j = takenDivNums.iterator(); j.hasNext();) { int div = ((Integer) j.next()).intValue(); dec += (div - lastDiv - 1); lastDiv = div; if (dec > 0) { sLog.debug(subpart.getSchedulingSubpartLabel() + ": " + div + "->" + (div - dec)); InstructionalOffering offering = subpart.getInstrOfferingConfig().getInstructionalOffering(); ItypeDesc itype = subpart.getItype(); for (Iterator i1 = offering.getInstrOfferingConfigs().iterator(); i1.hasNext();) { InstrOfferingConfig cfg = (InstrOfferingConfig) i1.next(); for (Iterator i2 = cfg.getSchedulingSubparts().iterator(); i2.hasNext();) { SchedulingSubpart s = (SchedulingSubpart) i2.next(); if (!s.getItype().equals(itype)) continue; for (Iterator i3 = s.getClasses().iterator(); i3.hasNext();) { Class_ clazz = (Class_) i3.next(); if (clazz.getClassSuffix() == null || clazz.getClassSuffix().length() != 6) continue; int clazzDivNum = Integer.parseInt(clazz.getClassSuffix().substring(0, 3)); int clazzSecNum = Integer.parseInt(clazz.getClassSuffix().substring(3, 6)); if (clazzDivNum == div) { clazz.setClassSuffix(sSufixFormat.format(clazzDivNum - dec) + sSufixFormat.format(clazzSecNum)); hibSession.update(clazz); } } } } } } } } private transient Hashtable iAssignmentTable = null; public Assignment getAssignment(Long classId) throws Exception { if (iAssignmentTable == null) { iAssignmentTable = new Hashtable(); for (Iterator i = getAssignments().iterator(); i.hasNext();) { Assignment a = (Assignment) i.next(); iAssignmentTable.put(a.getClassId(), a); } } return (Assignment) iAssignmentTable.get(classId); } public Assignment getAssignment(Class_ clazz) throws Exception { if (!getOwner().getDepartments().contains(clazz.getManagingDept())) return clazz.getCommittedAssignment(); return getAssignment(clazz.getUniqueId()); } public AssignmentPreferenceInfo getAssignmentInfo(Class_ clazz) throws Exception { return getAssignmentInfo(clazz.getUniqueId()); } public AssignmentPreferenceInfo getAssignmentInfo(Long classId) throws Exception { Assignment a = getAssignment(classId); return (a == null ? null : (AssignmentPreferenceInfo) a.getAssignmentInfo("AssignmentInfo")); } public Hashtable getAssignmentTable(Collection classesOrClassIds) throws Exception { Hashtable assignments = new Hashtable(); for (Iterator i = classesOrClassIds.iterator(); i.hasNext();) { Object classOrClassId = i.next(); if (classOrClassId instanceof Object[]) classOrClassId = ((Object[]) classOrClassId)[0]; Assignment assignment = (classOrClassId instanceof Class_ ? getAssignment((Class_) classOrClassId) : getAssignment((Long) classOrClassId)); if (assignment != null) assignments.put(classOrClassId instanceof Class_ ? ((Class_) classOrClassId).getUniqueId() : (Long) classOrClassId, assignment); } return assignments; } public Hashtable getAssignmentInfoTable(Collection classesOrClassIds) throws Exception { Hashtable infos = new Hashtable(); for (Iterator i = classesOrClassIds.iterator(); i.hasNext();) { Object classOrClassId = i.next(); if (classOrClassId instanceof Object[]) classOrClassId = ((Object[]) classOrClassId)[0]; AssignmentPreferenceInfo info = (classOrClassId instanceof Class_ ? getAssignmentInfo((Class_) classOrClassId) : getAssignmentInfo((Long) classOrClassId)); if (info != null) infos.put(classOrClassId instanceof Class_ ? ((Class_) classOrClassId).getUniqueId() : (Long) classOrClassId, info); } return infos; } private transient DataProperties iPropertiesCache = null; public synchronized DataProperties getProperties() { if (iPropertiesCache == null) { iPropertiesCache = new DataProperties(); for (Iterator i = getParameters().iterator(); i.hasNext();) { SolverParameter p = (SolverParameter) i.next(); iPropertiesCache.setProperty(p.getDefinition().getName(), p.getValue()); } } return iPropertiesCache; } public static void refreshSolution(Long solutionId) { SolutionDAO dao = new SolutionDAO(); org.hibernate.Session hibSession = dao.getSession(); SessionFactory hibSessionFactory = hibSession.getSessionFactory(); hibSessionFactory.getCache().evictEntity(Solution.class, solutionId); hibSessionFactory.getCache().evictCollection(Solution.class.getName() + ".parameters", solutionId); hibSessionFactory.getCache().evictCollection(Solution.class.getName() + ".assignments", solutionId); for (Iterator i = hibSession .createQuery("select c.uniqueId from " + "Class_ c, Solution s where s.uniqueId=:solutionId and " + "c.managingDept.uniqueId in elements (s.owner.departments)") .setLong("solutionId", solutionId.longValue()).iterate(); i.hasNext();) { Number classId = (Number) i.next(); hibSessionFactory.getCache().evictEntity(Class_.class, classId); hibSessionFactory.getCache().evictCollection(Class_.class.getName() + ".assignments", classId); } hibSessionFactory.getCache().evictCollection(SolverGroup.class.getName() + ".solutions", (Long) hibSession.createQuery("select owner.uniqueId from Solution s where s.uniqueId=:solutionId") .setLong("solutionId", solutionId).uniqueResult()); } public static boolean hasTimetable(Long sessionId) { return ((Number) new SolutionDAO().getSession() .createQuery("select count(s) from Solution s " + "where s.owner.session.uniqueId=:sessionId and " + "s.commited = true") .setLong("sessionId", sessionId).setCacheable(true).uniqueResult()).longValue() > 0; } @Override public boolean hasConflicts(Long offeringId) throws Exception { InstructionalOffering offering = InstructionalOfferingDAO.getInstance().get(offeringId); if (offering == null || offering.isNotOffered()) return false; for (InstrOfferingConfig config : offering.getInstrOfferingConfigs()) for (SchedulingSubpart subpart : config.getSchedulingSubparts()) for (Class_ clazz : subpart.getClasses()) { if (clazz.isCancelled()) continue; Assignment assignment = getAssignment(clazz); if (assignment == null) continue; if (assignment.getRooms() != null) for (Location room : assignment.getRooms()) { if (!room.isIgnoreRoomCheck()) { for (Assignment a : room.getCommitedAssignments()) if (!assignment.equals(a) && !a.getClazz().isCancelled() && assignment.overlaps(a) && !clazz.canShareRoom(a.getClazz())) return true; } } if (clazz.getClassInstructors() != null) for (ClassInstructor instructor : clazz.getClassInstructors()) { if (!instructor.isLead()) continue; for (DepartmentalInstructor di : DepartmentalInstructor .getAllForInstructor(instructor.getInstructor())) { for (ClassInstructor ci : di.getClasses()) { if (ci.equals(instructor)) continue; Assignment a = getAssignment(ci.getClassInstructing()); if (a != null && !a.getClazz().isCancelled() && assignment.overlaps(a) && !clazz.canShareInstructor(a.getClazz())) return true; } } } Class_ parent = clazz.getParentClass(); while (parent != null) { Assignment a = getAssignment(parent); if (a != null && !a.getClazz().isCancelled() && assignment.overlaps(a)) return true; parent = parent.getParentClass(); } for (Iterator<SchedulingSubpart> i = clazz.getSchedulingSubpart().getInstrOfferingConfig() .getSchedulingSubparts().iterator(); i.hasNext();) { SchedulingSubpart ss = i.next(); if (ss.getClasses().size() == 1) { Class_ child = ss.getClasses().iterator().next(); if (clazz.equals(child)) continue; Assignment a = getAssignment(child); if (a != null && !a.getClazz().isCancelled() && assignment.overlaps(a)) return true; } } } return false; } @Override public Set<Assignment> getConflicts(Long classId) throws Exception { if (classId == null) return null; Class_ clazz = Class_DAO.getInstance().get(classId); if (clazz == null || clazz.isCancelled()) return null; Assignment assignment = getAssignment(clazz); if (assignment == null) return null; Set<Assignment> conflicts = new HashSet<Assignment>(); if (assignment.getRooms() != null) for (Location room : assignment.getRooms()) { if (!room.isIgnoreRoomCheck()) { for (Assignment a : room.getAssignments(this)) if (!assignment.equals(a) && !a.getClazz().isCancelled() && assignment.overlaps(a) && !clazz.canShareRoom(a.getClazz())) conflicts.add(a); } } if (clazz.getClassInstructors() != null) for (ClassInstructor instructor : clazz.getClassInstructors()) { if (!instructor.isLead()) continue; for (DepartmentalInstructor di : DepartmentalInstructor .getAllForInstructor(instructor.getInstructor())) { for (ClassInstructor ci : di.getClasses()) { if (ci.equals(instructor)) continue; Assignment a = getAssignment(ci.getClassInstructing()); if (a != null && !a.getClazz().isCancelled() && assignment.overlaps(a) && !clazz.canShareInstructor(a.getClazz())) conflicts.add(a); } } } Class_ parent = clazz.getParentClass(); while (parent != null) { Assignment a = getAssignment(parent); if (a != null && !a.getClazz().isCancelled() && assignment.overlaps(a)) conflicts.add(a); parent = parent.getParentClass(); } Queue<Class_> children = new LinkedList(clazz.getChildClasses()); Class_ child = null; while ((child = children.poll()) != null) { Assignment a = getAssignment(child); if (a != null && !a.getClazz().isCancelled() && assignment.overlaps(a)) conflicts.add(a); if (!child.getChildClasses().isEmpty()) children.addAll(child.getChildClasses()); } for (Iterator<SchedulingSubpart> i = clazz.getSchedulingSubpart().getInstrOfferingConfig() .getSchedulingSubparts().iterator(); i.hasNext();) { SchedulingSubpart ss = i.next(); if (ss.getClasses().size() == 1) { child = ss.getClasses().iterator().next(); if (clazz.equals(child)) continue; Assignment a = getAssignment(child); if (a != null && !a.getClazz().isCancelled() && assignment.overlaps(a)) conflicts.add(a); } } return conflicts; } @Override public Set<TimeBlock> getConflictingTimeBlocks(Long classId) throws Exception { return null; } }