| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| package org.apache.geronimo.gshell.chronos; |
| |
| // |
| // NOTE: Copied and massaged from commons-lang 2.3 |
| // |
| |
| import java.util.ArrayList; |
| |
| /** |
| * Utilities for formatting a {@link Duration}. |
| * |
| * @version $Rev$ $Date$ |
| */ |
| class DurationFormatUtils |
| { |
| public DurationFormatUtils() {} |
| |
| public static String formatDurationHMS(long durationMillis) { |
| return formatDuration(durationMillis, "H:mm:ss.SSS", true); |
| } |
| |
| private static String formatDuration(long durationMillis, String format, boolean padWithZeros) { |
| Token[] tokens = lexx(format); |
| |
| int days = 0; |
| int hours = 0; |
| int minutes = 0; |
| int seconds = 0; |
| int milliseconds = 0; |
| |
| if (Token.containsTokenWithValue(tokens, d) ) { |
| days = (int) (durationMillis / DateUtils_MILLIS_PER_DAY); |
| durationMillis = durationMillis - (days * DateUtils_MILLIS_PER_DAY); |
| } |
| if (Token.containsTokenWithValue(tokens, H) ) { |
| hours = (int) (durationMillis / DateUtils_MILLIS_PER_HOUR); |
| durationMillis = durationMillis - (hours * DateUtils_MILLIS_PER_HOUR); |
| } |
| if (Token.containsTokenWithValue(tokens, m) ) { |
| minutes = (int) (durationMillis / DateUtils_MILLIS_PER_MINUTE); |
| durationMillis = durationMillis - (minutes * DateUtils_MILLIS_PER_MINUTE); |
| } |
| if (Token.containsTokenWithValue(tokens, s) ) { |
| seconds = (int) (durationMillis / DateUtils_MILLIS_PER_SECOND); |
| durationMillis = durationMillis - (seconds * DateUtils_MILLIS_PER_SECOND); |
| } |
| if (Token.containsTokenWithValue(tokens, S) ) { |
| milliseconds = (int) durationMillis; |
| } |
| |
| return format(tokens, 0, 0, days, hours, minutes, seconds, milliseconds, padWithZeros); |
| } |
| |
| private static String format(Token[] tokens, int years, int months, int days, int hours, int minutes, int seconds, int milliseconds, boolean padWithZeros) { |
| StringBuilder buffer = new StringBuilder(); |
| boolean lastOutputSeconds = false; |
| int sz = tokens.length; |
| for (int i = 0; i < sz; i++) { |
| Token token = tokens[i]; |
| Object value = token.getValue(); |
| int count = token.getCount(); |
| if (value instanceof StringBuilder) { |
| buffer.append(value.toString()); |
| } |
| else { |
| if (value == y) { |
| buffer.append(padWithZeros ? leftPad(Integer.toString(years), count, "0") : Integer.toString(years)); |
| lastOutputSeconds = false; |
| } |
| else if (value == M) { |
| buffer.append(padWithZeros ? leftPad(Integer.toString(months), count, "0") : Integer.toString(months)); |
| lastOutputSeconds = false; |
| } |
| else if (value == d) { |
| buffer.append(padWithZeros ? leftPad(Integer.toString(days), count, "0") : Integer.toString(days)); |
| lastOutputSeconds = false; |
| } |
| else if (value == H) { |
| buffer.append(padWithZeros ? leftPad(Integer.toString(hours), count, "0") : Integer.toString(hours)); |
| lastOutputSeconds = false; |
| } |
| else if (value == m) { |
| buffer.append(padWithZeros ? leftPad(Integer.toString(minutes), count, "0") : Integer.toString(minutes)); |
| lastOutputSeconds = false; |
| } |
| else if (value == s) { |
| buffer.append(padWithZeros ? leftPad(Integer.toString(seconds), count, "0") : Integer.toString(seconds)); |
| lastOutputSeconds = true; |
| } |
| else if (value == S) { |
| if (lastOutputSeconds) { |
| milliseconds += 1000; |
| String str = padWithZeros |
| ? leftPad(Integer.toString(milliseconds), count, "0") |
| : Integer.toString(milliseconds); |
| buffer.append(str.substring(1)); |
| } |
| else { |
| buffer.append(padWithZeros |
| ? leftPad(Integer.toString(milliseconds), count, "0") |
| : Integer.toString(milliseconds)); |
| } |
| lastOutputSeconds = false; |
| } |
| } |
| } |
| return buffer.toString(); |
| } |
| |
| private static final Object y = "y"; |
| private static final Object M = "M"; |
| private static final Object d = "d"; |
| private static final Object H = "H"; |
| private static final Object m = "m"; |
| private static final Object s = "s"; |
| private static final Object S = "S"; |
| |
| private static Token[] lexx(String format) { |
| char[] array = format.toCharArray(); |
| ArrayList<Token> list = new ArrayList<Token>(array.length); |
| |
| boolean inLiteral = false; |
| StringBuilder buffer = null; |
| Token previous = null; |
| int sz = array.length; |
| for(int i=0; i<sz; i++) { |
| char ch = array[i]; |
| if(inLiteral && ch != '\'') { |
| buffer.append(ch); |
| continue; |
| } |
| Object value = null; |
| switch (ch) { |
| // T O D O: Need to handle escaping of ' |
| case '\'' : |
| if (inLiteral) { |
| buffer = null; |
| inLiteral = false; |
| } |
| else { |
| buffer = new StringBuilder(); |
| list.add(new Token(buffer)); |
| inLiteral = true; |
| } |
| break; |
| case 'y': value = y; break; |
| case 'M': value = M; break; |
| case 'd': value = d; break; |
| case 'H': value = H; break; |
| case 'm': value = m; break; |
| case 's': value = s; break; |
| case 'S': value = S; break; |
| default : |
| if (buffer == null) { |
| buffer = new StringBuilder(); |
| list.add(new Token(buffer)); |
| } |
| buffer.append(ch); |
| } |
| |
| if (value != null) { |
| if (previous != null && previous.getValue() == value) { |
| previous.increment(); |
| } |
| else { |
| Token token = new Token(value); |
| list.add(token); |
| previous = token; |
| } |
| buffer = null; |
| } |
| } |
| return list.toArray( new Token[list.size()] ); |
| } |
| |
| private static class Token |
| { |
| static boolean containsTokenWithValue(Token[] tokens, Object value) { |
| int sz = tokens.length; |
| for (int i = 0; i < sz; i++) { |
| if (tokens[i].getValue() == value) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| private Object value; |
| private int count; |
| |
| Token(Object value) { |
| this.value = value; |
| this.count = 1; |
| } |
| |
| Token(Object value, int count) { |
| this.value = value; |
| this.count = count; |
| } |
| |
| void increment() { |
| count++; |
| } |
| |
| int getCount() { |
| return count; |
| } |
| |
| Object getValue() { |
| return value; |
| } |
| |
| public boolean equals(Object obj2) { |
| if (obj2 instanceof Token) { |
| Token tok2 = (Token) obj2; |
| if (this.value.getClass() != tok2.value.getClass()) { |
| return false; |
| } |
| if (this.count != tok2.count) { |
| return false; |
| } |
| if (this.value instanceof StringBuilder) { |
| return this.value.toString().equals(tok2.value.toString()); |
| } |
| else if (this.value instanceof Number) { |
| return this.value.equals(tok2.value); |
| } |
| else { |
| return this.value == tok2.value; |
| } |
| } |
| return false; |
| } |
| |
| public int hashCode() { |
| return this.value.hashCode(); |
| } |
| |
| public String toString() { |
| return repeat(this.value.toString(), this.count); |
| } |
| } |
| |
| // |
| // NOTE: Copied from plexus-utils StringUtils 1.5.5 |
| // |
| |
| private static String repeat(String str, int repeat) { |
| StringBuilder buffer = new StringBuilder(repeat * str.length()); |
| for (int i = 0; i < repeat; i++) { |
| buffer.append(str); |
| } |
| return buffer.toString(); |
| } |
| |
| private static String leftPad(String str, int size, String delim) { |
| size = (size - str.length()) / delim.length(); |
| if (size > 0) { |
| str = repeat(delim, size) + str; |
| } |
| return str; |
| } |
| |
| // Copied from commons-lang DateUtils 2.3 |
| |
| private static final long DateUtils_MILLIS_PER_SECOND = 1000; |
| |
| private static final long DateUtils_MILLIS_PER_MINUTE = 60 * DateUtils_MILLIS_PER_SECOND; |
| |
| private static final long DateUtils_MILLIS_PER_HOUR = 60 * DateUtils_MILLIS_PER_MINUTE; |
| |
| private static final long DateUtils_MILLIS_PER_DAY = 24 * DateUtils_MILLIS_PER_HOUR; |
| } |