Update ooo320-m1
[ooovba.git] / qadevOOo / runner / lib / MultiPropertyTest.java
blob234a7ca04f23b2170a7375f1b388c7b926a3fb0e
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: MultiPropertyTest.java,v $
10 * $Revision: 1.7 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
30 package lib;
32 import com.sun.star.beans.Property;
33 import com.sun.star.beans.PropertyAttribute;
34 import com.sun.star.beans.PropertyVetoException;
35 import com.sun.star.beans.XPropertySet;
36 import com.sun.star.beans.XPropertySetInfo;
37 import com.sun.star.beans.UnknownPropertyException;
38 import com.sun.star.lang.XServiceInfo;
39 import com.sun.star.lang.IllegalArgumentException;
40 import com.sun.star.lang.WrappedTargetException;
41 import com.sun.star.uno.UnoRuntime;
43 import java.lang.reflect.Method;
45 import util.ValueChanger;
46 import util.ValueComparer;
48 import com.sun.star.uno.Any;
49 import com.sun.star.uno.AnyConverter;
50 import com.sun.star.uno.Type;
52 /**
53 * MultiPropertyTest extends the functionality of MultiMethodTest to support
54 * services testing. Since, in most cases, service tests has one method testing
55 * most of its properties, the MultiPropertyTest provides unified version of
56 * the method: testProperty().
58 * <p>The testProperty() is called, when the MultiMethodTest's testing method
59 * is not found in the subclass. So, by defining such methods for properties
60 * the standard testing behavioutr can be changed.
62 * <p>The testing behaviour also can be changed by overriding compare(),
63 * getNewVAlue() or toString(Object) methods, or by extending PropertyTester
64 * class.
66 * @see MultiMethodTest
67 * @see #testProperty(String)
68 * @see #testProperty(String, Propertytester)
69 * @see #getNewValue
70 * @see #compare
71 * @see #toString(Object)
73 public class MultiPropertyTest extends MultiMethodTest
76 /**
77 * Contains a XPropertySet interface of the tested object. Is initialized
78 * in MultiMethodTest code.
80 public XPropertySet oObj;
81 protected boolean optionalService = false;
83 /**
84 * Overrides super.before() to check the service is supported by the object.
86 protected void before()
88 XServiceInfo xInfo = (XServiceInfo) UnoRuntime.queryInterface(
89 XServiceInfo.class, oObj);
91 optionalService = entry.isOptional;
93 String theService = getTestedClassName();
94 if (xInfo != null && !xInfo.supportsService(theService))
96 log.println("Service " + theService + " not available");
97 if (optionalService)
99 log.println("This is OK since it is optional");
101 else
103 Status.failed(theService + " is not supported");
109 * Overrides MultiMethodTest.invokeTestMethod(). If the test for the
110 * <code>meth</code> is not available (<code>meth</code> == <tt>null</tt>)
111 * calls testProperty method for the method. Otherwise calls
112 * super.invokeTestMethod().
114 * @see #MultiMethodTest.invokeTestMethod()
116 protected void invokeTestMethod(Method meth, String methName)
118 if (meth != null)
120 super.invokeTestMethod(meth, methName);
122 else
124 testProperty(methName);
129 * PropertyTester class defines how to test a property and defined
130 * to allow subclasses of MultiPropertyTest to change the testing
131 * behaviour more flexible, since the behaviour can be customized for
132 * each property separately, by providing subclass of PropertyTester
133 * and passing it to testProperty(String, PropertyTester method).
135 public class PropertyTester
139 * The method defines the whole process of testing propName
140 * property.
142 * <p>First, it checks if the property exists(it maybe optional).
143 * Then, a value to set the property with is calculated with
144 * getNewValue method. Normally, the new value is calculated
145 * based on old value, but subclasses can override the behaviour
146 * (for example, if old value is null) and specify their own value.
147 * Then the property is set with that new value and the result(
148 * it maybe an exception too, for example a PropertyVetoException)
149 * is checked with checkResult method.
151 * @param propName - the property to test.
152 * @result - adds the result of testing propName property to
153 * MultiMethodTest.tRes.
155 protected void testProperty(String propName)
157 XPropertySetInfo info = oObj.getPropertySetInfo();
159 if (info != null)
161 if (!info.hasPropertyByName(propName))
163 if (isOptional(propName) || optionalService)
165 // skipping optional property test
166 log.println("Property '" + propName + "' is optional and not supported");
167 tRes.tested(propName, true);
168 return;
170 else
172 // cannot test the property
173 log.println("Tested XPropertySet does not contain'" + propName + "' property");
174 tRes.tested(propName, false);
175 return;
182 Object oldValue = oObj.getPropertyValue(propName);
184 Object newValue;
186 // trying to create new value
189 newValue = getNewValue(propName, oldValue);
191 catch (java.lang.IllegalArgumentException e)
193 // skipping test since new value is not available
194 Status.failed("Cannot create new value for '" + propName + " : " + e.getMessage());
195 return;
198 // for an exception thrown during setting new value
199 // to pass it to checkResult method
200 Exception exception = null;
204 log.println("try to set:");
205 log.println("old = " + toString(oldValue));
206 log.println("new = " + toString(newValue));
207 oObj.setPropertyValue(propName, newValue);
209 catch (IllegalArgumentException e)
211 exception = e;
213 catch (PropertyVetoException e)
215 exception = e;
217 catch (WrappedTargetException e)
219 exception = e;
221 catch (UnknownPropertyException e)
223 exception = e;
225 catch (RuntimeException e)
227 exception = e;
230 // getting result value
231 Object resValue = oObj.getPropertyValue(propName);
233 // checking results
234 checkResult(propName, oldValue, newValue, resValue, exception);
236 catch (Exception e)
238 log.println("Exception occured while testing property '" + propName + "'");
239 e.printStackTrace(log);
240 tRes.tested(propName, false);
245 * The method checks result of setting a new value to the
246 * property based o the following arguments:
247 * @propName - the property to test
248 * @oldValue - the old value of the property, before changing it.
249 * @newValue - the new value the property has been set with
250 * @resValue - the value of the property after having changed it
251 * @exception - if not null - the exception thrown by
252 * XPropertySet.setPropertyValue, else indicates
253 * normal method completion.
255 * <p>If the property is READ_ONLY, than either PropertyVetoException
256 * should be thrown or the value of property should not have changed
257 * (resValue is compared with oldValue with compare method).
259 * <p>If the property is not READ_ONLY, checks that the new value has
260 * been successfully set(resValue is compared with newValue with
261 * compare method).
263 * <p>If the exception is not null then(except the case of read-only
264 * property and PropertyVetoException above) it is rethrown to allow
265 * further catching it if needed.
267 * <p>Subclasses can override to change this behaviour.
269 protected void checkResult(String propName, Object oldValue,
270 Object newValue, Object resValue, Exception exception)
271 throws Exception
273 XPropertySetInfo info = oObj.getPropertySetInfo();
274 if (info == null)
276 log.println("Can't get XPropertySetInfo for property " + propName);
277 tRes.tested(propName, false);
278 return;
280 Property prop = info.getPropertyByName(propName);
282 short attr = prop.Attributes;
283 boolean readOnly = (prop.Attributes & PropertyAttribute.READONLY) != 0;
284 boolean maybeVoid = (prop.Attributes & PropertyAttribute.MAYBEVOID) != 0;
285 //check get-set methods
286 if (maybeVoid)
288 log.println("Property " + propName + " is void");
290 if (readOnly)
292 log.println("Property " + propName + " is readOnly");
294 if (util.utils.isVoid(oldValue) && !maybeVoid)
296 log.println(propName + " is void, but it's not MAYBEVOID");
297 tRes.tested(propName, false);
299 else if (oldValue == null)
301 log.println(propName + " has null value, and therefore can't be changed");
302 tRes.tested(propName, true);
304 else if (readOnly)
306 // check if exception was thrown
307 if (exception != null)
309 if (exception instanceof PropertyVetoException)
311 // the change of read only prohibited - OK
312 log.println("Property is ReadOnly and wasn't changed");
313 log.println("Property '" + propName + "' OK");
314 tRes.tested(propName, true);
316 else if (exception instanceof IllegalArgumentException)
318 // the change of read only prohibited - OK
319 log.println("Property is ReadOnly and wasn't changed");
320 log.println("Property '" + propName + "' OK");
321 tRes.tested(propName, true);
323 else if (exception instanceof UnknownPropertyException)
325 // the change of read only prohibited - OK
326 log.println("Property is ReadOnly and wasn't changed");
327 log.println("Property '" + propName + "' OK");
328 tRes.tested(propName, true);
330 else if (exception instanceof RuntimeException)
332 // the change of read only prohibited - OK
333 log.println("Property is ReadOnly and wasn't changed");
334 log.println("Property '" + propName + "' OK");
335 tRes.tested(propName, true);
337 else
339 throw exception;
342 else
344 // if no exception - check that value
345 // has not changed
346 if (!compare(resValue, oldValue))
348 log.println("Read only property '" + propName + "' has changed");
351 if (!util.utils.isVoid(oldValue) && oldValue instanceof Any)
353 oldValue = AnyConverter.toObject(new Type(((Any) oldValue).getClass()), oldValue);
355 // log.println("old = " + toString(oldValue));
356 // log.println("new = " + toString(newValue));
357 log.println("result = " + toString(resValue));
359 catch (com.sun.star.lang.IllegalArgumentException iae)
361 log.println("NOTIFY: this property needs further investigations.");
362 log.println("\t The type seems to be an Any with value of NULL.");
363 log.println("\t Maybe the property should get it's own test method.");
366 tRes.tested(propName, false);
368 else
370 log.println("Read only property '" + propName + "' hasn't changed");
371 log.println("Property '" + propName + "' OK");
372 tRes.tested(propName, true);
376 else
378 if (exception == null)
380 // if no exception thrown
381 // check that the new value is set
382 if ((!compare(resValue, newValue)) || (compare(resValue, oldValue)))
384 log.println("Value for '" + propName + "' hasn't changed as expected");
387 if (!util.utils.isVoid(oldValue) && oldValue instanceof Any)
389 oldValue = AnyConverter.toObject(new Type(((Any) oldValue).getClass()), oldValue);
391 // log.println("old = " + toString(oldValue));
392 // log.println("new = " + toString(newValue));
393 log.println("result = " + toString(resValue));
395 catch (com.sun.star.lang.IllegalArgumentException iae)
397 log.println("NOTIFY: this property needs further investigations.");
398 log.println("\t The type seems to be an Any with value of NULL.");
399 log.println("\t Maybe the property should get it's own test method.");
401 if (resValue != null)
403 if ((!compare(resValue, oldValue)) || (!resValue.equals(oldValue)))
405 log.println("But it has changed.");
406 tRes.tested(propName, true);
408 else
410 tRes.tested(propName, false);
413 else
415 tRes.tested(propName, false);
417 //tRes.tested(propName, false);
419 else
421 log.println("Property '" + propName + "' OK");
424 if (!util.utils.isVoid(oldValue) && oldValue instanceof Any)
426 oldValue = AnyConverter.toObject(new Type(((Any) oldValue).getClass()), oldValue);
428 // log.println("old = " + toString(oldValue));
429 // log.println("new = " + toString(newValue));
430 log.println("result = " + toString(resValue));
432 catch (com.sun.star.lang.IllegalArgumentException iae)
435 tRes.tested(propName, true);
438 else
440 throw exception;
446 * The method produces new value of the property from the oldValue.
447 * It returns the result of ValueChanger.changePValue method.
448 * Subclasses can override the method to return their own value,
449 * when the changePValue beahviour is not enough, for example,
450 * when oldValue is null.
452 protected Object getNewValue(String propName, Object oldValue)
453 throws java.lang.IllegalArgumentException
455 return ValueChanger.changePValue(oldValue);
459 * The method compares obj1 and obj2. It calls
460 * MultiPropertyTest.compare, but subclasses can override to change
461 * the behaviour, since normally compare calls Object.equals method
462 * which is not apropriate in some cases(e.g., structs with equals
463 * not overridden).
465 protected boolean compare(Object obj1, Object obj2)
467 return callCompare(obj1, obj2);
471 * The method returns a String representation of the obj. It calls
472 * MultipropertyTest.toString(Object), but subclasses can override
473 * to change the behaviour.
475 protected String toString(Object obj)
477 return callToString(obj);
482 * Extension for <code>PropertyTester</code> which switches two
483 * different values. <code>getNewValue()</code> method of this
484 * class returns one of these two values depending on the
485 * old value, so new value is not equal to old value.
487 public class PropertyValueSwitcher extends PropertyTester
490 Object val1 = null;
491 Object val2 = null;
494 * Constructs a property tester with two different values
495 * specified as parameters.
497 * @param val1 Not <code>null</code> value for the property
498 * tested.
499 * @param val1 Not <code>null</code> value for the property
500 * tested which differs from the first value.
502 public PropertyValueSwitcher(Object val1, Object val2)
504 this.val1 = val1;
505 this.val2 = val2;
509 * Overriden method of <code>PropertyTester</code> which
510 * retruns new value from two values specified.
512 * @return The second value if old value is equal to the first
513 * one, the first value otherwise.
515 protected Object getNewValue(String propName, Object old)
517 if (ValueComparer.equalValue(val1, old))
519 return val2;
521 else
523 return val1;
529 * The method performs testing of propName property using propTester.
531 protected void testProperty(String propName, PropertyTester propTester)
533 propTester.testProperty(propName);
537 * The method performs testing of propName property. It uses PropertyTester
538 * instance for testing.
540 protected void testProperty(String propName)
542 testProperty(propName, new PropertyTester());
546 * Tests the property using <code>PropertyValueSwitcher</code>
547 * tester and two values for this property.
549 * @see #PropertyValueSwitcher
551 protected void testProperty(String propName, Object val1, Object val2)
553 testProperty(propName, new PropertyValueSwitcher(val1, val2));
557 * The method just calls compare. This is a workaround to CodeWarrior's
558 * compiler bug.
560 private boolean callCompare(Object obj1, Object obj2)
562 return compare(obj1, obj2);
566 * Compares two object. In the implementation calls obj1.equals(obj2).
568 protected boolean compare(Object obj1, Object obj2)
570 return ValueComparer.equalValue(obj1, obj2);
574 * The method just calls toString. This is a workaround to
575 * CodeWarrior's compiler bug.
577 private String callToString(Object obj)
579 return toString(obj);
583 * Gets string representation of the obj. In the implementation
584 * returns obj.toString().
586 protected String toString(Object obj)
588 return obj == null ? "null" : obj.toString();