@Override
  public FilterRpcResponse execute(
      SectioningStatusFilterRpcRequest request, SessionContext context) {
    try {
      boolean online = "true".equals(request.getOption("online"));

      if (context.isAuthenticated()) {
        request.setOption("user", context.getUser().getExternalUserId());
        if (context.getUser().getCurrentAuthority() != null
            && context.getUser().getCurrentAuthority().hasRight(Right.ConsentApproval))
          request.setOption("approval", "true");
      }

      if (online) {
        Long sessionId = getStatusPageSessionId(context);

        OnlineSectioningServer server =
            solverServerService
                .getOnlineStudentSchedulingContainer()
                .getSolver(sessionId.toString());
        if (server == null) throw new SectioningException(MSG.exceptionBadSession());

        context.checkPermission(
            server.getAcademicSession().getUniqueId(), "Session", Right.SchedulingDashboard);
        request.setSessionId(server.getAcademicSession().getUniqueId());

        return server.execute(
            server.createAction(SectioningStatusFilterAction.class).forRequest(request),
            currentUser(context));
      } else {
        OnlineSectioningServer server = studentSectioningSolverService.getSolver();
        if (server == null) throw new SectioningException(MSG.exceptionNoSolver());

        context.checkPermission(
            server.getAcademicSession().getUniqueId(),
            "Session",
            Right.StudentSectioningSolverDashboard);
        request.setSessionId(server.getAcademicSession().getUniqueId());

        return server.execute(
            server.createAction(SectioningStatusFilterAction.class).forRequest(request),
            currentUser(context));
      }
    } catch (PageAccessException e) {
      throw e;
    } catch (SectioningException e) {
      throw e;
    } catch (Exception e) {
      sLog.error(e.getMessage(), e);
      throw new SectioningException(MSG.exceptionUnknown(e.getMessage()), e);
    }
  }
예제 #2
0
 @Override
 public String getValue() {
   if (iCourses.getSelectedRow() < 0) {
     return null;
   } else {
     WebTable.Row row = iCourses.getRows()[iCourses.getSelectedRow()];
     String courseName = MESSAGES.courseName(row.getCell(0).getValue(), row.getCell(1).getValue());
     if ("false".equals(row.getId()))
       courseName =
           MESSAGES.courseNameWithTitle(
               row.getCell(0).getValue(), row.getCell(1).getValue(), row.getCell(2).getValue());
     return courseName;
   }
 }
 private Long getStatusPageSessionId(SessionContext context)
     throws SectioningException, PageAccessException {
   UserContext user = context.getUser();
   if (user == null)
     throw new PageAccessException(
         context.isHttpSessionNew()
             ? MSG.exceptionHttpSessionExpired()
             : MSG.exceptionLoginRequired());
   if (user.getCurrentAcademicSessionId() == null) {
     Long sessionId = getLastSessionId(context);
     if (sessionId != null) return sessionId;
   } else {
     return user.getCurrentAcademicSessionId();
   }
   throw new SectioningException(MSG.exceptionNoAcademicSession());
 }
예제 #4
0
  @Override
  public Boolean execute(OnlineSectioningServer server, OnlineSectioningHelper helper) {
    for (Long offeringId : getOfferingIds()) {
      helper
          .getAction()
          .addOther(
              OnlineSectioningLog.Entity.newBuilder()
                  .setUniqueId(offeringId)
                  .setType(OnlineSectioningLog.Entity.EntityType.OFFERING));

      List<Long> studentIds =
          (List<Long>)
              helper
                  .getHibSession()
                  .createQuery(
                      "select distinct cr.courseDemand.student.uniqueId from CourseRequest cr "
                          + "where cr.courseOffering.instructionalOffering.uniqueId = :offeringId")
                  .setLong("offeringId", offeringId)
                  .list();
      studentIds.addAll(
          helper
              .getHibSession()
              .createQuery(
                  "select distinct e.student.uniqueId from StudentClassEnrollment e "
                      + "where e.courseOffering.instructionalOffering.uniqueId = :offeringId and e.courseRequest is null")
              .setLong("offeringId", offeringId)
              .list());
      /*
      List<Long> studentIds = (List<Long>)helper.getHibSession().createQuery(
      		"select distinct s.uniqueId from Student s " +
      		"left outer join s.classEnrollments e " +
      		"left outer join s.courseDemands d left outer join d.courseRequests r left outer join r.courseOffering co " +
      		"where e.courseOffering.instructionalOffering.uniqueId = :offeringId or " +
      		"co.instructionalOffering.uniqueId = :offeringId").setLong("offeringId", offeringId).list();
      */

      Lock lock = server.lockOffering(offeringId, studentIds, name());
      try {
        helper.beginTransaction();
        try {
          reloadOffering(server, helper, offeringId);

          helper.commitTransaction();
        } catch (Exception e) {
          helper.rollbackTransaction();
          if (e instanceof SectioningException) throw (SectioningException) e;
          throw new SectioningException(MSG.exceptionUnknown(e.getMessage()), e);
        }
      } finally {
        lock.release();
      }
    }
    return true;
  }
예제 #5
0
  @Override
  public Boolean execute(OnlineSectioningServer server, OnlineSectioningHelper helper) {
    StudentSectioningStatus status =
        (hasStatus()
            ? (StudentSectioningStatus)
                helper
                    .getHibSession()
                    .createQuery("from StudentSectioningStatus where reference = :ref")
                    .setString("ref", getStatus())
                    .uniqueResult()
            : null);
    for (Long studentId : getStudentIds()) {
      Lock lock = server.lockStudent(studentId, null, name());
      try {
        XStudent student = server.getStudent(studentId);
        helper.beginTransaction();
        try {
          Student dbStudent = StudentDAO.getInstance().get(studentId, helper.getHibSession());
          if (student != null && dbStudent != null) {

            OnlineSectioningLog.Action.Builder action =
                helper.addAction(this, server.getAcademicSession());
            action.setStudent(
                OnlineSectioningLog.Entity.newBuilder()
                    .setUniqueId(student.getStudentId())
                    .setExternalId(student.getExternalId())
                    .setName(student.getName()));
            if (status != null) {
              action.addOther(
                  OnlineSectioningLog.Entity.newBuilder()
                      .setUniqueId(status.getUniqueId())
                      .setName(status.getLabel())
                      .setExternalId(status.getReference())
                      .setType(OnlineSectioningLog.Entity.EntityType.OTHER));
            }

            student.setStatus(getStatus());
            dbStudent.setSectioningStatus(status);
            helper.getHibSession().saveOrUpdate(dbStudent);
            server.update(student, false);
          }
          helper.commitTransaction();
        } catch (Exception e) {
          helper.rollbackTransaction();
          if (e instanceof SectioningException) throw (SectioningException) e;
          throw new SectioningException(MSG.exceptionUnknown(e.getMessage()), e);
        }

      } finally {
        lock.release();
      }
    }
    return true;
  }
예제 #6
0
 public static synchronized DegreePlansProvider getProvider() {
   String providerClass = ApplicationProperty.CustomizationDegreePlans.value();
   if (providerClass == null) {
     if (sProvider != null) {
       sProvider.dispose();
       sProvider = null;
     }
   } else if (!providerClass.equals(sProviderClass)) {
     if (sProvider != null) {
       sProvider.dispose();
       sProvider = null;
     }
     sProviderClass = providerClass;
     try {
       sProvider = ((DegreePlansProvider) Class.forName(sProviderClass).newInstance());
     } catch (Exception e) {
       throw new SectioningException(MSG.exceptionDegreePlansProvider(e.getMessage()), e);
     }
   }
   return sProvider;
 }
예제 #7
0
  public CourseFinderCourses() {
    super();

    iCourses = new WebTable();
    iCourses.setHeader(
        new WebTable.Row(
            new WebTable.Cell(MESSAGES.colSubject(), 1, "80px"),
            new WebTable.Cell(MESSAGES.colCourse(), 1, "80px"),
            new WebTable.Cell(MESSAGES.colLimit(), 1, "60px"),
            new WebTable.Cell(MESSAGES.colTitle(), 1, "300px"),
            new WebTable.Cell(MESSAGES.colCredit(), 1, "60px"),
            new WebTable.Cell(MESSAGES.colNote(), 1, "300px")));
    iCourses.addRowDoubleClickHandler(
        new WebTable.RowDoubleClickHandler() {
          public void onRowDoubleClick(WebTable.RowDoubleClickEvent event) {
            iCourses.setSelectedRow(event.getRowIdx());
            updateCourseDetails();
            SelectionEvent.fire(CourseFinderCourses.this, getValue());
          }
        });
    iCourses.addRowClickHandler(
        new WebTable.RowClickHandler() {
          public void onRowClick(WebTable.RowClickEvent event) {
            iCourses.setSelectedRow(event.getRowIdx());
            updateCourseDetails();
          }
        });

    iCoursesPanel = new ScrollPanel(iCourses);
    iCoursesPanel.getElement().getStyle().setWidth(780, Unit.PX);
    iCoursesPanel.getElement().getStyle().setHeight(200, Unit.PX);
    iCoursesPanel.setStyleName("unitime-ScrollPanel");

    iCoursesTip =
        new Label(CONSTANTS.courseTips()[(int) (Math.random() * CONSTANTS.courseTips().length)]);
    iCoursesTip.setStyleName("unitime-Hint");
    ToolBox.disableTextSelectInternal(iCoursesTip.getElement());
    iCoursesTip.addClickHandler(
        new ClickHandler() {
          public void onClick(ClickEvent event) {
            String oldText = iCoursesTip.getText();
            do {
              iCoursesTip.setText(
                  CONSTANTS.courseTips()[(int) (Math.random() * CONSTANTS.courseTips().length)]);
            } while (oldText.equals(iCoursesTip.getText()));
          }
        });

    iCourseDetailsTabPanel = new UniTimeTabPanel();
    iCourseDetailsTabPanel.setDeckStyleName("unitime-TabPanel");
    iCourseDetailsTabPanel.addSelectionHandler(
        new SelectionHandler<Integer>() {
          @Override
          public void onSelection(SelectionEvent<Integer> event) {
            Cookies.setCookie(
                "UniTime:CourseFinderCourses", String.valueOf(event.getSelectedItem()));
          }
        });

    setSpacing(10);
    add(iCoursesPanel);
    add(iCourseDetailsTabPanel);
    add(iCoursesTip);
  }
예제 #8
0
 protected void updateCourseDetails() {
   if (iCourses.getSelectedRow() < 0
       || iCourses.getRows() == null
       || iCourses.getRows().length == 0) {
     if (iDetails != null)
       for (CourseFinderCourseDetails detail : iDetails) {
         detail.setValue(null);
       }
     AriaStatus.getInstance().setHTML(ARIA.courseFinderNoCourse());
   } else {
     WebTable.Row row = iCourses.getRows()[iCourses.getSelectedRow()];
     String courseName = MESSAGES.courseName(row.getCell(0).getValue(), row.getCell(1).getValue());
     if ("false".equals(row.getId()))
       courseName =
           MESSAGES.courseNameWithTitle(
               row.getCell(0).getValue(), row.getCell(1).getValue(), row.getCell(2).getValue());
     for (CourseFinderCourseDetails detail : iDetails) detail.setValue(courseName);
     String title = row.getCell(3).getValue();
     String note = row.getCell(4).getValue();
     if (title.isEmpty()) {
       if (note.isEmpty()) {
         AriaStatus.getInstance()
             .setHTML(
                 ARIA.courseFinderSelected(
                     1 + iCourses.getSelectedRow(),
                     iCourses.getRowsCount(),
                     row.getCell(0).getValue(),
                     row.getCell(1).getValue()));
       } else {
         AriaStatus.getInstance()
             .setHTML(
                 ARIA.courseFinderSelectedWithNote(
                     1 + iCourses.getSelectedRow(),
                     iCourses.getRowsCount(),
                     row.getCell(0).getValue(),
                     row.getCell(1).getValue(),
                     note));
       }
     } else {
       if (note.isEmpty()) {
         AriaStatus.getInstance()
             .setHTML(
                 ARIA.courseFinderSelectedWithTitle(
                     1 + iCourses.getSelectedRow(),
                     iCourses.getRowsCount(),
                     row.getCell(0).getValue(),
                     row.getCell(1).getValue(),
                     title));
       } else {
         AriaStatus.getInstance()
             .setHTML(
                 ARIA.courseFinderSelectedWithTitleAndNote(
                     1 + iCourses.getSelectedRow(),
                     iCourses.getRowsCount(),
                     row.getCell(0).getValue(),
                     row.getCell(1).getValue(),
                     title,
                     note));
       }
     }
   }
 }
예제 #9
0
  @Override
  public void setValue(String value, final boolean fireEvents) {
    if (value == null || value.isEmpty()) {
      iLastQuery = null;
      iCourses.clearData(true);
      iCourses.setEmptyMessage(MESSAGES.courseSelectionNoCourseFilter());
      updateCourseDetails();
    } else if (!value.equals(iLastQuery)) {
      iLastQuery = value;
      iDataProvider.getData(
          value,
          new AsyncCallback<Collection<ClassAssignmentInterface.CourseAssignment>>() {
            public void onFailure(Throwable caught) {
              iCourses.clearData(true);
              iCourses.setEmptyMessage(caught.getMessage());
              if (isVisible()) AriaStatus.getInstance().setText(caught.getMessage());
              updateCourseDetails();
              ResponseEvent.fire(CourseFinderCourses.this, false);
            }

            public void onSuccess(Collection<ClassAssignmentInterface.CourseAssignment> result) {
              WebTable.Row[] records = new WebTable.Row[result.size()];
              int idx = 0;
              int selectRow = -1;
              for (ClassAssignmentInterface.CourseAssignment record : result) {
                records[idx] =
                    new WebTable.Row(
                        record.getSubject(),
                        record.getCourseNbr(),
                        (record.getLimit() == null
                                || record.getLimit() == 0
                                || record.getEnrollment() == null
                            ? ""
                            : record.getLimit() < 0
                                ? "&infin;"
                                : (record.getLimit() - record.getEnrollment())
                                    + " / "
                                    + record.getLimit()),
                        (record.getTitle() == null ? "" : record.getTitle()),
                        (record.hasCredit() ? record.getCreditAbbv() : ""),
                        (record.getNote() == null ? "" : record.getNote()));
                if (record.hasCredit()) records[idx].getCell(4).setTitle(record.getCreditText());
                records[idx].setId(record.hasUniqueName() ? "true" : "false");
                if (iLastQuery.equalsIgnoreCase(
                        MESSAGES.courseName(record.getSubject(), record.getCourseNbr()))
                    || (record.getTitle() != null
                        && iLastQuery.equalsIgnoreCase(
                            MESSAGES.courseNameWithTitle(
                                record.getSubject(), record.getCourseNbr(), record.getTitle()))))
                  selectRow = idx;
                if (record.getTitle() == null || record.getTitle().isEmpty()) {
                  if (record.getNote() == null || record.getNote().isEmpty()) {
                    records[idx].setAriaLabel(
                        ARIA.courseFinderCourse(record.getSubject(), record.getCourseNbr()));
                  } else {
                    records[idx].setAriaLabel(
                        ARIA.courseFinderCourseWithNote(
                            record.getSubject(), record.getCourseNbr(), record.getNote()));
                  }
                } else {
                  if (record.getNote() == null || record.getNote().isEmpty()) {
                    records[idx].setAriaLabel(
                        ARIA.courseFinderCourseWithTitle(
                            record.getSubject(), record.getCourseNbr(), record.getTitle()));
                  } else {
                    records[idx].setAriaLabel(
                        ARIA.courseFinderCourseWithTitleAndNote(
                            record.getSubject(),
                            record.getCourseNbr(),
                            record.getTitle(),
                            record.getNote()));
                  }
                }
                idx++;
              }
              iCourses.setData(records);
              if (records.length == 1) selectRow = 0;
              if (selectRow >= 0) {
                iCourses.setSelectedRow(selectRow);
                scrollToSelectedRow();
                if (fireEvents) ValueChangeEvent.fire(CourseFinderCourses.this, getValue());
              }
              updateCourseDetails();
              ResponseEvent.fire(CourseFinderCourses.this, !result.isEmpty());
            }
          });
    }
  }
예제 #10
0
 @Override
 public String getName() {
   return MESSAGES.courseSelectionCourses();
 }
  public CourseFinderDialog() {
    super(true, false);
    setText(MESSAGES.courseSelectionDialog());

    iFilter = new AriaTextBox();
    iFilter.setStyleName("gwt-SuggestBox");
    iFilter.getElement().getStyle().setWidth(600, Unit.PX);

    iFilterSelect = new AriaButton(MESSAGES.buttonSelect());
    iFilterSelect.addClickHandler(
        new ClickHandler() {
          @Override
          public void onClick(ClickEvent event) {
            CourseFinderTab tab = getSelectedTab();
            if (tab != null && tab.getValue() != null) iFilter.setValue((String) tab.getValue());
            hide();
            SelectionEvent.fire(CourseFinderDialog.this, getValue());
          }
        });

    HorizontalPanel filterWithSelect = new HorizontalPanel();
    filterWithSelect.add(iFilter);
    filterWithSelect.add(iFilterSelect);
    filterWithSelect.setCellVerticalAlignment(iFilter, HasVerticalAlignment.ALIGN_MIDDLE);
    filterWithSelect.setCellVerticalAlignment(iFilterSelect, HasVerticalAlignment.ALIGN_MIDDLE);
    iFilterSelect.getElement().getStyle().setMarginLeft(5, Unit.PX);

    iDialogPanel = new VerticalPanel();
    iDialogPanel.setSpacing(5);
    iDialogPanel.add(filterWithSelect);
    iDialogPanel.setCellHorizontalAlignment(filterWithSelect, HasHorizontalAlignment.ALIGN_CENTER);

    addCloseHandler(
        new CloseHandler<PopupPanel>() {
          public void onClose(CloseEvent<PopupPanel> event) {
            RootPanel.getBodyElement().getStyle().setOverflow(Overflow.AUTO);
          }
        });

    final Timer finderTimer =
        new Timer() {
          @Override
          public void run() {
            if (iTabs != null) {
              for (CourseFinderTab tab : iTabs) tab.setValue(iFilter.getValue(), false);
            }
          }
        };

    iFilter.addKeyUpHandler(
        new KeyUpHandler() {
          @Override
          public void onKeyUp(KeyUpEvent event) {
            finderTimer.schedule(250);
            if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
              CourseFinderTab tab = getSelectedTab();
              if (tab != null && tab.getValue() != null) iFilter.setValue((String) tab.getValue());
              hide();
              SelectionEvent.fire(CourseFinderDialog.this, getValue());
              return;
            } else if (event.getNativeKeyCode() == KeyCodes.KEY_ESCAPE) {
              hide();
              return;
            }
            if (event.isControlKeyDown() || event.isAltKeyDown()) {
              for (Map.Entry<Character, Integer> entry : iTabAccessKeys.entrySet())
                if (event.getNativeKeyCode() == Character.toLowerCase(entry.getKey())
                    || event.getNativeKeyCode() == Character.toUpperCase(entry.getKey())) {
                  iTabPanel.selectTab(entry.getValue());
                  event.preventDefault();
                  event.stopPropagation();
                }
            }
            if (iTabs != null) {
              for (CourseFinderTab tab : iTabs) tab.onKeyUp(event);
            }
          }
        });

    iFilter.addValueChangeHandler(
        new ValueChangeHandler<String>() {
          @Override
          public void onValueChange(ValueChangeEvent<String> event) {
            if (iTabs != null) {
              for (CourseFinderTab tab : iTabs) tab.setValue(event.getValue(), true);
            }
          }
        });
    addValueChangeHandler(
        new ValueChangeHandler<String>() {
          @Override
          public void onValueChange(ValueChangeEvent<String> event) {
            if (iTabs != null) {
              for (CourseFinderTab tab : iTabs) tab.setValue(event.getValue(), true);
            }
          }
        });

    iFilter.addBlurHandler(
        new BlurHandler() {
          @Override
          public void onBlur(BlurEvent event) {
            if (isShowing()) {
              Scheduler.get()
                  .scheduleDeferred(
                      new ScheduledCommand() {
                        @Override
                        public void execute() {
                          iFilter.setFocus(true);
                        }
                      });
            }
          }
        });

    setWidget(iDialogPanel);
  }
예제 #12
0
  public List<EnrollmentRequest> check(
      OnlineSectioningServer server, OnlineSectioningHelper helper) {
    XStudent student = server.getStudent(getStudentId());
    if (student == null) throw new SectioningException(MSG.exceptionBadStudentId());
    List<EnrollmentRequest> requests = new ArrayList<EnrollmentRequest>();
    Hashtable<Long, EnrollmentRequest> courseId2request = new Hashtable<Long, EnrollmentRequest>();
    Hashtable<Long, XOffering> courseId2offering = new Hashtable<Long, XOffering>();
    for (ClassAssignmentInterface.ClassAssignment ca : getAssignment()) {
      // Skip free times and dummy sections
      if (ca == null || ca.isFreeTime() || ca.getClassId() == null || ca.isDummy()) continue;

      XCourse course = server.getCourse(ca.getCourseId());
      if (course == null)
        throw new SectioningException(
            MSG.exceptionCourseDoesNotExist(MSG.courseName(ca.getSubject(), ca.getClassNumber())));
      XOffering offering = server.getOffering(course.getOfferingId());
      if (offering == null)
        throw new SectioningException(
            MSG.exceptionCourseDoesNotExist(MSG.courseName(ca.getSubject(), ca.getClassNumber())));

      // Check section limits
      XSection section = offering.getSection(ca.getClassId());
      if (section == null)
        throw new SectioningException(
            MSG.exceptionEnrollNotAvailable(
                MSG.clazz(ca.getSubject(), ca.getCourseNbr(), ca.getSubpart(), ca.getSection())));

      // Check cancelled flag
      if (section.isCancelled()) {
        if (server.getConfig().getPropertyBoolean("Enrollment.CanKeepCancelledClass", false)) {
          boolean contains = false;
          for (XRequest r : student.getRequests())
            if (r instanceof XCourseRequest) {
              XCourseRequest cr = (XCourseRequest) r;
              if (cr.getEnrollment() != null
                  && cr.getEnrollment().getSectionIds().contains(section.getSectionId())) {
                contains = true;
                break;
              }
            }
          if (!contains)
            throw new SectioningException(
                MSG.exceptionEnrollCancelled(
                    MSG.clazz(
                        ca.getSubject(), ca.getCourseNbr(), ca.getSubpart(), ca.getSection())));
        } else {
          throw new SectioningException(
              MSG.exceptionEnrollCancelled(
                  MSG.clazz(ca.getSubject(), ca.getCourseNbr(), ca.getSubpart(), ca.getSection())));
        }
      }

      EnrollmentRequest request = courseId2request.get(ca.getCourseId());
      if (request == null) {
        request = new EnrollmentRequest(course, new ArrayList<XSection>());
        courseId2request.put(ca.getCourseId(), request);
        requests.add(request);
      }
      request.getSections().add(section);
      courseId2offering.put(course.getCourseId(), offering);
    }

    // Check for NEW and CHANGE deadlines
    check:
    for (EnrollmentRequest request : requests) {
      XCourse course = request.getCourse();
      List<XSection> sections = request.getSections();

      for (XRequest r : student.getRequests()) {
        if (r instanceof XCourseRequest) {
          XEnrollment enrollment = ((XCourseRequest) r).getEnrollment();
          if (enrollment != null
              && enrollment.getCourseId().equals(course.getCourseId())) { // course change
            for (XSection s : sections)
              if (!enrollment.getSectionIds().contains(s.getSectionId())
                  && !server.checkDeadline(
                      course.getCourseId(), s.getTime(), OnlineSectioningServer.Deadline.CHANGE))
                throw new SectioningException(
                    MSG.exceptionEnrollDeadlineChange(
                        MSG.clazz(
                            course.getSubjectArea(),
                            course.getCourseNumber(),
                            s.getSubpartName(),
                            s.getName(course.getCourseId()))));
            continue check;
          }
        }
      }

      // new course
      for (XSection section : sections) {
        if (!server.checkDeadline(
            course.getOfferingId(), section.getTime(), OnlineSectioningServer.Deadline.NEW))
          throw new SectioningException(
              MSG.exceptionEnrollDeadlineNew(
                  MSG.clazz(
                      course.getSubjectArea(),
                      course.getCourseNumber(),
                      section.getSubpartName(),
                      section.getName(course.getCourseId()))));
      }
    }

    // Check for DROP deadlines
    for (XRequest r : student.getRequests()) {
      if (r instanceof XCourseRequest) {
        XEnrollment enrollment = ((XCourseRequest) r).getEnrollment();
        if (enrollment != null && !courseId2offering.containsKey(enrollment.getCourseId())) {
          XOffering offering = server.getOffering(enrollment.getOfferingId());
          if (offering != null)
            for (XSection section : offering.getSections(enrollment)) {
              if (!server.checkDeadline(
                  offering.getOfferingId(),
                  section.getTime(),
                  OnlineSectioningServer.Deadline.DROP))
                throw new SectioningException(
                    MSG.exceptionEnrollDeadlineDrop(enrollment.getCourseName()));
            }
        }
      }
    }

    Hashtable<Long, XConfig> courseId2config = new Hashtable<Long, XConfig>();
    for (EnrollmentRequest request : requests) {
      XCourse course = request.getCourse();
      XOffering offering = courseId2offering.get(course.getCourseId());
      XEnrollments enrollments = server.getEnrollments(course.getOfferingId());
      List<XSection> sections = request.getSections();
      XSubpart subpart = offering.getSubpart(sections.get(0).getSubpartId());
      XConfig config = offering.getConfig(subpart.getConfigId());
      courseId2config.put(course.getCourseId(), config);

      XReservation reservation = null;
      reservations:
      for (XReservation r : offering.getReservations()) {
        if (!r.isApplicable(student)) continue;
        if (r.getLimit() >= 0
            && r.getLimit() <= enrollments.countEnrollmentsForReservation(r.getReservationId())) {
          boolean contain = false;
          for (XEnrollment e : enrollments.getEnrollmentsForReservation(r.getReservationId()))
            if (e.getStudentId().equals(student.getStudentId())) {
              contain = true;
              break;
            }
          if (!contain) continue;
        }
        if (!r.getConfigsIds().isEmpty() && !r.getConfigsIds().contains(config.getConfigId()))
          continue;
        for (XSection section : sections)
          if (r.getSectionIds(section.getSubpartId()) != null
              && !r.getSectionIds(section.getSubpartId()).contains(section.getSectionId()))
            continue reservations;
        if (reservation == null || r.compareTo(reservation) < 0) reservation = r;
      }

      if (reservation == null || !reservation.canAssignOverLimit()) {
        for (XSection section : sections) {
          if (section.getLimit() >= 0
              && section.getLimit()
                  <= enrollments.countEnrollmentsForSection(section.getSectionId())) {
            boolean contain = false;
            for (XEnrollment e : enrollments.getEnrollmentsForSection(section.getSectionId()))
              if (e.getStudentId().equals(student.getStudentId())) {
                contain = true;
                break;
              }
            if (!contain)
              throw new SectioningException(
                  MSG.exceptionEnrollNotAvailable(
                      MSG.clazz(
                          course.getSubjectArea(),
                          course.getCourseNumber(),
                          section.getSubpartName(),
                          section.getName())));
          }
          if ((reservation == null
                  || !offering.getSectionReservations(section.getSectionId()).contains(reservation))
              && offering.getUnreservedSectionSpace(section.getSectionId(), enrollments) <= 0) {
            boolean contain = false;
            for (XEnrollment e : enrollments.getEnrollmentsForSection(section.getSectionId()))
              if (e.getStudentId().equals(student.getStudentId())) {
                contain = true;
                break;
              }
            if (!contain)
              throw new SectioningException(
                  MSG.exceptionEnrollNotAvailable(
                      MSG.clazz(
                          course.getSubjectArea(),
                          course.getCourseNumber(),
                          section.getSubpartName(),
                          section.getName())));
          }
        }

        if (config.getLimit() >= 0
            && config.getLimit() <= enrollments.countEnrollmentsForConfig(config.getConfigId())) {
          boolean contain = false;
          for (XEnrollment e : enrollments.getEnrollmentsForConfig(config.getConfigId()))
            if (e.getStudentId().equals(student.getStudentId())) {
              contain = true;
              break;
            }
          if (!contain)
            throw new SectioningException(
                MSG.exceptionEnrollNotAvailable(
                        MSG.courseName(course.getSubjectArea(), course.getCourseNumber()))
                    + " "
                    + config.getName());
        }
        if ((reservation == null
                || !offering.getConfigReservations(config.getConfigId()).contains(reservation))
            && offering.getUnreservedConfigSpace(config.getConfigId(), enrollments) <= 0) {
          boolean contain = false;
          for (XEnrollment e : enrollments.getEnrollmentsForConfig(config.getConfigId()))
            if (e.getStudentId().equals(student.getStudentId())) {
              contain = true;
              break;
            }
          if (!contain)
            throw new SectioningException(
                MSG.exceptionEnrollNotAvailable(
                        MSG.courseName(course.getSubjectArea(), course.getCourseNumber()))
                    + " "
                    + config.getName());
        }

        if (course.getLimit() >= 0
            && course.getLimit() <= enrollments.countEnrollmentsForCourse(course.getCourseId())) {
          boolean contain = false;
          for (XEnrollment e : enrollments.getEnrollmentsForCourse(course.getCourseId()))
            if (e.getStudentId().equals(student.getStudentId())) {
              contain = true;
              break;
            }
          if (!contain)
            throw new SectioningException(
                MSG.exceptionEnrollNotAvailable(
                    MSG.courseName(course.getSubjectArea(), course.getCourseNumber())));
        }
      }
    }

    for (EnrollmentRequest request : requests) {
      XCourse course = request.getCourse();
      XOffering offering = courseId2offering.get(course.getCourseId());
      List<XSection> sections = request.getSections();
      XSubpart subpart = offering.getSubpart(sections.get(0).getSubpartId());
      XConfig config = offering.getConfig(subpart.getConfigId());
      if (sections.size() < config.getSubparts().size()) {
        throw new SectioningException(
            MSG.exceptionEnrollmentIncomplete(
                MSG.courseName(course.getSubjectArea(), course.getCourseNumber())));
      } else if (sections.size() > config.getSubparts().size()) {
        throw new SectioningException(
            MSG.exceptionEnrollmentInvalid(
                MSG.courseName(course.getSubjectArea(), course.getCourseNumber())));
      }
      for (XSection s1 : sections) {
        for (XSection s2 : sections) {
          if (s1.getSectionId() < s2.getSectionId()
              && s1.isOverlapping(offering.getDistributions(), s2)) {
            throw new SectioningException(
                MSG.exceptionEnrollmentOverlapping(
                    MSG.courseName(course.getSubjectArea(), course.getCourseNumber())));
          }
          if (!s1.getSectionId().equals(s2.getSectionId())
              && s1.getSubpartId().equals(s2.getSubpartId())) {
            throw new SectioningException(
                MSG.exceptionEnrollmentInvalid(
                    MSG.courseName(course.getSubjectArea(), course.getCourseNumber())));
          }
        }
        if (!offering.getSubpart(s1.getSubpartId()).getConfigId().equals(config.getConfigId())) {
          throw new SectioningException(
              MSG.exceptionEnrollmentInvalid(
                  MSG.courseName(course.getSubjectArea(), course.getCourseNumber())));
        }
      }
      if (!offering.isAllowOverlap(student, config.getConfigId(), sections))
        for (EnrollmentRequest otherRequest : requests) {
          XOffering other = courseId2offering.get(otherRequest.getCourse().getCourseId());
          XConfig otherConfig = courseId2config.get(otherRequest.getCourse().getCourseId());
          if (!other.equals(offering)
              && !other.isAllowOverlap(
                  student, otherConfig.getConfigId(), otherRequest.getSections())) {
            List<XSection> assignment = otherRequest.getSections();
            for (XSection section : sections)
              if (section.isOverlapping(offering.getDistributions(), assignment))
                throw new SectioningException(
                    MSG.exceptionEnrollmentConflicting(
                        MSG.courseName(course.getSubjectArea(), course.getCourseNumber())));
          }
        }
    }

    return requests;
  }