1 7 34 35 package com.sun.tools.example.debug.tty; 36 37 import com.sun.jdi.*; 38 import com.sun.jdi.request.*; 39 40 import java.util.ArrayList ; 41 import java.util.List ; 42 import java.util.Iterator ; 43 44 class BreakpointSpec extends EventRequestSpec { 45 String methodId; 46 List methodArgs; 47 int lineNumber; 48 49 BreakpointSpec(ReferenceTypeSpec refSpec, int lineNumber) { 50 super(refSpec); 51 this.methodId = null; 52 this.methodArgs = null; 53 this.lineNumber = lineNumber; 54 } 55 56 BreakpointSpec(ReferenceTypeSpec refSpec, String methodId, 57 List methodArgs) throws MalformedMemberNameException { 58 super(refSpec); 59 this.methodId = methodId; 60 this.methodArgs = methodArgs; 61 this.lineNumber = 0; 62 if (!isValidMethodName(methodId)) { 63 throw new MalformedMemberNameException(methodId); 64 } 65 } 66 67 70 EventRequest resolveEventRequest(ReferenceType refType) 71 throws AmbiguousMethodException, 72 AbsentInformationException, 73 InvalidTypeException, 74 NoSuchMethodException , 75 LineNotFoundException { 76 Location location = location(refType); 77 if (location == null) { 78 throw new InvalidTypeException(); 79 } 80 EventRequestManager em = refType.virtualMachine().eventRequestManager(); 81 EventRequest bp = em.createBreakpointRequest(location); 82 bp.setSuspendPolicy(suspendPolicy); 83 bp.enable(); 84 return bp; 85 } 86 87 String methodName() { 88 return methodId; 89 } 90 91 int lineNumber() { 92 return lineNumber; 93 } 94 95 List methodArgs() { 96 return methodArgs; 97 } 98 99 boolean isMethodBreakpoint() { 100 return (methodId != null); 101 } 102 103 public int hashCode() { 104 return refSpec.hashCode() + lineNumber + 105 ((methodId != null) ? methodId.hashCode() : 0) + 106 ((methodArgs != null) ? methodArgs.hashCode() : 0); 107 } 108 109 public boolean equals(Object obj) { 110 if (obj instanceof BreakpointSpec) { 111 BreakpointSpec breakpoint = (BreakpointSpec)obj; 112 113 return ((methodId != null) ? 114 methodId.equals(breakpoint.methodId) 115 : methodId == breakpoint.methodId) && 116 ((methodArgs != null) ? 117 methodArgs.equals(breakpoint.methodArgs) 118 : methodArgs == breakpoint.methodArgs) && 119 refSpec.equals(breakpoint.refSpec) && 120 (lineNumber == breakpoint.lineNumber); 121 } else { 122 return false; 123 } 124 } 125 126 String errorMessageFor(Exception e) { 127 if (e instanceof AmbiguousMethodException) { 128 return (MessageOutput.format("Method is overloaded; specify arguments", 129 methodName())); 130 133 } else if (e instanceof NoSuchMethodException ) { 134 return (MessageOutput.format("No method in", 135 new Object [] {methodName(), 136 refSpec.toString()})); 137 } else if (e instanceof AbsentInformationException) { 138 return (MessageOutput.format("No linenumber information for", 139 refSpec.toString())); 140 } else if (e instanceof LineNotFoundException) { 141 return (MessageOutput.format("No code at line", 142 new Object [] {new Long (lineNumber()), 143 refSpec.toString()})); 144 } else if (e instanceof InvalidTypeException) { 145 return (MessageOutput.format("Breakpoints can be located only in classes.", 146 refSpec.toString())); 147 } else { 148 return super.errorMessageFor( e); 149 } 150 } 151 152 public String toString() { 153 StringBuffer buffer = new StringBuffer (refSpec.toString()); 154 if (isMethodBreakpoint()) { 155 buffer.append('.'); 156 buffer.append(methodId); 157 if (methodArgs != null) { 158 Iterator iter = methodArgs.iterator(); 159 boolean first = true; 160 buffer.append('('); 161 while (iter.hasNext()) { 162 if (!first) { 163 buffer.append(','); 164 } 165 buffer.append((String )iter.next()); 166 first = false; 167 } 168 buffer.append(")"); 169 } 170 } else { 171 buffer.append(':'); 172 buffer.append(lineNumber); 173 } 174 return MessageOutput.format("breakpoint", buffer.toString()); 175 } 176 177 private Location location(ReferenceType refType) throws 178 AmbiguousMethodException, 179 AbsentInformationException, 180 NoSuchMethodException , 181 LineNotFoundException { 182 Location location = null; 183 if (isMethodBreakpoint()) { 184 Method method = findMatchingMethod(refType); 185 location = method.location(); 186 } else { 187 List locs = refType.locationsOfLine(lineNumber()); 189 if (locs.size() == 0) { 190 throw new LineNotFoundException(); 191 } 192 location = (Location)locs.get(0); 194 if (location.method() == null) { 195 throw new LineNotFoundException(); 196 } 197 } 198 return location; 199 } 200 201 private boolean isValidMethodName(String s) { 202 return isJavaIdentifier(s) || 203 s.equals("<init>") || 204 s.equals("<clinit>"); 205 } 206 207 214 private boolean compareArgTypes(Method method, List nameList) { 215 List argTypeNames = method.argumentTypeNames(); 216 217 if (argTypeNames.size() != nameList.size()) { 219 return false; 220 } 221 222 int nTypes = argTypeNames.size(); 224 for (int i = 0; i < nTypes; ++i) { 225 String comp1 = (String )argTypeNames.get(i); 226 String comp2 = (String )nameList.get(i); 227 if (! comp1.equals(comp2)) { 228 235 if (i != nTypes - 1 || 236 !method.isVarArgs() || 237 !comp2.endsWith("...")) { 238 return false; 239 } 240 247 int comp1Length = comp1.length(); 248 if (comp1Length + 1 != comp2.length()) { 249 return false; 251 } 252 if (!comp1.regionMatches(0, comp2, 0, comp1Length - 2)) { 254 return false; 255 } 256 return true; 258 } 259 } 260 261 return true; 262 } 263 264 265 269 private String normalizeArgTypeName(String name) { 270 274 int i = 0; 275 StringBuffer typePart = new StringBuffer (); 276 StringBuffer arrayPart = new StringBuffer (); 277 name = name.trim(); 278 int nameLength = name.length(); 279 284 boolean isVarArgs = name.endsWith("..."); 285 if (isVarArgs) { 286 nameLength -= 3; 287 } 288 while (i < nameLength) { 289 char c = name.charAt(i); 290 if (Character.isWhitespace(c) || c == '[') { 291 break; } 293 typePart.append(c); 294 i++; 295 } 296 while (i < nameLength) { 297 char c = name.charAt(i); 298 if ( (c == '[') || (c == ']')) { 299 arrayPart.append(c); 300 } else if (!Character.isWhitespace(c)) { 301 throw new IllegalArgumentException 302 (MessageOutput.format("Invalid argument type name")); 303 } 304 i++; 305 } 306 name = typePart.toString(); 307 308 312 if ((name.indexOf('.') == -1) || name.startsWith("*.")) { 313 try { 314 ReferenceType argClass = Env.getReferenceTypeFromToken(name); 315 if (argClass != null) { 316 name = argClass.name(); 317 } 318 } catch (IllegalArgumentException e) { 319 } 321 } 322 name += arrayPart.toString(); 323 if (isVarArgs) { 324 name += "..."; 325 } 326 return name; 327 } 328 329 335 private Method findMatchingMethod(ReferenceType refType) 336 throws AmbiguousMethodException, 337 NoSuchMethodException { 338 339 List argTypeNames = null; 341 if (methodArgs() != null) { 342 argTypeNames = new ArrayList (methodArgs().size()); 343 Iterator iter = methodArgs().iterator(); 344 while (iter.hasNext()) { 345 String name = (String )iter.next(); 346 name = normalizeArgTypeName(name); 347 argTypeNames.add(name); 348 } 349 } 350 351 Iterator iter = refType.methods().iterator(); 353 Method firstMatch = null; Method exactMatch = null; int matchCount = 0; while (iter.hasNext()) { 357 Method candidate = (Method)iter.next(); 358 359 if (candidate.name().equals(methodName())) { 360 matchCount++; 361 362 if (matchCount == 1) { 364 firstMatch = candidate; 365 } 366 367 if ((argTypeNames != null) 369 && compareArgTypes(candidate, argTypeNames) == true) { 370 exactMatch = candidate; 371 break; 372 } 373 } 374 } 375 376 Method method = null; 378 if (exactMatch != null) { 379 method = exactMatch; 381 } else if ((argTypeNames == null) && (matchCount > 0)) { 382 if (matchCount == 1) { 384 method = firstMatch; } else { 386 throw new AmbiguousMethodException(); 387 } 388 } else { 389 throw new NoSuchMethodException (methodName()); 390 } 391 return method; 392 } 393 } 394 | Popular Tags |