/** * Helios, OpenSource Monitoring * Brought to you by the Helios Development Group * * Copyright 2007, Helios Development Group and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This 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 2.1 of * the License, or (at your option) any later version. * * This software 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 software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. * */ package org.helios.apmrouter.tsmodel; import java.util.HashMap; import java.util.Map; /** * <p>Title: TSUnit</p> * <p>Description: An extended analog of {@link java.util.concurrent.TimeUnit} that starts at SECONDS adds an extra member called WEEK and provides decodes for short names. </p> * <p>Company: Helios Development Group LLC</p> * @author Whitehead (nwhitehead AT heliosdev DOT org) * <p><code>org.helios.apmrouter.tsmodel.TSUnit</code></p> */ public enum TSUnit { /** The seconds TSUnit */ SECONDS(1L, "S") { @Override public long convertToSeconds(long value) { return value;}; @Override public long convertToMinutes(long value) { return value/60;}; @Override public long convertToHours(long value) { return value/60/60;}; @Override public long convertToDays(long value) { return value/60/60/24;}; @Override public long convertToWeeks(long value) { return value/60/60/24/7;}; @Override public long convert(long d, TSUnit u) { return u.convertToSeconds(d); } }, /** The minutes TSUnit */ MINUTES(60L, "M"){ @Override public long convertToSeconds(long value) { return value*60;}; @Override public long convertToMinutes(long value) { return value;}; @Override public long convertToHours(long value) { return value/60;}; @Override public long convertToDays(long value) { return value/60/24;}; @Override public long convertToWeeks(long value) { return value/60/24/7;}; @Override public long convert(long d, TSUnit u) { return u.convertToMinutes(d); } }, /** The hours TSUnit */ HOURS(3600L, "H") { @Override public long convertToSeconds(long value) { return value*60*60;}; @Override public long convertToMinutes(long value) { return value*60;}; @Override public long convertToHours(long value) { return value;}; @Override public long convertToDays(long value) { return value/24;}; @Override public long convertToWeeks(long value) { return value/24/7;}; @Override public long convert(long d, TSUnit u) { return u.convertToHours(d); } }, /** The days TSUnit */ DAYS(86400L, "D"){ @Override public long convertToSeconds(long value) { return value*60*60*24;}; @Override public long convertToMinutes(long value) { return value*60*24;}; @Override public long convertToHours(long value) { return value*24;}; @Override public long convertToDays(long value) { return value;}; @Override public long convertToWeeks(long value) { return value/7;}; @Override public long convert(long d, TSUnit u) { return u.convertToDays(d); } }, /** The weeks TSUnit */ WEEKS(86400L*7, "W"){ @Override public long convertToSeconds(long value) { return value*60*60*24*7;}; @Override public long convertToMinutes(long value) { return value*60*24*7;}; @Override public long convertToHours(long value) { return value*24*7;}; @Override public long convertToDays(long value) { return value*7;}; @Override public long convertToWeeks(long value) { return value;}; @Override public long convert(long d, TSUnit u) { return u.convertToDays(d); } }; private static final Map<String, TSUnit> CODE2TSUNIT = new HashMap<String, TSUnit>(TSUnit.values().length*2); private static final Map<Integer, TSUnit> ORD2TSUNIT = new HashMap<Integer, TSUnit>(TSUnit.values().length); static { for(TSUnit ts: TSUnit.values()) { CODE2TSUNIT.put(ts.shortCode, ts); CODE2TSUNIT.put(ts.shortCode.toLowerCase(), ts); ORD2TSUNIT.put(ts.ordinal(), ts); } } /** * Determines if the passed code is a valid short name regardless of case * @param code The code to test * @return true if the code is a valid code, false if it is not. */ public static boolean isValidCode(String code) { if(code==null) return false; return CODE2TSUNIT.containsKey(code); } /** * Returns the matching TSUnit for the passed short code. The passed code is trimmed. * @param code The short code to get the TSUnit for * @return the matching TSUnit */ public static TSUnit forCode(String code) { if(code==null) throw new IllegalArgumentException("The passed code was null", new Throwable()); code = code.trim(); TSUnit ts = CODE2TSUNIT.get(code); if(ts==null) throw new IllegalArgumentException("The passed code [" + code + "] was not a valid TSUnit short code", new Throwable()); return ts; } /** * Determines if there is a higher unit than this one * @return true if there is a higher unit than this one, false otherwise */ public boolean hasHigher() { return ORD2TSUNIT.containsKey(this.ordinal()+1); } /** * Determines if there is a lower unit than this one * @return true if there is a lower unit than this one, false otherwise */ public boolean hasLower() { return ORD2TSUNIT.containsKey(this.ordinal()-1); } /** * Returns the next highest unit * @return the next highest unit or null if there is no higher unit */ public TSUnit getHigher() { return ORD2TSUNIT.get(this.ordinal()+1); } /** * Returns the next lowest unit * @return the next lowest unit or null if there is no lower unit */ public TSUnit getLower() { return ORD2TSUNIT.get(this.ordinal()-1); } /** * Returns the number of this unit's in the passed unit. * Throws an exception if this unit is larger than the passed unit. * @param unit The unit to determine the conversion for * @return The number of this unit's in the passed unit */ public long conversion(TSUnit unit) { if(this.ordinal()>unit.ordinal()) throw new IllegalArgumentException("Invalid conversion [" + name() + "-->" + unit.name() + "]. This unit is larger than the passed unit", new Throwable()); return unit.secs / this.secs; } /** * Attempts to create an equivalently sized duration in a higher unit * @param size The size of the duration to refine * @return the refined duration or the same duration if it could not be refined */ public Duration refine(long size) { TSUnit higher = getHigher(); if(higher==null) return new Duration(size, this); if(mod(size, conversion(higher))==0) { Duration d = new Duration(size/conversion(higher), higher); return d.refine(); } return new Duration(size, this); } private double mod(double d, double mod) { return d%mod; } /** * Creates a new TSUnit * @param secs The number of seconds in one unit of this TSUnit * @param shortCode The short code for this unit */ private TSUnit(long secs, String shortCode) { this.secs= secs; this.shortCode = shortCode; } /** The number of seconds in this TSUnit */ public final long secs; /** The short name of this TSUnit */ public final String shortCode; public long convert(long sourceValue, TSUnit sourceUnit) { throw new AbstractMethodError(); } public static void main(String[] args) { log("TSUnit Test"); log("6 Hours in Minutes:" + TSUnit.HOURS.convert(6, TSUnit.MINUTES)); log("90 Hours in Minutes:" + TSUnit.HOURS.convert(90, TSUnit.MINUTES)); log("120 Minutes in Hours:" + TSUnit.MINUTES.convert(120, TSUnit.HOURS)); log("Minutes in Day:" + TSUnit.MINUTES.conversion(TSUnit.DAYS)); log("Refine 1440 Minutes:" + TSUnit.MINUTES.refine(1440)); log("Render 15 Minutes as Seconds:" + TSUnit.MINUTES.convert(15, TSUnit.SECONDS)); } public static void log(Object msg) { System.out.println(msg); } public long convertToSeconds(long value) {throw new AbstractMethodError();} public long convertToMinutes(long value) {throw new AbstractMethodError();}; public long convertToHours(long value) {throw new AbstractMethodError();}; public long convertToDays(long value) {throw new AbstractMethodError();}; public long convertToWeeks(long value) {throw new AbstractMethodError();}; }