private List<String> findFullyQualifiedSourceFileNames( IClassPathBuilder builder, IClassPath classPath) { List<ClassDescriptor> appClassList = builder.getAppClassList(); progress.startScanningClasses(appClassList.size()); List<String> fullyQualifiedSourceFileNameList = new LinkedList<String>(); for (ClassDescriptor classDesc : appClassList) { try { String fullyQualifiedSourceFileName = findFullyQualifiedSourceFileName(classPath, classDesc); fullyQualifiedSourceFileNameList.add(fullyQualifiedSourceFileName); } catch (IOException e) { errorLogger.logError("Couldn't scan class " + classDesc.toDottedClassName(), e); } catch (CheckedAnalysisException e) { errorLogger.logError("Couldn't scan class " + classDesc.toDottedClassName(), e); } } progress.doneScanningClasses(); return fullyQualifiedSourceFileNameList; }
private String findFullyQualifiedSourceFileName(IClassPath classPath, ClassDescriptor classDesc) throws IOException, CheckedAnalysisException { try { // Open and parse the class file to attempt // to discover the source file name. ICodeBaseEntry codeBaseEntry = classPath.lookupResource(classDesc.toResourceName()); ClassParserUsingASM classParser = new ClassParserUsingASM( new ClassReader(codeBaseEntry.openResource()), classDesc, codeBaseEntry); ClassInfo.Builder classInfoBuilder = new ClassInfo.Builder(); classParser.parse(classInfoBuilder); ClassInfo classInfo = classInfoBuilder.build(); // Construct the fully-qualified source file name // based on the package name and source file name. String packageName = classDesc.getPackageName(); String sourceFile = classInfo.getSource(); if (!packageName.equals("")) { packageName = packageName.replace('.', '/'); packageName += "/"; } String fullyQualifiedSourceFile = packageName + sourceFile; return fullyQualifiedSourceFile; } catch (CheckedAnalysisException e) { errorLogger.logError("Could scan class " + classDesc.toDottedClassName(), e); throw e; } finally { progress.finishClass(); } }
/* (non-Javadoc) * @see edu.umd.cs.findbugs.classfile.IErrorLogger#reportMissingClass(edu.umd.cs.findbugs.classfile.ClassDescriptor) */ public void reportMissingClass(ClassDescriptor classDescriptor) { if (DEBUG_MISSING_CLASSES) { System.out.println("Missing class: " + classDescriptor); new Throwable().printStackTrace(System.out); } if (verbosityLevel == SILENT) { return; } logMissingClass(classDescriptor.toDottedClassName()); }
/** * Lookup a class. <em>Use this method instead of Repository.lookupClass().</em> * * @param classDescriptor descriptor specifying the class to look up * @return the class * @throws ClassNotFoundException if the class can't be found */ public JavaClass lookupClass(@Nonnull ClassDescriptor classDescriptor) throws ClassNotFoundException { return lookupClass(classDescriptor.toDottedClassName()); }
private TypeQualifierValue(ClassDescriptor typeQualifier, @CheckForNull Object value) { this.typeQualifier = typeQualifier; this.value = value; boolean isStrict = false; // will be set to true if this is a strict // type qualifier value boolean isExclusive = false; // will be set to true if this is an // exclusive type qualifier value boolean isExhaustive = false; // will be set to true if this is an // exhaustive type qualifier value TypeQualifierValidator<A> validator = null; Class<A> qualifierClass = null; A proxy = null; try { XClass xclass = Global.getAnalysisCache().getClassAnalysis(XClass.class, typeQualifier); // Annotation elements appear as abstract methods in the annotation // class (interface). // So, if the type qualifier annotation has specified a default When // value, // it will appear as an abstract method called "when". XMethod whenMethod = xclass.findMethod("when", "()Ljavax/annotation/meta/When;", false); if (whenMethod == null) { isStrict = true; } for (XMethod xmethod : xclass.getXMethods()) { if (xmethod.getName().equals("value") && xmethod.getSignature().startsWith("()")) { isExhaustive = xmethod.getAnnotation(EXHAUSTIVE_ANNOTATION) != null; if (isExhaustive) { // exhaustive qualifiers are automatically exclusive isExclusive = true; } else { // see if there is an explicit @Exclusive annotation isExclusive = xmethod.getAnnotation(EXCLUSIVE_ANNOTATION) != null; } break; } } } catch (MissingClassException e) { AnalysisContext.currentAnalysisContext() .getLookupFailureCallback() .reportMissingClass(e.getClassNotFoundException()); } catch (CheckedAnalysisException e) { AnalysisContext.logError( "Error looking up annotation class " + typeQualifier.toDottedClassName(), e); } this.isStrict = isStrict; this.isExclusive = isExclusive; this.isExhaustive = isExhaustive; ClassDescriptor checkerName = DescriptorFactory.createClassDescriptor(typeQualifier.getClassName() + "$Checker"); try { Global.getAnalysisCache().getClassAnalysis(ClassData.class, checkerName); // found it. // System.out.println(checkerName); SecurityManager m = System.getSecurityManager(); if (m == null) System.setSecurityManager(new ValidationSecurityManager()); Class<?> c = validatorLoader.loadClass(checkerName.getDottedClassName()); if (TypeQualifierValidator.class.isAssignableFrom(c)) { Class<? extends TypeQualifierValidator> checkerClass = c.asSubclass(TypeQualifierValidator.class); validator = getValidator(checkerClass); qualifierClass = getQualifierClass(typeQualifier); InvocationHandler handler = new InvocationHandler() { public Object invoke(Object arg0, Method arg1, Object[] arg2) throws Throwable { if (arg1.getName() == "value") return TypeQualifierValue.this.value; throw new UnsupportedOperationException("Can't handle " + arg1); } }; proxy = qualifierClass.cast( Proxy.newProxyInstance(validatorLoader, new Class[] {qualifierClass}, handler)); } } catch (ClassNotFoundException e) { assert true; // ignore } catch (CheckedAnalysisException e) { assert true; // ignore } catch (Exception e) { AnalysisContext.logError("Unable to construct type qualifier checker " + checkerName, e); } catch (Throwable e) { AnalysisContext.logError( "Unable to construct type qualifier checker " + checkerName + " due to " + e.getClass().getSimpleName() + ":" + e.getMessage()); } this.validator = validator; this.typeQualifierClass = qualifierClass; this.proxy = proxy; }