1 /* 2 * Copyright (c) 2014, 2015, Dynatrace and/or its affiliates. All rights reserved. 3 * 4 * This file is part of the Lock Contention Tracing Subsystem for the HotSpot 5 * Virtual Machine, which is developed at Christian Doppler Laboratory on 6 * Monitoring and Evolution of Very-Large-Scale Software Systems. Please 7 * contact us at <http://mevss.jku.at/> if you need additional information 8 * or have any questions. 9 * 10 * This code is free software; you can redistribute it and/or modify it 11 * under the terms of the GNU General Public License version 2 only, as 12 * published by the Free Software Foundation. 13 * 14 * This code is distributed in the hope that it will be useful, but WITHOUT 15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 17 * version 2 for more details (a copy is included in the LICENSE file that 18 * accompanied this code). 19 * 20 * You should have received a copy of the GNU General Public License version 21 * 2 along with this work. If not, see <http://www.gnu.org/licenses/>. 22 * 23 */ 24 package sun.evtracing.parser.metadata; 25 26 import java.io.EOFException; 27 import java.io.IOException; 28 import java.io.Reader; 29 import java.io.StringReader; 30 31 public class JvmNamePrettyPrinter { 32 33 public static String prettyClassName(String className, boolean compact) { 34 try { 35 Reader reader = new StringReader(className); 36 StringBuilder sb = new StringBuilder(); 37 int c = peek(reader); 38 if (c == '[') { 39 prettyPrintNextType(reader, sb, compact); 40 } else { 41 int startLength = sb.length(); 42 c = reader.read(); 43 while (c != -1) { 44 if (c == '/') { 45 if (compact) { 46 sb.setLength(startLength); 47 } else { 48 sb.append('.'); 49 } 50 } else { 51 sb.append((char) c); 52 } 53 c = reader.read(); 54 } 55 } 56 return sb.toString(); 57 } catch (Exception ex) { 58 throw new RuntimeException(ex); 59 } 60 } 61 62 public static String prettyMethodName(String className, String methodName, boolean compact) { 63 return prettyClassName(className, compact) + "." + methodName; 64 } 65 66 public static String prettyMethodDescriptor(String className, String methodName, String signature, boolean compact) { 67 return prettyMethodName(className, methodName, compact) + prettyMethodSignature(signature, compact); 68 } 69 70 public static String prettyMethodSignature(String signature, boolean compact) { 71 StringBuilder sb = new StringBuilder(); 72 StringReader reader = new StringReader(signature); 73 try { 74 int c = reader.read(); 75 assert c == '('; 76 sb.append('('); 77 78 c = peek(reader); 79 if (c == -1) 80 throw new EOFException("closing parenthesis"); 81 82 // arguments 83 while (c != ')') { 84 prettyPrintNextType(reader, sb, compact); 85 86 c = peek(reader); 87 if (c == -1) 88 throw new EOFException("closing parenthesis"); 89 90 if (c != ')') 91 sb.append(", "); 92 } 93 94 c = reader.read(); // consume ')' 95 96 sb.append(')'); 97 98 // return type 99 sb.append(" : "); 100 prettyPrintNextType(reader, sb, compact); 101 } catch (Exception e) { 102 throw new RuntimeException("unparsable signature '" + signature + "'", e); 103 } 104 return sb.toString(); 105 } 106 107 private static int peek(Reader reader) throws IOException { 108 int c; 109 reader.mark(1); 110 c = reader.read(); 111 reader.reset(); 112 return c; 113 } 114 115 private static void prettyPrintNextType(Reader reader, StringBuilder sb, boolean compact) throws Exception { 116 int arrayDimensions = 0; 117 boolean atEnd; 118 do { 119 int c = reader.read(); 120 if (c == -1) 121 throw new EOFException(); 122 123 atEnd = true; 124 switch (c) { 125 case '[': 126 arrayDimensions++; 127 atEnd = false; 128 break; 129 case 'B': sb.append("byte"); break; 130 case 'C': sb.append("char"); break; 131 case 'D': sb.append("double"); break; 132 case 'F': sb.append("float"); break; 133 case 'I': sb.append("int"); break; 134 case 'J': sb.append("long"); break; 135 case 'S': sb.append("short"); break; 136 case 'Z': sb.append("boolean"); break; 137 case 'V': sb.append("void"); break; 138 case 'L': 139 int startLength = sb.length(); 140 do { 141 c = reader.read(); 142 if (c == -1) 143 throw new EOFException("in class name"); 144 if (c != ';') { 145 if (c == '/') { 146 if (compact) { 147 sb.setLength(startLength); 148 } else { 149 sb.append('.'); 150 } 151 } else { 152 sb.append((char) c); 153 } 154 } 155 } while (c != ';'); 156 break; 157 default: 158 throw new Exception("invalid type '" + (char) c + "'"); 159 } 160 } while (!atEnd); 161 162 for (int i = 0; i < arrayDimensions; i++) { 163 sb.append("[]"); 164 } 165 } 166 167 }