/******************************************************************************* * This file is part of OpenNMS(R). * * Copyright (C) 2006-2011 The OpenNMS Group, Inc. * OpenNMS(R) is Copyright (C) 1999-2011 The OpenNMS Group, Inc. * * OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc. * * OpenNMS(R) is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published * by the Free Software Foundation, either version 3 of the License, * or (at your option) any later version. * * OpenNMS(R) is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with OpenNMS(R). If not, see: * http://www.gnu.org/licenses/ * * For more information contact: * OpenNMS(R) Licensing <license@opennms.org> * http://www.opennms.org/ * http://www.opennms.com/ *******************************************************************************/ package org.opennms.web.admin.users.parsers; import java.util.ArrayList; import java.util.BitSet; import java.util.Calendar; import java.util.GregorianCalendar; import java.util.List; import java.util.StringTokenizer; import java.util.Vector; /** * This class holds information on the duty schedules that users can have. * Converstion between different formats of the duty schedule information are * possible, as is the comparision between a Calendar passed in and the start * and stop times of each day in a duty schedule. * * @author <A HREF="mailto:jason@opennms.org">Jason Johns </A> * @author <A HREF="http://www.opennms.org/">OpenNMS </A> * @author <A HREF="mailto:jason@opennms.org">Jason Johns </A> * @author <A HREF="http://www.opennms.org/">OpenNMS </A> * @version 1.1.1.1 * @since 1.8.1 */ public class DutySchedule { /** * Each boolean in the bit set represents a day of the week. Monday = 0, * Tuesday = 1 ... Sunday = 6 */ private BitSet m_days; /** * The starting time of this DutySchedule */ private int m_startTime; /** * The ending time of this DutySchedule */ private int m_stopTime; /** * A series of constants to identify the days of the week as used by the * DutySchedule class */ public static final int MONDAY = 0; /** Constant <code>TUESDAY=1</code> */ public static final int TUESDAY = 1; /** Constant <code>WEDNESDAY=2</code> */ public static final int WEDNESDAY = 2; /** Constant <code>THURSDAY=3</code> */ public static final int THURSDAY = 3; /** Constant <code>FRIDAY=4</code> */ public static final int FRIDAY = 4; /** Constant <code>SATURDAY=5</code> */ public static final int SATURDAY = 5; /** Constant <code>SUNDAY=6</code> */ public static final int SUNDAY = 6; /** * A list of names to abbreviate the days of the week */ public static final String[] DAY_NAMES = { "Mo", "Tu", "We", "Th", "Fr", "Sa", "Su" }; /** * A mapping between the days of the week as indexed by the DutySchedule * class and those of the Calendar class */ private static final int[] CALENDAR_DAY_MAPPING = { Calendar.MONDAY, Calendar.TUESDAY, Calendar.WEDNESDAY, Calendar.THURSDAY, Calendar.FRIDAY, Calendar.SATURDAY, Calendar.SUNDAY }; /** * Create a new DutySchedule. Builds the BitSet used to identify the days of * the week that are set. */ public DutySchedule() { m_days = new BitSet(7); } /** * Create a new DutySchedule. This constructor is designed to convert from a * Vector filled with 7 Boolean objects and two String objects into the * BitSet and integer start and stop time. Very useful for the ModifyUser * screen when it is converting from a table display to save the information * to a string format for the users.xml. * * @param aSchedule * Vector filled with 7 Boolean objects and two String objects */ public DutySchedule(Vector<?> aSchedule) { m_days = new BitSet(7); // set each day that is set to true for (int i = 0; i < 7; i++) { if (((Boolean) aSchedule.get(i)).booleanValue()) { m_days.set(i); } } // initialize the start and stop times, which should be in the last to // indexes of the vector m_startTime = Integer.parseInt((String) aSchedule.get(7)); m_stopTime = Integer.parseInt((String) aSchedule.get(8)); } /** * Create a new DutySchedule. This constructor is designed to build a new * DutySchedule from a String representation formatted as such. * <day_of_week_abbr><start>- <stop>eg. MoWeFr800-1700, TuTh900-1500. * * @param aSchedule * the string to convert to a new DutySchedule */ public DutySchedule(String aSchedule) { m_days = new BitSet(7); // parse the endtime and day/begin time out StringTokenizer timeTokens = new StringTokenizer(aSchedule, "-"); String daysAndStartTime = timeTokens.nextToken(); m_stopTime = Integer.parseInt(timeTokens.nextToken()); // loop through the first half of the string and get each two letter // day abbreviation, set the appropriate BitSet values for (int j = 0; j < daysAndStartTime.length(); j++) { // check to see if there is a character or digit at the current // index if (!Character.isDigit(daysAndStartTime.charAt(j))) { // look at the current and next characters, advance the loop // counter // by one and add one to get the propert substring m_days.set(getDayInt(daysAndStartTime.substring(j, ++j + 1))); } else { // if a digit was seen this is the start time, get it and stop // the loop m_startTime = Integer.parseInt(daysAndStartTime.substring(j, daysAndStartTime.length())); break; } } } /** * Gets the index value of a day. This method returns the index value of a * day abbreviation * * @param aDay * the day abbreviation * @return the index associated with this abbreviation */ private int getDayInt(String aDay) { int value = -1; for (int i = 0; i < DAY_NAMES.length; i++) { if (aDay.equals(DAY_NAMES[i])) { value = i; break; } } return value; } /** * Sets the day. This method sets the BitSet that tracks what days this * DutySchedule applies to. * * @param aDay * the day index to set in the BitSet */ public void setDay(int aDay) { m_days.set(aDay); } /** * Gets the start time. This method return the start time as an integer * * @return the start time of this DutySchedule */ public int getStartTime() { return m_startTime; } /** * Gets the stop time. This method return the stop time as an integer * * @return the stop time of this DutySchedule */ public int getStopTime() { return m_stopTime; } /** * Gets the days this DutySchedule is active. * * @return the days this DutySchedule is active. */ public List<Boolean> getDaysAsBooleanList() { List<Boolean> list = new ArrayList<Boolean>(m_days.size()); for (int i = 0; i < m_days.size(); i++) { list.add(m_days.get(i)); } return list; } /** * Gets the Vector representation of the DutySchedule. This method formats * the DutySchedule as a vector populated with the first seven objects as * Booleans set to indicate what days of the week are stored, and the last * two objects as Strings that reflect the start time and stop time * respectively. This method gives a Vector that can be passed to the * DutySchedule(Vector) constructor to create a new DutySchedule * * @return a Vector properly formatted to reflect this DutySchedule * @deprecated call the individual getters */ public Vector<Object> getAsVector() { Vector<Object> vector = new Vector<Object>(); for (int i = 0; i < 7; i++) { vector.add(new Boolean(m_days.get(i))); } vector.add(String.valueOf(m_startTime)); vector.add(String.valueOf(m_stopTime)); return vector; } /** * Test if time is contined in schedule. This method decides if a given time * falls within the duty schedule contained in this object. It creates two * partial Calendars from the Calendar that is passed in and then sets the * start time for one and the end time for the other. Then in a loop it * reassigns the day of week according to the BitSet. It makes a comparision * to see if the argument Calendar is between the start and stop times and * returns true immediately if it is. * * @param aTime * the time to check * @return true if the Calendar is contained in the duty schedule, false if * it isn't. */ public boolean isInSchedule(Calendar aTime) { boolean response = false; // make two new Calendar objects from the YEAR, MONTH and DATE of the // date we are checking. Calendar startTime = new GregorianCalendar(aTime.get(Calendar.YEAR), aTime.get(Calendar.MONTH), aTime.get(Calendar.DATE)); // the hour will be the integer part of the start time divided by 100 // cause it should be // in military time startTime.set(Calendar.HOUR_OF_DAY, (m_startTime / 100)); // the minute will be the start time mod 100 cause it should be in // military time startTime.set(Calendar.MINUTE, (m_startTime % 100)); startTime.set(Calendar.SECOND, 0); Calendar endTime = new GregorianCalendar(aTime.get(Calendar.YEAR), aTime.get(Calendar.MONTH), aTime.get(Calendar.DATE)); endTime.set(Calendar.HOUR_OF_DAY, (m_stopTime / 100)); endTime.set(Calendar.MINUTE, (m_stopTime % 100)); endTime.set(Calendar.SECOND, 0); // look at the BitSet to see what days are set for this duty schedule, // reassign the // day of weak for the start and stop time, then see if the argument // Calendar is // between these times. for (int i = 0; i < 7; i++) { // see if the now time corresponds to a day when the user is on duty if (m_days.get(i) && CALENDAR_DAY_MAPPING[i] == aTime.get(Calendar.DAY_OF_WEEK)) { // now check to see if the time given is between these two times // inclusive, if it is quit loop // we want the begin and end times for the ranges to be // includsive, so convert to milliseconds so we // can do a greater than/less than equal to comparisons long dateMillis = aTime.getTime().getTime(); long startMillis = startTime.getTime().getTime(); long endMillis = endTime.getTime().getTime(); // return true if the agrument date falls between the start and // stop time if ((startMillis <= dateMillis) && (dateMillis <= endMillis)) { response = true; break; } } } return response; } /** * Sets the start Hour. This method sets the start time of this DutySchedule * * @param anHour * the hour in military time to set the start time for the * DutySchedule */ public void setStartHour(int anHour) { m_startTime = anHour; } /** * Sets the stop Hour. This method sets the stop time of this DutySchedule * * @param anHour * the hour in military time to set the end time for the * DutySchedule */ public void setEndHour(int anHour) { m_stopTime = anHour; } /** * String representation. This method returns the DutySchedule formatted as * a string that the DutySchedule(String) constructor could parse. The * string will be formatted as such: <day_of_week_abbr><start>- <stop>eg. * MoWeFr800-1700, TuTh900-1500. * * @return a string representation of this DutySchedule */ public String toString() { StringBuffer buffer = new StringBuffer(); // put in abbreviations for the days of the week for (int i = 0; i < DAY_NAMES.length; i++) { if (m_days.get(i)) { buffer.append(DAY_NAMES[i]); } } // add the start and stop times to the end of the string buffer.append(m_startTime + "-" + m_stopTime); return buffer.toString(); } /** * <p>hasDay</p> * * @param aDay a int. * @return a boolean. */ public boolean hasDay(int aDay) { return m_days.get(aDay); } /** * <p>clone</p> * * @return a {@link org.opennms.web.admin.users.parsers.DutySchedule} object. */ public DutySchedule clone() { return new DutySchedule(toString()); } }