View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *  http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  
20  package org.apache.geronimo.gshell.chronos;
21  
22  //
23  // NOTE: Copied and massaged from commons-lang 2.3
24  //
25  
26  import java.util.ArrayList;
27  
28  /**
29   * Utilities for formatting a {@link Duration}.
30   * 
31   * @version $Rev: 707093 $ $Date: 2008-10-22 16:44:18 +0200 (Wed, 22 Oct 2008) $
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                 // T O D O: Need to handle escaping of '
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     // NOTE: Copied from plexus-utils StringUtils 1.5.5
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     // Copied from commons-lang DateUtils 2.3
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 }