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 ifc.beans;
29 
30 import java.io.PrintWriter;
31 import java.util.HashSet;
32 import java.util.Set;
33 import java.util.StringTokenizer;
34 
35 import lib.MultiMethodTest;
36 import lib.Status;
37 import util.ValueChanger;
38 
39 import com.sun.star.beans.Property;
40 import com.sun.star.beans.PropertyAttribute;
41 import com.sun.star.beans.PropertyChangeEvent;
42 import com.sun.star.beans.XMultiPropertySet;
43 import com.sun.star.beans.XPropertiesChangeListener;
44 import com.sun.star.beans.XPropertySetInfo;
45 import com.sun.star.lang.EventObject;
46 
47 
48 /**
49 * Testing <code>com.sun.star.beans.XMultiPropertySet</code>
50 * interface methods :
51 * <ul>
52 *  <li><code> getPropertySetInfo()</code></li>
53 *  <li><code> setPropertyValues()</code></li>
54 *  <li><code> getPropertyValues()</code></li>
55 *  <li><code> addPropertiesChangeListener()</code></li>
56 *  <li><code> removePropertiesChangeListener()</code></li>
57 *  <li><code> firePropertiesChangeEvent()</code></li>
58 * </ul> <p>
59 *
60 * Required relations :
61 * <ul>
62 *  <li> <code>'XMultiPropertySet.ExcludeProps'</code>
63 *    <b>(optional) </b> : java.util.Set.
64 *    Has property names which must be skipped from testing in
65 *    some reasons (for example property accepts restricted set
66 *    of values).
67 *  </li>
68 * <ul> <p>
69 *
70 * Test is <b> NOT </b> multithread compilant. <p>
71 * After test completion object environment has to be recreated.
72 * @see com.sun.star.beans.XMultiPropertySet
73 */
74 public class _XMultiPropertySet extends MultiMethodTest {
75 
76     public XMultiPropertySet oObj = null;
77 
78     private boolean propertiesChanged = false;
79     private XPropertySetInfo propertySetInfo = null;
80     private String [] testPropsNames = null;
81     private int testPropsAmount = 0;
82     private PrintWriter _log = null;
83 
84     private Object[] values = null;
85 
86     private Set exclProps = null;
87 
88     /**
89     * Initializes some fields.
90     */
91     public void before() {
92         _log = log;
93 
94         exclProps = (Set) tEnv.getObjRelation("XMultiPropertySet.ExcludeProps");
95         if (exclProps == null) exclProps = new HashSet(0);
96     }
97 
98     /**
99     * Listener implementation which sets a flag when
100     * listener was called.
101     */
102     public class MyChangeListener implements XPropertiesChangeListener {
103          public void propertiesChange(PropertyChangeEvent[] e) {
104              //_log.println("Listener was called");
105              propertiesChanged = true;
106          }
107          public void disposing (EventObject obj) {}
108     };
109 
110     private XPropertiesChangeListener PClistener =
111         new MyChangeListener();
112 
113     /**
114     * Test calls the method and checks return value.
115     * <code>PropertySetInfo</code> object is stored<p>
116     * Has <b> OK </b> status if the method returns not null value
117     * and no exceptions were thrown. <p>
118     */
119     public void _getPropertySetInfo() {
120         boolean bResult = true;
121         propertySetInfo = oObj.getPropertySetInfo();
122 
123         if (propertySetInfo == null) {
124             log.println("getPropertySetInfo() method returned null");
125             bResult = false;
126         }
127 
128         tRes.tested("getPropertySetInfo()", bResult) ;
129     }
130 
131 
132     /**
133     * Test collects all property names and retrieves their values,
134     * then checks the value returned. Finally it also collects
135     * bound properties for other methods tests.<p>
136     * Has <b> OK </b> status if the method  returns non null value
137     * and no exceptions were thrown. <p>
138     * The following method tests are to be completed successfully before :
139     * <ul>
140     *  <li> <code> getPropertySetInfo() </code> : to have a list
141     *   of properties.</li>
142     * </ul>
143     */
144     public void _getPropertyValues() {
145         requiredMethod("getPropertySetInfo()");
146         boolean bResult = true;
147 
148         Property[] properties = propertySetInfo.getProperties();
149         String[] allnames = new String[properties.length];
150         for (int i = 0; i < properties.length; i++) {
151             allnames[i] = properties[i].Name;
152         }
153 
154         values = oObj.getPropertyValues(allnames);
155 
156         bResult &= values!=null;
157         tRes.tested("getPropertyValues()", bResult) ;
158 
159         getPropsToTest(properties);
160     }
161 
162     /**
163     * Test adds listener for all bound properties then each property
164     * is changed and listener call . <p>
165     * Has <b> OK </b> status if on each property change the listener was
166     * called and no exceptions were thrown. <p>
167     * The following method tests are to be completed successfully before :
168     * <ul>
169     *  <li> <code> getPropertyValues() </code> : to collect bound
170     *   properties.</li>
171     * </ul>
172     */
173     public void _addPropertiesChangeListener() {
174 
175         requiredMethod("getPropertyValues()");
176 
177         boolean result  = true ;
178         // Creating listener
179         oObj.addPropertiesChangeListener(testPropsNames, PClistener);
180 
181         if ((testPropsAmount==1) && (testPropsNames[0].equals("none"))) {
182             testPropsAmount = 0;
183         }
184 
185 
186         // Change one of the property to be sure, that this event was cauched.
187         //Random rnd = new Random();
188         //int idx = rnd.nextInt(testPropsAmount);
189         for (int i=0; i<testPropsAmount;i++) {
190             log.print("Trying to change property " + testPropsNames[i]);
191             try {
192                 Object[] gValues = oObj.getPropertyValues(testPropsNames);
193                 Object newValue = ValueChanger.changePValue(gValues[i]);
194                 gValues[i] = newValue;
195                 propertiesChanged = false;
196                 oObj.setPropertyValues(testPropsNames, gValues);
197                 waitAMoment() ;
198                 result &= propertiesChanged ;
199                 log.println(" ... done");
200             } catch (com.sun.star.beans.PropertyVetoException e) {
201                 log.println("Exception occured while trying to change "+
202                     "property '"+testPropsNames[i] + "' :" + e);
203                 e.printStackTrace(log);
204             } catch (com.sun.star.lang.IllegalArgumentException e) {
205                 log.println("Exception occured while trying to change "+
206                     "property '"+testPropsNames[i] + "' :" + e);
207                 e.printStackTrace(log);
208             } catch (com.sun.star.lang.WrappedTargetException e) {
209                 log.println("Exception occured while trying to change "+
210                     "property '"+testPropsNames[i] + "' :" + e);
211                 e.printStackTrace(log);
212             } // end of try-catch
213         }
214         if (testPropsAmount == 0) {
215             log.println("all properties are read only");
216             tRes.tested("addPropertiesChangeListener()", Status.skipped(true));
217         } else {
218             tRes.tested("addPropertiesChangeListener()", propertiesChanged);
219         }
220     }
221 
222     /**
223     * Calls method and check if listener was called. <p>
224     * Has <b> OK </b> status if the listener was
225     * called and no exceptions were thrown. <p>
226     * The following method tests are to be completed successfully before :
227     * <ul>
228     *  <li> <code> addPropertiesChangeListener() </code> : listener to
229     *    be added.</li>
230     * </ul>
231     */
232     public void _firePropertiesChangeEvent() {
233         requiredMethod("addPropertiesChangeListener()");
234         propertiesChanged = false ;
235 
236         oObj.firePropertiesChangeEvent(testPropsNames, PClistener);
237         waitAMoment() ;
238 
239         tRes.tested("firePropertiesChangeEvent()", propertiesChanged);
240     }
241 
242 
243     /**
244     * Removes listener added before. <p>
245     * Has <b> OK </b> status no exceptions were thrown. <p>
246     * The following method tests are to be completed successfully before :
247     * <ul>
248     *  <li> <code> addPropertiesChangeListener() </code> : listener to
249     *    be added.</li>
250     * </ul>
251     */
252     public void _removePropertiesChangeListener() {
253         requiredMethod("firePropertiesChangeEvent()");
254         boolean bResult = true;
255 
256         oObj.removePropertiesChangeListener(PClistener);
257 
258         tRes.tested("removePropertiesChangeListener()", bResult);
259     }
260 
261 
262     /**
263     * Changes all properties, then set them to new values, get them
264     * and checks if their values were changed properly. <p>
265     * Has <b> OK </b> status if all properties properly changed
266     * and no exceptions were thrown. <p>
267     * The following method tests are to be completed successfully before :
268     * <ul>
269     *  <li> <code> getPropertyValues() </code> : to collect bound
270     *   properties.</li>
271     * </ul>
272     */
273     public void _setPropertyValues() {
274         requiredMethod("getPropertyValues()");
275         boolean bResult = true;
276 
277         if ((testPropsNames.length==1)&&(testPropsNames[0].equals("none"))) {
278             log.println("all properties are readOnly");
279             tRes.tested("setPropertyValues()",Status.skipped(true));
280             return;
281         }
282 
283         log.println("Changing all properties");
284         Object[] gValues = oObj.getPropertyValues(testPropsNames);
285         for (int i=0; i<testPropsAmount;i++) {
286             Object oldValue = gValues[i];
287             Object newValue = ValueChanger.changePValue(oldValue);
288             gValues[i] = newValue;
289         }
290 
291         try {
292             oObj.setPropertyValues(testPropsNames, gValues);
293             Object[] newValues = oObj.getPropertyValues(testPropsNames);
294             for (int i=0; i<testPropsAmount;i++) {
295                 if (newValues[i].equals(gValues[i])) {
296                     bResult = true;
297                 }
298             }
299         } catch (com.sun.star.beans.PropertyVetoException e) {
300             log.println("Exception occured while setting properties");
301             e.printStackTrace(log);
302             bResult = false;
303         } catch (com.sun.star.lang.IllegalArgumentException e) {
304             log.println("Exception occured while setting properties");
305             e.printStackTrace(log);
306             bResult = false;
307         } catch (com.sun.star.lang.WrappedTargetException e) {
308             log.println("Exception occured while setting properties");
309             e.printStackTrace(log);
310             bResult = false;
311         } // end of try-catch
312 
313         tRes.tested("setPropertyValues()", bResult);
314     }
315 
316     //Get the properties being tested
317     private void getPropsToTest(Property[] properties) {
318 
319         String bound = "";
320 
321         for (int i = 0; i < properties.length; i++) {
322 
323             Property property = properties[i];
324             String name = property.Name;
325             boolean isWritable = ((property.Attributes &
326                 PropertyAttribute.READONLY) == 0);
327             boolean isNotNull = ((property.Attributes &
328                 PropertyAttribute.MAYBEVOID) == 0);
329             boolean isBound = ((property.Attributes &
330                 PropertyAttribute.BOUND) != 0);
331             boolean isExcluded = exclProps.contains(name);
332 
333             //exclude UserDefined, because we can't change XNameContainer
334             if (name.indexOf("UserDefined")>0 || name.indexOf("Device")>0) {
335                 isWritable=false;
336             }
337 
338             values = oObj.getPropertyValues(new String[]{property.Name});
339 
340             boolean isVoid = util.utils.isVoid(values[0]);
341 
342             if ( isWritable && isNotNull && isBound && !isExcluded && !isVoid) {
343                 bound+=name+";";
344             }
345 
346         } // endfor
347 
348         //get a array of bound properties
349         if (bound.equals("")) bound = "none";
350         StringTokenizer ST=new StringTokenizer(bound,";");
351         int nr = ST.countTokens();
352         testPropsNames = new String[nr];
353         for (int i=0; i<nr; i++) testPropsNames[i] = ST.nextToken();
354         testPropsAmount = nr;
355         return;
356 
357     }
358 
359     /**
360     * Waits some time for listener to be called.
361     */
362     private void waitAMoment() {
363         try {
364             Thread.sleep(200) ;
365         } catch (java.lang.InterruptedException e) {
366             log.println("!!! Exception while waiting !!!") ;
367         }
368     }
369 
370     /*
371     * Does nothing.
372     */
373     protected void after() {
374         disposeEnvironment();
375     }
376 }
377 
378 
379