1*ef39d40dSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*ef39d40dSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*ef39d40dSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*ef39d40dSAndrew Rist  * distributed with this work for additional information
6*ef39d40dSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*ef39d40dSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*ef39d40dSAndrew Rist  * "License"); you may not use this file except in compliance
9*ef39d40dSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*ef39d40dSAndrew Rist  *
11*ef39d40dSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*ef39d40dSAndrew Rist  *
13*ef39d40dSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*ef39d40dSAndrew Rist  * software distributed under the License is distributed on an
15*ef39d40dSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*ef39d40dSAndrew Rist  * KIND, either express or implied.  See the License for the
17*ef39d40dSAndrew Rist  * specific language governing permissions and limitations
18*ef39d40dSAndrew Rist  * under the License.
19*ef39d40dSAndrew Rist  *
20*ef39d40dSAndrew Rist  *************************************************************/
21*ef39d40dSAndrew Rist 
22*ef39d40dSAndrew Rist 
23cdf0e10cSrcweir package lib;
24cdf0e10cSrcweir 
25cdf0e10cSrcweir import com.sun.star.beans.Property;
26cdf0e10cSrcweir import com.sun.star.beans.PropertyAttribute;
27cdf0e10cSrcweir import com.sun.star.beans.PropertyVetoException;
28cdf0e10cSrcweir import com.sun.star.beans.XPropertySet;
29cdf0e10cSrcweir import com.sun.star.beans.XPropertySetInfo;
30cdf0e10cSrcweir import com.sun.star.beans.UnknownPropertyException;
31cdf0e10cSrcweir import com.sun.star.lang.XServiceInfo;
32cdf0e10cSrcweir import com.sun.star.lang.IllegalArgumentException;
33cdf0e10cSrcweir import com.sun.star.lang.WrappedTargetException;
34cdf0e10cSrcweir import com.sun.star.uno.UnoRuntime;
35cdf0e10cSrcweir 
36cdf0e10cSrcweir import java.lang.reflect.Method;
37cdf0e10cSrcweir 
38cdf0e10cSrcweir import util.ValueChanger;
39cdf0e10cSrcweir import util.ValueComparer;
40cdf0e10cSrcweir import util.utils;
41cdf0e10cSrcweir 
42cdf0e10cSrcweir import com.sun.star.uno.Any;
43cdf0e10cSrcweir import com.sun.star.uno.AnyConverter;
44cdf0e10cSrcweir import com.sun.star.uno.Type;
45cdf0e10cSrcweir 
46cdf0e10cSrcweir /**
47cdf0e10cSrcweir  * MultiPropertyTest extends the functionality of MultiMethodTest to support
48cdf0e10cSrcweir  * services testing. Since, in most cases, service tests has one method testing
49cdf0e10cSrcweir  * most of its properties, the MultiPropertyTest provides unified version of
50cdf0e10cSrcweir  * the method: testProperty().
51cdf0e10cSrcweir  *
52cdf0e10cSrcweir  * <p>The testProperty() is called, when the MultiMethodTest's testing method
53cdf0e10cSrcweir  * is not found in the subclass. So, by defining such methods for properties
54cdf0e10cSrcweir  * the standard testing behavioutr can be changed.
55cdf0e10cSrcweir  *
56cdf0e10cSrcweir  * <p>The testing behaviour also can be changed by overriding compare(),
57cdf0e10cSrcweir  * getNewVAlue() or toString(Object) methods, or by extending PropertyTester
58cdf0e10cSrcweir  * class.
59cdf0e10cSrcweir  *
60cdf0e10cSrcweir  * @see MultiMethodTest
61cdf0e10cSrcweir  * @see #testProperty(String)
62cdf0e10cSrcweir  * @see #testProperty(String, Propertytester)
63cdf0e10cSrcweir  * @see #getNewValue
64cdf0e10cSrcweir  * @see #compare
65cdf0e10cSrcweir  * @see #toString(Object)
66cdf0e10cSrcweir  */
67cdf0e10cSrcweir public class MultiPropertyTest extends MultiMethodTest
68cdf0e10cSrcweir {
69cdf0e10cSrcweir 
70cdf0e10cSrcweir     /**
71cdf0e10cSrcweir      * Contains a XPropertySet interface of the tested object. Is initialized
72cdf0e10cSrcweir      * in MultiMethodTest code.
73cdf0e10cSrcweir      */
74cdf0e10cSrcweir     public XPropertySet oObj;
75cdf0e10cSrcweir     protected boolean optionalService = false;
76cdf0e10cSrcweir 
77cdf0e10cSrcweir     /**
78cdf0e10cSrcweir      * Overrides super.before() to check the service is supported by the object.
79cdf0e10cSrcweir      */
80cdf0e10cSrcweir     protected void before()
81cdf0e10cSrcweir     {
82cdf0e10cSrcweir         XServiceInfo xInfo = (XServiceInfo) UnoRuntime.queryInterface(
83cdf0e10cSrcweir                 XServiceInfo.class, oObj);
84cdf0e10cSrcweir 
85cdf0e10cSrcweir         optionalService = entry.isOptional;
86cdf0e10cSrcweir 
87cdf0e10cSrcweir         String theService = getTestedClassName();
88cdf0e10cSrcweir         if (xInfo != null && !xInfo.supportsService(theService))
89cdf0e10cSrcweir         {
90cdf0e10cSrcweir             log.println("Service " + theService + " not available");
91cdf0e10cSrcweir             if (optionalService)
92cdf0e10cSrcweir             {
93cdf0e10cSrcweir                 log.println("This is OK since it is optional");
94cdf0e10cSrcweir             }
95cdf0e10cSrcweir             else
96cdf0e10cSrcweir             {
97cdf0e10cSrcweir                 Status.failed(theService + " is not supported");
98cdf0e10cSrcweir             }
99cdf0e10cSrcweir         }
100cdf0e10cSrcweir     }
101cdf0e10cSrcweir 
102cdf0e10cSrcweir     /**
103cdf0e10cSrcweir      * Overrides MultiMethodTest.invokeTestMethod(). If the test for the
104cdf0e10cSrcweir      * <code>meth</code> is not available (<code>meth</code> == <tt>null</tt>)
105cdf0e10cSrcweir      * calls testProperty method for the method. Otherwise calls
106cdf0e10cSrcweir      * super.invokeTestMethod().
107cdf0e10cSrcweir      *
108cdf0e10cSrcweir      * @see #MultiMethodTest.invokeTestMethod()
109cdf0e10cSrcweir      */
110cdf0e10cSrcweir     protected void invokeTestMethod(Method meth, String methName)
111cdf0e10cSrcweir     {
112cdf0e10cSrcweir         if (meth != null)
113cdf0e10cSrcweir         {
114cdf0e10cSrcweir             super.invokeTestMethod(meth, methName);
115cdf0e10cSrcweir         }
116cdf0e10cSrcweir         else
117cdf0e10cSrcweir         {
118cdf0e10cSrcweir             testProperty(methName);
119cdf0e10cSrcweir         }
120cdf0e10cSrcweir     }
121cdf0e10cSrcweir 
122cdf0e10cSrcweir     /**
123cdf0e10cSrcweir      * PropertyTester class defines how to test a property and defined
124cdf0e10cSrcweir      * to allow subclasses of MultiPropertyTest to change the testing
125cdf0e10cSrcweir      * behaviour more flexible, since the behaviour can be customized for
126cdf0e10cSrcweir      * each property separately, by providing subclass of PropertyTester
127cdf0e10cSrcweir      * and passing it to testProperty(String, PropertyTester method).
128cdf0e10cSrcweir      */
129cdf0e10cSrcweir     public class PropertyTester
130cdf0e10cSrcweir     {
131cdf0e10cSrcweir 
132cdf0e10cSrcweir         /**
133cdf0e10cSrcweir          * The method defines the whole process of testing propName
134cdf0e10cSrcweir          * property.
135cdf0e10cSrcweir          *
136cdf0e10cSrcweir          * <p>First, it checks if the property exists(it maybe optional).
137cdf0e10cSrcweir          * Then, a value to set the property with is calculated with
138cdf0e10cSrcweir          * getNewValue method. Normally, the new value is calculated
139cdf0e10cSrcweir          * based on old value, but subclasses can override the behaviour
140cdf0e10cSrcweir          * (for example, if old value is null) and specify their own value.
141cdf0e10cSrcweir          * Then the property is set with that new value and the result(
142cdf0e10cSrcweir          * it maybe an exception too, for example a PropertyVetoException)
143cdf0e10cSrcweir          * is checked with checkResult method.
144cdf0e10cSrcweir          *
145cdf0e10cSrcweir          * @param propName - the property to test.
146cdf0e10cSrcweir          * @result - adds the result of testing propName property to
147cdf0e10cSrcweir          *           MultiMethodTest.tRes.
148cdf0e10cSrcweir          */
149cdf0e10cSrcweir         protected void testProperty(String propName)
150cdf0e10cSrcweir         {
151cdf0e10cSrcweir             XPropertySetInfo info = oObj.getPropertySetInfo();
152cdf0e10cSrcweir 
153cdf0e10cSrcweir             if (info != null)
154cdf0e10cSrcweir             {
155cdf0e10cSrcweir                 final boolean bHasProperty = info.hasPropertyByName(propName);
156cdf0e10cSrcweir                 if (!bHasProperty)
157cdf0e10cSrcweir                 {
158cdf0e10cSrcweir                     if (isOptional(propName) || optionalService)
159cdf0e10cSrcweir                     {
160cdf0e10cSrcweir                         // skipping optional property test
161cdf0e10cSrcweir                         log.println("Property '" + propName + "' is optional and not supported");
162cdf0e10cSrcweir                         tRes.tested(propName, true);
163cdf0e10cSrcweir                         return;
164cdf0e10cSrcweir                     }
165cdf0e10cSrcweir                     else
166cdf0e10cSrcweir                     {
167cdf0e10cSrcweir                         // cannot test the property
168cdf0e10cSrcweir                         log.println("Tested XPropertySet does not contain'" + propName + "' property");
169cdf0e10cSrcweir                         tRes.tested(propName, false);
170cdf0e10cSrcweir                         return;
171cdf0e10cSrcweir                     }
172cdf0e10cSrcweir                 }
173cdf0e10cSrcweir             }
174cdf0e10cSrcweir 
175cdf0e10cSrcweir             try
176cdf0e10cSrcweir             {
177cdf0e10cSrcweir                 Object oldValue = oObj.getPropertyValue(propName);
178cdf0e10cSrcweir 
179cdf0e10cSrcweir                 if( (oldValue==null) || utils.isVoid(oldValue) )
180cdf0e10cSrcweir                 {
181cdf0e10cSrcweir                     // #i111560# method getNewValue() does not work with an empty oldValue
182cdf0e10cSrcweir                     Property prop = info.getPropertyByName(propName);
183cdf0e10cSrcweir                     if( (prop.Attributes & PropertyAttribute.MAYBEVOID) != 0 )
184cdf0e10cSrcweir                     {
185cdf0e10cSrcweir                         // todo: implement a new test independent from method getNewValue()
186cdf0e10cSrcweir                         log.println("changing initially empty MAYBEVOID properties is not supported by the test framework so far - skip test of property: " + propName);
187cdf0e10cSrcweir                         tRes.tested(propName, true);
188cdf0e10cSrcweir                         return;
189cdf0e10cSrcweir                     }
190cdf0e10cSrcweir                     else
191cdf0e10cSrcweir                     {
192cdf0e10cSrcweir                         log.println( "property '"+propName+"' is not set but is not MAYBEVOID");
193cdf0e10cSrcweir                         tRes.tested(propName, false);
194cdf0e10cSrcweir                         return;
195cdf0e10cSrcweir                     }
196cdf0e10cSrcweir                 }
197cdf0e10cSrcweir 
198cdf0e10cSrcweir                 Object newValue;
199cdf0e10cSrcweir 
200cdf0e10cSrcweir                 // trying to create new value
201cdf0e10cSrcweir                 try
202cdf0e10cSrcweir                 {
203cdf0e10cSrcweir                     newValue = getNewValue(propName, oldValue);
204cdf0e10cSrcweir                 }
205cdf0e10cSrcweir                 catch (java.lang.IllegalArgumentException e)
206cdf0e10cSrcweir                 {
207cdf0e10cSrcweir                     // skipping test since new value is not available
208cdf0e10cSrcweir                     Status.failed("Cannot create new value for '" + propName + " : " + e.getMessage());
209cdf0e10cSrcweir                     return;
210cdf0e10cSrcweir                 }
211cdf0e10cSrcweir 
212cdf0e10cSrcweir                 // for an exception thrown during setting new value
213cdf0e10cSrcweir                 // to pass it to checkResult method
214cdf0e10cSrcweir                 Exception exception = null;
215cdf0e10cSrcweir 
216cdf0e10cSrcweir                 try
217cdf0e10cSrcweir                 {
218cdf0e10cSrcweir                     log.println("try to set:");
219cdf0e10cSrcweir                     log.println("old = " + toString(oldValue));
220cdf0e10cSrcweir                     log.println("new = " + toString(newValue));
221cdf0e10cSrcweir                     oObj.setPropertyValue(propName, newValue);
222cdf0e10cSrcweir                 }
223cdf0e10cSrcweir                 catch (IllegalArgumentException e)
224cdf0e10cSrcweir                 {
225cdf0e10cSrcweir                     exception = e;
226cdf0e10cSrcweir                 }
227cdf0e10cSrcweir                 catch (PropertyVetoException e)
228cdf0e10cSrcweir                 {
229cdf0e10cSrcweir                     exception = e;
230cdf0e10cSrcweir                 }
231cdf0e10cSrcweir                 catch (WrappedTargetException e)
232cdf0e10cSrcweir                 {
233cdf0e10cSrcweir                     exception = e;
234cdf0e10cSrcweir                 }
235cdf0e10cSrcweir                 catch (UnknownPropertyException e)
236cdf0e10cSrcweir                 {
237cdf0e10cSrcweir                     exception = e;
238cdf0e10cSrcweir                 }
239cdf0e10cSrcweir                 catch (RuntimeException e)
240cdf0e10cSrcweir                 {
241cdf0e10cSrcweir                     exception = e;
242cdf0e10cSrcweir                 }
243cdf0e10cSrcweir 
244cdf0e10cSrcweir                 // getting result value
245cdf0e10cSrcweir                 Object resValue = oObj.getPropertyValue(propName);
246cdf0e10cSrcweir 
247cdf0e10cSrcweir                 // checking results
248cdf0e10cSrcweir                 checkResult(propName, oldValue, newValue, resValue, exception);
249cdf0e10cSrcweir             }
250cdf0e10cSrcweir             catch (Exception e)
251cdf0e10cSrcweir             {
252cdf0e10cSrcweir                 log.println("Exception occured while testing property '" + propName + "'");
253cdf0e10cSrcweir                 e.printStackTrace(log);
254cdf0e10cSrcweir                 tRes.tested(propName, false);
255cdf0e10cSrcweir             }
256cdf0e10cSrcweir         }
257cdf0e10cSrcweir 
258cdf0e10cSrcweir         /**
259cdf0e10cSrcweir          * The method checks result of setting a new value to the
260cdf0e10cSrcweir          * property based o the following arguments:
261cdf0e10cSrcweir          *   @propName - the property to test
262cdf0e10cSrcweir          *   @oldValue - the old value of the property, before changing it.
263cdf0e10cSrcweir          *   @newValue - the new value the property has been set with
264cdf0e10cSrcweir          *   @resValue - the value of the property after having changed it
265cdf0e10cSrcweir          *   @exception - if not null - the exception thrown by
266cdf0e10cSrcweir          *                 XPropertySet.setPropertyValue, else indicates
267cdf0e10cSrcweir          *                 normal method completion.
268cdf0e10cSrcweir          *
269cdf0e10cSrcweir          * <p>If the property is READ_ONLY, than either PropertyVetoException
270cdf0e10cSrcweir          * should be thrown or the value of property should not have changed
271cdf0e10cSrcweir          * (resValue is compared with oldValue with compare method).
272cdf0e10cSrcweir          *
273cdf0e10cSrcweir          * <p>If the property is not READ_ONLY, checks that the new value has
274cdf0e10cSrcweir          * been successfully set(resValue is compared with newValue with
275cdf0e10cSrcweir          * compare method).
276cdf0e10cSrcweir          *
277cdf0e10cSrcweir          * <p>If the exception is not null then(except the case of read-only
278cdf0e10cSrcweir          * property and PropertyVetoException above) it is rethrown to allow
279cdf0e10cSrcweir          * further catching it if needed.
280cdf0e10cSrcweir          *
281cdf0e10cSrcweir          * <p>Subclasses can override to change this behaviour.
282cdf0e10cSrcweir          */
283cdf0e10cSrcweir         protected void checkResult(String propName, Object oldValue,
284cdf0e10cSrcweir                 Object newValue, Object resValue, Exception exception)
285cdf0e10cSrcweir                 throws Exception
286cdf0e10cSrcweir         {
287cdf0e10cSrcweir             XPropertySetInfo info = oObj.getPropertySetInfo();
288cdf0e10cSrcweir             if (info == null)
289cdf0e10cSrcweir             {
290cdf0e10cSrcweir                 log.println("Can't get XPropertySetInfo for property " + propName);
291cdf0e10cSrcweir                 tRes.tested(propName, false);
292cdf0e10cSrcweir                 return;
293cdf0e10cSrcweir             }
294cdf0e10cSrcweir             Property prop = info.getPropertyByName(propName);
295cdf0e10cSrcweir 
296cdf0e10cSrcweir             short attr = prop.Attributes;
297cdf0e10cSrcweir             boolean readOnly = (prop.Attributes & PropertyAttribute.READONLY) != 0;
298cdf0e10cSrcweir             boolean maybeVoid = (prop.Attributes & PropertyAttribute.MAYBEVOID) != 0;
299cdf0e10cSrcweir             //check get-set methods
300cdf0e10cSrcweir             if (maybeVoid)
301cdf0e10cSrcweir             {
302cdf0e10cSrcweir                 log.println("Property " + propName + " is void");
303cdf0e10cSrcweir             }
304cdf0e10cSrcweir             if (readOnly)
305cdf0e10cSrcweir             {
306cdf0e10cSrcweir                 log.println("Property " + propName + " is readOnly");
307cdf0e10cSrcweir             }
308cdf0e10cSrcweir             if (util.utils.isVoid(oldValue) && !maybeVoid)
309cdf0e10cSrcweir             {
310cdf0e10cSrcweir                 log.println(propName + " is void, but it's not MAYBEVOID");
311cdf0e10cSrcweir                 tRes.tested(propName, false);
312cdf0e10cSrcweir             }
313cdf0e10cSrcweir             else if (oldValue == null)
314cdf0e10cSrcweir             {
315cdf0e10cSrcweir                 log.println(propName + " has null value, and therefore can't be changed");
316cdf0e10cSrcweir                 tRes.tested(propName, true);
317cdf0e10cSrcweir             }
318cdf0e10cSrcweir             else if (readOnly)
319cdf0e10cSrcweir             {
320cdf0e10cSrcweir                 // check if exception was thrown
321cdf0e10cSrcweir                 if (exception != null)
322cdf0e10cSrcweir                 {
323cdf0e10cSrcweir                     if (exception instanceof PropertyVetoException)
324cdf0e10cSrcweir                     {
325cdf0e10cSrcweir                         // the change of read only prohibited - OK
326cdf0e10cSrcweir                         log.println("Property is ReadOnly and wasn't changed");
327cdf0e10cSrcweir                         log.println("Property '" + propName + "' OK");
328cdf0e10cSrcweir                         tRes.tested(propName, true);
329cdf0e10cSrcweir                     }
330cdf0e10cSrcweir                     else if (exception instanceof IllegalArgumentException)
331cdf0e10cSrcweir                     {
332cdf0e10cSrcweir                         // the change of read only prohibited - OK
333cdf0e10cSrcweir                         log.println("Property is ReadOnly and wasn't changed");
334cdf0e10cSrcweir                         log.println("Property '" + propName + "' OK");
335cdf0e10cSrcweir                         tRes.tested(propName, true);
336cdf0e10cSrcweir                     }
337cdf0e10cSrcweir                     else if (exception instanceof UnknownPropertyException)
338cdf0e10cSrcweir                     {
339cdf0e10cSrcweir                         // the change of read only prohibited - OK
340cdf0e10cSrcweir                         log.println("Property is ReadOnly and wasn't changed");
341cdf0e10cSrcweir                         log.println("Property '" + propName + "' OK");
342cdf0e10cSrcweir                         tRes.tested(propName, true);
343cdf0e10cSrcweir                     }
344cdf0e10cSrcweir                     else if (exception instanceof RuntimeException)
345cdf0e10cSrcweir                     {
346cdf0e10cSrcweir                         // the change of read only prohibited - OK
347cdf0e10cSrcweir                         log.println("Property is ReadOnly and wasn't changed");
348cdf0e10cSrcweir                         log.println("Property '" + propName + "' OK");
349cdf0e10cSrcweir                         tRes.tested(propName, true);
350cdf0e10cSrcweir                     }
351cdf0e10cSrcweir                     else
352cdf0e10cSrcweir                     {
353cdf0e10cSrcweir                         throw exception;
354cdf0e10cSrcweir                     }
355cdf0e10cSrcweir                 }
356cdf0e10cSrcweir                 else
357cdf0e10cSrcweir                 {
358cdf0e10cSrcweir                     // if no exception - check that value
359cdf0e10cSrcweir                     // has not changed
360cdf0e10cSrcweir                     if (!compare(resValue, oldValue))
361cdf0e10cSrcweir                     {
362cdf0e10cSrcweir                         log.println("Read only property '" + propName + "' has changed");
363cdf0e10cSrcweir                         try
364cdf0e10cSrcweir                         {
365cdf0e10cSrcweir                             if (!util.utils.isVoid(oldValue) && oldValue instanceof Any)
366cdf0e10cSrcweir                             {
367cdf0e10cSrcweir                                 oldValue = AnyConverter.toObject(new Type(((Any) oldValue).getClass()), oldValue);
368cdf0e10cSrcweir                             }
369cdf0e10cSrcweir //                            log.println("old = " + toString(oldValue));
370cdf0e10cSrcweir //                            log.println("new = " + toString(newValue));
371cdf0e10cSrcweir                             log.println("result = " + toString(resValue));
372cdf0e10cSrcweir                         }
373cdf0e10cSrcweir                         catch (com.sun.star.lang.IllegalArgumentException iae)
374cdf0e10cSrcweir                         {
375cdf0e10cSrcweir                             log.println("NOTIFY: this property needs further investigations.");
376cdf0e10cSrcweir                             log.println("\t The type seems to be an Any with value of NULL.");
377cdf0e10cSrcweir                             log.println("\t Maybe the property should get it's own test method.");
378cdf0e10cSrcweir                         }
379cdf0e10cSrcweir 
380cdf0e10cSrcweir                         tRes.tested(propName, false);
381cdf0e10cSrcweir                     }
382cdf0e10cSrcweir                     else
383cdf0e10cSrcweir                     {
384cdf0e10cSrcweir                         log.println("Read only property '" + propName + "' hasn't changed");
385cdf0e10cSrcweir                         log.println("Property '" + propName + "' OK");
386cdf0e10cSrcweir                         tRes.tested(propName, true);
387cdf0e10cSrcweir                     }
388cdf0e10cSrcweir                 }
389cdf0e10cSrcweir             }
390cdf0e10cSrcweir             else
391cdf0e10cSrcweir             {
392cdf0e10cSrcweir                 if (exception == null)
393cdf0e10cSrcweir                 {
394cdf0e10cSrcweir                     // if no exception thrown
395cdf0e10cSrcweir                     // check that the new value is set
396cdf0e10cSrcweir                     if ((!compare(resValue, newValue)) || (compare(resValue, oldValue)))
397cdf0e10cSrcweir                     {
398cdf0e10cSrcweir                         log.println("Value for '" + propName + "' hasn't changed as expected");
399cdf0e10cSrcweir                         try
400cdf0e10cSrcweir                         {
401cdf0e10cSrcweir                             if (!util.utils.isVoid(oldValue) && oldValue instanceof Any)
402cdf0e10cSrcweir                             {
403cdf0e10cSrcweir                                 oldValue = AnyConverter.toObject(new Type(((Any) oldValue).getClass()), oldValue);
404cdf0e10cSrcweir                             }
405cdf0e10cSrcweir //                            log.println("old = " + toString(oldValue));
406cdf0e10cSrcweir //                            log.println("new = " + toString(newValue));
407cdf0e10cSrcweir                             log.println("result = " + toString(resValue));
408cdf0e10cSrcweir                         }
409cdf0e10cSrcweir                         catch (com.sun.star.lang.IllegalArgumentException iae)
410cdf0e10cSrcweir                         {
411cdf0e10cSrcweir                             log.println("NOTIFY: this property needs further investigations.");
412cdf0e10cSrcweir                             log.println("\t The type seems to be an Any with value of NULL.");
413cdf0e10cSrcweir                             log.println("\t Maybe the property should get it's own test method.");
414cdf0e10cSrcweir                         }
415cdf0e10cSrcweir                         if (resValue != null)
416cdf0e10cSrcweir                         {
417cdf0e10cSrcweir                             if ((!compare(resValue, oldValue)) || (!resValue.equals(oldValue)))
418cdf0e10cSrcweir                             {
419cdf0e10cSrcweir                                 log.println("But it has changed.");
420cdf0e10cSrcweir                                 tRes.tested(propName, true);
421cdf0e10cSrcweir                             }
422cdf0e10cSrcweir                             else
423cdf0e10cSrcweir                             {
424cdf0e10cSrcweir                                 tRes.tested(propName, false);
425cdf0e10cSrcweir                             }
426cdf0e10cSrcweir                         }
427cdf0e10cSrcweir                         else
428cdf0e10cSrcweir                         {
429cdf0e10cSrcweir                             tRes.tested(propName, false);
430cdf0e10cSrcweir                         }
431cdf0e10cSrcweir                         //tRes.tested(propName, false);
432cdf0e10cSrcweir                     }
433cdf0e10cSrcweir                     else
434cdf0e10cSrcweir                     {
435cdf0e10cSrcweir                         log.println("Property '" + propName + "' OK");
436cdf0e10cSrcweir                         try
437cdf0e10cSrcweir                         {
438cdf0e10cSrcweir                             if (!util.utils.isVoid(oldValue) && oldValue instanceof Any)
439cdf0e10cSrcweir                             {
440cdf0e10cSrcweir                                 oldValue = AnyConverter.toObject(new Type(((Any) oldValue).getClass()), oldValue);
441cdf0e10cSrcweir                             }
442cdf0e10cSrcweir //                            log.println("old = " + toString(oldValue));
443cdf0e10cSrcweir //                            log.println("new = " + toString(newValue));
444cdf0e10cSrcweir                             log.println("result = " + toString(resValue));
445cdf0e10cSrcweir                         }
446cdf0e10cSrcweir                         catch (com.sun.star.lang.IllegalArgumentException iae)
447cdf0e10cSrcweir                         {
448cdf0e10cSrcweir                         }
449cdf0e10cSrcweir                         tRes.tested(propName, true);
450cdf0e10cSrcweir                     }
451cdf0e10cSrcweir                 }
452cdf0e10cSrcweir                 else
453cdf0e10cSrcweir                 {
454cdf0e10cSrcweir                     throw exception;
455cdf0e10cSrcweir                 }
456cdf0e10cSrcweir             }
457cdf0e10cSrcweir         }
458cdf0e10cSrcweir 
459cdf0e10cSrcweir         /**
460cdf0e10cSrcweir          * The method produces new value of the property from the oldValue.
461cdf0e10cSrcweir          * It returns the result of ValueChanger.changePValue method.
462cdf0e10cSrcweir          * Subclasses can override the method to return their own value,
463cdf0e10cSrcweir          * when the changePValue beahviour is not enough, for example,
464cdf0e10cSrcweir          * when oldValue is null.
465cdf0e10cSrcweir          */
466cdf0e10cSrcweir         protected Object getNewValue(String propName, Object oldValue)
467cdf0e10cSrcweir                 throws java.lang.IllegalArgumentException
468cdf0e10cSrcweir         {
469cdf0e10cSrcweir             return ValueChanger.changePValue(oldValue);
470cdf0e10cSrcweir         }
471cdf0e10cSrcweir 
472cdf0e10cSrcweir         /**
473cdf0e10cSrcweir          * The method compares obj1 and obj2. It calls
474cdf0e10cSrcweir          * MultiPropertyTest.compare, but subclasses can override to change
475cdf0e10cSrcweir          * the behaviour, since normally compare calls Object.equals method
476cdf0e10cSrcweir          * which is not apropriate in some cases(e.g., structs with equals
477cdf0e10cSrcweir          * not overridden).
478cdf0e10cSrcweir          */
479cdf0e10cSrcweir         protected boolean compare(Object obj1, Object obj2)
480cdf0e10cSrcweir         {
481cdf0e10cSrcweir             return callCompare(obj1, obj2);
482cdf0e10cSrcweir         }
483cdf0e10cSrcweir 
484cdf0e10cSrcweir         /**
485cdf0e10cSrcweir          * The method returns a String representation of the obj. It calls
486cdf0e10cSrcweir          * MultipropertyTest.toString(Object), but subclasses can override
487cdf0e10cSrcweir          * to change the behaviour.
488cdf0e10cSrcweir          */
489cdf0e10cSrcweir         protected String toString(Object obj)
490cdf0e10cSrcweir         {
491cdf0e10cSrcweir             return callToString(obj);
492cdf0e10cSrcweir         }
493cdf0e10cSrcweir     }
494cdf0e10cSrcweir 
495cdf0e10cSrcweir     /**
496cdf0e10cSrcweir      * Extension for <code>PropertyTester</code> which switches two
497cdf0e10cSrcweir      * different values. <code>getNewValue()</code> method of this
498cdf0e10cSrcweir      * class returns one of these two values depending on the
499cdf0e10cSrcweir      * old value, so new value is not equal to old value.
500cdf0e10cSrcweir      */
501cdf0e10cSrcweir     public class PropertyValueSwitcher extends PropertyTester
502cdf0e10cSrcweir     {
503cdf0e10cSrcweir 
504cdf0e10cSrcweir         Object val1 = null;
505cdf0e10cSrcweir         Object val2 = null;
506cdf0e10cSrcweir 
507cdf0e10cSrcweir         /**
508cdf0e10cSrcweir          * Constructs a property tester with two different values
509cdf0e10cSrcweir          * specified as parameters.
510cdf0e10cSrcweir          *
511cdf0e10cSrcweir          * @param val1 Not <code>null</code> value for the property
512cdf0e10cSrcweir          * tested.
513cdf0e10cSrcweir          * @param val1 Not <code>null</code> value for the property
514cdf0e10cSrcweir          * tested which differs from the first value.
515cdf0e10cSrcweir          */
516cdf0e10cSrcweir         public PropertyValueSwitcher(Object val1, Object val2)
517cdf0e10cSrcweir         {
518cdf0e10cSrcweir             this.val1 = val1;
519cdf0e10cSrcweir             this.val2 = val2;
520cdf0e10cSrcweir         }
521cdf0e10cSrcweir 
522cdf0e10cSrcweir         /**
523cdf0e10cSrcweir          * Overriden method of <code>PropertyTester</code> which
524cdf0e10cSrcweir          * retruns new value from two values specified.
525cdf0e10cSrcweir          *
526cdf0e10cSrcweir          * @return The second value if old value is equal to the first
527cdf0e10cSrcweir          * one, the first value otherwise.
528cdf0e10cSrcweir          */
529cdf0e10cSrcweir         protected Object getNewValue(String propName, Object old)
530cdf0e10cSrcweir         {
531cdf0e10cSrcweir             if (ValueComparer.equalValue(val1, old))
532cdf0e10cSrcweir             {
533cdf0e10cSrcweir                 return val2;
534cdf0e10cSrcweir             }
535cdf0e10cSrcweir             else
536cdf0e10cSrcweir             {
537cdf0e10cSrcweir                 return val1;
538cdf0e10cSrcweir             }
539cdf0e10cSrcweir         }
540cdf0e10cSrcweir     }
541cdf0e10cSrcweir 
542cdf0e10cSrcweir     /**
543cdf0e10cSrcweir      * The method performs testing of propName property using propTester.
544cdf0e10cSrcweir      */
545cdf0e10cSrcweir     protected void testProperty(String propName, PropertyTester propTester)
546cdf0e10cSrcweir     {
547cdf0e10cSrcweir         propTester.testProperty(propName);
548cdf0e10cSrcweir     }
549cdf0e10cSrcweir 
550cdf0e10cSrcweir     /**
551cdf0e10cSrcweir      * The method performs testing of propName property. It uses PropertyTester
552cdf0e10cSrcweir      * instance for testing.
553cdf0e10cSrcweir      */
554cdf0e10cSrcweir     protected void testProperty(String propName)
555cdf0e10cSrcweir     {
556cdf0e10cSrcweir         testProperty(propName, new PropertyTester());
557cdf0e10cSrcweir     }
558cdf0e10cSrcweir 
559cdf0e10cSrcweir     /**
560cdf0e10cSrcweir      * Tests the property using <code>PropertyValueSwitcher</code>
561cdf0e10cSrcweir      * tester and two values for this property.
562cdf0e10cSrcweir      *
563cdf0e10cSrcweir      * @see #PropertyValueSwitcher
564cdf0e10cSrcweir      */
565cdf0e10cSrcweir     protected void testProperty(String propName, Object val1, Object val2)
566cdf0e10cSrcweir     {
567cdf0e10cSrcweir         testProperty(propName, new PropertyValueSwitcher(val1, val2));
568cdf0e10cSrcweir     }
569cdf0e10cSrcweir 
570cdf0e10cSrcweir     /**
571cdf0e10cSrcweir      * The method just calls compare. This is a workaround to CodeWarrior's
572cdf0e10cSrcweir      * compiler bug.
573cdf0e10cSrcweir      */
574cdf0e10cSrcweir     private boolean callCompare(Object obj1, Object obj2)
575cdf0e10cSrcweir     {
576cdf0e10cSrcweir         return compare(obj1, obj2);
577cdf0e10cSrcweir     }
578cdf0e10cSrcweir 
579cdf0e10cSrcweir     /**
580cdf0e10cSrcweir      * Compares two object. In the implementation calls obj1.equals(obj2).
581cdf0e10cSrcweir      */
582cdf0e10cSrcweir     protected boolean compare(Object obj1, Object obj2)
583cdf0e10cSrcweir     {
584cdf0e10cSrcweir         return ValueComparer.equalValue(obj1, obj2);
585cdf0e10cSrcweir     }
586cdf0e10cSrcweir 
587cdf0e10cSrcweir     /**
588cdf0e10cSrcweir      * The method just calls toString. This is a workaround to
589cdf0e10cSrcweir      * CodeWarrior's compiler bug.
590cdf0e10cSrcweir      */
591cdf0e10cSrcweir     private String callToString(Object obj)
592cdf0e10cSrcweir     {
593cdf0e10cSrcweir         return toString(obj);
594cdf0e10cSrcweir     }
595cdf0e10cSrcweir 
596cdf0e10cSrcweir     /**
597cdf0e10cSrcweir      * Gets string representation of the obj. In the implementation
598cdf0e10cSrcweir      * returns obj.toString().
599cdf0e10cSrcweir      */
600cdf0e10cSrcweir     protected String toString(Object obj)
601cdf0e10cSrcweir     {
602cdf0e10cSrcweir         return obj == null ? "null" : obj.toString();
603cdf0e10cSrcweir     }
604cdf0e10cSrcweir }
605