1 7 34 35 package com.sun.tools.example.debug.bdi; 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 public class MethodBreakpointSpec extends BreakpointSpec { 45 String methodId; 46 List methodArgs; 47 48 MethodBreakpointSpec(EventRequestSpecList specs, 49 ReferenceTypeSpec refSpec, 50 String methodId, List methodArgs) { 51 super(specs, refSpec); 52 this.methodId = methodId; 53 this.methodArgs = methodArgs; 54 } 55 56 59 void resolve(ReferenceType refType) throws MalformedMemberNameException, 60 AmbiguousMethodException, 61 InvalidTypeException, 62 NoSuchMethodException , 63 NoSessionException { 64 if (!isValidMethodName(methodId)) { 65 throw new MalformedMemberNameException(methodId); 66 } 67 if (!(refType instanceof ClassType)) { 68 throw new InvalidTypeException(); 69 } 70 Location location = location((ClassType)refType); 71 setRequest(refType.virtualMachine().eventRequestManager() 72 .createBreakpointRequest(location)); 73 } 74 75 private Location location(ClassType clazz) throws 76 AmbiguousMethodException, 77 NoSuchMethodException , 78 NoSessionException { 79 Method method = findMatchingMethod(clazz); 80 Location location = method.location(); 81 return location; 82 } 83 84 public String methodName() { 85 return methodId; 86 } 87 88 public List methodArgs() { 89 return methodArgs; 90 } 91 92 public int hashCode() { 93 return refSpec.hashCode() + 94 ((methodId != null) ? methodId.hashCode() : 0) + 95 ((methodArgs != null) ? methodArgs.hashCode() : 0); 96 } 97 98 public boolean equals(Object obj) { 99 if (obj instanceof MethodBreakpointSpec) { 100 MethodBreakpointSpec breakpoint = (MethodBreakpointSpec)obj; 101 102 return methodId.equals(breakpoint.methodId) && 103 methodArgs.equals(breakpoint.methodArgs) && 104 refSpec.equals(breakpoint.refSpec); 105 } else { 106 return false; 107 } 108 } 109 110 public String errorMessageFor(Exception e) { 111 if (e instanceof AmbiguousMethodException) { 112 return ("Method " + methodName() + " is overloaded; specify arguments"); 113 116 } else if (e instanceof NoSuchMethodException ) { 117 return ("No method " + methodName() + " in " + refSpec); 118 } else if (e instanceof InvalidTypeException) { 119 return ("Breakpoints can be located only in classes. " + 120 refSpec + " is an interface or array"); 121 } else { 122 return super.errorMessageFor( e); 123 } 124 } 125 126 public String toString() { 127 StringBuffer buffer = new StringBuffer ("breakpoint "); 128 buffer.append(refSpec.toString()); 129 buffer.append('.'); 130 buffer.append(methodId); 131 if (methodArgs != null) { 132 Iterator iter = methodArgs.iterator(); 133 boolean first = true; 134 buffer.append('('); 135 while (iter.hasNext()) { 136 if (!first) { 137 buffer.append(','); 138 } 139 buffer.append((String )iter.next()); 140 first = false; 141 } 142 buffer.append(")"); 143 } 144 buffer.append(" ("); 145 buffer.append(getStatusString()); 146 buffer.append(')'); 147 return buffer.toString(); 148 } 149 150 private boolean isValidMethodName(String s) { 151 return isJavaIdentifier(s) || 152 s.equals("<init>") || 153 s.equals("<clinit>"); 154 } 155 156 163 private boolean compareArgTypes(Method method, List nameList) { 164 List argTypeNames = method.argumentTypeNames(); 165 166 if (argTypeNames.size() != nameList.size()) { 168 return false; 169 } 170 171 int nTypes = argTypeNames.size(); 173 for (int i = 0; i < nTypes; ++i) { 174 String comp1 = (String )argTypeNames.get(i); 175 String comp2 = (String )nameList.get(i); 176 if (! comp1.equals(comp2)) { 177 184 if (i != nTypes - 1 || 185 !method.isVarArgs() || 186 !comp2.endsWith("...")) { 187 return false; 188 } 189 196 int comp1Length = comp1.length(); 197 if (comp1Length + 1 != comp2.length()) { 198 return false; 200 } 201 if (!comp1.regionMatches(0, comp2, 0, comp1Length - 2)) { 203 return false; 204 } 205 return true; 207 } 208 } 209 210 return true; 211 } 212 213 private VirtualMachine vm() { 214 return request.virtualMachine(); 215 } 216 217 221 private String normalizeArgTypeName(String name) throws NoSessionException { 222 226 int i = 0; 227 StringBuffer typePart = new StringBuffer (); 228 StringBuffer arrayPart = new StringBuffer (); 229 name = name.trim(); 230 int nameLength = name.length(); 231 236 boolean isVarArgs = name.endsWith("..."); 237 if (isVarArgs) { 238 nameLength -= 3; 239 } 240 241 while (i < nameLength) { 242 char c = name.charAt(i); 243 if (Character.isWhitespace(c) || c == '[') { 244 break; } 246 typePart.append(c); 247 i++; 248 } 249 while (i < nameLength) { 250 char c = name.charAt(i); 251 if ( (c == '[') || (c == ']')) { 252 arrayPart.append(c); 253 } else if (!Character.isWhitespace(c)) { 254 throw new IllegalArgumentException ( 255 "Invalid argument type name"); 256 257 } 258 i++; 259 } 260 261 name = typePart.toString(); 262 263 268 if ((name.indexOf('.') == -1) || name.startsWith("*.")) { 269 try { 270 List refs = specs.runtime.findClassesMatchingPattern(name); 271 if (refs.size() > 0) { name = ((ReferenceType)(refs.get(0))).name(); 273 } 274 } catch (IllegalArgumentException e) { 275 } 277 } 278 name += arrayPart.toString(); 279 if (isVarArgs) { 280 name += "..."; 281 } 282 return name; 283 } 284 285 291 private Method findMatchingMethod(ClassType clazz) 292 throws AmbiguousMethodException, 293 NoSuchMethodException , 294 NoSessionException { 295 296 List argTypeNames = null; 298 if (methodArgs() != null) { 299 argTypeNames = new ArrayList (methodArgs().size()); 300 Iterator iter = methodArgs().iterator(); 301 while (iter.hasNext()) { 302 String name = (String )iter.next(); 303 name = normalizeArgTypeName(name); 304 argTypeNames.add(name); 305 } 306 } 307 308 Iterator iter = clazz.methods().iterator(); 310 Method firstMatch = null; Method exactMatch = null; int matchCount = 0; while (iter.hasNext()) { 314 Method candidate = (Method)iter.next(); 315 316 if (candidate.name().equals(methodName())) { 317 matchCount++; 318 319 if (matchCount == 1) { 321 firstMatch = candidate; 322 } 323 324 if ((argTypeNames != null) 326 && compareArgTypes(candidate, argTypeNames) == true) { 327 exactMatch = candidate; 328 break; 329 } 330 } 331 } 332 333 Method method = null; 335 if (exactMatch != null) { 336 method = exactMatch; 338 } else if ((argTypeNames == null) && (matchCount > 0)) { 339 if (matchCount == 1) { 341 method = firstMatch; } else { 343 throw new AmbiguousMethodException(); 344 } 345 } else { 346 throw new NoSuchMethodException (methodName()); 347 } 348 return method; 349 } 350 } 351 | Popular Tags |