protected void saveSolution(org.hibernate.Session hibSession) { TimetableManager owner = TimetableManager.findByExternalId( getModel().getProperties().getProperty("General.OwnerPuid")); Collection exams = org.unitime.timetable.model.Exam.findAll(iSessionId, iExamTypeId); Hashtable<Long, ExamEvent> examEvents = new Hashtable(); for (Iterator i = hibSession .createQuery( "select e from ExamEvent e where e.exam.session.uniqueId=:sessionId and e.exam.examType.uniqueId=:examTypeId") .setLong("sessionId", iSessionId) .setLong("examTypeId", iExamTypeId) .iterate(); i.hasNext(); ) { ExamEvent e = (ExamEvent) i.next(); examEvents.put(e.getExam().getUniqueId(), e); } iProgress.setPhase("Saving assignments...", exams.size()); Hashtable examTable = new Hashtable(); for (Iterator i = exams.iterator(); i.hasNext(); ) { iProgress.incProgress(); org.unitime.timetable.model.Exam exam = (org.unitime.timetable.model.Exam) i.next(); ExamAssignment oldAssignment = new ExamAssignment(exam); exam.setAssignedPeriod(null); exam.setAssignedPreference(null); exam.getAssignedRooms().clear(); ExamEvent event = examEvents.get(exam.getUniqueId()); if (event != null) hibSession.delete(event); for (Iterator j = exam.getConflicts().iterator(); j.hasNext(); ) { ExamConflict conf = (ExamConflict) j.next(); hibSession.delete(conf); j.remove(); } Exam examVar = null; for (Exam x : getModel().variables()) { if (exam.getUniqueId().equals(x.getId())) { examVar = x; break; } } if (examVar == null) { iProgress.warn("Exam " + getExamLabel(exam) + " was not loaded."); if (oldAssignment.getPeriodId() != null) { SubjectArea subject = null; Department dept = null; for (Iterator j = new TreeSet(exam.getOwners()).iterator(); j.hasNext(); ) { ExamOwner xo = (ExamOwner) j.next(); subject = xo.getCourse().getSubjectArea(); dept = subject.getDepartment(); break; } ChangeLog.addChange( hibSession, owner, exam.getSession(), exam, exam.getName() + " (" + oldAssignment.getPeriodAbbreviation() + " " + oldAssignment.getRoomsName(", ") + " → N/A)", ChangeLog.Source.EXAM_SOLVER, ChangeLog.Operation.UNASSIGN, subject, dept); } continue; } examTable.put(examVar.getId(), exam); ExamPlacement placement = getAssignment().getValue(examVar); if (placement == null) { iProgress.warn("Exam " + getExamLabel(exam) + " has no assignment."); if (oldAssignment.getPeriodId() != null) { SubjectArea subject = null; Department dept = null; for (Iterator j = new TreeSet(exam.getOwners()).iterator(); j.hasNext(); ) { ExamOwner xo = (ExamOwner) j.next(); subject = xo.getCourse().getSubjectArea(); dept = subject.getDepartment(); break; } ChangeLog.addChange( hibSession, owner, exam.getSession(), exam, exam.getName() + " (" + oldAssignment.getPeriodAbbreviation() + " " + oldAssignment.getRoomsName(", ") + " → N/A)", ChangeLog.Source.EXAM_SOLVER, ChangeLog.Operation.UNASSIGN, subject, dept); } continue; } ExamPeriod period = new ExamPeriodDAO().get(placement.getPeriod().getId()); if (period == null) { iProgress.warn( "Examination period " + placement.getPeriod().getDayStr() + " " + placement.getPeriod().getTimeStr() + " not found."); if (oldAssignment.getPeriodId() != null) { SubjectArea subject = null; Department dept = null; for (Iterator j = new TreeSet(exam.getOwners()).iterator(); j.hasNext(); ) { ExamOwner xo = (ExamOwner) j.next(); subject = xo.getCourse().getSubjectArea(); dept = subject.getDepartment(); break; } ChangeLog.addChange( hibSession, owner, exam.getSession(), exam, exam.getName() + " (" + oldAssignment.getPeriodAbbreviation() + " " + oldAssignment.getRoomsName(", ") + " → N/A)", ChangeLog.Source.EXAM_SOLVER, ChangeLog.Operation.UNASSIGN, subject, dept); } continue; } exam.setAssignedPeriod(period); for (Iterator j = placement.getRoomPlacements().iterator(); j.hasNext(); ) { ExamRoomPlacement room = (ExamRoomPlacement) j.next(); Location location = new LocationDAO().get(room.getId()); if (location == null) { iProgress.warn("Location " + room.getName() + " (id:" + room.getId() + ") not found."); continue; } exam.getAssignedRooms().add(location); } exam.setAssignedPreference( new ExamAssignment(placement, getAssignment()).getAssignedPreferenceString()); hibSession.saveOrUpdate(exam); ExamAssignment newAssignment = new ExamAssignment(exam); if (!ToolBox.equals(newAssignment.getPeriodId(), oldAssignment.getPeriodId()) || !ToolBox.equals(newAssignment.getRooms(), oldAssignment.getRooms())) { SubjectArea subject = null; Department dept = null; for (Iterator j = new TreeSet(exam.getOwners()).iterator(); j.hasNext(); ) { ExamOwner xo = (ExamOwner) j.next(); subject = xo.getCourse().getSubjectArea(); dept = subject.getDepartment(); break; } ChangeLog.addChange( hibSession, owner, exam.getSession(), exam, exam.getName() + " (" + (oldAssignment.getPeriod() == null ? "N/A" : oldAssignment.getPeriodAbbreviation() + " " + oldAssignment.getRoomsName(", ")) + " → " + newAssignment.getPeriodAbbreviation() + " " + newAssignment.getRoomsName(", ") + ")", ChangeLog.Source.EXAM_SOLVER, ChangeLog.Operation.ASSIGN, subject, dept); } } iProgress.setPhase("Saving conflicts...", getAssignment().nrAssignedVariables()); for (Exam examVar : getAssignment().assignedVariables()) { iProgress.incProgress(); org.unitime.timetable.model.Exam exam = (org.unitime.timetable.model.Exam) examTable.get(examVar.getId()); if (exam == null) continue; ExamPlacement placement = (ExamPlacement) getAssignment().getValue(examVar); ExamAssignmentInfo info = new ExamAssignmentInfo(placement, getAssignment()); for (Iterator i = info.getDirectConflicts().iterator(); i.hasNext(); ) { ExamAssignmentInfo.DirectConflict dc = (ExamAssignmentInfo.DirectConflict) i.next(); if (dc.getOtherExam() == null) continue; if (examVar.getId() < dc.getOtherExam().getExamId().longValue()) { org.unitime.timetable.model.Exam otherExam = (org.unitime.timetable.model.Exam) examTable.get(dc.getOtherExam().getExamId()); if (otherExam == null) { iProgress.warn( "Exam " + dc.getOtherExam().getExamName() + " (id:" + dc.getOtherExam().getExamId() + ") not found."); continue; } ExamConflict conf = new ExamConflict(); conf.setConflictType(ExamConflict.sConflictTypeDirect); conf.setStudents(getStudents(hibSession, dc.getStudents())); conf.setNrStudents(conf.getStudents().size()); hibSession.save(conf); exam.getConflicts().add(conf); otherExam.getConflicts().add(conf); iProgress.debug( "Direct conflict of " + dc.getStudents().size() + " students between " + exam.getLabel() + " and " + otherExam.getLabel()); } } for (Iterator i = info.getBackToBackConflicts().iterator(); i.hasNext(); ) { ExamAssignmentInfo.BackToBackConflict btb = (ExamAssignmentInfo.BackToBackConflict) i.next(); if (examVar.getId() < btb.getOtherExam().getExamId().longValue()) { org.unitime.timetable.model.Exam otherExam = (org.unitime.timetable.model.Exam) examTable.get(btb.getOtherExam().getExamId()); if (otherExam == null) { iProgress.warn( "Exam " + btb.getOtherExam().getExamName() + " (id:" + btb.getOtherExam().getExamId() + ") not found."); continue; } ExamConflict conf = new ExamConflict(); conf.setConflictType( btb.isDistance() ? ExamConflict.sConflictTypeBackToBackDist : ExamConflict.sConflictTypeBackToBack); conf.setDistance(btb.getDistance()); conf.setStudents(getStudents(hibSession, btb.getStudents())); conf.setNrStudents(conf.getStudents().size()); exam.getConflicts().add(conf); otherExam.getConflicts().add(conf); hibSession.save(conf); iProgress.debug( "Back-to-back conflict of " + btb.getStudents().size() + " students between " + exam.getLabel() + " and " + otherExam.getLabel()); } } m2d: for (Iterator i = info.getMoreThanTwoADaysConflicts().iterator(); i.hasNext(); ) { ExamAssignmentInfo.MoreThanTwoADayConflict m2d = (ExamAssignmentInfo.MoreThanTwoADayConflict) i.next(); HashSet confExams = new HashSet(); confExams.add(exam); for (Iterator j = m2d.getOtherExams().iterator(); j.hasNext(); ) { ExamAssignment otherExamAsg = (ExamAssignment) j.next(); if (examVar.getId() >= otherExamAsg.getExamId().longValue()) continue m2d; org.unitime.timetable.model.Exam otherExam = (org.unitime.timetable.model.Exam) examTable.get(otherExamAsg.getExamId()); if (otherExam == null) { iProgress.warn( "Exam " + otherExamAsg.getExamName() + " (id:" + otherExamAsg.getExamId() + ") not found."); continue; } confExams.add(otherExam); } if (confExams.size() >= 3) { ExamConflict conf = new ExamConflict(); conf.setConflictType(ExamConflict.sConflictTypeMoreThanTwoADay); conf.setStudents(getStudents(hibSession, m2d.getStudents())); conf.setNrStudents(conf.getStudents().size()); hibSession.save(conf); for (Iterator j = confExams.iterator(); j.hasNext(); ) ((org.unitime.timetable.model.Exam) j.next()).getConflicts().add(conf); iProgress.debug( "More than 2 a day conflict of " + m2d.getStudents().size() + " students between " + exam.getLabel() + " and " + m2d.getOtherExams()); } } for (Iterator i = info.getInstructorDirectConflicts().iterator(); i.hasNext(); ) { ExamAssignmentInfo.DirectConflict dc = (ExamAssignmentInfo.DirectConflict) i.next(); if (dc.getOtherExam() == null) continue; if (examVar.getId() < dc.getOtherExam().getExamId().longValue()) { org.unitime.timetable.model.Exam otherExam = (org.unitime.timetable.model.Exam) examTable.get(dc.getOtherExam().getExamId()); if (otherExam == null) { iProgress.warn( "Exam " + dc.getOtherExam().getExamName() + " (id:" + dc.getOtherExam().getExamId() + ") not found."); continue; } ExamConflict conf = new ExamConflict(); conf.setConflictType(ExamConflict.sConflictTypeDirect); conf.setInstructors(getInstructors(hibSession, dc.getStudents())); conf.setNrInstructors(conf.getInstructors().size()); hibSession.save(conf); exam.getConflicts().add(conf); otherExam.getConflicts().add(conf); iProgress.debug( "Direct conflict of " + dc.getStudents().size() + " instructors between " + exam.getLabel() + " and " + otherExam.getLabel()); } } for (Iterator i = info.getInstructorBackToBackConflicts().iterator(); i.hasNext(); ) { ExamAssignmentInfo.BackToBackConflict btb = (ExamAssignmentInfo.BackToBackConflict) i.next(); if (examVar.getId() < btb.getOtherExam().getExamId().longValue()) { org.unitime.timetable.model.Exam otherExam = (org.unitime.timetable.model.Exam) examTable.get(btb.getOtherExam().getExamId()); if (otherExam == null) { iProgress.warn( "Exam " + btb.getOtherExam().getExamName() + " (id:" + btb.getOtherExam().getExamId() + ") not found."); continue; } ExamConflict conf = new ExamConflict(); conf.setConflictType( btb.isDistance() ? ExamConflict.sConflictTypeBackToBackDist : ExamConflict.sConflictTypeBackToBack); conf.setDistance(btb.getDistance()); conf.setInstructors(getInstructors(hibSession, btb.getStudents())); conf.setNrInstructors(conf.getInstructors().size()); exam.getConflicts().add(conf); otherExam.getConflicts().add(conf); hibSession.save(conf); iProgress.debug( "Back-to-back conflict of " + btb.getStudents().size() + " instructors between " + exam.getLabel() + " and " + otherExam.getLabel()); } } m2d: for (Iterator i = info.getInstructorMoreThanTwoADaysConflicts().iterator(); i.hasNext(); ) { ExamAssignmentInfo.MoreThanTwoADayConflict m2d = (ExamAssignmentInfo.MoreThanTwoADayConflict) i.next(); HashSet confExams = new HashSet(); confExams.add(exam); for (Iterator j = m2d.getOtherExams().iterator(); j.hasNext(); ) { ExamAssignment otherExamAsg = (ExamAssignment) j.next(); if (examVar.getId() >= otherExamAsg.getExamId().longValue()) continue m2d; org.unitime.timetable.model.Exam otherExam = (org.unitime.timetable.model.Exam) examTable.get(otherExamAsg.getExamId()); if (otherExam == null) { iProgress.warn( "Exam " + otherExamAsg.getExamName() + " (id:" + otherExamAsg.getExamId() + ") not found."); continue; } confExams.add(otherExam); } if (confExams.size() >= 3) { ExamConflict conf = new ExamConflict(); conf.setConflictType(ExamConflict.sConflictTypeMoreThanTwoADay); conf.setInstructors(getInstructors(hibSession, m2d.getStudents())); conf.setNrInstructors(conf.getInstructors().size()); hibSession.save(conf); for (Iterator j = confExams.iterator(); j.hasNext(); ) ((org.unitime.timetable.model.Exam) j.next()).getConflicts().add(conf); iProgress.debug( "More than 2 a day conflict of " + m2d.getStudents().size() + " instructors between " + exam.getLabel() + " and " + m2d.getOtherExams()); } } } iProgress.setPhase("Saving events...", getAssignment().nrAssignedVariables()); String ownerPuid = getModel().getProperties().getProperty("General.OwnerPuid"); EventContact contact = EventContact.findByExternalUniqueId(ownerPuid); if (contact == null) { TimetableManager manager = TimetableManager.findByExternalId(ownerPuid); 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); } for (Exam examVar : getAssignment().assignedVariables()) { iProgress.incProgress(); org.unitime.timetable.model.Exam exam = (org.unitime.timetable.model.Exam) examTable.get(examVar.getId()); if (exam == null) continue; ExamEvent event = exam.generateEvent(null, true); if (event != null) { event.setEventName(examVar.getName()); event.setMinCapacity(examVar.getSize()); event.setMaxCapacity(examVar.getSize()); event.setMainContact(contact); hibSession.saveOrUpdate(event); } if (event != null || !exam.getConflicts().isEmpty()) hibSession.saveOrUpdate(exam); } }
@Override public SaveOrApproveEventRpcResponse execute(SaveEventRpcRequest request, EventContext context) { if (request.getEvent().hasContact() && (request.getEvent().getContact().getExternalId() == null || !request .getEvent() .getContact() .getExternalId() .equals(context.getUser().getExternalUserId()))) { switch (request.getEvent().getType()) { case Special: case Course: case Unavailabile: context.checkPermission(Right.EventLookupContact); } } if (request.getEvent().getId() == null) { // new even switch (request.getEvent().getType()) { case Special: context.checkPermission(Right.EventAddSpecial); break; case Course: context.checkPermission(Right.EventAddCourseRelated); break; case Unavailabile: context.checkPermission(Right.EventAddUnavailable); break; default: throw context.getException(); } } else { // existing event context.checkPermission(request.getEvent().getId(), "Event", Right.EventEdit); } // Check main contact email if (request.getEvent().hasContact() && request.getEvent().getContact().hasEmail()) { try { new InternetAddress(request.getEvent().getContact().getEmail(), true); } catch (AddressException e) { throw new GwtRpcException( MESSAGES.badEmailAddress(request.getEvent().getContact().getEmail(), e.getMessage())); } } // Check additional emails if (request.getEvent().hasEmail()) { String suffix = ApplicationProperty.EmailDefaultAddressSuffix.value(); for (String address : request.getEvent().getEmail().split("[\n,]")) { String email = address.trim(); if (email.isEmpty()) continue; if (suffix != null && email.indexOf('@') < 0) email += suffix; try { new InternetAddress(email, true); } catch (AddressException e) { throw new GwtRpcException(MESSAGES.badEmailAddress(address, e.getMessage())); } } } org.hibernate.Session hibSession = SessionDAO.getInstance().getSession(); Transaction tx = hibSession.beginTransaction(); try { Session session = SessionDAO.getInstance().get(request.getSessionId(), hibSession); Date now = new Date(); Event event = null; if (request.getEvent().getId() != null) { event = EventDAO.getInstance().get(request.getEvent().getId(), hibSession); } else { switch (request.getEvent().getType()) { case Special: event = new SpecialEvent(); break; case Course: event = new CourseEvent(); break; case Unavailabile: event = new UnavailableEvent(); break; default: throw new GwtRpcException( MESSAGES.failedSaveEventWrongType(request.getEvent().getType().getName(CONSTANTS))); } } SaveOrApproveEventRpcResponse response = new SaveOrApproveEventRpcResponse(); event.setEventName(request.getEvent().getName()); if (event.getEventName() == null || event.getEventName().isEmpty() && request.getEvent().getType() == EventType.Unavailabile) event.setEventName(MESSAGES.unavailableEventDefaultName()); event.setEmail(request.getEvent().getEmail()); if (context.hasPermission(Right.EventSetExpiration) || event.getExpirationDate() != null) event.setExpirationDate(request.getEvent().getExpirationDate()); event.setSponsoringOrganization( request.getEvent().hasSponsor() ? SponsoringOrganizationDAO.getInstance() .get(request.getEvent().getSponsor().getUniqueId()) : null); if (event instanceof UnavailableEvent) { } else if (event instanceof SpecialEvent) { event.setMinCapacity(request.getEvent().getMaxCapacity()); event.setMaxCapacity(request.getEvent().getMaxCapacity()); } if (event.getAdditionalContacts() == null) { event.setAdditionalContacts(new HashSet<EventContact>()); } if (context.hasPermission(Right.EventLookupContact)) { Set<EventContact> existingContacts = new HashSet<EventContact>(event.getAdditionalContacts()); event.getAdditionalContacts().clear(); if (request.getEvent().hasAdditionalContacts()) for (ContactInterface c : request.getEvent().getAdditionalContacts()) { if (c.getExternalId() == null) continue; EventContact contact = null; for (EventContact x : existingContacts) if (c.getExternalId().equals(x.getExternalUniqueId())) { contact = x; break; } if (contact == null) { contact = (EventContact) hibSession .createQuery("from EventContact where externalUniqueId = :externalId") .setString("externalId", c.getExternalId()) .setMaxResults(1) .uniqueResult(); } if (contact == null) { contact = new EventContact(); contact.setExternalUniqueId(c.getExternalId()); contact.setFirstName(c.getFirstName()); contact.setMiddleName(c.getMiddleName()); contact.setLastName(c.getLastName()); contact.setAcademicTitle(c.getAcademicTitle()); contact.setEmailAddress(c.getEmail()); contact.setPhone(c.getPhone()); hibSession.save(contact); } event.getAdditionalContacts().add(contact); } } EventContact main = event.getMainContact(); if (main == null || main.getExternalUniqueId() == null || !main.getExternalUniqueId().equals(request.getEvent().getContact().getExternalId())) { main = (EventContact) hibSession .createQuery("from EventContact where externalUniqueId = :externalId") .setString("externalId", request.getEvent().getContact().getExternalId()) .setMaxResults(1) .uniqueResult(); if (main == null) { main = new EventContact(); main.setExternalUniqueId(request.getEvent().getContact().getExternalId()); } } main.setFirstName(request.getEvent().getContact().getFirstName()); main.setMiddleName(request.getEvent().getContact().getMiddleName()); main.setLastName(request.getEvent().getContact().getLastName()); main.setAcademicTitle(request.getEvent().getContact().getAcademicTitle()); main.setEmailAddress(request.getEvent().getContact().getEmail()); main.setPhone(request.getEvent().getContact().getPhone()); hibSession.saveOrUpdate(main); event.setMainContact(main); if (event.getNotes() == null) event.setNotes(new HashSet<EventNote>()); if (event.getMeetings() == null) event.setMeetings(new HashSet<Meeting>()); Set<Meeting> remove = new HashSet<Meeting>(event.getMeetings()); TreeSet<Meeting> createdMeetings = new TreeSet<Meeting>(); Set<Meeting> cancelledMeetings = new TreeSet<Meeting>(); Set<Meeting> updatedMeetings = new TreeSet<Meeting>(); for (MeetingInterface m : request.getEvent().getMeetings()) { Meeting meeting = null; if (m.getApprovalStatus() == ApprovalStatus.Deleted) { if (!context.hasPermission(meeting, Right.EventMeetingDelete) && context.hasPermission(meeting, Right.EventMeetingCancel)) { // Cannot delete, but can cancel --> cancel the meeting instead m.setApprovalStatus(ApprovalStatus.Cancelled); } else { continue; } } if (m.getId() != null) for (Iterator<Meeting> i = remove.iterator(); i.hasNext(); ) { Meeting x = i.next(); if (m.getId().equals(x.getUniqueId())) { meeting = x; i.remove(); break; } } if (meeting != null) { if (m.getApprovalStatus().ordinal() != meeting.getApprovalStatus()) { switch (m.getApprovalStatus()) { case Cancelled: switch (meeting.getEvent().getEventType()) { case Event.sEventTypeFinalExam: case Event.sEventTypeMidtermExam: if (!context.hasPermission(meeting, Right.EventMeetingCancelExam)) throw new GwtRpcException( MESSAGES.failedApproveEventNoRightsToCancel(toString(meeting))); break; case Event.sEventTypeClass: if (!context.hasPermission(meeting, Right.EventMeetingCancelClass)) throw new GwtRpcException( MESSAGES.failedApproveEventNoRightsToCancel(toString(meeting))); break; default: if (!context.hasPermission(meeting, Right.EventMeetingCancel)) throw new GwtRpcException( MESSAGES.failedApproveEventNoRightsToCancel(toString(meeting))); break; } meeting.setStatus(Meeting.Status.CANCELLED); meeting.setApprovalDate(now); hibSession.update(meeting); cancelledMeetings.add(meeting); response.addCancelledMeeting(m); } } else { if (m.getStartOffset() != (meeting.getStartOffset() == null ? 0 : meeting.getStartOffset()) || m.getEndOffset() != (meeting.getStopOffset() == null ? 0 : meeting.getStopOffset())) { if (!context.hasPermission(meeting, Right.EventMeetingEdit)) throw new GwtRpcException( MESSAGES.failedSaveEventCanNotEditMeeting(toString(meeting))); meeting.setStartOffset(m.getStartOffset()); meeting.setStopOffset(m.getEndOffset()); hibSession.update(meeting); response.addUpdatedMeeting(m); updatedMeetings.add(meeting); } } } else { response.addCreatedMeeting(m); meeting = new Meeting(); meeting.setEvent(event); Location location = null; if (m.hasLocation()) { if (m.getLocation().getId() != null) location = LocationDAO.getInstance().get(m.getLocation().getId(), hibSession); else if (m.getLocation().getName() != null) location = Location.findByName( hibSession, request.getSessionId(), m.getLocation().getName()); } if (location == null) throw new GwtRpcException(MESSAGES.failedSaveEventNoLocation(toString(m))); meeting.setLocationPermanentId(location.getPermanentId()); meeting.setStatus(Meeting.Status.PENDING); meeting.setApprovalDate(null); if (!context.hasPermission(location, Right.EventLocation)) throw new GwtRpcException(MESSAGES.failedSaveEventWrongLocation(m.getLocationName())); if (request.getEvent().getType() == EventType.Unavailabile && !context.hasPermission(location, Right.EventLocationUnavailable)) throw new GwtRpcException( MESSAGES.failedSaveCannotMakeUnavailable(m.getLocationName())); if (m.getApprovalStatus() == ApprovalStatus.Approved && context.hasPermission(location, Right.EventLocationApprove)) { meeting.setStatus(Meeting.Status.APPROVED); meeting.setApprovalDate(now); } if (context.isPastOrOutside(m.getMeetingDate())) throw new GwtRpcException( MESSAGES.failedSaveEventPastOrOutside(getDateFormat().format(m.getMeetingDate()))); if (!context.hasPermission(location, Right.EventLocationOverbook)) { List<MeetingConflictInterface> conflicts = computeConflicts(hibSession, m, event.getUniqueId()); if (!conflicts.isEmpty()) throw new GwtRpcException( MESSAGES.failedSaveEventConflict(toString(m), toString(conflicts.get(0)))); } m.setApprovalDate(meeting.getApprovalDate()); m.setApprovalStatus(meeting.getApprovalStatus()); meeting.setStartPeriod(m.getStartSlot()); meeting.setStopPeriod(m.getEndSlot()); meeting.setStartOffset(m.getStartOffset()); meeting.setStopOffset(m.getEndOffset()); meeting.setClassCanOverride(true); meeting.setMeetingDate(m.getMeetingDate()); event.getMeetings().add(meeting); createdMeetings.add(meeting); } // automatic approval if (meeting.getApprovalDate() == null) { switch (request.getEvent().getType()) { case Unavailabile: case Class: case FinalExam: case MidtermExam: meeting.setStatus(Meeting.Status.APPROVED); meeting.setApprovalDate(now); break; } } } if (!remove.isEmpty()) { for (Iterator<Meeting> i = remove.iterator(); i.hasNext(); ) { Meeting m = i.next(); if (!context.hasPermission(m, Right.EventMeetingDelete)) { if (m.getStatus() == Status.CANCELLED || m.getStatus() == Status.REJECTED) { i.remove(); continue; } throw new GwtRpcException(MESSAGES.failedSaveEventCanNotDeleteMeeting(toString(m))); } MeetingInterface meeting = new MeetingInterface(); meeting.setId(m.getUniqueId()); meeting.setMeetingDate(m.getMeetingDate()); meeting.setDayOfWeek(Constants.getDayOfWeek(m.getMeetingDate())); meeting.setStartTime(m.getStartTime().getTime()); meeting.setStopTime(m.getStopTime().getTime()); meeting.setDayOfYear( CalendarUtils.date2dayOfYear(session.getSessionStartYear(), m.getMeetingDate())); meeting.setStartSlot(m.getStartPeriod()); meeting.setEndSlot(m.getStopPeriod()); meeting.setStartOffset(m.getStartOffset() == null ? 0 : m.getStartOffset()); meeting.setEndOffset(m.getStopOffset() == null ? 0 : m.getStopOffset()); meeting.setPast(context.isPastOrOutside(m.getStartTime())); meeting.setApprovalDate(m.getApprovalDate()); meeting.setApprovalStatus(m.getApprovalStatus()); if (m.getLocation() != null) { ResourceInterface location = new ResourceInterface(); location.setType(ResourceType.ROOM); location.setId(m.getLocation().getUniqueId()); location.setName(m.getLocation().getLabel()); location.setSize(m.getLocation().getCapacity()); location.setRoomType(m.getLocation().getRoomTypeLabel()); location.setBreakTime(m.getLocation().getEffectiveBreakTime()); location.setMessage(m.getLocation().getEventMessage()); location.setIgnoreRoomCheck(m.getLocation().isIgnoreRoomCheck()); meeting.setLocation(location); } response.addDeletedMeeting(meeting); } event.getMeetings().removeAll(remove); } EventInterface.DateFormatter df = new EventInterface.DateFormatter() { Formats.Format<Date> dfShort = Formats.getDateFormat(Formats.Pattern.DATE_EVENT_SHORT); Formats.Format<Date> dfLong = Formats.getDateFormat(Formats.Pattern.DATE_EVENT_LONG); @Override public String formatFirstDate(Date date) { return dfShort.format(date); } @Override public String formatLastDate(Date date) { return dfLong.format(date); } }; FileItem attachment = (FileItem) context.getAttribute(UploadServlet.SESSION_LAST_FILE); boolean attached = false; if (response.hasCreatedMeetings()) { EventNote note = new EventNote(); note.setEvent(event); note.setNoteType( event.getUniqueId() == null ? EventNote.sEventNoteTypeCreateEvent : EventNote.sEventNoteTypeAddMeetings); note.setTimeStamp(now); note.setUser(context.getUser().getTrueName()); note.setUserId(context.getUser().getTrueExternalUserId()); if (request.hasMessage()) note.setTextNote(request.getMessage()); note.setMeetings( EventInterface.toString(response.getCreatedMeetings(), CONSTANTS, "\n", df)); note.setAffectedMeetings(createdMeetings); event.getNotes().add(note); NoteInterface n = new NoteInterface(); n.setDate(now); n.setMeetings(note.getMeetings()); n.setUser(context.getUser().getTrueName()); n.setType(NoteInterface.NoteType.values()[note.getNoteType()]); n.setNote(note.getTextNote()); if (attachment != null) { note.setAttachedName(attachment.getName()); note.setAttachedFile(attachment.get()); note.setAttachedContentType(attachment.getContentType()); attached = true; n.setAttachment(attachment.getName()); } response.addNote(n); } if (response.hasUpdatedMeetings() || (!response.hasCreatedMeetings() && !response.hasDeletedMeetings() && !response.hasCancelledMeetings())) { EventNote note = new EventNote(); note.setEvent(event); note.setNoteType(EventNote.sEventNoteTypeEditEvent); note.setTimeStamp(now); note.setUser(context.getUser().getTrueName()); note.setUserId(context.getUser().getTrueExternalUserId()); note.setAffectedMeetings(updatedMeetings); if (request.hasMessage()) note.setTextNote(request.getMessage()); if (response.hasUpdatedMeetings()) note.setMeetings( EventInterface.toString(response.getUpdatedMeetings(), CONSTANTS, "\n", df)); event.getNotes().add(note); NoteInterface n = new NoteInterface(); n.setDate(now); n.setMeetings(note.getMeetings()); n.setUser(context.getUser().getTrueName()); n.setType(NoteInterface.NoteType.values()[note.getNoteType()]); n.setNote(note.getTextNote()); if (attachment != null && !attached) { note.setAttachedName(attachment.getName()); note.setAttachedFile(attachment.get()); note.setAttachedContentType(attachment.getContentType()); attached = true; n.setAttachment(attachment.getName()); } response.addNote(n); } if (response.hasDeletedMeetings()) { EventNote note = new EventNote(); note.setEvent(event); note.setNoteType(EventNote.sEventNoteTypeDeletion); note.setTimeStamp(now); note.setUser(context.getUser().getTrueName()); note.setUserId(context.getUser().getTrueExternalUserId()); if (request.hasMessage()) note.setTextNote(request.getMessage()); note.setMeetings( EventInterface.toString(response.getDeletedMeetings(), CONSTANTS, "\n", df)); event.getNotes().add(note); NoteInterface n = new NoteInterface(); n.setDate(now); n.setMeetings(note.getMeetings()); n.setUser(context.getUser().getTrueName()); n.setType(NoteInterface.NoteType.values()[note.getNoteType()]); n.setNote(note.getTextNote()); if (attachment != null && !attached) { note.setAttachedName(attachment.getName()); note.setAttachedFile(attachment.get()); note.setAttachedContentType(attachment.getContentType()); attached = true; n.setAttachment(attachment.getName()); } response.addNote(n); } if (response.hasCancelledMeetings()) { EventNote note = new EventNote(); note.setEvent(event); note.setNoteType(EventNote.sEventNoteTypeCancel); note.setTimeStamp(now); note.setUser(context.getUser().getTrueName()); note.setUserId(context.getUser().getTrueExternalUserId()); note.setAffectedMeetings(cancelledMeetings); if (request.hasMessage()) note.setTextNote(request.getMessage()); note.setMeetings( EventInterface.toString(response.getCancelledMeetings(), CONSTANTS, "\n", df)); event.getNotes().add(note); NoteInterface n = new NoteInterface(); n.setDate(now); n.setMeetings(note.getMeetings()); n.setUser(context.getUser().getTrueName()); n.setType(NoteInterface.NoteType.values()[note.getNoteType()]); n.setNote(note.getTextNote()); if (attachment != null && !attached) { note.setAttachedName(attachment.getName()); note.setAttachedFile(attachment.get()); note.setAttachedContentType(attachment.getContentType()); attached = true; n.setAttachment(attachment.getName()); } response.addNote(n); } if (request.getEvent().getType() == EventType.Course) { CourseEvent ce = (CourseEvent) event; ce.setReqAttendance(request.getEvent().hasRequiredAttendance()); if (ce.getRelatedCourses() == null) ce.setRelatedCourses(new HashSet<RelatedCourseInfo>()); else ce.getRelatedCourses().clear(); if (request.getEvent().hasRelatedObjects()) for (RelatedObjectInterface r : request.getEvent().getRelatedObjects()) { RelatedCourseInfo related = new RelatedCourseInfo(); related.setEvent(ce); if (r.getSelection() != null) { related.setOwnerId(r.getUniqueId()); related.setOwnerType(r.getType().ordinal()); related.setCourse( CourseOfferingDAO.getInstance().get(r.getSelection()[1], hibSession)); } else { switch (r.getType()) { case Course: related.setOwner(CourseOfferingDAO.getInstance().get(r.getUniqueId())); break; case Class: related.setOwner(Class_DAO.getInstance().get(r.getUniqueId())); break; case Config: related.setOwner(InstrOfferingConfigDAO.getInstance().get(r.getUniqueId())); break; case Offering: related.setOwner(InstructionalOfferingDAO.getInstance().get(r.getUniqueId())); break; } } ce.getRelatedCourses().add(related); } } if (event.getUniqueId() == null) { hibSession.save(event); response.setEvent( EventDetailBackend.getEventDetail( SessionDAO.getInstance().get(request.getSessionId(), hibSession), event, context)); } else if (event.getMeetings().isEmpty()) { response.setEvent( EventDetailBackend.getEventDetail( SessionDAO.getInstance().get(request.getSessionId(), hibSession), event, context)); response.getEvent().setId(null); hibSession.delete(event); } else { hibSession.update(event); response.setEvent( EventDetailBackend.getEventDetail( SessionDAO.getInstance().get(request.getSessionId(), hibSession), event, context)); } tx.commit(); new EventEmail(request, response).send(context); return response; } catch (Exception ex) { tx.rollback(); if (ex instanceof GwtRpcException) throw (GwtRpcException) ex; throw new GwtRpcException(ex.getMessage(), ex); } }