001 /* 002 * Cumulus4j - Securing your data in the cloud - http://cumulus4j.org 003 * Copyright (C) 2011 NightLabs Consulting GmbH 004 * 005 * This program is free software: you can redistribute it and/or modify 006 * it under the terms of the GNU Affero General Public License as 007 * published by the Free Software Foundation, either version 3 of the 008 * License, or (at your option) any later version. 009 * 010 * This program is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 013 * GNU Affero General Public License for more details. 014 * 015 * You should have received a copy of the GNU Affero General Public License 016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 017 */ 018 package org.cumulus4j.keymanager.cli; 019 020 import org.kohsuke.args4j.CmdLineException; 021 import org.kohsuke.args4j.CmdLineParser; 022 import org.kohsuke.args4j.Option; 023 import org.kohsuke.args4j.OptionDef; 024 import org.kohsuke.args4j.spi.OneArgumentOptionHandler; 025 import org.kohsuke.args4j.spi.Setter; 026 027 /** 028 * <p> 029 * Option handler implementation to interprete a time period (e.g. "5 minutes". 030 * </p> 031 * <p> 032 * The time period is specified in the command line by writing a number 033 * directly followed (no space!) by a unit. For example 5 minutes could be 034 * written as "5min" or "300s" (300 seconds are 5 minutes). 035 * </p> 036 * <p> 037 * This handler can be chosen for every <code>long</code> property using 038 * the {@link Option} annotation like this: 039 * </p> 040 * <pre> 041 * @Option(name="-myArg", handler=TimePeriodOptionHandler.class) 042 * private long myArg; 043 * </pre> 044 * <p> 045 * The <code>long</code> property will be set to the milliseconds value. 046 * For example, if the command line user passes "5min", the <code>long</code> value 047 * will be 300000 (5 min * 60 s * 1000 ms). 048 * </p> 049 * 050 * @author Marco หงุ่ยตระกูล-Schulze - marco at nightlabs dot de 051 */ 052 public class TimePeriodOptionHandler extends OneArgumentOptionHandler<Long> 053 { 054 /** 055 * Units based on <a target="_blank" href="http://en.wikipedia.org/wiki/ISO_31-1">ISO 31-1</a> (where it exists). 056 * 057 * @author Marco หงุ่ยตระกูล-Schulze - marco at nightlabs dot de 058 */ 059 public static enum Unit { 060 /** 061 * Millisecond. 062 */ 063 ms("Millisecond", 1L), 064 065 /** 066 * Second. 067 */ 068 s("Second", 1000L), 069 070 /** 071 * Minute. 072 */ 073 min("Minute", 60L * s.msec), 074 075 /** 076 * Hour. 077 */ 078 h("Hour", 60L * min.msec), 079 080 /** 081 * Day. 082 */ 083 d("Day", 24L * h.msec), 084 085 /** 086 * Year. <a target="_blank" href="http://en.wikipedia.org/wiki/Year">Abbreviation from latin "annus".</a> 087 */ 088 a("Year", 365L * d.msec), 089 090 /** 091 * Year (alternative for convenience). 092 */ 093 y("Year", 365L * d.msec) 094 ; 095 096 private String displayName; 097 private long msec; 098 099 private Unit(String displayName, long msec) 100 { 101 this.displayName = displayName; 102 this.msec = msec; 103 } 104 105 public long toMSec(long value) 106 { 107 return value * msec; 108 } 109 110 public String getDisplayName() { 111 return displayName; 112 } 113 114 public static String getAllUnitsWithDisplayName() 115 { 116 return getAllUnitsWithDisplayName(", "); 117 } 118 119 public static String getAllUnitsWithDisplayName(String separator) 120 { 121 return getAllUnitsWithDisplayName("%s (%s)", separator); 122 } 123 124 public static String getAllUnitsWithDisplayName(String unitFormat, String separator) 125 { 126 StringBuilder sb = new StringBuilder(); 127 128 for (Unit u : values()) { 129 if (sb.length() > 0) 130 sb.append(separator); 131 132 sb.append(String.format(unitFormat, u.name(), u.getDisplayName())); 133 } 134 135 return sb.toString(); 136 } 137 } 138 139 public TimePeriodOptionHandler(CmdLineParser parser, OptionDef option, Setter<Long> setter) 140 { 141 super(parser, option, setter); 142 } 143 144 @Override 145 protected Long parse(String argument) throws NumberFormatException, CmdLineException 146 { 147 Unit unit = null; 148 for (Unit u : Unit.values()) { 149 if (argument.endsWith(u.name()) && (unit == null || unit.name().length() < u.name().length())) 150 unit = u; 151 } 152 153 if (unit == null) 154 throw new CmdLineException(owner, "Argument '" + argument + "' does not end with one of the following unit-suffixes: " + Unit.getAllUnitsWithDisplayName()); 155 156 String numberVal = argument.substring(0, argument.length() - unit.name().length()).trim(); 157 long valueMSec = Long.parseLong(numberVal); 158 return unit.toMSec(valueMSec); 159 } 160 161 }