All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.cpsolver.studentsct.report.AbstractStudentSectioningReport Maven / Gradle / Ivy

Go to download

The constraint solver library contains a local search based framework that allows modeling of a problem using constraint programming primitives (variables, values, constraints).

The newest version!
package org.cpsolver.studentsct.report;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.cpsolver.coursett.Constants;
import org.cpsolver.coursett.model.RoomLocation;
import org.cpsolver.ifs.assignment.Assignment;
import org.cpsolver.ifs.util.CSVFile;
import org.cpsolver.ifs.util.DataProperties;
import org.cpsolver.ifs.util.Query;
import org.cpsolver.studentsct.StudentSectioningModel;
import org.cpsolver.studentsct.model.Config;
import org.cpsolver.studentsct.model.Course;
import org.cpsolver.studentsct.model.CourseRequest;
import org.cpsolver.studentsct.model.Enrollment;
import org.cpsolver.studentsct.model.Instructor;
import org.cpsolver.studentsct.model.Request;
import org.cpsolver.studentsct.model.Request.RequestPriority;
import org.cpsolver.studentsct.model.Section;
import org.cpsolver.studentsct.model.Student;
import org.cpsolver.studentsct.model.Student.BackToBackPreference;
import org.cpsolver.studentsct.model.Student.ModalityPreference;
import org.cpsolver.studentsct.reservation.UniversalOverride;

/**
 * Abstract student sectioning report. Adds filtering capabilities using the 
 * filter parameter. It also checks the lastlike and real parameters (whether to
 * include projected and real students respectively) and passes on the useAmPm parameter
 * as {@link #isUseAmPm()}. The filter replicates most of the capabilities available
 * in UniTime on the Batch Student Solver Dashboard page.
 * 
 * 
*
* * @author Tomas Muller * @version StudentSct 1.3 (Student Sectioning)
* Copyright (C) 2007 - 2014 Tomas Muller
* [email protected]
* http://muller.unitime.org
*
* This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 3 of the * License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public * License along with this library; if not see * http://www.gnu.org/licenses/. */ public abstract class AbstractStudentSectioningReport implements StudentSectioningReport, StudentSectioningReport.Filter { private StudentSectioningModel iModel = null; private Query iFilter = null; private String iUser = null; private Assignment iAssignment; private boolean iIncludeLastLike = false; private boolean iIncludeReal = true; private boolean iUseAmPm = true; public AbstractStudentSectioningReport(StudentSectioningModel model) { iModel = model; } /** * Returns the student sectioning model */ public StudentSectioningModel getModel() { return iModel; } @Override public CSVFile create(Assignment assignment, DataProperties properties) { String filter = properties.getProperty("filter"); if (filter != null && !filter.isEmpty()) iFilter = new Query(filter); iUser = properties.getProperty("user"); iIncludeLastLike = properties.getPropertyBoolean("lastlike", false); iIncludeReal = properties.getPropertyBoolean("real", true); iUseAmPm = properties.getPropertyBoolean("useAmPm", true); iAssignment = assignment; return createTable(assignment, properties); } @Override public boolean matches(Request r, Enrollment e) { if (iFilter == null) return true; if (r.getStudent().isDummy() && !iIncludeLastLike) return false; if (!r.getStudent().isDummy() && !iIncludeReal) return false; return iFilter.match(new RequestMatcher(r, e, iAssignment, iUser)); } @Override public boolean matches(Request r) { if (iFilter == null) return true; if (r.getStudent().isDummy() && !iIncludeLastLike) return false; if (!r.getStudent().isDummy() && !iIncludeReal) return false; return iFilter.match(new RequestMatcher(r, iAssignment.getValue(r), iAssignment, iUser)); } @Override public boolean matches(Course c) { if (iFilter == null) return true; return iFilter.match(new CourseMatcher(c)); } @Override public boolean matches(Student student) { for (Request r: student.getRequests()) if (matches(r)) return true; return false; } /** * Time display settings */ public boolean isUseAmPm() { return iUseAmPm; } public abstract CSVFile createTable(Assignment assignment, DataProperties properties); public static class RequestMatcher extends UniversalOverride.StudentMatcher { private Request iRequest; private Enrollment iEnrollment; private String iUser; private Assignment iAssignment; public RequestMatcher(Request request, Enrollment enrollment, Assignment assignment, String user) { super(request.getStudent()); iRequest = request; iEnrollment = enrollment; iAssignment = assignment; iUser = user; } public boolean isAssigned() { return iEnrollment != null; } public Enrollment enrollment() { return iEnrollment; } public Request request() { return iRequest; } public CourseRequest cr() { return iRequest instanceof CourseRequest ? (CourseRequest) iRequest : null; } public Course course() { if (enrollment() != null) return enrollment().getCourse(); else if (request() instanceof CourseRequest) return ((CourseRequest) request()).getCourses().get(0); else return null; } @Override public boolean match(String attr, String term) { if (super.match(attr, term)) return true; if ("assignment".equals(attr)) { if (eq("Assigned", term)) { return isAssigned(); } else if (eq("Reserved", term)) { return isAssigned() && enrollment().getReservation() != null; } else if (eq("Not Assigned", term)) { return !isAssigned() && !request().isAlternative(); } else if (eq("Wait-Listed", term)) { if (enrollment() == null) return cr() != null && cr().isWaitlist(); else return enrollment().isWaitlisted(); } else if (eq("Critical", term)) { return request().getRequestPriority() == RequestPriority.Critical; } else if (eq("Assigned Critical", term)) { return request().getRequestPriority() == RequestPriority.Critical && isAssigned(); } else if (eq("Not Assigned Critical", term)) { return request().getRequestPriority() == RequestPriority.Critical && !isAssigned(); } else if (eq("Vital", term)) { return request().getRequestPriority() == RequestPriority.Vital; } else if (eq("Assigned Vital", term)) { return request().getRequestPriority() == RequestPriority.Vital && isAssigned(); } else if (eq("Not Assigned Vital", term)) { return request().getRequestPriority() == RequestPriority.Vital && !isAssigned(); } else if (eq("Visiting F2F", term)) { return request().getRequestPriority() == RequestPriority.VisitingF2F; } else if (eq("Assigned Visiting F2F", term)) { return request().getRequestPriority() == RequestPriority.VisitingF2F && isAssigned(); } else if (eq("Not Assigned Visiting F2F", term)) { return request().getRequestPriority() == RequestPriority.VisitingF2F && !isAssigned(); } else if (eq("LC", term)) { return request().getRequestPriority() == RequestPriority.LC; } else if (eq("Assigned LC", term)) { return request().getRequestPriority() == RequestPriority.LC && isAssigned(); } else if (eq("Not Assigned LC", term)) { return request().getRequestPriority() == RequestPriority.LC && !isAssigned(); } else if (eq("Important", term)) { return request().getRequestPriority() == RequestPriority.Important; } else if (eq("Assigned Important", term)) { return request().getRequestPriority() == RequestPriority.Important && isAssigned(); } else if (eq("Not Assigned Important", term)) { return request().getRequestPriority() == RequestPriority.Important && !isAssigned(); } else if (eq("No-Subs", term) || eq("No-Substitutes", term)) { return cr() != null && cr().isWaitlist(); } else if (eq("Assigned No-Subs", term) || eq("Assigned No-Substitutes", term)) { return cr() != null && cr().isWaitlist() && isAssigned(); } else if (eq("Not Assigned No-Subs", term) || eq("Not Assigned No-Substitutes", term)) { return cr() != null && cr().isWaitlist() && !isAssigned(); } } if ("assigned".equals(attr) || "scheduled".equals(attr)) { if (eq("true", term) || eq("1", term)) return isAssigned(); else return !isAssigned(); } if ("waitlisted".equals(attr) || "waitlist".equals(attr)) { if (eq("true", term) || eq("1", term)) return !isAssigned() && cr() != null && cr().isWaitlist(); else return isAssigned() && cr() != null && cr().isWaitlist(); } if ("no-substitutes".equals(attr) || "no-subs".equals(attr)) { if (eq("true", term) || eq("1", term)) return !isAssigned() && cr() != null && cr().isWaitlist(); else return isAssigned() && cr() != null && cr().isWaitlist(); } if ("reservation".equals(attr) || "reserved".equals(attr)) { if (eq("true", term) || eq("1", term)) return isAssigned() && enrollment().getReservation() != null; else return isAssigned() && enrollment().getReservation() == null; } if ("mode".equals(attr)) { if (eq("My Students", term)) { if (iUser == null) return false; for (Instructor a : student().getAdvisors()) if (eq(a.getExternalId(), iUser)) return true; return false; } return true; } if ("status".equals(attr)) { if ("default".equalsIgnoreCase(term) || "Not Set".equalsIgnoreCase(term)) return student().getStatus() == null; return like(student().getStatus(), term); } if ("credit".equals(attr)) { float min = 0, max = Float.MAX_VALUE; Credit prefix = Credit.eq; String number = term; if (number.startsWith("<=")) { prefix = Credit.le; number = number.substring(2); } else if (number.startsWith(">=")) { prefix = Credit.ge; number = number.substring(2); } else if (number.startsWith("<")) { prefix = Credit.lt; number = number.substring(1); } else if (number.startsWith(">")) { prefix = Credit.gt; number = number.substring(1); } else if (number.startsWith("=")) { prefix = Credit.eq; number = number.substring(1); } String im = null; try { float a = Float.parseFloat(number); switch (prefix) { case eq: min = max = a; break; // = a case le: max = a; break; // <= a case ge: min = a; break; // >= a case lt: max = a - 1; break; // < a case gt: min = a + 1; break; // > a } } catch (NumberFormatException e) { Matcher m = Pattern.compile("([0-9]+\\.?[0-9]*)([^0-9\\.].*)").matcher(number); if (m.matches()) { float a = Float.parseFloat(m.group(1)); im = m.group(2).trim(); switch (prefix) { case eq: min = max = a; break; // = a case le: max = a; break; // <= a case ge: min = a; break; // >= a case lt: max = a - 1; break; // < a case gt: min = a + 1; break; // > a } } } if (term.contains("..")) { try { String a = term.substring(0, term.indexOf('.')); String b = term.substring(term.indexOf("..") + 2); min = Float.parseFloat(a); max = Float.parseFloat(b); } catch (NumberFormatException e) { Matcher m = Pattern.compile("([0-9]+\\.?[0-9]*)\\.\\.([0-9]+\\.?[0-9]*)([^0-9].*)") .matcher(term); if (m.matches()) { min = Float.parseFloat(m.group(1)); max = Float.parseFloat(m.group(2)); im = m.group(3).trim(); } } } float credit = 0; for (Request r : student().getRequests()) { if (r instanceof CourseRequest) { CourseRequest cr = (CourseRequest) r; Enrollment e = iAssignment.getValue(cr); if (e == null) continue; Config g = e.getConfig(); if (g != null) { if ("!".equals(im) && g.getInstructionalMethodReference() != null) continue; if (im != null && !"!".equals(im) && !im.equalsIgnoreCase(g.getInstructionalMethodReference())) continue; if (g.hasCreditValue()) credit += g.getCreditValue(); else if (e.getCourse().hasCreditValue()) credit += e.getCourse().getCreditValue(); } } } return min <= credit && credit <= max; } if ("rc".equals(attr) || "requested-credit".equals(attr)) { int min = 0, max = Integer.MAX_VALUE; Credit prefix = Credit.eq; String number = term; if (number.startsWith("<=")) { prefix = Credit.le; number = number.substring(2); } else if (number.startsWith(">=")) { prefix = Credit.ge; number = number.substring(2); } else if (number.startsWith("<")) { prefix = Credit.lt; number = number.substring(1); } else if (number.startsWith(">")) { prefix = Credit.gt; number = number.substring(1); } else if (number.startsWith("=")) { prefix = Credit.eq; number = number.substring(1); } try { int a = Integer.parseInt(number); switch (prefix) { case eq: min = max = a; break; // = a case le: max = a; break; // <= a case ge: min = a; break; // >= a case lt: max = a - 1; break; // < a case gt: min = a + 1; break; // > a } } catch (NumberFormatException e) { } if (term.contains("..")) { try { String a = term.substring(0, term.indexOf('.')); String b = term.substring(term.indexOf("..") + 2); min = Integer.parseInt(a); max = Integer.parseInt(b); } catch (NumberFormatException e) { } } if (min == 0 && max == Integer.MAX_VALUE) return true; float studentMinTot = 0f, studentMaxTot = 0f; int nrCoursesTot = 0; List minsTot = new ArrayList(); List maxsTot = new ArrayList(); for (Request r : student().getRequests()) { if (r instanceof CourseRequest) { CourseRequest cr = (CourseRequest) r; Float minTot = null, maxTot = null; for (Course c : cr.getCourses()) { if (c.hasCreditValue()) { if (minTot == null || minTot > c.getCreditValue()) minTot = c.getCreditValue(); if (maxTot == null || maxTot < c.getCreditValue()) maxTot = c.getCreditValue(); } } if (cr.isWaitlist()) { if (minTot != null) { studentMinTot += minTot; studentMaxTot += maxTot; } } else { if (minTot != null) { minsTot.add(minTot); maxsTot.add(maxTot); if (!r.isAlternative()) nrCoursesTot++; } } } } Collections.sort(minsTot); Collections.sort(maxsTot); for (int i = 0; i < nrCoursesTot; i++) { studentMinTot += minsTot.get(i); studentMaxTot += maxsTot.get(maxsTot.size() - i - 1); } return min <= studentMaxTot && studentMinTot <= max; } if ("fc".equals(attr) || "first-choice-credit".equals(attr)) { int min = 0, max = Integer.MAX_VALUE; Credit prefix = Credit.eq; String number = term; if (number.startsWith("<=")) { prefix = Credit.le; number = number.substring(2); } else if (number.startsWith(">=")) { prefix = Credit.ge; number = number.substring(2); } else if (number.startsWith("<")) { prefix = Credit.lt; number = number.substring(1); } else if (number.startsWith(">")) { prefix = Credit.gt; number = number.substring(1); } else if (number.startsWith("=")) { prefix = Credit.eq; number = number.substring(1); } try { int a = Integer.parseInt(number); switch (prefix) { case eq: min = max = a; break; // = a case le: max = a; break; // <= a case ge: min = a; break; // >= a case lt: max = a - 1; break; // < a case gt: min = a + 1; break; // > a } } catch (NumberFormatException e) { } if (term.contains("..")) { try { String a = term.substring(0, term.indexOf('.')); String b = term.substring(term.indexOf("..") + 2); min = Integer.parseInt(a); max = Integer.parseInt(b); } catch (NumberFormatException e) { } } if (min == 0 && max == Integer.MAX_VALUE) return true; float credit = 0f; for (Request r : student().getRequests()) { if (r instanceof CourseRequest) { CourseRequest cr = (CourseRequest) r; for (Course c : cr.getCourses()) { if (c != null && c.hasCreditValue()) { credit += c.getCreditValue(); break; } } } } return min <= credit && credit <= max; } if ("rp".equals(attr)) { if ("subst".equalsIgnoreCase(term)) return request().isAlternative(); int min = 0, max = Integer.MAX_VALUE; Credit prefix = Credit.eq; String number = term; if (number.startsWith("<=")) { prefix = Credit.le; number = number.substring(2); } else if (number.startsWith(">=")) { prefix = Credit.ge; number = number.substring(2); } else if (number.startsWith("<")) { prefix = Credit.lt; number = number.substring(1); } else if (number.startsWith(">")) { prefix = Credit.gt; number = number.substring(1); } else if (number.startsWith("=")) { prefix = Credit.eq; number = number.substring(1); } try { int a = Integer.parseInt(number); switch (prefix) { case eq: min = max = a; break; // = a case le: max = a; break; // <= a case ge: min = a; break; // >= a case lt: max = a - 1; break; // < a case gt: min = a + 1; break; // > a } } catch (NumberFormatException e) { } if (term.contains("..")) { try { String a = term.substring(0, term.indexOf('.')); String b = term.substring(term.indexOf("..") + 2); min = Integer.parseInt(a); max = Integer.parseInt(b); } catch (NumberFormatException e) { } } if (min == 0 && max == Integer.MAX_VALUE) return true; return !request().isAlternative() && min <= request().getPriority() + 1 && request().getPriority() + 1 <= max; } if ("choice".equals(attr) || "ch".equals(attr)) { if (cr() == null) return false; int min = 0, max = Integer.MAX_VALUE; Credit prefix = Credit.eq; String number = term; if (number.startsWith("<=")) { prefix = Credit.le; number = number.substring(2); } else if (number.startsWith(">=")) { prefix = Credit.ge; number = number.substring(2); } else if (number.startsWith("<")) { prefix = Credit.lt; number = number.substring(1); } else if (number.startsWith(">")) { prefix = Credit.gt; number = number.substring(1); } else if (number.startsWith("=")) { prefix = Credit.eq; number = number.substring(1); } try { int a = Integer.parseInt(number); switch (prefix) { case eq: min = max = a; break; // = a case le: max = a; break; // <= a case ge: min = a; break; // >= a case lt: max = a - 1; break; // < a case gt: min = a + 1; break; // > a } } catch (NumberFormatException e) { } if (term.contains("..")) { try { String a = term.substring(0, term.indexOf('.')); String b = term.substring(term.indexOf("..") + 2); min = Integer.parseInt(a); max = Integer.parseInt(b); } catch (NumberFormatException e) { } } if (min == 0 && max == Integer.MAX_VALUE) return true; if (enrollment() != null) { int choice = 1; for (Course course : cr().getCourses()) { if (course.equals(enrollment().getCourse())) { return min <= choice && choice <= max; } choice++; } return false; } else if (!request().isAlternative()) { int choice = cr().getCourses().size(); return min <= choice && choice <= max; } else { return false; } } if ("btb".equals(attr)) { if ("prefer".equalsIgnoreCase(term) || "preferred".equalsIgnoreCase(term)) return student().getBackToBackPreference() == BackToBackPreference.BTB_PREFERRED; else if ("disc".equalsIgnoreCase(term) || "discouraged".equalsIgnoreCase(term)) return student().getBackToBackPreference() == BackToBackPreference.BTB_DISCOURAGED; else return student().getBackToBackPreference() == BackToBackPreference.NO_PREFERENCE; } if ("online".equals(attr)) { if ("prefer".equalsIgnoreCase(term) || "preferred".equalsIgnoreCase(term)) return student().getModalityPreference() == ModalityPreference.ONLINE_PREFERRED; else if ("require".equalsIgnoreCase(term) || "required".equalsIgnoreCase(term)) return student().getModalityPreference() == ModalityPreference.ONLINE_REQUIRED; else if ("disc".equalsIgnoreCase(term) || "discouraged".equalsIgnoreCase(term)) return student().getModalityPreference() == ModalityPreference.ONILNE_DISCOURAGED; else if ("no".equalsIgnoreCase(term) || "no-preference".equalsIgnoreCase(term)) return student().getModalityPreference() == ModalityPreference.NO_PREFERENCE; } if ("online".equals(attr) || "face-to-face".equals(attr) || "f2f".equals(attr) || "no-time".equals(attr) || "has-time".equals(attr)) { int min = 0, max = Integer.MAX_VALUE; Credit prefix = Credit.eq; String number = term; if (number.startsWith("<=")) { prefix = Credit.le; number = number.substring(2); } else if (number.startsWith(">=")) { prefix = Credit.ge; number = number.substring(2); } else if (number.startsWith("<")) { prefix = Credit.lt; number = number.substring(1); } else if (number.startsWith(">")) { prefix = Credit.gt; number = number.substring(1); } else if (number.startsWith("=")) { prefix = Credit.eq; number = number.substring(1); } boolean perc = false; if (number.endsWith("%")) { perc = true; number = number.substring(0, number.length() - 1).trim(); } try { int a = Integer.parseInt(number); switch (prefix) { case eq: min = max = a; break; // = a case le: max = a; break; // <= a case ge: min = a; break; // >= a case lt: max = a - 1; break; // < a case gt: min = a + 1; break; // > a } } catch (NumberFormatException e) { } if (term.contains("..")) { try { String a = term.substring(0, term.indexOf('.')); String b = term.substring(term.indexOf("..") + 2); min = Integer.parseInt(a); max = Integer.parseInt(b); } catch (NumberFormatException e) { } } if (min == 0 && max == Integer.MAX_VALUE) return true; int match = 0, total = 0; for (Request r : student().getRequests()) { if (r instanceof CourseRequest) { CourseRequest cr = (CourseRequest) r; Enrollment e = iAssignment.getValue(cr); if (e == null) continue; for (Section section : enrollment().getSections()) { if ("online".equals(attr) && section.isOnline()) match++; else if (("face-to-face".equals(attr) || "f2f".equals(attr)) && !section.isOnline()) match++; else if ("no-time".equals(attr) && (section.getTime() == null || section.getTime().getDayCode() == 0)) match++; else if ("has-time".equals(attr) && section.getTime() != null && section.getTime().getDayCode() != 0) match++; total++; } } } if (total == 0) return false; if (perc) { double percentage = 100.0 * match / total; return min <= percentage && percentage <= max; } else { return min <= match && match <= max; } } if ("overlap".equals(attr)) { int min = 0, max = Integer.MAX_VALUE; Credit prefix = Credit.eq; String number = term; if (number.startsWith("<=")) { prefix = Credit.le; number = number.substring(2); } else if (number.startsWith(">=")) { prefix = Credit.ge; number = number.substring(2); } else if (number.startsWith("<")) { prefix = Credit.lt; number = number.substring(1); } else if (number.startsWith(">")) { prefix = Credit.gt; number = number.substring(1); } else if (number.startsWith("=")) { prefix = Credit.eq; number = number.substring(1); } try { int a = Integer.parseInt(number); switch (prefix) { case eq: min = max = a; break; // = a case le: max = a; break; // <= a case ge: min = a; break; // >= a case lt: max = a - 1; break; // < a case gt: min = a + 1; break; // > a } } catch (NumberFormatException e) { } if (term.contains("..")) { try { String a = term.substring(0, term.indexOf('.')); String b = term.substring(term.indexOf("..") + 2); min = Integer.parseInt(a); max = Integer.parseInt(b); } catch (NumberFormatException e) { } } int share = 0; for (Request r : student().getRequests()) { if (r instanceof CourseRequest) { CourseRequest cr = (CourseRequest) r; Enrollment e = iAssignment.getValue(cr); if (e == null) continue; for (Section section : e.getSections()) { if (section.getTime() == null) continue; for (Request q : student().getRequests()) { if (q.equals(request())) continue; Enrollment otherEnrollment = iAssignment.getValue(q); if (otherEnrollment != null && otherEnrollment.getCourse() != null) { for (Section otherSection : otherEnrollment.getSections()) { if (otherSection.getTime() != null && otherSection.getTime().hasIntersection(section.getTime())) { share += 5 * section.getTime().nrSharedHours(otherSection.getTime()) * section.getTime().nrSharedDays(otherSection.getTime()); } } } } } } } return min <= share && share <= max; } if ("prefer".equals(attr)) { if (cr() == null) return false; if (eq("Any Preference", term)) return !cr().getSelectedChoices().isEmpty() || !cr().getRequiredChoices().isEmpty(); if (eq("Met Preference", term) || eq("Unmet Preference", term)) { if (enrollment() == null) { if (eq("Unmet Preference", term)) return !cr().getSelectedChoices().isEmpty() || !cr().getRequiredChoices().isEmpty(); return false; } if (eq("Met Preference", term)) return enrollment().isSelected(); else return !enrollment().isSelected(); } return false; } if ("require".equals(attr)) { if (cr() == null) return false; if (eq("Any Requirement", term)) { return !cr().getRequiredChoices().isEmpty(); } if (eq("Met Requirement", term)) { return enrollment() != null && enrollment().isRequired(); } if (eq("Unmet Requirement", term)) { return enrollment() != null && !enrollment().isRequired(); } return false; } if ("im".equals(attr)) { if (cr() == null) return false; if (enrollment() == null) { for (Course course : cr().getCourses()) { for (Config config : course.getOffering().getConfigs()) { if (term.equals(config.getInstructionalMethodReference())) return true; } break; } return false; } else { Config config = enrollment().getConfig(); if (config == null) return false; return term.equals(config.getInstructionalMethodReference()); } } if (enrollment() != null && enrollment().getCourse() != null) { for (Section section : enrollment().getSections()) { if (attr == null || attr.equals("crn") || attr.equals("id") || attr.equals("externalId") || attr.equals("exid") || attr.equals("name")) { if (section.getName(enrollment().getCourse().getId()) != null && section .getName(enrollment().getCourse().getId()).toLowerCase().startsWith(term.toLowerCase())) return true; } if (attr == null || attr.equals("day")) { if (section.getTime() == null && term.equalsIgnoreCase("none")) return true; if (section.getTime() != null) { int day = parseDay(term); if (day > 0 && (section.getTime().getDayCode() & day) == day) return true; } } if (attr == null || attr.equals("time")) { if (section.getTime() == null && term.equalsIgnoreCase("none")) return true; if (section.getTime() != null) { int start = parseStart(term); if (start >= 0 && section.getTime().getStartSlot() == start) return true; } } if (attr != null && attr.equals("before")) { if (section.getTime() != null) { int end = parseStart(term); if (end >= 0 && section.getTime().getStartSlot() + section.getTime().getLength() - section.getTime().getBreakTime() / 5 <= end) return true; } } if (attr != null && attr.equals("after")) { if (section.getTime() != null) { int start = parseStart(term); if (start >= 0 && section.getTime().getStartSlot() >= start) return true; } } if (attr == null || attr.equals("room")) { if ((section.getRooms() == null || section.getRooms().isEmpty()) && term.equalsIgnoreCase("none")) return true; if (section.getRooms() != null) { for (RoomLocation r : section.getRooms()) { if (has(r.getName(), term)) return true; } } } if (attr == null || attr.equals("instr") || attr.equals("instructor")) { if (attr != null && section.getInstructors().isEmpty() && term.equalsIgnoreCase("none")) return true; for (Instructor instuctor : section.getInstructors()) { if (has(instuctor.getName(), term) || eq(instuctor.getExternalId(), term)) return true; if (instuctor.getEmail() != null) { String email = instuctor.getEmail(); if (email.indexOf('@') >= 0) email = email.substring(0, email.indexOf('@')); if (eq(email, term)) return true; } } } } } if (attr == null || "name".equals(attr) || "course".equals(attr)) { return course() != null && (course().getSubjectArea().equalsIgnoreCase(term) || course().getCourseNumber().equalsIgnoreCase(term) || (course().getSubjectArea() + " " + course().getCourseNumber()).equalsIgnoreCase(term)); } if ("title".equals(attr)) { return course() != null && course().getTitle().toLowerCase().contains(term.toLowerCase()); } if ("subject".equals(attr)) { return course() != null && course().getSubjectArea().equalsIgnoreCase(term); } if ("number".equals(attr)) { return course() != null && course().getCourseNumber().equalsIgnoreCase(term); } return false; } private boolean eq(String name, String term) { if (name == null) return false; return name.equalsIgnoreCase(term); } private boolean has(String name, String term) { if (name == null) return false; if (eq(name, term)) return true; for (String t : name.split(" |,")) if (t.equalsIgnoreCase(term)) return true; return false; } private boolean like(String name, String term) { if (name == null) return false; if (term.indexOf('%') >= 0) { return name.matches("(?i)" + term.replaceAll("%", ".*")); } else { return name.equalsIgnoreCase(term); } } public static enum Credit { eq, lt, gt, le, ge } public static String DAY_NAMES_CHARS[] = new String[] { "M", "T", "W", "R", "F", "S", "X" }; private int parseDay(String token) { int days = 0; boolean found = false; do { found = false; for (int i = 0; i < Constants.DAY_NAMES_SHORT.length; i++) { if (token.toLowerCase().startsWith(Constants.DAY_NAMES_SHORT[i].toLowerCase())) { days |= Constants.DAY_CODES[i]; token = token.substring(Constants.DAY_NAMES_SHORT[i].length()); while (token.startsWith(" ")) token = token.substring(1); found = true; } } for (int i = 0; i < DAY_NAMES_CHARS.length; i++) { if (token.toLowerCase().startsWith(DAY_NAMES_CHARS[i].toLowerCase())) { days |= Constants.DAY_CODES[i]; token = token.substring(DAY_NAMES_CHARS[i].length()); while (token.startsWith(" ")) token = token.substring(1); found = true; } } } while (found); return (token.isEmpty() ? days : 0); } private int parseStart(String token) { int startHour = 0, startMin = 0; String number = ""; while (!token.isEmpty() && token.charAt(0) >= '0' && token.charAt(0) <= '9') { number += token.substring(0, 1); token = token.substring(1); } if (number.isEmpty()) return -1; if (number.length() > 2) { startHour = Integer.parseInt(number) / 100; startMin = Integer.parseInt(number) % 100; } else { startHour = Integer.parseInt(number); } while (token.startsWith(" ")) token = token.substring(1); if (token.startsWith(":")) { token = token.substring(1); while (token.startsWith(" ")) token = token.substring(1); number = ""; while (!token.isEmpty() && token.charAt(0) >= '0' && token.charAt(0) <= '9') { number += token.substring(0, 1); token = token.substring(1); } if (number.isEmpty()) return -1; startMin = Integer.parseInt(number); } while (token.startsWith(" ")) token = token.substring(1); boolean hasAmOrPm = false; if (token.toLowerCase().startsWith("am")) { token = token.substring(2); hasAmOrPm = true; } if (token.toLowerCase().startsWith("a")) { token = token.substring(1); hasAmOrPm = true; } if (token.toLowerCase().startsWith("pm")) { token = token.substring(2); hasAmOrPm = true; if (startHour < 12) startHour += 12; } if (token.toLowerCase().startsWith("p")) { token = token.substring(1); hasAmOrPm = true; if (startHour < 12) startHour += 12; } if (startHour < 7 && !hasAmOrPm) startHour += 12; if (startMin % 5 != 0) startMin = 5 * ((startMin + 2) / 5); if (startHour == 7 && startMin == 0 && !hasAmOrPm) startHour += 12; return (60 * startHour + startMin) / 5; } } public static class CourseMatcher implements Query.TermMatcher { private Course iCourse; public CourseMatcher(Course course) { iCourse = course; } public Course course() { return iCourse; } @Override public boolean match(String attr, String term) { if (attr == null || "name".equals(attr) || "course".equals(attr)) { return course() != null && (course().getSubjectArea().equalsIgnoreCase(term) || course().getCourseNumber().equalsIgnoreCase(term) || (course().getSubjectArea() + " " + course().getCourseNumber()).equalsIgnoreCase(term)); } if ("title".equals(attr)) { return course() != null && course().getTitle().toLowerCase().contains(term.toLowerCase()); } if ("subject".equals(attr)) { return course() != null && course().getSubjectArea().equalsIgnoreCase(term); } if ("number".equals(attr)) { return course() != null && course().getCourseNumber().equalsIgnoreCase(term); } return true; } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy