Resolves an unqualified class name to a Class object by searching the registered class imports and package imports. The name must not contain a dot. Results are cached for performance. If the name is ambiguous across multiple packages, an ELException is thrown. @param name the unqua
(String name)
| 424 | * @throws ELException if the class name is ambiguous across imported packages |
| 425 | */ |
| 426 | public Class<?> resolveClass(String name) { |
| 427 | if (name == null || name.contains(".")) { |
| 428 | return null; |
| 429 | } |
| 430 | |
| 431 | // Has it been previously resolved? |
| 432 | Class<?> result = clazzes.get(name); |
| 433 | |
| 434 | if (result != null) { |
| 435 | if (NotFound.class.equals(result)) { |
| 436 | return null; |
| 437 | } else { |
| 438 | return result; |
| 439 | } |
| 440 | } |
| 441 | |
| 442 | // Search the class imports |
| 443 | String className = classNames.get(name); |
| 444 | if (className != null) { |
| 445 | Class<?> clazz = findClass(className, true); |
| 446 | if (clazz != null) { |
| 447 | clazzes.put(name, clazz); |
| 448 | return clazz; |
| 449 | } |
| 450 | // Might be an inner class |
| 451 | StringBuilder sb = new StringBuilder(className); |
| 452 | int replacementPosition = sb.lastIndexOf("."); |
| 453 | while (replacementPosition > -1) { |
| 454 | sb.setCharAt(replacementPosition, '$'); |
| 455 | clazz = findClass(sb.toString(), true); |
| 456 | if (clazz != null) { |
| 457 | clazzes.put(name, clazz); |
| 458 | return clazz; |
| 459 | } |
| 460 | replacementPosition = sb.lastIndexOf(".", replacementPosition); |
| 461 | } |
| 462 | } |
| 463 | |
| 464 | // Search the package imports - note there may be multiple matches |
| 465 | // (which correctly triggers an error) |
| 466 | for (Map.Entry<String,Set<String>> entry : packageNames.entrySet()) { |
| 467 | if (!entry.getValue().isEmpty()) { |
| 468 | // Standard package where we know all the class names |
| 469 | if (!entry.getValue().contains(name)) { |
| 470 | // Requested name isn't in the list so it isn't in this |
| 471 | // package so move on to next package. This allows the |
| 472 | // class loader look-up to be skipped. |
| 473 | continue; |
| 474 | } |
| 475 | } |
| 476 | className = entry.getKey() + '.' + name; |
| 477 | Class<?> clazz = findClass(className, false); |
| 478 | if (clazz != null) { |
| 479 | if (result != null) { |
| 480 | throw new ELException( |
| 481 | Util.message(null, "importHandler.ambiguousImport", className, result.getName())); |
| 482 | } |
| 483 | result = clazz; |