View Javadoc

1   /**
2    * Copyright 2010-2012 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.common.aws.s3;
17  
18  import java.text.NumberFormat;
19  import java.text.SimpleDateFormat;
20  import java.util.Date;
21  
22  /**
23   * Format time, bytes, counts, and transfer rate into human friendly form
24   *
25   * @author Jeff Caddel
26   * @since May 27, 2010 6:46:17 PM
27   */
28  public class SimpleFormatter {
29  	private static final double SECOND = 1000;
30  	private static final double MINUTE = 60 * SECOND;
31  	private static final double HOUR = 60 * MINUTE;
32  	private static final double DAY = 24 * HOUR;
33  	private static final double YEAR = 365 * DAY;
34  	private static final double DECADE = 10 * YEAR;
35  	private static final double CENTURY = 10 * DECADE;
36  	private static final String DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SZ";
37  
38  	NumberFormat largeSizeFormatter = NumberFormat.getInstance();
39  	NumberFormat sizeFormatter = NumberFormat.getInstance();
40  	NumberFormat timeFormatter = NumberFormat.getInstance();
41  	NumberFormat rateFormatter = NumberFormat.getInstance();
42  	NumberFormat countFormatter = NumberFormat.getInstance();
43  	SimpleDateFormat dateFormatter = new SimpleDateFormat(DATE_FORMAT);
44  
45  	public SimpleFormatter() {
46  		super();
47  		sizeFormatter.setGroupingUsed(false);
48  		sizeFormatter.setMaximumFractionDigits(1);
49  		sizeFormatter.setMinimumFractionDigits(1);
50  		largeSizeFormatter.setGroupingUsed(false);
51  		largeSizeFormatter.setMaximumFractionDigits(3);
52  		largeSizeFormatter.setMinimumFractionDigits(3);
53  		timeFormatter.setGroupingUsed(false);
54  		timeFormatter.setMaximumFractionDigits(3);
55  		timeFormatter.setMinimumFractionDigits(3);
56  		rateFormatter.setGroupingUsed(false);
57  		rateFormatter.setMaximumFractionDigits(3);
58  		rateFormatter.setMinimumFractionDigits(3);
59  		countFormatter.setGroupingUsed(true);
60  		countFormatter.setMaximumFractionDigits(0);
61  		countFormatter.setMinimumFractionDigits(0);
62  	}
63  
64  	/**
65  	 * Return a formatted date
66  	 */
67  	public String getDate(long millis) {
68  		return getDate(new Date(millis));
69  	}
70  
71  	/**
72  	 * Return a formatted date
73  	 */
74  	public String getDate(Date date) {
75  		return dateFormatter.format(date);
76  	}
77  
78  	/**
79  	 * Given a number of bytes and the number of milliseconds it took to transfer that number of bytes, return bytes/s, KB/s, MB/s, GB/s,
80  	 * TB/s, PB/s, or EB/s as appropriate
81  	 */
82  	public String getRate(long millis, long bytes) {
83  		double seconds = millis / SECOND;
84  		double bytesPerSecond = bytes / seconds;
85  		Size bandwidthLevel = getSizeEnum(bytesPerSecond);
86  		double transferRate = bytesPerSecond / bandwidthLevel.getValue();
87  		return rateFormatter.format(transferRate) + " " + bandwidthLevel.getRateLabel();
88  	}
89  
90  	/**
91  	 * Return a formatted <code>count</code>
92  	 */
93  	public String getCount(long count) {
94  		return countFormatter.format(count);
95  	}
96  
97  	/**
98  	 * Given milliseconds, return milliseconds, seconds, minutes, hours, days, years, decades, or centuries as appropriate. Note that years,
99  	 * decades, and centuries are approximations since the logic always assumes there are exactly 365 days per year.
100 	 */
101 	public String getTime(long millis) {
102 		if (millis < SECOND) {
103 			return millis + "ms";
104 		} else if (millis < MINUTE) {
105 			return timeFormatter.format(millis / SECOND) + "s";
106 		} else if (millis < HOUR) {
107 			return timeFormatter.format(millis / MINUTE) + "m";
108 		} else if (millis < DAY) {
109 			return timeFormatter.format(millis / HOUR) + " hours";
110 		} else if (millis < YEAR) {
111 			return timeFormatter.format(millis / DAY) + " days";
112 		} else if (millis < DECADE) {
113 			return timeFormatter.format(millis / YEAR) + " years";
114 		} else if (millis < CENTURY) {
115 			return timeFormatter.format(millis / DECADE) + " decades";
116 		} else {
117 			return timeFormatter.format(millis / CENTURY) + " centuries";
118 		}
119 	}
120 
121 	/**
122 	 * Given a number of bytes return bytes, kilobytes, megabytes, gigabytes, terabytes, petabytes, or exabytes as appropriate.
123 	 */
124 	public String getSize(long bytes) {
125 		return getSize(bytes, null);
126 	}
127 
128 	/**
129 	 * Given a number of bytes return bytes, kilobytes, megabytes, gigabytes, terabytes, petabytes, or exabytes as appropriate.
130 	 */
131 	public String getSize(long bytes, Size size) {
132 		size = (size == null) ? getSizeEnum(bytes) : size;
133 		StringBuilder sb = new StringBuilder();
134 		sb.append(getFormattedSize(bytes, size));
135 		if (needsSpaceBeforeLabel(size)) {
136 			sb.append(" ");
137 		}
138 		sb.append(size.getSizeLabel());
139 		return sb.toString();
140 	}
141 
142 	protected boolean needsSpaceBeforeLabel(Size size) {
143 		switch (size) {
144 		case BYTE:
145 		case TB:
146 		case PB:
147 		case EB:
148 			return true;
149 		default:
150 			return false;
151 		}
152 	}
153 
154 	public String getFormattedSize(long bytes, Size size) {
155 		switch (size) {
156 		case BYTE:
157 			return bytes + "";
158 		case KB:
159 		case MB:
160 		case GB:
161 			return sizeFormatter.format(bytes / (double) size.getValue());
162 		default:
163 			return largeSizeFormatter.format(bytes / (double) size.getValue());
164 		}
165 	}
166 
167 	public Size getSizeEnum(double bytes) {
168 		if (bytes < Size.KB.getValue()) {
169 			return Size.BYTE;
170 		} else if (bytes < Size.MB.getValue()) {
171 			return Size.KB;
172 		} else if (bytes < Size.GB.getValue()) {
173 			return Size.MB;
174 		} else if (bytes < Size.TB.getValue()) {
175 			return Size.GB;
176 		} else if (bytes < Size.PB.getValue()) {
177 			return Size.TB;
178 		} else if (bytes < Size.EB.getValue()) {
179 			return Size.PB;
180 		} else {
181 			return Size.EB;
182 		}
183 	}
184 
185 	public NumberFormat getLargeSizeFormatter() {
186 		return largeSizeFormatter;
187 	}
188 
189 	public void setLargeSizeFormatter(NumberFormat sizeFormatter) {
190 		this.largeSizeFormatter = sizeFormatter;
191 	}
192 
193 	public NumberFormat getTimeFormatter() {
194 		return timeFormatter;
195 	}
196 
197 	public void setTimeFormatter(NumberFormat timeFormatter) {
198 		this.timeFormatter = timeFormatter;
199 	}
200 
201 	public NumberFormat getRateFormatter() {
202 		return rateFormatter;
203 	}
204 
205 	public void setRateFormatter(NumberFormat rateFormatter) {
206 		this.rateFormatter = rateFormatter;
207 	}
208 
209 	public NumberFormat getSizeFormatter() {
210 		return sizeFormatter;
211 	}
212 
213 	public void setSizeFormatter(NumberFormat smallSizeFormatter) {
214 		this.sizeFormatter = smallSizeFormatter;
215 	}
216 }