1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 package util;
29 
30 import com.sun.star.beans.PropertyValue;
31 import java.lang.reflect.Array;
32 import java.lang.reflect.Field;
33 import java.lang.reflect.Modifier;
34 import com.sun.star.uno.Type;
35 import com.sun.star.uno.Enum;
36 import com.sun.star.uno.XInterface;
37 import com.sun.star.uno.Any;
38 import com.sun.star.uno.AnyConverter;
39 import java.util.HashMap;
40 
41 
42 public class ValueComparer {
43 
44     // Method to change a Value, thought for properties
45     public static boolean equalValue( Object first, Object second ) {
46 
47         if (first instanceof com.sun.star.uno.Any) {
48             try {
49                 first = AnyConverter.toObject(((Any) first).getType(),first);
50             } catch (com.sun.star.lang.IllegalArgumentException iae) {
51             }
52         }
53         if (second instanceof com.sun.star.uno.Any) {
54             try {
55                 second = AnyConverter.toObject(((Any) second).getType(),second);
56             } catch (com.sun.star.lang.IllegalArgumentException iae) {
57             }
58         }
59         boolean eq = false;
60         try {
61             if ( (first==null) || (second == null) ) {
62                 eq = (first == second);
63             }
64             else {
65                 if ( util.utils.isVoid(first) && util.utils.isVoid(second) ) {
66                     eq=true;
67                 } else if ( util.utils.isVoid(first) || util.utils.isVoid(second) ) {
68                     eq = (first == second);
69                 } else {
70                     eq = compareObjects(first, second);
71                 }
72             }
73         }
74         catch (Exception e) {
75             System.out.println("Exception occured while comparing Objects");
76             e.printStackTrace();
77         }
78         return eq;
79     } // end of equalValue
80 
81     static boolean compareArrayOfPropertyValue(PropertyValue[] pv1, PropertyValue[] pv2){
82         if ( pv1.length != pv2.length) {
83             return  false;
84         }
85         HashMap hm1 = new HashMap();
86         boolean result = true;
87         int i = 0;
88 
89         for (i = 0; i < pv1.length; i++){
90             hm1.put(pv1[i].Name, pv1[i].Value);
91         }
92 
93         i = 0;
94         while (i < pv2.length && result) {
95             result &= equalValue(hm1.get(pv2[i].Name),pv2[i].Value);
96             i++;
97         }
98         return result;
99     }
100 
101     static boolean compareArrays(Object op1, Object op2) throws Exception {
102 
103         if (op1 instanceof PropertyValue[] && op2 instanceof PropertyValue[]) {
104            return compareArrayOfPropertyValue((PropertyValue[])op1,(PropertyValue[])op2);
105        }
106         boolean result = true;
107         if((op1.getClass().getComponentType() == op2.getClass().getComponentType())
108            && (Array.getLength(op1) == Array.getLength(op2)))
109         {
110             Class zClass = op1.getClass().getComponentType();
111 
112             for(int i = 0; i < Array.getLength(op1); ++ i)
113                 result = result & compareObjects(Array.get(op1, i), Array.get(op2, i));
114         } else {
115             result = false ;
116         }
117 
118         return result;
119     }
120 
121     static boolean compareInterfaces(XInterface op1, XInterface op2) {
122         return op1 == op2;
123     }
124 
125     static boolean compareUntil(Class zClass, Class untilClass, Object op1, Object op2) throws Exception {
126         boolean result = true;
127 
128         // write inherited members first
129         Class superClass = zClass.getSuperclass();
130         if(superClass != null && superClass != untilClass)
131             result = result & compareUntil(superClass, untilClass, op1, op2);
132 
133         Field fields[] = zClass.getDeclaredFields();
134 
135         for(int i = 0; i < fields.length && result; ++ i) {
136             if((fields[i].getModifiers() & (Modifier.STATIC | Modifier.TRANSIENT)) == 0) { // neither static nor transient ?
137                 Object obj1 = fields[i].get(op1);
138                 Object obj2 = fields[i].get(op2);
139                 if (obj1 instanceof com.sun.star.uno.Any) {
140                     try {
141                         if (utils.isVoid(obj1)) {
142                             obj1 = null;
143                         } else {
144                             obj1 = AnyConverter.toObject(((Any) obj1).getType(),obj1);
145                         }
146                     } catch (com.sun.star.lang.IllegalArgumentException iae) {
147                     }
148                 }
149                 if (obj2 instanceof com.sun.star.uno.Any) {
150                     try {
151                         if (utils.isVoid(obj2)) {
152                             obj2 = null;
153                         } else {
154                             obj2 = AnyConverter.toObject(((Any) obj2).getType(),obj2);
155                         }
156                     } catch (com.sun.star.lang.IllegalArgumentException iae) {
157                     }
158                 }
159 
160                 result = result & compareObjects(obj1, obj2);
161 
162             }
163         }
164 
165         return result;
166     }
167 
168     static boolean compareStructs(Object op1, Object op2) throws Exception {
169         boolean result = true;
170 
171         if(op1.getClass() != op2.getClass())
172             result = false;
173         else {
174             result = compareUntil(op1.getClass(), Object.class, op1, op2);
175         }
176 
177         return result;
178     }
179 
180     static boolean compareThrowable(Throwable op1, Throwable op2) throws Exception {
181         boolean result = true;
182 
183         if(op1.getClass() != op2.getClass())
184             result = false;
185         else {
186             result = compareUntil(op1.getClass(), Throwable.class, op1, op2);
187 
188             result = result & op1.getMessage().equals(op2.getMessage());
189         }
190 
191         return result;
192     }
193 
194     static boolean compareEnums(Enum en1, Enum en2) {
195         return en1.getValue() == en2.getValue();
196     }
197 
198     static boolean compareObjects(Object op1, Object op2) throws Exception {
199         boolean result = false;
200 
201         if(op1 == op2)
202             result = true;
203 
204         if ( (op1==null) || (op2 == null) ) {
205             result = (op1 == op2);
206             }
207 
208         else if(op1.getClass().isPrimitive() && op2.getClass().isPrimitive())
209             result = op1.equals(op2);
210 
211         else if(op1.getClass() == Byte.class && op2.getClass() == Byte.class)
212             result = op1.equals(op2);
213 
214         else if(op1.getClass() == Type.class && op2.getClass() == Type.class)
215             result = op1.equals(op2);
216 
217         else if(op1.getClass() == Boolean.class && op2.getClass() == Boolean.class)
218             result = op1.equals(op2);
219 
220         else if(op1.getClass() == Short.class && op2.getClass() == Short.class)
221             result = op1.equals(op2);
222 
223         else if(Throwable.class.isAssignableFrom(op1.getClass()) && Throwable.class.isAssignableFrom(op2.getClass()))
224             result = compareThrowable((Throwable)op1, (Throwable)op2);
225 
226         else if(op1.getClass() == Integer.class && op2.getClass() == Integer.class)
227             result = op1.equals(op2);
228 
229         else if(op1.getClass() == Character.class && op2.getClass() == Character.class)
230             result = op1.equals(op2);
231 
232         else if(op1.getClass() == Long.class && op2.getClass() == Long.class)
233             result = op1.equals(op2);
234 
235         else if(op1.getClass() == Void.class && op2.getClass() == Void.class)
236             result = op1.equals(op2);
237 
238         else if(op1.getClass() == Float.class && op2.getClass() == Float.class)
239             result = op1.equals(op2);
240 
241         else if(op1.getClass() == Double.class && op2.getClass() == Double.class)
242             result = op1.equals(op2);
243 
244         else if(op1.getClass().isArray() && op2.getClass().isArray())
245             result = compareArrays(op1, op2);
246 
247         else if(op1.getClass() == Void.class || op2.getClass() == void.class) // write nothing ?
248             result = true;
249 
250         else if(XInterface.class.isAssignableFrom(op1.getClass()) && XInterface.class.isAssignableFrom(op2.getClass()))
251             compareInterfaces((XInterface)op1, (XInterface)op2);
252 
253         else if(Enum.class.isAssignableFrom(op1.getClass()) && Enum.class.isAssignableFrom(op2.getClass()))
254             compareEnums((Enum)op1, (Enum)op2);
255 
256         else if(op1.getClass() == String.class && op2.getClass() == String.class) // is it a String ?
257             result = ((String)op1).equals((String)op2);
258 
259         else // otherwise it must be a struct
260             result = compareStructs(op1, op2);
261 
262         return result;
263     }
264 
265 
266 }
267