/*
 * FindBugs - Find bugs in Java programs
 * Copyright (C) 2003, University of Maryland
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package edu.umd.cs.findbugs;

import java.util.*;
import org.apache.bcel.Constants;
import org.apache.bcel.Repository;
import org.apache.bcel.classfile.*;
import org.apache.bcel.generic.*;
import edu.umd.cs.daveho.ba.*;
import edu.umd.cs.findbugs.*;

public abstract class ResourceTrackingDetector<Resource> implements Detector {

	public abstract boolean prescreen(ClassContext classContext, Method method);
	public abstract ResourceTracker<Resource> getResourceTracker();
	public abstract void inspectResult(JavaClass javaClass, MethodGen methodGen, CFG cfg,
		Dataflow<ResourceValueFrame> dataflow, Resource resource);

	public void visitClassContext(ClassContext classContext) {
		final ResourceTracker<Resource> resourceTracker = getResourceTracker();

		try {
			final JavaClass jclass = classContext.getJavaClass();
			Method[] methodList = jclass.getMethods();
			for (int i = 0; i < methodList.length; ++i) {
				Method method = methodList[i];
				if (method.isAbstract() || method.isNative())
					continue;

				if (!prescreen(classContext, method))
					continue;

				final MethodGen methodGen = classContext.getMethodGen(method);
				if (methodGen == null)
					continue;
				final CFG cfg = classContext.getCFG(method);

				new LocationScanner(cfg).scan(new LocationScanner.Callback() {
					public void visitLocation(Location location) {
						BasicBlock basicBlock = location.getBasicBlock();
						InstructionHandle handle = location.getHandle();

						Resource resource = resourceTracker.isResourceCreation(basicBlock, handle, methodGen.getConstantPool());
						if (resource != null) {
							ResourceValueAnalysis<Resource> analysis =
								new ResourceValueAnalysis<Resource>(methodGen, resourceTracker, resource);
							Dataflow<ResourceValueFrame> dataflow = new Dataflow<ResourceValueFrame>(cfg, analysis);

							try {
								dataflow.execute();
								inspectResult(jclass, methodGen, cfg, dataflow, resource);
							} catch (DataflowAnalysisException e) {
								throw new AnalysisException("FindOpenResource caught exception: " + e.toString(), e);
							}
						}
					}
				});
			}
		} catch (CFGBuilderException e) {
			throw new AnalysisException(e.getMessage());
		}

	}

	public void report() {
	}

}

// vim:ts=4

@@ -1301,17 +1301,113 @@
 Tracker(
-)
+ClassContext classContext, Method method)%0A%09%09throws DataflowAnalysisException, CFGBuilderException
 ;%0A%09publi
@@ -1612,82 +1612,8 @@
 t) %7B
-%0A%09%09final ResourceTracker%3CResource%3E resourceTracker = getResourceTracker();
 %0A%0A%09%09
@@ -1913,16 +1913,16 @@
 ethod))%0A
-
 %09%09%09%09%09con
@@ -1925,24 +1925,121 @@
 %09continue;%0A%0A
+%09%09%09%09final ResourceTracker%3CResource%3E resourceTracker = getResourceTracker(classContext, method);%0A%0A
 %09%09%09%09final Me
@@ -3146,20 +3146,112 @@
 n(e.
-getMessage()
+toString(), e);%0A%09%09%7D catch (DataflowAnalysisException e) %7B%0A%09%09%09throw new AnalysisException(e.toString(), e
 );%0A%09

Allow getResourceTracker() to throw CFGBuilderException and DataflowAnalysisException.