KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > edu > umd > cs > findbugs > detect > StreamFrameModelingVisitor


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

19
20 package edu.umd.cs.findbugs.detect;
21
22
23 import edu.umd.cs.findbugs.ba.*;
24 import org.apache.bcel.Constants;
25 import org.apache.bcel.Repository;
26 import org.apache.bcel.generic.*;
27
28 /**
29  * A visitor to model the effect of instructions on the status
30  * of the resource (in this case, Streams).
31  */

32 public class StreamFrameModelingVisitor extends ResourceValueFrameModelingVisitor {
33     private StreamResourceTracker resourceTracker;
34     private Stream stream;
35     private Location location;
36
37     public StreamFrameModelingVisitor(ConstantPoolGen cpg, StreamResourceTracker resourceTracker,
38                                       Stream stream) {
39         super(cpg);
40         this.resourceTracker = resourceTracker;
41         this.stream = stream;
42     }
43
44     @Override JavaDoc
45          public void transferInstruction(InstructionHandle handle, BasicBlock basicBlock) throws DataflowAnalysisException {
46         // Record what Location we are analyzing
47
this.location = new Location(handle, basicBlock);
48
49         final Instruction ins = handle.getInstruction();
50         final ConstantPoolGen cpg = getCPG();
51         final ResourceValueFrame frame = getFrame();
52
53         int status = -1;
54         boolean created = false;
55
56         // Is a resource created, opened, or closed by this instruction?
57
Location creationPoint = stream.getLocation();
58         if (handle == creationPoint.getHandle() && basicBlock == creationPoint.getBasicBlock()) {
59             // Resource creation
60
if (stream.isOpenOnCreation()) {
61                 status = ResourceValueFrame.OPEN;
62                 stream.setOpenLocation(location);
63                 resourceTracker.addStreamOpenLocation(location, stream);
64             } else {
65                 status = ResourceValueFrame.CREATED;
66             }
67             created = true;
68         } else if (resourceTracker.isResourceOpen(basicBlock, handle, cpg, stream, frame)) {
69             // Resource opened
70
status = ResourceValueFrame.OPEN;
71             stream.setOpenLocation(location);
72             resourceTracker.addStreamOpenLocation(location, stream);
73         } else if (resourceTracker.isResourceClose(basicBlock, handle, cpg, stream, frame)) {
74             // Resource closed
75
status = ResourceValueFrame.CLOSED;
76         }
77
78         // Model use of instance values in frame slots
79
analyzeInstruction(ins);
80
81         // If needed, update frame status
82
if (status != -1) {
83             frame.setStatus(status);
84             if (created)
85                 frame.setValue(frame.getNumSlots() - 1, ResourceValue.instance());
86         }
87
88     }
89
90     @Override JavaDoc
91          protected boolean instanceEscapes(InvokeInstruction inv, int instanceArgNum) {
92         ConstantPoolGen cpg = getCPG();
93         String JavaDoc className = inv.getClassName(cpg);
94
95         //System.out.print("[Passed as arg="+instanceArgNum+" at " + inv + "]");
96

97         boolean escapes = (inv.getOpcode() == Constants.INVOKESTATIC || instanceArgNum != 0);
98         String JavaDoc methodName = inv.getMethodName(cpg);
99         String JavaDoc methodSig = inv.getSignature(cpg);
100         if (inv.getOpcode() == Constants.INVOKEVIRTUAL
101                     && (methodName.equals("load") || methodName.equals("loadFromXml") || methodName.equals("store")
102                             || methodName.equals("save"))
103                     && className.equals("java.util.Properties"))
104                 escapes = false;
105         if (inv.getOpcode() == Constants.INVOKEVIRTUAL
106                     && (methodName.equals("load") || methodName.equals("store"))
107                     && className.equals("java.security.KeyStore"))
108                 escapes = false;
109         if (inv.getOpcode() == Constants.INVOKEVIRTUAL
110                     && "getChannel".equals(methodName)
111                     && "()Ljava/nio/channels/FileChannel;".equals(methodSig))
112                 escapes = true;
113     
114         if (FindOpenStream.DEBUG && escapes) {
115             System.out.println("ESCAPE at " + location + " at call to " + className +"." + methodName +":" + methodSig);
116         }
117
118         // Record the fact that this might be a stream escape
119
if (stream.getOpenLocation() != null)
120             resourceTracker.addStreamEscape(stream, location);
121
122         return escapes;
123     }
124 }
125
126 // vim:ts=3
127
Popular Tags