001package co.codewizards.cloudstore.client; 002 003import org.kohsuke.args4j.CmdLineException; 004import org.kohsuke.args4j.CmdLineParser; 005import org.kohsuke.args4j.Option; 006import org.kohsuke.args4j.OptionDef; 007import org.kohsuke.args4j.spi.OneArgumentOptionHandler; 008import org.kohsuke.args4j.spi.Setter; 009 010/** 011 * <p> 012 * Option handler implementation to interprete a time period (e.g. "5 minutes". 013 * </p> 014 * <p> 015 * The time period is specified in the command line by writing a number 016 * directly followed (no space!) by a unit. For example 5 minutes could be 017 * written as "5min" or "300s" (300 seconds are 5 minutes). 018 * </p> 019 * <p> 020 * This handler can be chosen for every <code>long</code> property using 021 * the {@link Option} annotation like this: 022 * </p> 023 * <pre> 024 * @Option(name="-myArg", handler=TimePeriodOptionHandler.class) 025 * private long myArg; 026 * </pre> 027 * <p> 028 * The <code>long</code> property will be set to the milliseconds value. 029 * For example, if the command line user passes "5min", the <code>long</code> value 030 * will be 300000 (5 min * 60 s * 1000 ms). 031 * </p> 032 * 033 * @author Marco หงุ่ยตระกูล-Schulze - marco at nightlabs dot de 034 */ 035public class TimePeriodOptionHandler extends OneArgumentOptionHandler<Long> 036{ 037 /** 038 * Units based on <a target="_blank" href="http://en.wikipedia.org/wiki/ISO_31-1">ISO 31-1</a> (where it exists). 039 * 040 * @author Marco หงุ่ยตระกูล-Schulze - marco at nightlabs dot de 041 */ 042 public static enum Unit { 043 /** 044 * Millisecond. 045 */ 046 ms("Millisecond", 1L), 047 048 /** 049 * Second. 050 */ 051 s("Second", 1000L), 052 053 /** 054 * Minute. 055 */ 056 min("Minute", 60L * s.msec), 057 058 /** 059 * Hour. 060 */ 061 h("Hour", 60L * min.msec), 062 063 /** 064 * Day. 065 */ 066 d("Day", 24L * h.msec), 067 068 /** 069 * Year. <a target="_blank" href="http://en.wikipedia.org/wiki/Year">Abbreviation from latin "annus".</a> 070 */ 071 a("Year", 365L * d.msec), 072 073 /** 074 * Year (alternative for convenience). 075 */ 076 y("Year", 365L * d.msec) 077 ; 078 079 private String displayName; 080 private long msec; 081 082 private Unit(String displayName, long msec) 083 { 084 this.displayName = displayName; 085 this.msec = msec; 086 } 087 088 public long toMSec(long value) 089 { 090 return value * msec; 091 } 092 093 public String getDisplayName() { 094 return displayName; 095 } 096 097 public static String getAllUnitsWithDisplayName() 098 { 099 return getAllUnitsWithDisplayName(", "); 100 } 101 102 public static String getAllUnitsWithDisplayName(String separator) 103 { 104 return getAllUnitsWithDisplayName("%s (%s)", separator); 105 } 106 107 public static String getAllUnitsWithDisplayName(String unitFormat, String separator) 108 { 109 StringBuilder sb = new StringBuilder(); 110 111 for (Unit u : values()) { 112 if (sb.length() > 0) 113 sb.append(separator); 114 115 sb.append(String.format(unitFormat, u.name(), u.getDisplayName())); 116 } 117 118 return sb.toString(); 119 } 120 } 121 122 public TimePeriodOptionHandler(CmdLineParser parser, OptionDef option, Setter<Long> setter) 123 { 124 super(parser, option, setter); 125 } 126 127 @Override 128 protected Long parse(String argument) throws NumberFormatException, CmdLineException 129 { 130 Unit unit = null; 131 for (Unit u : Unit.values()) { 132 if (argument.endsWith(u.name()) && (unit == null || unit.name().length() < u.name().length())) 133 unit = u; 134 } 135 136 if (unit == null) 137 throw new CmdLineException(owner, "Argument '" + argument + "' does not end with one of the following unit-suffixes: " + Unit.getAllUnitsWithDisplayName()); 138 139 String numberVal = argument.substring(0, argument.length() - unit.name().length()).trim(); 140 long valueMSec = Long.parseLong(numberVal); 141 return unit.toMSec(valueMSec); 142 } 143 144}