01: /*
02: * Bytecode Analysis Framework
03: * Copyright (C) 2003,2004 University of Maryland
04: *
05: * This library is free software; you can redistribute it and/or
06: * modify it under the terms of the GNU Lesser General Public
07: * License as published by the Free Software Foundation; either
08: * version 2.1 of the License, or (at your option) any later version.
09: *
10: * This library is distributed in the hope that it will be useful,
11: * but WITHOUT ANY WARRANTY; without even the implied warranty of
12: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13: * Lesser General Public License for more details.
14: *
15: * You should have received a copy of the GNU Lesser General Public
16: * License along with this library; if not, write to the Free Software
17: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18: */
19:
20: package edu.umd.cs.findbugs.ba;
21:
22: import java.util.ArrayList;
23: import java.util.regex.Matcher;
24: import java.util.regex.Pattern;
25:
26: import edu.umd.cs.findbugs.classfile.ClassDescriptor;
27: import edu.umd.cs.findbugs.classfile.DescriptorFactory;
28: import edu.umd.cs.findbugs.classfile.ResourceNotFoundException;
29:
30: /**
31: * Parse the detail message in a ClassNotFoundException
32: * to extract the name of the missing class.
33: * Unfortunately, this information is not directly available
34: * from the exception object. So, this class parses the
35: * detail message in several common formats (such as the
36: * format used by BCEL).
37: *
38: * @author David Hovemeyer
39: */
40: public class ClassNotFoundExceptionParser {
41: // BCEL reports missing classes in this format
42: private static final Pattern BCEL_MISSING_CLASS_PATTERN = Pattern
43: .compile("^.*while looking for class ([^:]*):.*$");
44:
45: // edu.umd.cs.findbugs.ba.type.TypeRepository
46: // and edu.umd.cs.findbugs.ba.ch.Subtypes2 uses this format
47: private static final Pattern TYPE_REPOSITORY_MISSING_CLASS_PATTERN = Pattern
48: .compile("^Class ([^ ]*) cannot be resolved.*$");
49:
50: private static final Pattern[] patternList;
51:
52: static {
53: ArrayList<Pattern> list = new ArrayList<Pattern>();
54: list.add(BCEL_MISSING_CLASS_PATTERN);
55: list.add(TYPE_REPOSITORY_MISSING_CLASS_PATTERN);
56:
57: patternList = list.toArray(new Pattern[list.size()]);
58: }
59:
60: /**
61: * Get the name of the missing class from a ClassNotFoundException.
62: *
63: * @param ex the ClassNotFoundException
64: * @return the name of the missing class, or null if we
65: * couldn't figure out the class name
66: */
67: public static String getMissingClassName(ClassNotFoundException ex) {
68: // If the exception has a ResourceNotFoundException as the cause,
69: // then we have an easy answer.
70: Throwable cause = ex.getCause();
71: if (cause instanceof ResourceNotFoundException) {
72: String resourceName = ((ResourceNotFoundException) cause)
73: .getResourceName();
74: if (resourceName != null) {
75: ClassDescriptor classDesc = DescriptorFactory
76: .createClassDescriptorFromResourceName(resourceName);
77: return classDesc.toDottedClassName();
78: }
79: }
80:
81: if (ex.getMessage() == null) {
82: return null;
83: }
84:
85: // Try the regular expression patterns to parse the class name
86: // from the exception message.
87: for (Pattern pattern : patternList) {
88: Matcher matcher = pattern.matcher(ex.getMessage());
89: if (matcher.matches())
90: return matcher.group(1);
91: }
92: return null;
93: }
94:
95: }
96:
97: // vim:ts=4
|