1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.geronimo.gshell.chronos;
21
22
23
24
25
26 import java.util.ArrayList;
27
28
29
30
31
32
33 class DurationFormatUtils
34 {
35 public DurationFormatUtils() {}
36
37 public static String formatDurationHMS(long durationMillis) {
38 return formatDuration(durationMillis, "H:mm:ss.SSS", true);
39 }
40
41 private static String formatDuration(long durationMillis, String format, boolean padWithZeros) {
42 Token[] tokens = lexx(format);
43
44 int days = 0;
45 int hours = 0;
46 int minutes = 0;
47 int seconds = 0;
48 int milliseconds = 0;
49
50 if (Token.containsTokenWithValue(tokens, d) ) {
51 days = (int) (durationMillis / DateUtils_MILLIS_PER_DAY);
52 durationMillis = durationMillis - (days * DateUtils_MILLIS_PER_DAY);
53 }
54 if (Token.containsTokenWithValue(tokens, H) ) {
55 hours = (int) (durationMillis / DateUtils_MILLIS_PER_HOUR);
56 durationMillis = durationMillis - (hours * DateUtils_MILLIS_PER_HOUR);
57 }
58 if (Token.containsTokenWithValue(tokens, m) ) {
59 minutes = (int) (durationMillis / DateUtils_MILLIS_PER_MINUTE);
60 durationMillis = durationMillis - (minutes * DateUtils_MILLIS_PER_MINUTE);
61 }
62 if (Token.containsTokenWithValue(tokens, s) ) {
63 seconds = (int) (durationMillis / DateUtils_MILLIS_PER_SECOND);
64 durationMillis = durationMillis - (seconds * DateUtils_MILLIS_PER_SECOND);
65 }
66 if (Token.containsTokenWithValue(tokens, S) ) {
67 milliseconds = (int) durationMillis;
68 }
69
70 return format(tokens, 0, 0, days, hours, minutes, seconds, milliseconds, padWithZeros);
71 }
72
73 private static String format(Token[] tokens, int years, int months, int days, int hours, int minutes, int seconds, int milliseconds, boolean padWithZeros) {
74 StringBuilder buffer = new StringBuilder();
75 boolean lastOutputSeconds = false;
76 int sz = tokens.length;
77 for (int i = 0; i < sz; i++) {
78 Token token = tokens[i];
79 Object value = token.getValue();
80 int count = token.getCount();
81 if (value instanceof StringBuilder) {
82 buffer.append(value.toString());
83 }
84 else {
85 if (value == y) {
86 buffer.append(padWithZeros ? leftPad(Integer.toString(years), count, "0") : Integer.toString(years));
87 lastOutputSeconds = false;
88 }
89 else if (value == M) {
90 buffer.append(padWithZeros ? leftPad(Integer.toString(months), count, "0") : Integer.toString(months));
91 lastOutputSeconds = false;
92 }
93 else if (value == d) {
94 buffer.append(padWithZeros ? leftPad(Integer.toString(days), count, "0") : Integer.toString(days));
95 lastOutputSeconds = false;
96 }
97 else if (value == H) {
98 buffer.append(padWithZeros ? leftPad(Integer.toString(hours), count, "0") : Integer.toString(hours));
99 lastOutputSeconds = false;
100 }
101 else if (value == m) {
102 buffer.append(padWithZeros ? leftPad(Integer.toString(minutes), count, "0") : Integer.toString(minutes));
103 lastOutputSeconds = false;
104 }
105 else if (value == s) {
106 buffer.append(padWithZeros ? leftPad(Integer.toString(seconds), count, "0") : Integer.toString(seconds));
107 lastOutputSeconds = true;
108 }
109 else if (value == S) {
110 if (lastOutputSeconds) {
111 milliseconds += 1000;
112 String str = padWithZeros
113 ? leftPad(Integer.toString(milliseconds), count, "0")
114 : Integer.toString(milliseconds);
115 buffer.append(str.substring(1));
116 }
117 else {
118 buffer.append(padWithZeros
119 ? leftPad(Integer.toString(milliseconds), count, "0")
120 : Integer.toString(milliseconds));
121 }
122 lastOutputSeconds = false;
123 }
124 }
125 }
126 return buffer.toString();
127 }
128
129 private static final Object y = "y";
130 private static final Object M = "M";
131 private static final Object d = "d";
132 private static final Object H = "H";
133 private static final Object m = "m";
134 private static final Object s = "s";
135 private static final Object S = "S";
136
137 private static Token[] lexx(String format) {
138 char[] array = format.toCharArray();
139 ArrayList<Token> list = new ArrayList<Token>(array.length);
140
141 boolean inLiteral = false;
142 StringBuilder buffer = null;
143 Token previous = null;
144 int sz = array.length;
145 for(int i=0; i<sz; i++) {
146 char ch = array[i];
147 if(inLiteral && ch != '\'') {
148 buffer.append(ch);
149 continue;
150 }
151 Object value = null;
152 switch (ch) {
153
154 case '\'' :
155 if (inLiteral) {
156 buffer = null;
157 inLiteral = false;
158 }
159 else {
160 buffer = new StringBuilder();
161 list.add(new Token(buffer));
162 inLiteral = true;
163 }
164 break;
165 case 'y': value = y; break;
166 case 'M': value = M; break;
167 case 'd': value = d; break;
168 case 'H': value = H; break;
169 case 'm': value = m; break;
170 case 's': value = s; break;
171 case 'S': value = S; break;
172 default :
173 if (buffer == null) {
174 buffer = new StringBuilder();
175 list.add(new Token(buffer));
176 }
177 buffer.append(ch);
178 }
179
180 if (value != null) {
181 if (previous != null && previous.getValue() == value) {
182 previous.increment();
183 }
184 else {
185 Token token = new Token(value);
186 list.add(token);
187 previous = token;
188 }
189 buffer = null;
190 }
191 }
192 return list.toArray( new Token[list.size()] );
193 }
194
195 private static class Token
196 {
197 static boolean containsTokenWithValue(Token[] tokens, Object value) {
198 int sz = tokens.length;
199 for (int i = 0; i < sz; i++) {
200 if (tokens[i].getValue() == value) {
201 return true;
202 }
203 }
204 return false;
205 }
206
207 private Object value;
208 private int count;
209
210 Token(Object value) {
211 this.value = value;
212 this.count = 1;
213 }
214
215 Token(Object value, int count) {
216 this.value = value;
217 this.count = count;
218 }
219
220 void increment() {
221 count++;
222 }
223
224 int getCount() {
225 return count;
226 }
227
228 Object getValue() {
229 return value;
230 }
231
232 public boolean equals(Object obj2) {
233 if (obj2 instanceof Token) {
234 Token tok2 = (Token) obj2;
235 if (this.value.getClass() != tok2.value.getClass()) {
236 return false;
237 }
238 if (this.count != tok2.count) {
239 return false;
240 }
241 if (this.value instanceof StringBuilder) {
242 return this.value.toString().equals(tok2.value.toString());
243 }
244 else if (this.value instanceof Number) {
245 return this.value.equals(tok2.value);
246 }
247 else {
248 return this.value == tok2.value;
249 }
250 }
251 return false;
252 }
253
254 public int hashCode() {
255 return this.value.hashCode();
256 }
257
258 public String toString() {
259 return repeat(this.value.toString(), this.count);
260 }
261 }
262
263
264
265
266
267 private static String repeat(String str, int repeat) {
268 StringBuilder buffer = new StringBuilder(repeat * str.length());
269 for (int i = 0; i < repeat; i++) {
270 buffer.append(str);
271 }
272 return buffer.toString();
273 }
274
275 private static String leftPad(String str, int size, String delim) {
276 size = (size - str.length()) / delim.length();
277 if (size > 0) {
278 str = repeat(delim, size) + str;
279 }
280 return str;
281 }
282
283
284
285 private static final long DateUtils_MILLIS_PER_SECOND = 1000;
286
287 private static final long DateUtils_MILLIS_PER_MINUTE = 60 * DateUtils_MILLIS_PER_SECOND;
288
289 private static final long DateUtils_MILLIS_PER_HOUR = 60 * DateUtils_MILLIS_PER_MINUTE;
290
291 private static final long DateUtils_MILLIS_PER_DAY = 24 * DateUtils_MILLIS_PER_HOUR;
292 }