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 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;
 import  org.apache.bcel.generic.Type;
 
 import  edu.umd.cs.findbugs.BugInstance;
 import  edu.umd.cs.findbugs.BugReporter;
 import  edu.umd.cs.findbugs.BytecodeScanningDetector;
 import  edu.umd.cs.findbugs.FieldAnnotation;
 import  edu.umd.cs.findbugs.SourceLineAnnotation;
 import  edu.umd.cs.findbugs.ba.ClassContext;

looks for tag libraries that are not recycleable because backing members of taglib attributes are set in areas besides the setter method for the attribute.
 
 public class NonRecycleableTaglibs extends BytecodeScanningDetector
 {
 	private static final int MAX_ATTRIBUTE_CODE_LENGTH = 60;
 
 	private static final Set<StringtagClasses = new HashSet<String>();
 	static {
 		.add("javax.servlet.jsp.tagext.TagSupport");
 		.add("javax.servlet.jsp.tagext.BodyTagSupport");
 	}
 
 	private static final Set<StringvalidAttrTypes = new HashSet<String>();
 	static {
 		.add("Ljava/lang/String;");
 		.add("Ljava/util/Date;");
 	}
 
 	private final BugReporter bugReporter;
methodname:methodsig -> type of setter methods
 
 	private Map<StringStringattributes;
methodname:methodsig -> (fieldname:fieldtype)s
 
 	private Map<StringMap<String, SourceLineAnnotation>> methodWrites;
 	private Map<String, FieldAnnotation> fieldAnnotations;

constructs a NRTL detector given the reporter to report bugs on.

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

implements the visitor to look for classes that extend the TagSupport or BodyTagSupport class

Parameters:
classContext the context object for the currently parsed class
 
 	public void visitClassContext(ClassContext classContext) {
 		try {
 			JavaClass cls = classContext.getJavaClass();
 			JavaClass[] superClasses = cls.getSuperClasses();
 			for (JavaClass superCls : superClasses) {
 				if (.contains(superCls.getClassName())) {
 
					if (.size() > 0) {
						 = new HashMap<StringMap<String, SourceLineAnnotation>>();
						 = new HashMap<String, FieldAnnotation>();
						super.visitClassContext(classContext);
					}
					break;
				}
			}
catch (ClassNotFoundException cnfe) {
			.reportMissingClass(cnfe);
		}
		finally {
			 = null;
			 = null;
		}
	}

collect all possible attributes given the name of methods available.

Returns:
the map of possible attributes/types
	private Map<StringStringgetAttributes(JavaClass cls) {
		Map<StringStringatts = new HashMap<StringString>();
		Method[] methods = cls.getMethods();
		for (Method m : methods) {
			String name = m.getName();
			if (name.startsWith("set") && m.isPublic() && !m.isStatic()) {
				String sig = m.getSignature();
				Type ret = Type.getReturnType(sig);
				Type[] args = Type.getArgumentTypes(sig);
				if (ret.equals(Type.VOID) && (args.length == 1)) {
					String parmSig = args[0].getSignature();
					if (.contains(parmSig)) {
						Code code = m.getCode();
						if ((code != null) && (code.getCode().length < )) {
							atts.put(name + ":" + sigparmSig);
						}
					}
				}
			}
		}
		return atts;
	}

implements the visitor to

Parameters:
obj the context object for the currently parsed code object
	public void visitCode(Code obj) {
		Method m = getMethod();
		if (!"<init>".equals(m.getName())) {
			super.visitCode(obj);
		}
	}
	public void sawOpcode(int seen) {
		if (seen == PUTFIELD) {
			String methodInfo = getMethodName() + ":" + getMethodSig();
			Map<String, SourceLineAnnotation> fields = .get(methodInfo);
			if (fields == null) {
				fields = new HashMap<String, SourceLineAnnotation>();
				.put(methodInfofields);
			}
			FieldAnnotation fa = new FieldAnnotation(getDottedClassName(), fieldNamefieldSigfalse);
			.put(fieldNamefa);
			fields.put(fieldName + ":" + fieldSig, SourceLineAnnotation.fromVisitedInstruction(this));
		}
	}

generates all the bug reports for attributes that are not recycleable
	private void reportBugs() {
		for (Map.Entry<StringStringattEntry : .entrySet()) {
			String methodInfo = attEntry.getKey();
			String attType = attEntry.getValue();
			Map<String, SourceLineAnnotation> fields = .get(methodInfo);
			if ((fields == null) || (fields.size() != 1)) {
				continue;
			}
			String fieldInfo = fields.keySet().iterator().next();
			int colonPos = fieldInfo.indexOf(':');
			String fieldName = fieldInfo.substring(0, colonPos);
			String fieldType = fieldInfo.substring(colonPos+1);
			if (!attType.equals(fieldType)) {
				continue;
			}
			for (Map.Entry<StringMap<String, SourceLineAnnotation>> fwEntry : .entrySet()) {
				if (fwEntry.getKey().equals(methodInfo)) {
					continue;
				}
				SourceLineAnnotation sla = fwEntry.getValue().get(fieldInfo);
				if (sla != null) {
					.reportBug(new BugInstance(this"NRTL_NON_RECYCLEABLE_TAG_LIB", NORMAL_PRIORITY)
					.addClass(this)
					.addField(.get(fieldName))
					.addSourceLine(sla));
					break;
				}
			}
		}
	}
New to GrepCode? Check out our FAQ X