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  package org.apache.maven.cli.transfer;
20  
21  import org.apache.maven.api.services.MessageBuilder;
22  
23  /**
24   * Formats file size with the associated <a href="https://en.wikipedia.org/wiki/Metric_prefix">SI</a> prefix
25   * (GB, MB, kB) and using the patterns <code>#0.0</code> for numbers between 1 and 10
26   * and <code>###0</code> for numbers between 10 and 1000+ by default.
27   *
28   * @see <a href="https://en.wikipedia.org/wiki/Metric_prefix">https://en.wikipedia.org/wiki/Metric_prefix</a>
29   * @see <a href="https://en.wikipedia.org/wiki/Binary_prefix">https://en.wikipedia.org/wiki/Binary_prefix</a>
30   * @see <a
31   *      href="https://en.wikipedia.org/wiki/Octet_%28computing%29">https://en.wikipedia.org/wiki/Octet_(computing)</a>
32   */
33  @Deprecated
34  public class FileSizeFormat {
35      public enum ScaleUnit {
36          BYTE {
37              @Override
38              public long bytes() {
39                  return 1L;
40              }
41  
42              @Override
43              public String symbol() {
44                  return "B";
45              }
46          },
47          KILOBYTE {
48              @Override
49              public long bytes() {
50                  return 1000L;
51              }
52  
53              @Override
54              public String symbol() {
55                  return "kB";
56              }
57          },
58          MEGABYTE {
59              @Override
60              public long bytes() {
61                  return KILOBYTE.bytes() * KILOBYTE.bytes();
62              }
63  
64              @Override
65              public String symbol() {
66                  return "MB";
67              }
68          },
69          GIGABYTE {
70              @Override
71              public long bytes() {
72                  return MEGABYTE.bytes() * KILOBYTE.bytes();
73              }
74              ;
75  
76              @Override
77              public String symbol() {
78                  return "GB";
79              }
80          };
81  
82          public abstract long bytes();
83  
84          public abstract String symbol();
85  
86          public static ScaleUnit getScaleUnit(long size) {
87              if (size < 0L) {
88                  throw new IllegalArgumentException("file size cannot be negative: " + size);
89              }
90  
91              if (size >= GIGABYTE.bytes()) {
92                  return GIGABYTE;
93              } else if (size >= MEGABYTE.bytes()) {
94                  return MEGABYTE;
95              } else if (size >= KILOBYTE.bytes()) {
96                  return KILOBYTE;
97              } else {
98                  return BYTE;
99              }
100         }
101     }
102 
103     public String format(long size) {
104         return format(size, null);
105     }
106 
107     public String format(long size, ScaleUnit unit) {
108         return format(size, unit, false);
109     }
110 
111     public String format(long size, ScaleUnit unit, boolean omitSymbol) {
112         StringBuilder sb = new StringBuilder();
113         format(sb, size, unit, omitSymbol);
114         return sb.toString();
115     }
116 
117     public void format(StringBuilder builder, long size) {
118         format(builder, size, null, false);
119     }
120 
121     public void format(StringBuilder builder, long size, ScaleUnit unit) {
122         format(builder, size, unit, false);
123     }
124 
125     private void format(StringBuilder builder, long size, ScaleUnit unit, boolean omitSymbol) {
126         if (size < 0L) {
127             throw new IllegalArgumentException("file size cannot be negative: " + size);
128         }
129         if (unit == null) {
130             unit = ScaleUnit.getScaleUnit(size);
131         }
132 
133         double scaledSize = (double) size / unit.bytes();
134 
135         if (unit == ScaleUnit.BYTE) {
136             builder.append(size);
137         } else if (scaledSize < 0.05d || scaledSize >= 10.0d) {
138             builder.append(Math.round(scaledSize));
139         } else {
140             builder.append(Math.round(scaledSize * 10d) / 10d);
141         }
142 
143         if (!omitSymbol) {
144             builder.append(" ").append(unit.symbol());
145         }
146     }
147 
148     public void format(MessageBuilder builder, long size) {
149         format(builder, size, null, false);
150     }
151 
152     public void format(MessageBuilder builder, long size, ScaleUnit unit) {
153         format(builder, size, unit, false);
154     }
155 
156     private void format(MessageBuilder builder, long size, ScaleUnit unit, boolean omitSymbol) {
157         if (size < 0L) {
158             throw new IllegalArgumentException("file size cannot be negative: " + size);
159         }
160         if (unit == null) {
161             unit = ScaleUnit.getScaleUnit(size);
162         }
163 
164         double scaledSize = (double) size / unit.bytes();
165 
166         if (unit == ScaleUnit.BYTE) {
167             builder.append(Long.toString(size));
168         } else if (scaledSize < 0.05d || scaledSize >= 10.0d) {
169             builder.append(Long.toString(Math.round(scaledSize)));
170         } else {
171             builder.append(Double.toString(Math.round(scaledSize * 10d) / 10d));
172         }
173 
174         if (!omitSymbol) {
175             builder.append(" ").append(unit.symbol());
176         }
177     }
178 
179     public String formatProgress(long progressedSize, long size) {
180         StringBuilder sb = new StringBuilder();
181         formatProgress(sb, progressedSize, size);
182         return sb.toString();
183     }
184 
185     public void formatProgress(StringBuilder builder, long progressedSize, long size) {
186         if (progressedSize < 0L) {
187             throw new IllegalArgumentException("progressed file size cannot be negative: " + size);
188         }
189         if (size >= 0 && progressedSize > size) {
190             throw new IllegalArgumentException(
191                     "progressed file size cannot be greater than size: " + progressedSize + " > " + size);
192         }
193 
194         if (size >= 0L && progressedSize != size) {
195             ScaleUnit unit = ScaleUnit.getScaleUnit(size);
196             format(builder, progressedSize, unit, true);
197             builder.append("/");
198             format(builder, size, unit, false);
199         } else {
200             ScaleUnit unit = ScaleUnit.getScaleUnit(progressedSize);
201 
202             format(builder, progressedSize, unit, false);
203         }
204     }
205 }