KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > edu > umd > cs > findbugs > ba > MethodHash


1 /*
2  * FindBugs - Find Bugs in Java programs
3  * Copyright (C) 2005, 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.ba;
21
22 import java.security.MessageDigest JavaDoc;
23 import java.security.NoSuchAlgorithmException JavaDoc;
24 import java.util.Arrays JavaDoc;
25
26 import org.apache.bcel.classfile.Method;
27
28
29 /**
30  * Compute a hash of the bytecode for given method.
31  * This can find methods which have not been changed other
32  * than accessing different constant pool entries.
33  *
34  * @author David Hovemeyer
35  */

36 public class MethodHash implements Comparable JavaDoc<MethodHash> {
37     public static final String JavaDoc METHOD_HASH_ELEMENT_NAME = "MethodHash";
38     
39     private byte[] hash;
40     private String JavaDoc methodName;
41     private String JavaDoc methodSig;
42     private boolean isStatic;
43
44     /**
45      * Constructor.
46      * computeHash(Method) must be used to initialize the contents.
47      */

48     public MethodHash() {
49     }
50     
51     /**
52      * Constructor.
53      *
54      * @param methodName method name
55      * @param methodSig method signature
56      * @param isStatic true if the method is static, false if not
57      * @param hash the pre-computed hash
58      */

59     public MethodHash(String JavaDoc methodName, String JavaDoc methodSig, boolean isStatic, byte[] hash) {
60         this.methodName = methodName;
61         this.methodSig = methodSig;
62         this.isStatic = isStatic;
63         this.hash = new byte[hash.length];
64         System.arraycopy(hash, 0, this.hash, 0, hash.length);
65     }
66     
67     /**
68      * @return Returns the method name.
69      */

70     public String JavaDoc getMethodName() {
71         return methodName;
72     }
73     
74     /**
75      * @return Returns the method signature.
76      */

77     public String JavaDoc getMethodSig() {
78         return methodSig;
79     }
80     
81     /**
82      * @return Returns whether the method is static.
83      */

84     public boolean isStatic() {
85         return isStatic;
86     }
87     
88     /**
89      * Get the computed method hash.
90      *
91      * @return the method hash
92      */

93     public byte[] getMethodHash() {
94         return hash;
95     }
96     
97     /**
98      * Compute hash on given method.
99      *
100      * @param method the method
101      * @return this object
102      */

103     public MethodHash computeHash(Method method) {
104         MessageDigest JavaDoc digest_;
105         try {
106             digest_ = MessageDigest.getInstance("MD5");
107         } catch (NoSuchAlgorithmException JavaDoc e) {
108             throw new IllegalStateException JavaDoc("No algorithm for computing method hash", e);
109         }
110         final MessageDigest JavaDoc digest = digest_;
111
112         byte[] code;
113         if (method.getCode() == null || method.getCode().getCode() == null) {
114             code = new byte[0];
115         } else {
116             code = method.getCode().getCode();
117         }
118         
119         BytecodeScanner.Callback callback = new BytecodeScanner.Callback() {
120             public void handleInstruction(int opcode, int index) {
121                 digest.update((byte) opcode);
122             }
123         };
124         
125         BytecodeScanner bytecodeScanner = new BytecodeScanner();
126         bytecodeScanner.scan(code, callback);
127         
128         hash = digest.digest();
129         
130         return this;
131     }
132     
133     /**
134      * Return whether or not this method hash has the same value as the one given.
135      *
136      * @param other another MethodHash
137      * @return true if the hash values are the same, false if not
138      */

139     public boolean isSameHash(MethodHash other) {
140         return Arrays.equals(this.hash, other.hash);
141     }
142
143     /* (non-Javadoc)
144      * @see java.lang.Comparable#compareTo(T)
145      */

146     public int compareTo(MethodHash other) {
147         return MethodHash.compareHashes(this.hash, other.hash);
148     }
149     
150     public boolean equals(Object JavaDoc o) {
151         if (o instanceof MethodHash)
152             return isSameHash((MethodHash)o);
153         return false;
154     }
155     public int hashCode() {
156         int result = 0;
157         for(byte b : hash)
158             result = result * 17 + b;
159         return result;
160     }
161     public static int compareHashes(byte[] a, byte[] b) {
162         int pfxlen = Math.min(a.length, b.length);
163         for (int i = 0; i < pfxlen; ++i) {
164             int cmp = toUnsigned(a[i]) - toUnsigned(b[i]);
165             if (cmp != 0)
166                 return cmp;
167         }
168         return a.length - b.length;
169     }
170
171     /**
172      * Convert a byte to an unsigned int.
173      *
174      * @param b a byte value
175      * @return the unsigned integer value of the byte
176      */

177     private static int toUnsigned(byte b) {
178         int value = b & 0x7F;
179         if ((b & 0x80) != 0) {
180             value |= 0x80;
181         }
182         return value;
183     }
184
185 }
186
Popular Tags