/******************************************************************************* * 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.netmgt.config; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Collection; import java.util.Date; import java.util.Enumeration; import java.util.GregorianCalendar; import java.util.HashMap; import java.util.Map; import org.opennms.core.utils.LogUtils; import org.opennms.netmgt.config.groups.Schedule; import org.opennms.netmgt.config.poller.Outage; /** * <p>BasicScheduleUtils class.</p> * * @author ranger * @version $Id: $ */ public abstract class BasicScheduleUtils { /** * The day of the week values to name mapping */ protected static Map<String,Integer> m_dayOfWeekMap; /** Constant <code>FORMAT1="dd-MMM-yyyy HH:mm:ss"</code> */ public static String FORMAT1 = "dd-MMM-yyyy HH:mm:ss"; /** Constant <code>FORMAT2="HH:mm:ss"</code> */ public static String FORMAT2 = "HH:mm:ss"; /** * <p>isTimeInSchedule</p> * * @param cal a {@link java.util.Calendar} object. * @param sched a {@link org.opennms.netmgt.config.common.BasicSchedule} object. * @return a boolean. */ public static boolean isTimeInSchedule(final Calendar cal, final BasicSchedule sched) { LogUtils.debugf(BasicScheduleUtils.class, "isTimeInOutage: checking for time '%s' in schedule '%s'", cal.getTime(), sched.getName()); if (cal == null || sched == null) return false; Calendar outCalBegin = new GregorianCalendar(); Calendar outCalEnd = new GregorianCalendar(); long curCalTime = cal.getTimeInMillis(); // check if day is part of outage boolean inOutage = false; Enumeration<Time> e = sched.enumerateTime(); while (e.hasMoreElements() && !inOutage) { outCalBegin.setTimeInMillis(curCalTime); outCalEnd.setTimeInMillis(curCalTime); final Time oTime = (Time) e.nextElement(); final String oTimeDay = oTime.getDay(); final String begins = oTime.getBegins(); final String ends = oTime.getEnds(); if (oTimeDay != null) { // see if outage time was specified as sunday/monday.. final Integer dayInMap = getDayOfWeekIndex(oTimeDay); if (dayInMap != null) { // check if value specified matches current date if (cal.get(Calendar.DAY_OF_WEEK) == dayInMap.intValue()) { inOutage = true; } outCalBegin.set(Calendar.DAY_OF_WEEK, dayInMap.intValue()); outCalEnd.set(Calendar.DAY_OF_WEEK, dayInMap.intValue()); } // else see if outage time was specified as day of month else { int intOTimeDay = Integer.valueOf(oTimeDay); if (cal.get(Calendar.DAY_OF_MONTH) == intOTimeDay) { inOutage = true; } outCalBegin.set(Calendar.DAY_OF_MONTH, intOTimeDay); outCalEnd.set(Calendar.DAY_OF_MONTH, intOTimeDay); } } // if time of day was specified and did not match, continue if (oTimeDay != null && !inOutage) continue; // set time in out calendars setOutCalTime(outCalBegin, begins); setOutCalTime(outCalEnd, ends); // check if calendar passed is in the out cal range LogUtils.debugf(BasicScheduleUtils.class, "isTimeInOutage: checking begin/end time...\n current: %s\n begin: %s\n end: %s", cal.getTime(), outCalBegin.getTime(), outCalEnd.getTime()); // round these to the surrounding seconds since we can only specify // this to seconds // accuracy in the config file final long outCalBeginTime = outCalBegin.getTimeInMillis() / 1000 * 1000; final long outCalEndTime = (outCalEnd.getTimeInMillis() / 1000 + 1) * 1000; if (curCalTime >= outCalBeginTime && curCalTime < outCalEndTime) { inOutage = true; } else { inOutage = false; } } return inOutage; } /** * Set the time in outCal from timeStr. 'timeStr'is in either the * 'dd-MMM-yyyy HH:mm:ss' or the 'HH:mm:ss' formats * * @param outCal * the calendar in which time is to be set * @param timeStr * the time string */ public static void setOutCalTime(final Calendar outCal, final String timeStr) { if (timeStr.length() == BasicScheduleUtils.FORMAT1.length()) { SimpleDateFormat format = new SimpleDateFormat(BasicScheduleUtils.FORMAT1); // parse the date string passed Date tempDate = null; try { tempDate = format.parse(timeStr); } catch (ParseException pE) { tempDate = null; } if (tempDate == null) return; Calendar tempCal = new GregorianCalendar(); tempCal.setTime(tempDate); // set outCal outCal.set(Calendar.YEAR, tempCal.get(Calendar.YEAR)); outCal.set(Calendar.MONTH, tempCal.get(Calendar.MONTH)); outCal.set(Calendar.DAY_OF_MONTH, tempCal.get(Calendar.DAY_OF_MONTH)); outCal.set(Calendar.HOUR_OF_DAY, tempCal.get(Calendar.HOUR_OF_DAY)); outCal.set(Calendar.MINUTE, tempCal.get(Calendar.MINUTE)); outCal.set(Calendar.SECOND, tempCal.get(Calendar.SECOND)); outCal.set(Calendar.MILLISECOND, 0); } else if (timeStr.length() == BasicScheduleUtils.FORMAT2.length()) { SimpleDateFormat format = new SimpleDateFormat(BasicScheduleUtils.FORMAT2); // parse the date string passed Date tempDate = null; try { tempDate = format.parse(timeStr); } catch (ParseException pE) { tempDate = null; } if (tempDate == null) return; Calendar tempCal = new GregorianCalendar(); tempCal.setTime(tempDate); // set outCal outCal.set(Calendar.HOUR_OF_DAY, tempCal.get(Calendar.HOUR_OF_DAY)); outCal.set(Calendar.MINUTE, tempCal.get(Calendar.MINUTE)); outCal.set(Calendar.SECOND, tempCal.get(Calendar.SECOND)); outCal.set(Calendar.MILLISECOND, 0); } } /** * <p>getDayOfWeekIndex</p> * * @param dayName a {@link java.lang.String} object. * @return a {@link java.lang.Integer} object. */ public static Integer getDayOfWeekIndex(String dayName) { createDayOfWeekMapping(); return (Integer)m_dayOfWeekMap.get(dayName); } /** * <p>getEndOfSchedule</p> * * @param out a {@link org.opennms.netmgt.config.common.BasicSchedule} object. * @return a {@link java.util.Calendar} object. */ public static Calendar getEndOfSchedule(final BasicSchedule out) { long curCalTime = System.currentTimeMillis(); Calendar cal = new GregorianCalendar(); cal.setTimeInMillis(curCalTime); // check if day is part of outage boolean inOutage = false; Enumeration<Time> en = out.enumerateTime(); while (en.hasMoreElements() && !inOutage) { Calendar outCalBegin = new GregorianCalendar(); Calendar outCalEnd = new GregorianCalendar(); Time oTime = (Time) en.nextElement(); String oTimeDay = oTime.getDay(); String begins = oTime.getBegins(); String ends = oTime.getEnds(); if (oTimeDay != null) { // see if outage time was specified as sunday/monday.. Integer dayInMap = getDayOfWeekIndex(oTimeDay); if (dayInMap != null) { // check if value specified matches current date if (cal.get(Calendar.DAY_OF_WEEK) == dayInMap.intValue()) inOutage = true; outCalBegin.set(Calendar.DAY_OF_WEEK, dayInMap.intValue()); outCalEnd.set(Calendar.DAY_OF_WEEK, dayInMap.intValue()); } // else see if outage time was specified as day of month else { int intOTimeDay = (new Integer(oTimeDay)).intValue(); if (cal.get(Calendar.DAY_OF_MONTH) == intOTimeDay) inOutage = true; outCalBegin.set(Calendar.DAY_OF_MONTH, intOTimeDay); outCalEnd.set(Calendar.DAY_OF_MONTH, intOTimeDay); } } // if time of day was specified and did not match, continue if (oTimeDay != null && !inOutage) { continue; } // set time in out calendars setOutCalTime(outCalBegin, begins); setOutCalTime(outCalEnd, ends); long outCalBeginTime = outCalBegin.getTime().getTime() / 1000 * 1000; long outCalEndTime = (outCalEnd.getTime().getTime() / 1000 + 1) * 1000; if (curCalTime >= outCalBeginTime && curCalTime < outCalEndTime) return outCalEnd; } return null; // Couldn't find a time period that matches } /** * Create the day of week mapping */ private static void createDayOfWeekMapping() { if (BasicScheduleUtils.m_dayOfWeekMap == null) { BasicScheduleUtils.m_dayOfWeekMap = new HashMap<String,Integer>(); BasicScheduleUtils.m_dayOfWeekMap.put("sunday", Calendar.SUNDAY); BasicScheduleUtils.m_dayOfWeekMap.put("monday", Calendar.MONDAY); BasicScheduleUtils.m_dayOfWeekMap.put("tuesday", Calendar.TUESDAY); BasicScheduleUtils.m_dayOfWeekMap.put("wednesday", Calendar.WEDNESDAY); BasicScheduleUtils.m_dayOfWeekMap.put("thursday", Calendar.THURSDAY); BasicScheduleUtils.m_dayOfWeekMap.put("friday", Calendar.FRIDAY); BasicScheduleUtils.m_dayOfWeekMap.put("saturday", Calendar.SATURDAY); } } /** * <p>isTimeInSchedule</p> * * @param time a {@link java.util.Date} object. * @param sched a {@link org.opennms.netmgt.config.common.BasicSchedule} object. * @return a boolean. */ public static boolean isTimeInSchedule(final Date time, final BasicSchedule sched) { final Calendar cal = Calendar.getInstance(); cal.setTime(time); return isTimeInSchedule(cal, sched); } /** * <p>isDaily</p> * * @param time a {@link org.opennms.netmgt.config.common.Time} object. * @return a boolean. */ public static boolean isDaily(final Time time) { return time.getDay() == null && !isSpecific(time); } /** * <p>isWeekly</p> * * @param time a {@link org.opennms.netmgt.config.common.Time} object. * @return a boolean. */ public static boolean isWeekly(final Time time) { return time.getDay() != null && getDayOfWeekIndex(time.getDay()) != null; } /** * <p>isMonthly</p> * * @param time a {@link org.opennms.netmgt.config.common.Time} object. * @return a boolean. */ public static boolean isMonthly(final Time time) { return time.getDay() != null && getDayOfWeekIndex(time.getDay()) == null; } /** * <p>isSpecific</p> * * @param time a {@link org.opennms.netmgt.config.common.Time} object. * @return a boolean. */ public static boolean isSpecific(final Time time) { if (time.getDay() == null) { if (time.getBegins().matches("^\\d\\d\\d\\d-\\d\\d-\\d\\d .*$")) { return true; } else if (time.getBegins().matches("^\\d\\d-...-\\d\\d\\d\\d .*$")) { return true; } } return false; } /** * <p>getSpecificTime</p> * * @param specificString a {@link java.lang.String} object. * @return a {@link java.util.Date} object. */ public static Date getSpecificTime(final String specificString) { final Calendar cal = Calendar.getInstance(); setOutCalTime(cal, specificString); return cal.getTime(); } /** * <p>getMonthlyTime</p> * * @param referenceTime a {@link java.util.Date} object. * @param day a {@link java.lang.String} object. * @param timeString a {@link java.lang.String} object. * @return a {@link java.util.Date} object. */ public static Date getMonthlyTime(final Date referenceTime, final String day, final String timeString) { final Calendar ref = Calendar.getInstance(); ref.setTime(referenceTime); ref.set(Calendar.DAY_OF_MONTH, Integer.parseInt(day)); setOutCalTime(ref, timeString); return ref.getTime(); } /** * <p>getWeeklyTime</p> * * @param referenceTime a {@link java.util.Date} object. * @param day a {@link java.lang.String} object. * @param timeString a {@link java.lang.String} object. * @return a {@link java.util.Date} object. */ public static Date getWeeklyTime(final Date referenceTime, final String day, final String timeString) { final Calendar ref = Calendar.getInstance(); ref.setTime(referenceTime); ref.set(Calendar.DAY_OF_WEEK, getDayOfWeekIndex(day).intValue()); setOutCalTime(ref, timeString); return ref.getTime(); } /** * <p>getDailyTime</p> * * @param referenceTime a {@link java.util.Date} object. * @param timeString a {@link java.lang.String} object. * @return a {@link java.util.Date} object. */ public static Date getDailyTime(final Date referenceTime, final String timeString) { final Calendar ref = Calendar.getInstance(); ref.setTime(referenceTime); setOutCalTime(ref, timeString); return ref.getTime(); } /** * <p>getInterval</p> * * @param ref a {@link java.util.Date} object. * @param time a {@link org.opennms.netmgt.config.common.Time} object. * @param owner a {@link org.opennms.netmgt.config.Owner} object. * @return a {@link org.opennms.netmgt.config.OwnedInterval} object. */ public static OwnedInterval getInterval(final Date ref, final Time time, final Owner owner) { if (isWeekly(time)) { return new OwnedInterval(owner, getWeeklyTime(ref, time.getDay(), time.getBegins()), getWeeklyTime(ref, time.getDay(), time.getEnds())); } else if (isMonthly(time)) { return new OwnedInterval(owner, getMonthlyTime(ref, time.getDay(), time.getBegins()), getMonthlyTime(ref, time.getDay(), time.getEnds())); } else if (isDaily(time)) { return new OwnedInterval(owner, getDailyTime(ref, time.getBegins()), getDailyTime(ref, time.getEnds())); } else { return new OwnedInterval(owner, getSpecificTime(time.getBegins()), getSpecificTime(time.getEnds())); } } /** * <p>nextDay</p> * * @param date a {@link java.util.Date} object. * @return a {@link java.util.Date} object. */ public static Date nextDay(final Date date) { final Calendar cal = Calendar.getInstance(); cal.setTime(date); cal.add(Calendar.DAY_OF_MONTH, 1); return cal.getTime(); } /** * <p>nextWeek</p> * * @param date a {@link java.util.Date} object. * @return a {@link java.util.Date} object. */ public static Date nextWeek(final Date date) { Calendar cal = Calendar.getInstance(); cal.setTime(date); cal.add(Calendar.DAY_OF_YEAR, 7); return cal.getTime(); } /** * <p>nextMonth</p> * * @param date a {@link java.util.Date} object. * @return a {@link java.util.Date} object. */ public static Date nextMonth(final Date date) { Calendar cal = Calendar.getInstance(); cal.setTime(date); cal.add(Calendar.MONTH, 1); return cal.getTime(); } /** * <p>getIntervals</p> * * @param start a {@link java.util.Date} object. * @param end a {@link java.util.Date} object. * @param time a {@link org.opennms.netmgt.config.common.Time} object. * @param owner a {@link org.opennms.netmgt.config.Owner} object. * @return a {@link org.opennms.netmgt.config.OwnedIntervalSequence} object. */ public static OwnedIntervalSequence getIntervals(final Date start, final Date end, final Time time, final Owner owner) { final OwnedIntervalSequence seq = new OwnedIntervalSequence(); // return an empty list for entries that have a zero length interval specified if (time.getBegins().equals(time.getEnds())) return seq; if (isWeekly(time)) { final Date done = nextWeek(end); for(Date ref = start; done.after(ref); ref = nextWeek(ref)) { seq.addInterval(getInterval(ref, time, owner)); } } else if (isMonthly(time)) { final Date done = nextMonth(end); for(Date ref = start; done.after(ref); ref = nextMonth(ref)) { seq.addInterval(getInterval(ref, time, owner)); } } else if (isDaily(time)) { final Date done = nextDay(end); for(Date ref = start; done.after(ref); ref = nextDay(ref)) { seq.addInterval(getInterval(ref, time, owner)); } } else { seq.addInterval(getInterval(start, time, owner)); } seq.bound(start, end); return seq; } /** * <p>getIntervals</p> * * @param interval a {@link org.opennms.netmgt.config.TimeInterval} object. * @param time a {@link org.opennms.netmgt.config.common.Time} object. * @param owner a {@link org.opennms.netmgt.config.Owner} object. * @return a {@link org.opennms.netmgt.config.OwnedIntervalSequence} object. */ public static OwnedIntervalSequence getIntervals(final TimeInterval interval, final Time time, final Owner owner) { return getIntervals(interval.getStart(), interval.getEnd(), time, owner); } /** * <p>getIntervalsCovering</p> * * @param start a {@link java.util.Date} object. * @param end a {@link java.util.Date} object. * @param sched a {@link org.opennms.netmgt.config.common.BasicSchedule} object. * @param owner a {@link org.opennms.netmgt.config.Owner} object. * @return a {@link org.opennms.netmgt.config.OwnedIntervalSequence} object. */ public static OwnedIntervalSequence getIntervalsCovering(final Date start, final Date end, final BasicSchedule sched, final Owner owner) { final OwnedIntervalSequence seq = new OwnedIntervalSequence(); for (int i = 0; i < sched.getTimeCount(); i++) { final Time time = sched.getTime(i); final Owner thisOwner = owner.addTimeIndex(i); seq.addAll(getIntervals(start, end, time, thisOwner)); } return seq; } /** * <p>getIntervalsCovering</p> * * @param interval a {@link org.opennms.netmgt.config.TimeInterval} object. * @param sched a {@link org.opennms.netmgt.config.common.BasicSchedule} object. * @param owner a {@link org.opennms.netmgt.config.Owner} object. * @return a {@link org.opennms.netmgt.config.OwnedIntervalSequence} object. */ public static OwnedIntervalSequence getIntervalsCovering(final TimeInterval interval, final BasicSchedule sched, final Owner owner) { return getIntervalsCovering(interval.getStart(), interval.getEnd(), sched, owner); } static BasicSchedule getBasicOutageSchedule(final Outage out) { if (out == null) return null; final BasicSchedule schedule = new BasicSchedule(); schedule.setName(out.getName()); schedule.setType(out.getType()); final Collection<Time> times = new ArrayList<Time>(); for (final org.opennms.netmgt.config.poller.Time time : out.getTimeCollection()) { times.add(new Time(time.getId(), time.getDay(), time.getBegins(), time.getEnds())); } schedule.setTimeCollection(times); return schedule; } public static BasicSchedule getGroupSchedule(final Schedule schedule) { if (schedule == null) return null; final BasicSchedule basicSchedule = new BasicSchedule(); basicSchedule.setName(schedule.getName()); basicSchedule.setType(schedule.getType()); final Collection<Time> times = new ArrayList<Time>(); for (final org.opennms.netmgt.config.groups.Time time : schedule.getTimeCollection()) { times.add(new Time(time.getId(), time.getDay(), time.getBegins(), time.getEnds())); } basicSchedule.setTimeCollection(times); return basicSchedule; } public static BasicSchedule getRancidSchedule(org.opennms.netmgt.config.rancid.adapter.Schedule schedule) { if (schedule == null) return null; final BasicSchedule basicSchedule = new BasicSchedule(); basicSchedule.setName(schedule.getName()); basicSchedule.setType(schedule.getType()); final Collection<Time> times = new ArrayList<Time>(); for (final org.opennms.netmgt.config.rancid.adapter.Time time : schedule.getTimeCollection()) { times.add(new Time(time.getId(), time.getDay(), time.getBegins(), time.getEnds())); } basicSchedule.setTimeCollection(times); return basicSchedule; } }