001: /*
002: * @(#)ChecksumUtil.java
003: *
004: * Copyright (C) 2002-2004 Matt Albrecht
005: * groboclown@users.sourceforge.net
006: * http://groboutils.sourceforge.net
007: *
008: * Permission is hereby granted, free of charge, to any person obtaining a
009: * copy of this software and associated documentation files (the "Software"),
010: * to deal in the Software without restriction, including without limitation
011: * the rights to use, copy, modify, merge, publish, distribute, sublicense,
012: * and/or sell copies of the Software, and to permit persons to whom the
013: * Software is furnished to do so, subject to the following conditions:
014: *
015: * The above copyright notice and this permission notice shall be included in
016: * all copies or substantial portions of the Software.
017: *
018: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
019: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
020: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
021: * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
022: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
023: * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
024: * DEALINGS IN THE SOFTWARE.
025: */
026:
027: package net.sourceforge.groboutils.codecoverage.v2.util;
028:
029: import java.util.Comparator;
030: import java.util.zip.CRC32;
031: import java.util.zip.Checksum;
032:
033: /**
034: * A "universal" method to extract a checksum from the various kinds of
035: * data the codecoverage package needs.
036: * <P>
037: * This is made such that the equivalent types between the BCEL library and
038: * JDI library return the same CRC.
039: *
040: * @author Matt Albrecht <a href="mailto:groboclown@users.sourceforge.net">groboclown@users.sourceforge.net</a>
041: * @version $Date: 2004/04/15 05:48:26 $
042: * @since Feb 3, 2003
043: */
044: public class ChecksumUtil {
045: protected static ChecksumUtil s_instance = new ChecksumUtil();
046:
047: // ensure that we ALWAYS get the same collator, no matter the
048: // executing environment.
049: protected final Comparator StringCollator = java.text.Collator
050: .getInstance(new java.util.Locale("en", "US", ""));
051:
052: /**
053: * Creates a new finder using the default (system) classpath.
054: */
055: protected ChecksumUtil() {
056: // do nothing
057: }
058:
059: public static ChecksumUtil getInstance() {
060: return s_instance;
061: }
062:
063: public long checksum(byte[] buff) {
064: Checksum crc = createChecksum();
065: update(crc, buff);
066: return crc.getValue();
067: }
068:
069: /*
070: public long checksum( JavaClass jc )
071: {
072: Checksum crc = createChecksum();
073: update( crc, jc );
074: return crc.getValue();
075: }
076: */
077:
078: /*
079: public long checksum( ReferenceType rt )
080: {
081: Checksum crc = createChecksum();
082: update( crc, rt );
083: return crc.getValue();
084: }
085: */
086:
087: /*
088: public long checksum( org.apache.bcel.classfile.Method m )
089: {
090: Checksum crc = createChecksum();
091: update( crc, m );
092: return crc.getValue();
093: }
094: */
095:
096: /*
097: public long checksum( Code c )
098: {
099: Checksum crc = createChecksum();
100: update( crc, c );
101: return crc.getValue();
102: }
103: */
104:
105: /*
106: public long checksum( com.sun.jdi.Method m )
107: {
108: Checksum crc = createChecksum();
109: update( crc, m );
110: return crc.getValue();
111: }
112: */
113:
114: //------------------------------------------------------------------------
115: // Factory methods
116: protected Checksum createChecksum() {
117: return new CRC32();
118: }
119:
120: protected void update(Checksum crc, byte[] buff) {
121: if (buff != null) {
122: crc.update(buff, 0, buff.length);
123: }
124: }
125:
126: /*
127: protected void update( Checksum crc, JavaClass jc )
128: {
129: // If JDI allowed for "bytecodes()" on the class level, as
130: // opposed to the Method level, then we could just do this:
131:
132: // update( crc, jc.getBytes() );
133:
134: // However, JDI only allows bytecodes() on the method level,
135: // so we must parse the checksum on a per-method basis.
136:
137: // Note that to ensure that the correct CRC is generated, we
138: // need to ensure that the ORDER of methods is identical across
139: // all runs and all types!
140:
141: org.apache.bcel.classfile.Method ms[] = jc.getMethods();
142: ArrayList list = new ArrayList();
143: for (int i = 0; i < ms.length; ++i)
144: {
145: list.add( ms[i] );
146: }
147: Iterator iter = sortList( list.iterator(), new Comparator()
148: {
149: public int compare( Object o1, Object o2 )
150: {
151: org.apache.bcel.classfile.Method m1 =
152: (org.apache.bcel.classfile.Method)o1;
153: org.apache.bcel.classfile.Method m2 =
154: (org.apache.bcel.classfile.Method)o2;
155:
156: return StringCollator.compare( m1.getSignature(),
157: m2.getSignature() );
158: }
159: public boolean equals( Object o1 )
160: {
161: if (o1 == null) return false;
162: if (o1 == this) return true;
163: return (o1.getClass().equals( this.getClass() ));
164: }
165: } );
166: while (iter.hasNext())
167: {
168: update( crc, (org.apache.bcel.classfile.Method)iter.next() );
169: }
170: }
171: */
172:
173: /*
174: protected void update( Checksum crc, ReferenceType rt )
175: {
176: // JDI does not have a "bytecodes()" method on ReferenceType,
177: // but does on methods.
178:
179: // Note that to ensure that the correct CRC is generated, we
180: // need to ensure that the ORDER of methods is identical across
181: // all runs and all types!
182:
183: Iterator iter = sortList( rt.methods().iterator(), new Comparator()
184: {
185: public int compare( Object o1, Object o2 )
186: {
187: com.sun.jdi.Method m1 =
188: (com.sun.jdi.Method)o1;
189: com.sun.jdi.Method m2 =
190: (com.sun.jdi.Method)o2;
191:
192: return StringCollator.compare( m1.signature(),
193: m2.signature() );
194: }
195: public boolean equals( Object o1 )
196: {
197: if (o1 == null) return false;
198: if (o1 == this) return true;
199: return (o1.getClass().equals( this.getClass() ));
200: }
201: } );
202: while (iter.hasNext())
203: {
204: update( crc, (com.sun.jdi.Method)iter.next() );
205: }
206: }
207: */
208:
209: /*
210: protected void update( Checksum crc, org.apache.bcel.classfile.Method m )
211: {
212: update( crc, m.getCode() );
213: }
214: */
215:
216: /*
217: protected void update( Checksum crc, Code c )
218: {
219: // abstract methods don't have code.
220: if (c != null)
221: {
222: update( crc, c.getCode() );
223: }
224: }
225: */
226:
227: /*
228: protected void update( Checksum crc, com.sun.jdi.Method m )
229: {
230: // abstract methods may not have any bytecodes.
231: // thus, this called method needs to be null-proof.
232: update( crc, m.bytecodes() );
233: }
234: */
235:
236: /*
237: * Sorts the given iteration with the given comparator.
238: * Made generic enough to allow an iterator. Should allow a
239: * Collection to simplify this method, but it's simple enough.
240: protected Iterator sortList( Iterator list, Comparator c )
241: {
242: TreeSet ts = new TreeSet( c );
243: while (list.hasNext())
244: {
245: ts.add( list.next() );
246: }
247: return ts.iterator();
248: }
249: */
250: }
|