001/* ===========================================================
002 * JFreeChart : a free chart library for the Java(tm) platform
003 * ===========================================================
004 *
005 * (C) Copyright 2000-2007, by Object Refinery Limited and Contributors.
006 *
007 * Project Info:  http://www.jfree.org/jfreechart/index.html
008 *
009 * This library is free software; you can redistribute it and/or modify it 
010 * under the terms of the GNU Lesser General Public License as published by 
011 * the Free Software Foundation; either version 2.1 of the License, or 
012 * (at your option) any later version.
013 *
014 * This library is distributed in the hope that it will be useful, but 
015 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
016 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
017 * License for more details.
018 *
019 * You should have received a copy of the GNU Lesser General Public
020 * License along with this library; if not, write to the Free Software
021 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
022 * USA.  
023 *
024 * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 
025 * in the United States and other countries.]
026 *
027 * ------------------
028 * HashUtilities.java
029 * ------------------
030 * (C) Copyright 2006, 2007, by Object Refinery Limited;
031 *
032 * Original Author:  David Gilbert (for Object Refinery Limited);
033 * Contributor(s):   -;
034 *
035 * Changes
036 * -------
037 * 03-Oct-2006 : Version 1 (DG);
038 * 06-Mar-2007 : Fix for hashCodeForDoubleArray() method (DG);
039 * 13-Nov-2007 : Added new utility methods (DG);
040 *
041 */
042
043package org.jfree.chart;
044
045import java.awt.GradientPaint;
046import java.awt.Paint;
047import java.awt.Stroke;
048
049/**
050 * Some utility methods for calculating hash codes.  
051 * 
052 * @since 1.0.3
053 */
054public class HashUtilities {
055    
056    /**
057     * Returns a hash code for a <code>Paint</code> instance.  If 
058     * <code>p</code> is <code>null</code>, this method returns zero.
059     * 
060     * @param p  the paint (<code>null</code> permitted).
061     * 
062     * @return The hash code.
063     */
064    public static int hashCodeForPaint(Paint p) {
065        if (p == null) {
066            return 0;
067        }
068        int result = 0;
069        // handle GradientPaint as a special case
070        if (p instanceof GradientPaint) {
071            GradientPaint gp = (GradientPaint) p;
072            result = 193;
073            result = 37 * result + gp.getColor1().hashCode();
074            result = 37 * result + gp.getPoint1().hashCode();
075            result = 37 * result + gp.getColor2().hashCode();
076            result = 37 * result + gp.getPoint2().hashCode();
077        }
078        else {
079            // we assume that all other Paint instances implement equals() and
080            // hashCode()...of course that might not be true, but what can we
081            // do about it?
082            result = p.hashCode();
083        }
084        return result;
085    }
086    
087    /**
088     * Returns a hash code for a <code>double[]</code> instance.  If the array
089     * is <code>null</code>, this method returns zero.
090     * 
091     * @param a  the array (<code>null</code> permitted).
092     * 
093     * @return The hash code.
094     */
095    public static int hashCodeForDoubleArray(double[] a) {
096        if (a == null) { 
097            return 0;
098        }
099        int result = 193;
100        long temp;
101        for (int i = 0; i < a.length; i++) {
102            temp = Double.doubleToLongBits(a[i]);
103            result = 29 * result + (int) (temp ^ (temp >>> 32));
104        }
105        return result;
106    }
107    
108    /**
109     * Returns a hash value based on a seed value and the value of a boolean
110     * primitive.
111     * 
112     * @param pre  the seed value.
113     * @param b  the boolean value.
114     * 
115     * @return A hash value.
116     * 
117     * @since 1.0.7
118     */
119    public static int hashCode(int pre, boolean b) {
120        return 37 * pre + (b ? 0 : 1);
121    }
122    
123    /**
124     * Returns a hash value based on a seed value and the value of a double
125     * primitive.
126     * 
127     * @param pre  the seed value.
128     * @param d  the double value.
129     * 
130     * @return A hash value.
131     * 
132     * @since 1.0.7
133     */
134    public static int hashCode(int pre, double d) {
135        long l = Double.doubleToLongBits(d);
136        return 37 * pre + (int) (l ^ (l >>> 32));
137    }
138    
139    /**
140     * Returns a hash value based on a seed value and a paint instance.
141     * 
142     * @param pre  the seed value.
143     * @param p  the paint (<code>null</code> permitted).
144     * 
145     * @return A hash value.
146     * 
147     * @since 1.0.7
148     */
149    public static int hashCode(int pre, Paint p) {
150        return 37 * pre + hashCodeForPaint(p);
151    }
152
153    /**
154     * Returns a hash value based on a seed value and a stroke instance.
155     * 
156     * @param pre  the seed value.
157     * @param s  the stroke (<code>null</code> permitted).
158     * 
159     * @return A hash value.
160     * 
161     * @since 1.0.7
162     */
163    public static int hashCode(int pre, Stroke s) {
164        int h = (s != null ? s.hashCode() : 0);
165        return 37 * pre + h;
166    }
167
168    /**
169     * Returns a hash value based on a seed value and a string instance.
170     * 
171     * @param pre  the seed value.
172     * @param s  the string (<code>null</code> permitted).
173     * 
174     * @return A hash value.
175     * 
176     * @since 1.0.7
177     */
178    public static int hashCode(int pre, String s) {
179        int h = (s != null ? s.hashCode() : 0);
180        return 37 * pre + h;
181    }
182
183    /**
184     * Returns a hash value based on a seed value and a <code>Comparable</code>
185     * instance.
186     * 
187     * @param pre  the seed value.
188     * @param c  the comparable (<code>null</code> permitted).
189     * 
190     * @return A hash value.
191     * 
192     * @since 1.0.7
193     */
194    public static int hashCode(int pre, Comparable c) {
195        int h = (c != null ? c.hashCode() : 0);
196        return 37 * pre + h;
197    }
198}