1 19 20 package edu.umd.cs.findbugs.detect; 21 22 import org.apache.bcel.Constants; 23 import org.apache.bcel.generic.ConstantPoolGen; 24 import org.apache.bcel.generic.INVOKEINTERFACE; 25 import org.apache.bcel.generic.INVOKESPECIAL; 26 import org.apache.bcel.generic.INVOKEVIRTUAL; 27 import org.apache.bcel.generic.Instruction; 28 import org.apache.bcel.generic.InstructionHandle; 29 import org.apache.bcel.generic.InvokeInstruction; 30 31 import edu.umd.cs.findbugs.ResourceCreationPoint; 32 import edu.umd.cs.findbugs.ba.BasicBlock; 33 import edu.umd.cs.findbugs.ba.Hierarchy; 34 import edu.umd.cs.findbugs.ba.Location; 35 import edu.umd.cs.findbugs.ba.RepositoryLookupFailureCallback; 36 import edu.umd.cs.findbugs.ba.ResourceValue; 37 import edu.umd.cs.findbugs.ba.ResourceValueFrame; 38 39 53 public class Stream extends ResourceCreationPoint implements Comparable <Stream> { 54 private String streamBase; 55 private boolean isUninteresting; 56 private boolean isOpenOnCreation; 57 private Location openLocation; 58 private boolean ignoreImplicitExceptions; 59 private String bugType; 60 private int instanceParam; 61 private boolean isClosed; 62 63 @Override 64 public String toString() { 65 return streamBase +":" + openLocation; 66 } 67 78 public Stream(Location location, String streamClass, String streamBase) { 79 super(location, streamClass); 80 this.streamBase = streamBase; 81 isUninteresting = true; 82 instanceParam = -1; 83 } 84 85 91 public Stream setInteresting(String bugType) { 92 this.isUninteresting = false; 93 this.bugType = bugType; 94 return this; 95 } 96 97 102 public Stream setIgnoreImplicitExceptions(boolean enable) { 103 ignoreImplicitExceptions = enable; 104 return this; 105 } 106 107 112 public Stream setIsOpenOnCreation(boolean enable) { 113 isOpenOnCreation = enable; 114 return this; 115 } 116 117 123 public void setInstanceParam(int instanceParam) { 124 this.instanceParam = instanceParam; 125 } 126 127 131 public void setClosed() { 132 isClosed = true; 133 } 134 135 public String getStreamBase() { 136 return streamBase; 137 } 138 139 public boolean isUninteresting() { 140 return isUninteresting; 141 } 142 143 public boolean isOpenOnCreation() { 144 return isOpenOnCreation; 145 } 146 147 public void setOpenLocation(Location openLocation) { 148 this.openLocation = openLocation; 149 } 150 151 public Location getOpenLocation() { 152 return openLocation; 153 } 154 155 public boolean ignoreImplicitExceptions() { 156 return ignoreImplicitExceptions; 157 } 158 159 public int getInstanceParam() { 160 return instanceParam; 161 } 162 163 public String getBugType() { 164 return bugType; 165 } 166 167 171 public boolean isClosed() { 172 return isClosed; 173 } 174 175 public boolean isStreamOpen(BasicBlock basicBlock, InstructionHandle handle, 176 ConstantPoolGen cpg, ResourceValueFrame frame) { 177 if (isOpenOnCreation) 178 return false; 179 180 Instruction ins = handle.getInstruction(); 181 if (!(ins instanceof INVOKESPECIAL)) 182 return false; 183 184 INVOKESPECIAL inv = (INVOKESPECIAL) ins; 186 187 return frame.isValid() 188 && getInstanceValue(frame, inv, cpg).isInstance() 189 && matchMethod(inv, cpg, this.getResourceClass(), "<init>"); 190 } 191 192 public boolean isStreamClose(BasicBlock basicBlock, InstructionHandle handle, 193 ConstantPoolGen cpg, ResourceValueFrame frame, 194 RepositoryLookupFailureCallback lookupFailureCallback) { 195 196 Instruction ins = handle.getInstruction(); 197 198 if ((ins instanceof INVOKEVIRTUAL) || (ins instanceof INVOKEINTERFACE)) { 199 InvokeInstruction inv = (InvokeInstruction) ins; 201 202 if (!frame.isValid() || 203 !getInstanceValue(frame, inv, cpg).isInstance()) 204 return false; 205 206 try { 210 return inv.getName(cpg).equals("close") 211 && inv.getSignature(cpg).equals("()V") 212 && Hierarchy.isSubtype(inv.getClassName(cpg), streamBase); 213 } catch (ClassNotFoundException e) { 214 lookupFailureCallback.reportMissingClass(e); 215 return false; 216 } 217 } 218 219 return false; 220 } 221 222 private ResourceValue getInstanceValue(ResourceValueFrame frame, InvokeInstruction inv, 223 ConstantPoolGen cpg) { 224 int numConsumed = inv.consumeStack(cpg); 225 if (numConsumed == Constants.UNPREDICTABLE) 226 throw new IllegalStateException (); 227 return frame.getValue(frame.getNumSlots() - numConsumed); 228 } 229 230 private boolean matchMethod(InvokeInstruction inv, ConstantPoolGen cpg, String className, 231 String methodName) { 232 return inv.getClassName(cpg).equals(className) 233 && inv.getName(cpg).equals(methodName); 234 } 235 236 public int hashCode() { 237 return 238 getLocation().hashCode() 239 + 3*streamBase.hashCode() 240 + 7*getResourceClass().hashCode() 241 + 11*instanceParam; 242 } 243 public boolean equals(Object o) { 244 if (!(o instanceof Stream)) return false; 245 Stream other = (Stream) o; 246 if (!getLocation().equals(other.getLocation())) return false; 247 if (!streamBase.equals(other.streamBase)) return false; 248 if (!getResourceClass().equals(other.getResourceClass())) return false; 249 if (instanceParam != other.instanceParam) return false; 250 return true; 251 } 252 public int compareTo(Stream other) { 253 int cmp; 254 255 261 cmp = getLocation().compareTo(other.getLocation()); 262 if (cmp != 0) return cmp; 263 cmp = streamBase.compareTo(other.streamBase); 264 if (cmp != 0) return cmp; 265 cmp = getResourceClass().compareTo(other.getResourceClass()); 266 if (cmp != 0) return cmp; 267 cmp = instanceParam - other.instanceParam; 268 if (cmp != 0) return cmp; 269 270 return 0; 271 } 272 } 273 274 | Popular Tags |