KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > syndication > feed > impl > EqualsBean


1 /*
2  * Copyright 2004 Sun Microsystems, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */

17 package com.sun.syndication.feed.impl;
18
19 import java.beans.PropertyDescriptor JavaDoc;
20 import java.lang.reflect.Array JavaDoc;
21 import java.lang.reflect.Method JavaDoc;
22 import java.io.Serializable JavaDoc;
23
24 /**
25  * Provides deep <b>Bean</b> equals() and hashCode() functionality for Java Beans.
26  * <p>
27  * It works on all read/write properties, recursively. It support all primitive types, Strings, Collections,
28  * bean-like objects and multi-dimensional arrays of any of them.
29  * <p>
30  * The hashcode is calculated by getting the hashcode of the Bean String representation.
31  * <p>
32  * @author Alejandro Abdelnur
33  *
34  */

35 public class EqualsBean implements Serializable JavaDoc {
36
37     private static final Object JavaDoc[] NO_PARAMS = new Object JavaDoc[0];
38
39     private Class JavaDoc _beanClass;
40     private Object JavaDoc _obj;
41
42     /**
43      * Default constructor.
44      * <p>
45      * To be used by classes extending EqualsBean only.
46      * <p>
47      * @param beanClass the class/interface to be used for property scanning.
48      *
49      */

50     protected EqualsBean(Class JavaDoc beanClass) {
51         _beanClass = beanClass;
52         _obj = this;
53     }
54
55     /**
56      * Creates a EqualsBean to be used in a delegation pattern.
57      * <p>
58      * For example:
59      * <p>
60      * <code>
61      * public class Foo implements FooI {
62      * private EqualsBean _equalsBean;
63      *
64      * public Foo() {
65      * _equalsBean = new EqualsBean(FooI.class);
66      * }
67      *
68      * public boolean equals(Object obj) {
69      * return _equalsBean.beanEquals(obj);
70      * }
71      *
72      * public int hashCode() {
73      * return _equalsBean.beanHashCode();
74      * }
75      *
76      * }
77      * </code>
78      * <p>
79      * @param beanClass the class/interface to be used for property scanning.
80      * @param obj object bean to test equality.
81      *
82      */

83     public EqualsBean(Class JavaDoc beanClass,Object JavaDoc obj) {
84         if (!beanClass.isInstance(obj)) {
85             throw new IllegalArgumentException JavaDoc(obj.getClass()+" is not instance of "+beanClass);
86         }
87         _beanClass = beanClass;
88         _obj = obj;
89     }
90
91     /**
92      * Indicates whether some other object is "equal to" this object as defined by the Object equals() method.
93      * <p>
94      * To be used by classes extending EqualsBean. Although it works also for classes using
95      * EqualsBean in a delegation pattern, for correctness those classes should use the
96      * @see #beanEquals(Object) beanEquals method.
97      * <p>
98      * @param obj he reference object with which to compare.
99      * @return <b>true</b> if 'this' object is equal to the 'other' object.
100      *
101      */

102     public boolean equals(Object JavaDoc obj) {
103         return beanEquals(obj);
104     }
105
106     /**
107      * Indicates whether some other object is "equal to" the object passed in the constructor,
108      * as defined by the Object equals() method.
109      * <p>
110      * To be used by classes using EqualsBean in a delegation pattern,
111      * @see #EqualsBean(Class,Object) constructor.
112      * <p>
113      * @param obj he reference object with which to compare.
114      * @return <b>true</b> if the object passed in the constructor is equal to the 'obj' object.
115      *
116      */

117     public boolean beanEquals(Object JavaDoc obj) {
118         Object JavaDoc bean1 = _obj;
119         Object JavaDoc bean2 = obj;
120         boolean eq;
121         if (bean1==null && bean2==null) {
122             eq = true;
123         }
124         else
125             if (bean1==null || bean2==null) {
126                 eq = false;
127             }
128             else {
129                 if (!_beanClass.isInstance(bean2)) {
130                     eq = false;
131                 }
132                 else {
133                     eq = true;
134                     try {
135                         PropertyDescriptor JavaDoc[] pds = BeanIntrospector.getPropertyDescriptors(_beanClass);
136                         if (pds!=null) {
137                             for (int i = 0; eq && i<pds.length; i++) {
138                                 Method JavaDoc pReadMethod = pds[i].getReadMethod();
139                                 if (pReadMethod!=null && // ensure it has a getter method
140
pReadMethod.getDeclaringClass()!=Object JavaDoc.class && // filter Object.class getter methods
141
pReadMethod.getParameterTypes().length==0) { // filter getter methods that take parameters
142
Object JavaDoc value1 = pReadMethod.invoke(bean1, NO_PARAMS);
143                                     Object JavaDoc value2 = pReadMethod.invoke(bean2, NO_PARAMS);
144                                     eq = doEquals(value1, value2);
145                                 }
146                             }
147                         }
148                     }
149                     catch (Exception JavaDoc ex) {
150                         throw new RuntimeException JavaDoc("Could not execute equals()", ex);
151                     }
152                 }
153             }
154         return eq;
155     }
156
157     /**
158      * Returns the hashcode for this object.
159      * <p>
160      * It follows the contract defined by the Object hashCode() method.
161      * <p>
162      * The hashcode is calculated by getting the hashcode of the Bean String representation.
163      * <p>
164      * To be used by classes extending EqualsBean. Although it works also for classes using
165      * EqualsBean in a delegation pattern, for correctness those classes should use the
166      * @see #beanHashCode() beanHashCode method.
167      * <p>
168      * @return the hashcode of the bean object.
169      *
170      */

171     public int hashCode() {
172         return beanHashCode();
173     }
174
175     /**
176      * Returns the hashcode for the object passed in the constructor.
177      * <p>
178      * It follows the contract defined by the Object hashCode() method.
179      * <p>
180      * The hashcode is calculated by getting the hashcode of the Bean String representation.
181      * <p>
182      * To be used by classes using EqualsBean in a delegation pattern,
183      * @see #EqualsBean(Class,Object) constructor.
184      * <p>
185      * @return the hashcode of the bean object.
186      *
187      */

188     public int beanHashCode() {
189         return _obj.toString().hashCode();
190     }
191
192
193     private boolean doEquals(Object JavaDoc obj1, Object JavaDoc obj2) {
194         boolean eq = obj1==obj2;
195         if (!eq && obj1!=null && obj2!=null) {
196             Class JavaDoc classObj1 = obj1.getClass();
197             Class JavaDoc classObj2 = obj2.getClass();
198             if (classObj1.isArray() && classObj2.isArray()) {
199                 eq = equalsArray(obj1, obj2);
200             }
201             else {
202                 eq = obj1.equals(obj2);
203             }
204         }
205         return eq;
206     }
207
208     private boolean equalsArray(Object JavaDoc array1, Object JavaDoc array2) {
209         boolean eq;
210         int length1 = Array.getLength(array1);
211         int length2 = Array.getLength(array2);
212         if (length1==length2) {
213             eq = true;
214             for (int i = 0; eq && i<length1; i++) {
215                 Object JavaDoc e1 = Array.get(array1, i);
216                 Object JavaDoc e2 = Array.get(array2, i);
217                 eq = doEquals(e1, e2);
218             }
219         }
220         else {
221             eq = false;
222         }
223         return eq;
224     }
225
226 }
227
228
Popular Tags