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.container;
29 
30 import java.io.PrintWriter;
31 
32 import lib.MultiMethodTest;
33 import lib.Status;
34 import lib.StatusException;
35 
36 import com.sun.star.awt.XControl;
37 import com.sun.star.awt.XControlContainer;
38 import com.sun.star.container.ContainerEvent;
39 import com.sun.star.container.XContainer;
40 import com.sun.star.container.XContainerListener;
41 import com.sun.star.container.XNameContainer;
42 import com.sun.star.container.XNameReplace;
43 import com.sun.star.lang.EventObject;
44 import com.sun.star.uno.UnoRuntime;
45 import com.sun.star.uno.XNamingService;
46 
47 
48 /**
49 * Testing <code>com.sun.star.container.XContainer</code>
50 * interface methods :
51 * <ul>
52 *  <li><code> addContainerListener()</code></li>
53 *  <li><code> removeContainerListener()</code></li>
54 * </ul>
55 * This test needs the following object relations :
56 * <ul>
57 *  <li> <code>'INSTANCE'</code> : Object which can be inserted into
58 *    container.</li>
59 *  <li> <code>'INSTANCE2'</code> : <b>(optional)</b>
60 *     Object which can be inserted into container. The relation
61 *     must be specified when container cann't contain two
62 *     identical objects. Replaces the first instance.</li>
63 *  <li> <code>'XContainer.Container'</code> (of type
64 *  <code>com.sun.star.container.XNameContainer</code>)
65 *  <b>optional</b> : is required when the tested component
66 *  doesn't implement <code>XNameContainer</code> and is used
67 *  for adding and removing elements.</li>
68 * <ul> <p>
69 * Object <b>must implement</b>
70 * <code>com.sun.star.container.XNameContainer</code>.
71 * <p>
72 * Test is <b> NOT </b> multithread compilant. <p>
73 * @see com.sun.star.container.XContainer
74 */
75 public class _XContainer extends MultiMethodTest {
76 
77     public XContainer oObj = null;
78     private boolean bElementInserted = false;
79     private boolean bElementRemoved  = false;
80     private boolean bElementReplaced = false;
81     private PrintWriter _log = null;
82     private XNameContainer NC = null ;
83     private XControlContainer CC = null ;
84     private XNamingService NV = null ;
85     private XNameReplace NR = null ;
86     private Object inst = null ;
87     private Object inst2 = null ;
88 
89     /**
90     * Retrieves object relations, and tries to query object for
91     * <code>XNameContainer</code> interface.
92     * @throws StatusException If one of relations not found or
93     * object doesn't implement <code>XNameContainer</code> interface.
94     */
95     public void before() throws StatusException {
96         _log = log;
97 
98         // do this test with a different object
99         Object altObj = tEnv.getObjRelation("XContainer.AlternateObject");
100         if (altObj != null) {
101             oObj = (XContainer)UnoRuntime.queryInterface(XContainer.class, altObj);
102         }
103 
104         NC = (XNameContainer) UnoRuntime.queryInterface
105             (XNameContainer.class, oObj) ;
106 
107         Object container = null;
108         if (NC == null) {
109             container = tEnv.getObjRelation("XContainer.Container") ;
110         }
111 
112         if (container != null) {
113             if (container instanceof com.sun.star.awt.XControlContainer) {
114                 CC = (XControlContainer) container;
115             } else if (container instanceof com.sun.star.uno.XNamingService) {
116                 NV = (XNamingService) container;
117             } else if (container instanceof com.sun.star.container.XNameReplace) {
118                 NR = (XNameReplace) container;
119                 inst2 = tEnv.getObjRelation("XContainer.NewValue");
120                 inst = tEnv.getObjRelation("XContainer.ElementName");
121             } else if (container instanceof com.sun.star.container.XNameContainer) {
122                 NC = (XNameContainer) container;
123             }
124         }
125 
126         if (NC == null && CC == null && NV == null && NR == null)
127             throw new StatusException(
128                 Status.failed("Neither object implements XNameContainer" +
129                     " nor relation 'XContainer.Container' found.")) ;
130 
131         if (inst == null)
132             inst = tEnv.getObjRelation("INSTANCE");
133         if (inst == null) {
134             log.println("No INSTANCE ObjRelation!!! ");
135             throw new StatusException(Status.failed("No INSTANCE ObjRelation!!!")) ;
136         }
137         if (inst2 == null)
138             inst2 = tEnv.getObjRelation("INSTANCE2");
139     }
140 
141     /**
142     * Listener implementation which just set flags on appropriate
143     * events.
144     */
145     public class MyListener implements XContainerListener {
146          public void elementInserted(ContainerEvent e) {
147             //_log.println("Element was inserted");
148             bElementInserted = true;
149          }
150          public void elementRemoved(ContainerEvent e) {
151             //_log.println("Element was removed");
152             bElementRemoved = true;
153          }
154          public void elementReplaced(ContainerEvent e) {
155             //_log.println("Element was replaced");
156             bElementReplaced = true;
157          }
158          public void disposing (EventObject obj) {}
159     };
160 
161     MyListener listener = new MyListener();
162 
163     /**
164     * Adds <code>MyListener</code> and performs all possible changes
165     * (insert, replace, remove) with container. The checks which
166     * events were called. <p>
167     * Has <b>OK</b> status if all methods of the listener were called.
168     */
169     public void _addContainerListener() {
170         boolean bResult = true;
171 
172         oObj.addContainerListener(listener);
173         bResult &= performChanges();
174         //we can't replace if the container is XControlContainer
175         if (NC != null) bResult &= bElementReplaced;
176         // we do not remove and insert if the listener is triggered by XNameReplace
177         if (NR == null) bResult &= bElementRemoved;
178         if (NR == null) bResult &= bElementInserted;
179 
180         if (!bResult) {
181             log.println("inserted was " + (bElementInserted ? "" : "NOT")
182                                                                 + " called.");
183 
184             if (NC != null) {
185                 log.println("replaced was " + (bElementReplaced ? "" : "NOT")
186                                                                     + " called.");
187             }
188             log.println("removed was " + (bElementRemoved ? "" : "NOT")
189                                                                 + " called.");
190         }
191 
192         tRes.tested("addContainerListener()", bResult);
193     }
194 
195     /**
196     * Removes listener added before and performs all possible changes
197     * (insert, replace, remove) with container. The checks which
198     * events were called. <p>
199     * Has <b>OK</b> status if no methods of the listener were called. <p>
200     * The following method tests are to be completed successfully before :
201     * <ul>
202     *  <li> <code> addContainerListener() </code> : to remove it now. </li>
203     * </ul>
204     */
205     public void _removeContainerListener() {
206         requiredMethod("addContainerListener()") ;
207 
208         boolean bResult = true;
209         bElementReplaced = bElementRemoved = bElementInserted = false;
210 
211         oObj.removeContainerListener(listener);
212         bResult &= performChanges();
213         bResult &= !bElementReplaced;
214         bResult &= !bElementRemoved;
215         bResult &= !bElementInserted;
216 
217         tRes.tested("removeContainerListener()", bResult);
218     }
219 
220     /**
221     * Inserts, replaces and finally removes object from container.
222     * Object is gotten from <code>'INSTANCE'</code> relation. If
223     * the relation <code>'INSTANCE2'</code> exists then the first
224     * instance is replaced with second.
225     */
226     protected boolean performChanges() {
227         if (CC != null) return performChanges2();
228         if (NV != null) return performChanges3();
229         if (NR != null) return performChanges4();
230         boolean bResult = true;
231         try {
232             String[] names = NC.getElementNames();
233             log.println("Elements count = " + names.length);
234             NC.insertByName("XContainer_dummy", inst);
235             names = NC.getElementNames();
236             log.println("Elements count = " + names.length);
237             if (inst2 == null) {
238                 NC.replaceByName("XContainer_dummy", inst);
239             } else {
240                 NC.replaceByName("XContainer_dummy", inst2);
241             }
242             NC.removeByName("XContainer_dummy");
243         } catch (com.sun.star.lang.IllegalArgumentException ex) {
244             log.println("Exception occured ");
245             ex.printStackTrace(log);
246             bResult = false;
247         } catch (com.sun.star.lang.WrappedTargetException ex) {
248             log.println("Exception occured ");
249             ex.printStackTrace(log);
250             bResult = false;
251         } catch (com.sun.star.container.NoSuchElementException ex) {
252             log.println("Exception occured ");
253             ex.printStackTrace(log);
254             bResult = false;
255         } catch (com.sun.star.container.ElementExistException ex) {
256             log.println("Exception occured ");
257             ex.printStackTrace(log);
258             bResult = false;
259         }
260 
261         return bResult;
262     }
263 
264     /**
265     * In case no XNameContainer is available, but a XControlContainer
266     * instead.
267     * the XControl instance is inserted
268     * Method returns true if the count of Controls is changed afterwards
269     */
270     protected boolean performChanges2() {
271         int precount = CC.getControls().length;
272         CC.addControl("NewControl",(XControl) inst);
273         shortWait();
274         int count = CC.getControls().length;
275         CC.removeControl(CC.getControl("NewControl"));
276         shortWait();
277         return count>precount;
278     }
279 
280     /**
281     * In case no XNameContainer is available, but a XNamingService
282     * instead.
283     * the instance is registered and revoked again
284     * Method return true if getRegisteredObject() works after
285     * registering and doesn't after revoke
286     */
287     protected boolean performChanges3() {
288         boolean res = true;
289         Object reg = null;
290 
291         try {
292             reg = NV.getRegisteredObject("MyFactory");
293             NV.revokeObject("MyFactory");
294         } catch (Exception e) {
295 
296         }
297 
298         try {
299             NV.registerObject("MyFactory", inst);
300             reg = NV.getRegisteredObject("MyFactory");
301             res &= (reg != null);
302         } catch (Exception e) {
303             e.printStackTrace(log);
304             log.println("registerObject failed");
305             res &= false;
306         }
307 
308         try {
309             NV.revokeObject("MyFactory");
310             reg = NV.getRegisteredObject("MyFactory");
311             log.println("revokeObject failed");
312             res &= false;
313         } catch (Exception e) {
314             res &= true;
315         }
316 
317         return res;
318     }
319 
320     /**
321     * In case no XNameContainer is available, but a XNamingReplace
322     * instead.
323     */
324     protected boolean performChanges4() {
325         boolean res = true;
326         Object newValue = inst2;
327         Object originalValue = null;
328         String name = null;
329 
330         try {
331             name = (String)inst;
332         }
333         catch(java.lang.ClassCastException e) {
334             log.write("Expected String as object relations 'XContainer.ElementName'.");
335             e.printStackTrace(log);
336             return false;
337         }
338 
339         try {
340             originalValue = NR.getByName(name);
341             NR.replaceByName(name, newValue);
342         } catch (Exception e) {
343             e.printStackTrace(log);
344             res = false;
345         }
346 
347         try {
348             NR.replaceByName(name, originalValue);
349         } catch (Exception e) {
350             e.printStackTrace(log);
351             res = false;
352         }
353 
354         return res;
355     }
356 
357     /**
358     * Sleeps for 0.5 sec. to allow StarOffice to react on <code>
359     * reset</code> call.
360     */
361     private void shortWait() {
362         try {
363             Thread.sleep(1000) ;
364         } catch (InterruptedException e) {
365             log.println("While waiting :" + e) ;
366         }
367     }
368 }
369 
370 
371