1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.imaging.internal;
18
19 import java.awt.color.ICC_Profile;
20 import java.io.File;
21 import java.text.DateFormat;
22 import java.text.SimpleDateFormat;
23 import java.util.ArrayList;
24 import java.util.Calendar;
25 import java.util.Date;
26 import java.util.List;
27 import java.util.Locale;
28 import java.util.Map;
29 import java.util.Objects;
30 import java.util.logging.Level;
31 import java.util.logging.Logger;
32
33
34
35
36
37 public final class Debug {
38
39 private static final Logger LOGGER = Logger.getLogger(Debug.class.getName());
40
41
42 private static final String NEWLINE = "\r\n";
43 private static long counter;
44
45 private static String byteQuadToString(final int byteQuad) {
46 final byte b1 = (byte) (byteQuad >> 24 & 0xff);
47 final byte b2 = (byte) (byteQuad >> 16 & 0xff);
48 final byte b3 = (byte) (byteQuad >> 8 & 0xff);
49 final byte b4 = (byte) (byteQuad >> 0 & 0xff);
50
51 final char c1 = (char) b1;
52 final char c2 = (char) b2;
53 final char c3 = (char) b3;
54 final char c4 = (char) b4;
55
56 final StringBuilder buffer = new StringBuilder(31);
57 buffer.append(new String(new char[] { c1, c2, c3, c4 }));
58 buffer.append(" byteQuad: ");
59 buffer.append(byteQuad);
60 buffer.append(" b1: ");
61 buffer.append(b1);
62 buffer.append(" b2: ");
63 buffer.append(b2);
64 buffer.append(" b3: ");
65 buffer.append(b3);
66 buffer.append(" b4: ");
67 buffer.append(b4);
68
69 return buffer.toString();
70 }
71
72 public static void debug() {
73 if (LOGGER.isLoggable(Level.FINEST)) {
74 LOGGER.finest(NEWLINE);
75 }
76 }
77
78 public static void debug(final String message) {
79 if (LOGGER.isLoggable(Level.FINEST)) {
80 LOGGER.finest(message);
81 }
82 }
83
84 private static void debug(final String message, final byte[] v) {
85 debug(getDebug(message, v));
86 }
87
88 private static void debug(final String message, final Calendar value) {
89 final DateFormat df = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss", Locale.ROOT);
90 debug(message, value == null ? "null" : df.format(value.getTime()));
91 }
92
93 private static void debug(final String message, final char[] v) {
94 debug(getDebug(message, v));
95 }
96
97 private static void debug(final String message, final Date value) {
98 final DateFormat df = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss", Locale.ROOT);
99 debug(message, value == null ? "null" : df.format(value));
100 }
101
102 private static void debug(final String message, final File file) {
103 debug(message + ": " + (file == null ? "null" : file.getPath()));
104 }
105
106 private static void debug(final String message, final ICC_Profile value) {
107 debug("ICC_Profile " + message + ": " + Objects.toString(value));
108 if (value != null) {
109 debug("\t getProfileClass: " + byteQuadToString(value.getProfileClass()));
110 debug("\t getPCSType: " + byteQuadToString(value.getPCSType()));
111 debug("\t getColorSpaceType() : " + byteQuadToString(value.getColorSpaceType()));
112 }
113 }
114
115 private static void debug(final String message, final int[] v) {
116 debug(getDebug(message, v));
117 }
118
119 private static void debug(final String message, final List<?> v) {
120 final String suffix = " [" + counter++ + "]";
121
122 debug(message + " (" + v.size() + ")" + suffix);
123 for (final Object aV : v) {
124 debug("\t" + aV.toString() + suffix);
125 }
126 debug();
127 }
128
129 private static void debug(final String message, final Map<?, ?> map) {
130 debug(getDebug(message, map));
131 }
132
133 public static void debug(final String message, final Object value) {
134 if (value == null) {
135 debug(message, "null");
136 } else if (value instanceof char[]) {
137 debug(message, (char[]) value);
138 } else if (value instanceof byte[]) {
139 debug(message, (byte[]) value);
140 } else if (value instanceof int[]) {
141 debug(message, (int[]) value);
142 } else if (value instanceof String) {
143 debug(message, (String) value);
144 } else if (value instanceof List) {
145 debug(message, (List<?>) value);
146 } else if (value instanceof Map) {
147 debug(message, (Map<?, ?>) value);
148 } else if (value instanceof ICC_Profile) {
149 debug(message, (ICC_Profile) value);
150 } else if (value instanceof File) {
151 debug(message, (File) value);
152 } else if (value instanceof Date) {
153 debug(message, (Date) value);
154 } else if (value instanceof Calendar) {
155 debug(message, (Calendar) value);
156 } else {
157 debug(message, value.toString());
158 }
159 }
160
161 private static void debug(final String message, final String value) {
162 debug(message + " " + value);
163 }
164
165 public static void debug(final Throwable e) {
166 debug(getDebug(e));
167 }
168
169 public static void debug(final Throwable e, final int value) {
170 debug(getDebug(e, value));
171 }
172
173 private static String getDebug(final String message, final byte[] v) {
174 final int max = 250;
175 return getDebug(message, v, max);
176 }
177
178 private static String getDebug(final String message, final byte[] v, final int max) {
179
180 final StringBuilder result = new StringBuilder();
181
182 if (v == null) {
183 result.append(message + " (" + null + ")" + NEWLINE);
184 } else {
185 result.append(message + " (" + v.length + ")" + NEWLINE);
186 for (int i = 0; i < max && i < v.length; i++) {
187 final int b = 0xff & v[i];
188
189 char c;
190 if (b == 0 || b == 10 || b == 11 || b == 13) {
191 c = ' ';
192 } else {
193 c = (char) b;
194 }
195
196 result.append("\t" + i + ": " + b + " (" + c + ", 0x" + Integer.toHexString(b) + ")" + NEWLINE);
197 }
198 if (v.length > max) {
199 result.append("\t..." + NEWLINE);
200 }
201
202 result.append(NEWLINE);
203 }
204 return result.toString();
205 }
206
207 private static String getDebug(final String message, final char[] v) {
208 final StringBuilder result = new StringBuilder();
209
210 if (v == null) {
211 result.append(message + " (" + null + ")" + NEWLINE);
212 } else {
213 result.append(message + " (" + v.length + ")" + NEWLINE);
214 for (final char element : v) {
215 result.append("\t" + element + " (" + (0xff & element) + ")" + NEWLINE);
216 }
217 result.append(NEWLINE);
218 }
219 return result.toString();
220 }
221
222 private static String getDebug(final String message, final int[] v) {
223 final StringBuilder result = new StringBuilder();
224
225 if (v == null) {
226 result.append(message + " (" + null + ")" + NEWLINE);
227 } else {
228 result.append(message + " (" + v.length + ")" + NEWLINE);
229 for (final int element : v) {
230 result.append("\t" + element + NEWLINE);
231 }
232 result.append(NEWLINE);
233 }
234 return result.toString();
235 }
236
237 private static String getDebug(final String message, final Map<?, ?> map) {
238 final StringBuilder result = new StringBuilder();
239
240 if (map == null) {
241 return message + " map: " + null;
242 }
243
244 final List<Object> keys = new ArrayList<>(map.keySet());
245 result.append(message + " map: " + keys.size() + NEWLINE);
246 for (int i = 0; i < keys.size(); i++) {
247 final Object key = keys.get(i);
248 final Object value = map.get(key);
249 result.append("\t" + i + ": '" + key + "' -> '" + value + "'" + NEWLINE);
250 }
251
252 result.append(NEWLINE);
253
254 return result.toString();
255 }
256
257 private static String getDebug(final Throwable e) {
258 return getDebug(e, -1);
259 }
260
261 private static String getDebug(final Throwable e, final int max) {
262 final StringBuilder result = new StringBuilder(35);
263
264 final SimpleDateFormat timestamp = new SimpleDateFormat("yyyy-MM-dd kk:mm:ss:SSS", Locale.ROOT);
265 final String datetime = timestamp.format(new Date()).toLowerCase();
266
267 result.append(NEWLINE);
268 result.append("Throwable: " + (e == null ? "" : "(" + e.getClass().getName() + ")") + ":" + datetime + NEWLINE);
269 result.append("Throwable: " + (e == null ? "null" : e.getLocalizedMessage()) + NEWLINE);
270 result.append(NEWLINE);
271
272 result.append(getStackTrace(e, max));
273
274 result.append("Caught here:" + NEWLINE);
275 result.append(getStackTrace(new Exception(), max, 1));
276
277 result.append(NEWLINE);
278 return result.toString();
279 }
280
281 private static String getStackTrace(final Throwable e, final int limit) {
282 return getStackTrace(e, limit, 0);
283 }
284
285 private static String getStackTrace(final Throwable e, final int limit, final int skip) {
286 final StringBuilder result = new StringBuilder();
287
288 if (e != null) {
289 final StackTraceElement[] stes = e.getStackTrace();
290 if (stes != null) {
291 for (int i = skip; i < stes.length && (limit < 0 || i < limit); i++) {
292 final StackTraceElement ste = stes[i];
293
294 result.append(
295 "\tat " + ste.getClassName() + "." + ste.getMethodName() + "(" + ste.getFileName() + ":" + ste.getLineNumber() + ")" + NEWLINE);
296 }
297 if (limit >= 0 && stes.length > limit) {
298 result.append("\t..." + NEWLINE);
299 }
300 }
301
302
303 result.append(NEWLINE);
304 }
305
306 return result.toString();
307 }
308
309 private Debug() {
310 }
311 }