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