Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * fb-contrib - Auxiliary detectors for Java programs
   * Copyright (C) 2005-2014 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 java.util.Map;
 import java.util.Set;
 
 import  org.apache.bcel.classfile.Code;
 import  org.apache.bcel.classfile.JavaClass;
 import  org.apache.bcel.classfile.Method;
 
looks for methods that implement awt or swing listeners and perform time consuming operations. Doing these operations in the gui thread will cause the interface to appear sluggish and non-responsive to the user. It is better to use a separate thread to do the time consuming work so that the user has a better experience.
 
 public class SluggishGui extends BytecodeScanningDetector
 {
 	
 	private static final Set<StringexpensiveCalls = new HashSet<String>();
 	static {
 		.add("java/io/BufferedOutputStream:<init>");
 		.add("java/io/DataOutputStream:<init>");
 		.add("java/io/FileOutputStream:<init>");
 		.add("java/io/ObjectOutputStream:<init>");
 		.add("java/io/PipedOutputStream:<init>");
 		.add("java/io/BufferedInputStream:<init>");
 		.add("java/io/DataInputStream:<init>");
 		.add("java/io/FileInputStream:<init>");
 		.add("java/io/ObjectInputStream:<init>");
 		.add("java/io/PipedInputStream:<init>");
 		.add("java/io/BufferedWriter:<init>");
 		.add("java/io/FileWriter:<init>");
 		.add("java/io/OutpuStreamWriter:<init>");
 		.add("java/io/BufferedReader:<init>");
 		.add("java/io/FileReader:<init>");
 		.add("java/io/InputStreamReader:<init>");
 		.add("java/io/RandomAccessFile:<init>");
 		.add("java/lang/Class:getResourceAsStream");
 		.add("java/lang/ClassLoader:getResourceAsStream");
 		.add("java/lang/ClassLoader:loadClass");
 		.add("java/sql/DriverManager:getConnection");
 		.add("java/sql/Connection:createStatement");
 		.add("java/sql/Connection:prepareStatement");
 		.add("java/sql/Connection:prepareCall");
 		.add("javax/sql/DataSource:getConnection");
 		.add("javax/xml/parsers/DocumentBuilder:parse");
 		.add("javax/xml/parsers/DocumentBuilder:parse");
 		.add("javax/xml/parsers/SAXParser:parse");
 		.add("javax/xml/transform/Transformer:transform");
 	}
 	
 	private Set<JavaClass> guiInterfaces;
 	private Map<Code,Method> listenerCode;
 	private String methodName;
 	private String methodSig;
 	private boolean isListenerMethod = false;
 	private boolean methodReported = false;

    
constructs a SG detector given the reporter to report bugs on

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

overrides the visitor to reset look for gui interfaces

Parameters:
classContext the context object for the currently parsed class
	public void visitClassContext(ClassContext classContext) {
		try {
			 = new HashSet<JavaClass>();
			JavaClass cls = classContext.getJavaClass();
			JavaClass[] infs = cls.getAllInterfaces();
			for (JavaClass inf : infs) {
				String name = inf.getClassName();
				if ((name.startsWith("java.awt.")
				||  name.startsWith("javax.swing."))
				&&  name.endsWith("Listener")) {
					.add(inf);
				}
			}
			if (.size() > 0) {
				 = new LinkedHashMap<Code,Method>();
				super.visitClassContext(classContext);
			}
catch (ClassNotFoundException cnfe) {
finally {
			 = null;
			 = null;
		}
	}

overrides the visitor to visit all of the collected listener methods

Parameters:
obj the context object of the currently parsed class
	public void visitAfter(JavaClass obj) {
		for (Code l : .keySet()) {
			 = false;
			super.visitCode(l);
		}
		super.visitAfter(obj);
	}
overrides the visitor collect method info

Parameters:
obj the context object of the currently parsed method
	public void visitMethod(Method obj) {
		 = obj.getName();
		 = obj.getSignature();
	}

overrides the visitor to segregate method into two, those that implement listeners, and those that don't. The ones that don't are processed first.

Parameters:
obj the context object of the currently parsed code block
	public void visitCode(Code obj) {
		for (JavaClass inf : ) {
			Method[] methods = inf.getMethods();
			for (Method m : methods) {
				if (m.getName().equals()) {
					if (m.getSignature().equals()) {
						.put(objthis.getMethod());
						return;
					}
				}
			}
		}
		 = false;
		super.visitCode(obj);
	}

overrides the visitor to look for the execution of expensive calls

Parameters:
seen the currently parsed opcode
	public void sawOpcode(int seen) {
			return;
		if ((seen == INVOKEINTERFACE)
		||  (seen == INVOKEVIRTUAL)
		||  (seen == INVOKESPECIAL)
		||  (seen == INVOKESTATIC)) {
			String methodInfo = clsName + ":" + mName;
			String thisMethodInfo = (clsName.equals(getClassName())) ? (mName + ":" + ) : "0";
			if (.contains(methodInfo) || .contains(thisMethodInfo)) {
					.reportBug(new BugInstance(this"SG_SLUGGISH_GUI", NORMAL_PRIORITY)
												.addClass(this)
												.addMethod(this.getClassContext().getJavaClass(), .get(this.getCode())));
else {
				}
			}
		}
	}
New to GrepCode? Check out our FAQ X