1 /* |
1 /* |
2 * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. Oracle designates this |
7 * published by the Free Software Foundation. Oracle designates this |
143 StringBuilder result = new StringBuilder(128); |
143 StringBuilder result = new StringBuilder(128); |
144 result.append('@'); |
144 result.append('@'); |
145 result.append(type.getName()); |
145 result.append(type.getName()); |
146 result.append('('); |
146 result.append('('); |
147 boolean firstMember = true; |
147 boolean firstMember = true; |
148 for (Map.Entry<String, Object> e : memberValues.entrySet()) { |
148 Set<Map.Entry<String, Object>> entries = memberValues.entrySet(); |
|
149 boolean loneValue = entries.size() == 1; |
|
150 for (Map.Entry<String, Object> e : entries) { |
149 if (firstMember) |
151 if (firstMember) |
150 firstMember = false; |
152 firstMember = false; |
151 else |
153 else |
152 result.append(", "); |
154 result.append(", "); |
153 |
155 |
154 result.append(e.getKey()); |
156 String key = e.getKey(); |
155 result.append('='); |
157 if (!loneValue || !"value".equals(key)) { |
|
158 result.append(key); |
|
159 result.append('='); |
|
160 } |
|
161 loneValue = false; |
156 result.append(memberValueToString(e.getValue())); |
162 result.append(memberValueToString(e.getValue())); |
157 } |
163 } |
158 result.append(')'); |
164 result.append(')'); |
159 return result.toString(); |
165 return result.toString(); |
160 } |
166 } |
176 return toSourceString((double) value); |
182 return toSourceString((double) value); |
177 else if (type == Float.class) |
183 else if (type == Float.class) |
178 return toSourceString((float) value); |
184 return toSourceString((float) value); |
179 else if (type == Long.class) |
185 else if (type == Long.class) |
180 return toSourceString((long) value); |
186 return toSourceString((long) value); |
|
187 else if (type == Byte.class) |
|
188 return toSourceString((byte) value); |
181 else |
189 else |
182 return value.toString(); |
190 return value.toString(); |
183 } else { |
191 } else { |
184 Stream<String> stringStream; |
192 Stream<String> stringStream; |
185 if (type == byte[].class) |
193 if (type == byte[].class) |
219 * Translates a Class value to a form suitable for use in the |
227 * Translates a Class value to a form suitable for use in the |
220 * string representation of an annotation. |
228 * string representation of an annotation. |
221 */ |
229 */ |
222 private static String toSourceString(Class<?> clazz) { |
230 private static String toSourceString(Class<?> clazz) { |
223 Class<?> finalComponent = clazz; |
231 Class<?> finalComponent = clazz; |
224 StringBuilder arrayBackets = new StringBuilder(); |
232 StringBuilder arrayBrackets = new StringBuilder(); |
225 |
233 |
226 while(finalComponent.isArray()) { |
234 while(finalComponent.isArray()) { |
227 finalComponent = finalComponent.getComponentType(); |
235 finalComponent = finalComponent.getComponentType(); |
228 arrayBackets.append("[]"); |
236 arrayBrackets.append("[]"); |
229 } |
237 } |
230 |
238 |
231 return finalComponent.getName() + arrayBackets.toString() + ".class" ; |
239 return finalComponent.getName() + arrayBrackets.toString() + ".class"; |
232 } |
240 } |
233 |
241 |
234 private static String toSourceString(float f) { |
242 private static String toSourceString(float f) { |
235 if (Float.isFinite(f)) |
243 if (Float.isFinite(f)) |
236 return Float.toString(f) + "f" ; |
244 return Float.toString(f) + "f" ; |
254 } |
262 } |
255 |
263 |
256 private static String toSourceString(char c) { |
264 private static String toSourceString(char c) { |
257 StringBuilder sb = new StringBuilder(4); |
265 StringBuilder sb = new StringBuilder(4); |
258 sb.append('\''); |
266 sb.append('\''); |
259 if (c == '\'') |
267 sb.append(quote(c)); |
260 sb.append("\\'"); |
268 return sb.append('\'') .toString(); |
261 else |
269 } |
262 sb.append(c); |
270 |
263 return sb.append('\'') |
271 /** |
264 .toString(); |
272 * Escapes a character if it has an escape sequence or is |
|
273 * non-printable ASCII. Leaves non-ASCII characters alone. |
|
274 */ |
|
275 private static String quote(char ch) { |
|
276 switch (ch) { |
|
277 case '\b': return "\\b"; |
|
278 case '\f': return "\\f"; |
|
279 case '\n': return "\\n"; |
|
280 case '\r': return "\\r"; |
|
281 case '\t': return "\\t"; |
|
282 case '\'': return "\\'"; |
|
283 case '\"': return "\\\""; |
|
284 case '\\': return "\\\\"; |
|
285 default: |
|
286 return (isPrintableAscii(ch)) |
|
287 ? String.valueOf(ch) |
|
288 : String.format("\\u%04x", (int) ch); |
|
289 } |
|
290 } |
|
291 |
|
292 /** |
|
293 * Is a character printable ASCII? |
|
294 */ |
|
295 private static boolean isPrintableAscii(char ch) { |
|
296 return ch >= ' ' && ch <= '~'; |
|
297 } |
|
298 |
|
299 private static String toSourceString(byte b) { |
|
300 return String.format("(byte)0x%02x", b); |
265 } |
301 } |
266 |
302 |
267 private static String toSourceString(long ell) { |
303 private static String toSourceString(long ell) { |
268 String str = String.valueOf(ell); |
304 return String.valueOf(ell) + "L"; |
269 return (ell < Integer.MIN_VALUE || ell > Integer.MAX_VALUE) |
|
270 ? (str + 'L') : str; |
|
271 } |
305 } |
272 |
306 |
273 /** |
307 /** |
274 * Return a string suitable for use in the string representation |
308 * Return a string suitable for use in the string representation |
275 * of an annotation. |
309 * of an annotation. |
276 */ |
310 */ |
277 private static String toSourceString(String s) { |
311 private static String toSourceString(String s) { |
278 StringBuilder sb = new StringBuilder(); |
312 StringBuilder sb = new StringBuilder(); |
279 sb.append('"'); |
313 sb.append('"'); |
280 // Escape embedded quote characters, if present, but don't do |
314 for (int i = 0; i < s.length(); i++) { |
281 // anything more heroic. |
315 sb.append(quote(s.charAt(i))); |
282 sb.append(s.replace("\"", "\\\"")); |
316 } |
283 sb.append('"'); |
317 sb.append('"'); |
284 return sb.toString(); |
318 return sb.toString(); |
285 } |
319 } |
286 |
320 |
287 private static Stream<String> convert(byte[] values) { |
321 private static Stream<String> convert(byte[] values) { |
288 List<String> list = new ArrayList<>(values.length); |
322 List<String> list = new ArrayList<>(values.length); |
289 for (byte b : values) |
323 for (byte b : values) |
290 list.add(Byte.toString(b)); |
324 list.add(toSourceString(b)); |
291 return list.stream(); |
325 return list.stream(); |
292 } |
326 } |
293 |
327 |
294 private static Stream<String> convert(char[] values) { |
328 private static Stream<String> convert(char[] values) { |
295 List<String> list = new ArrayList<>(values.length); |
329 List<String> list = new ArrayList<>(values.length); |