Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * fb-contrib - Auxiliary detectors for Java programs
   * Copyright (C) 2005-2013 Dave Brosius
   * 
   * 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 com.mebigfatguy.fbcontrib.detect;
 
 import  org.apache.bcel.Repository;
 import  org.apache.bcel.classfile.Code;
 import  org.apache.bcel.classfile.JavaClass;
 
 import  edu.umd.cs.findbugs.BugInstance;
 import  edu.umd.cs.findbugs.BugReporter;
 import  edu.umd.cs.findbugs.BytecodeScanningDetector;
 import  edu.umd.cs.findbugs.OpcodeStack;
 import  edu.umd.cs.findbugs.ba.ClassContext;

looks for uses of sets or keySets of maps that contain other collections. As collection typically implement hashCode, equals and compareTo by iterating the contents of the collection this can be costly from a performance point of view.
 
 public class DubiousSetOfCollections extends BytecodeScanningDetector {
 
 	private static JavaClass collectionCls;
 	private static JavaClass setCls;
 	private static JavaClass mapCls;
 	static {
 		try {
 			 = Repository.lookupClass("java/util/Collection");
 			 = Repository.lookupClass("java/util/Set");
 			 = Repository.lookupClass("java/util/Map");
 		} catch (ClassNotFoundException cnfe) {
 		}
 	}
 
 	private final BugReporter bugReporter;
 	private OpcodeStack stack;

constructs a DSOC detector given the reporter to report bugs on

Parameters:
bugReporter the sync of bug reports
 
 	public DubiousSetOfCollections(final BugReporter bugReporter) {
 		this. = bugReporter;
 	}

implement the visitor to set up the opcode stack, and make sure that collection, set and map classes could be loaded.

Parameters:
clsContext the context object of the currently parsed class
 
 	public void visitClassContext(ClassContext clsContext) {
 		try {
 			if (( == null) || ( == null) || ( == null))
 				return;
 			
 			 = new OpcodeStack();
 			super.visitClassContext(clsContext);
 		} finally {
 			 = null;
 		}
 	}

implements the visitor to reset the opcode stack

Parameters:
code the context object of the currently parsed code block
 
 	public void visitCode(Code code) {
 		.resetForMethodEntry(this);
 		super.visitCode(code);
 	}
implements the visitor look for adds to sets or puts to maps where the element to be added is a collection.

Parameters:
seen the opcode of the currently parsed instruction
 
 	public void sawOpcode(int seen) {
 		try {
 	        .precomputation(this);
	        
			if ((seen == INVOKEVIRTUAL) || (seen == INVOKEINTERFACE)) {
				String methodName = getNameConstantOperand();
				String signature = getSigConstantOperand();
				if ("add".equals(methodName)
				&&  "(Ljava/lang/Object;)Z".equals(signature)
				&&  isImplementationOf(clsName)) {
					if (.getStackDepth() > 1) {
						OpcodeStack.Item item = .getStackItem(0);
						JavaClass entryCls = item.getJavaClass();
						if (isImplementationOf(entryCls)) {
							.reportBug(new BugInstance(this"DSOC_DUBIOUS_SET_OF_COLLECTIONS", NORMAL_PRIORITY)
										.addClass(this)
										.addMethod(this)
										.addSourceLine(this));
						}
					}
else if ("put".equals(methodName)
					   &&  "(Ljava/lang/Object;LJava/lang/Object;)Ljava/lang/Object;".equals(signature)
					   &&  isImplementationOf(clsName)) {
					if (.getStackDepth() > 2) {
						OpcodeStack.Item item = .getStackItem(1);
						JavaClass entryCls = item.getJavaClass();
						if (isImplementationOf(entryCls)) {
							.reportBug(new BugInstance(this"DSOC_DUBIOUS_SET_OF_COLLECTIONS", NORMAL_PRIORITY)
										.addClass(this)
										.addMethod(this)
										.addSourceLine(this));
						}
					}				}
			}
catch (ClassNotFoundException cnfe) {
			.reportMissingClass(cnfe);
finally {
			.sawOpcode(thisseen);
		}
	}

returns whether the class implements the interface

Parameters:
clsName the name of the class
inf the interface to check
Returns:
if the class implements the interface
	private boolean isImplementationOf(String clsName, JavaClass inf) {
		try {
			if (clsName.startsWith("java/lang/"))
				return false;
			JavaClass cls = Repository.lookupClass(clsName);
			return isImplementationOf(clsinf);
catch (ClassNotFoundException cnfe) {
			.reportMissingClass(cnfe);
		}
		return false;
	}

returns whether the class implements the interface

Parameters:
cls the class
inf the interface to check
Returns:
if the class implements the interface
	private boolean isImplementationOf(JavaClass cls, JavaClass inf) {
		try {
			if (cls == null) {
				return false;
			}
			if (cls.implementationOf(inf)) {
				return true;
			}
catch (ClassNotFoundException cnfe) {
			.reportMissingClass(cnfe);
		}
		return false;
	}
New to GrepCode? Check out our FAQ X