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 package complex.dispatches;
28 
29 import com.sun.star.beans.PropertyValue;
30 import com.sun.star.frame.DispatchInformation;
31 import com.sun.star.frame.XComponentLoader;
32 import com.sun.star.frame.XDispatchInformationProvider;
33 import com.sun.star.frame.XDispatchProviderInterception;
34 import com.sun.star.frame.XDispatchProviderInterceptor;
35 import com.sun.star.frame.XFrame;
36 import com.sun.star.lang.XComponent;
37 import com.sun.star.lang.XMultiServiceFactory;
38 import com.sun.star.uno.UnoRuntime;
39 import com.sun.star.util.XCloseable;
40 import complex.dispatches.Interceptor;
41 import java.util.HashMap;
42 
43 
44 
45 
46 
47 // ---------- junit imports -----------------
48 import org.junit.After;
49 import org.junit.AfterClass;
50 import org.junit.Before;
51 import org.junit.BeforeClass;
52 import org.junit.Test;
53 import org.openoffice.test.OfficeConnection;
54 import static org.junit.Assert.*;
55 // ------------------------------------------
56 
57 //-----------------------------------------------
58 /** @short  Check the interface XDispatchInformationProvider
59 
60 @descr  Because there exists more then one implementation of a dispatch
61 object, we have to test all these implementations ...
62  */
63 public class checkdispatchapi
64 {
65     //-------------------------------------------
66     // some const
67 
68     //-------------------------------------------
69     // member
70     /** points to the global uno service manager. */
71     private XMultiServiceFactory m_xMSF = null;
72     private connectivity.tools.HsqlDatabase db;
73     /** can be used to create new test frames. */
74     private XFrame m_xDesktop = null;
75     /** provides XDispatchInformationProvider interface. */
76     private XFrame m_xFrame = null;
77 
78     //-------------------------------------------
79     // test environment
80     //-------------------------------------------
81     /** @short  A function to tell the framework,
82     which test functions are available.
83 
84     @return All test methods.
85     @todo   Think about selection of tests from outside ...
86      */
87 //    public String[] getTestMethodNames()
88 //    {
89 //        return new String[]
90 //                {
91 //                    "checkDispatchInfoOfWriter",
92 //                    "checkDispatchInfoOfCalc",
93 //                    "checkDispatchInfoOfDraw",
94 //                    "checkDispatchInfoOfImpress",
95 //                    "checkDispatchInfoOfMath",
96 //                    "checkDispatchInfoOfChart",
97 //                    "checkDispatchInfoOfBibliography",
98 //                    "checkDispatchInfoOfQueryDesign",
99 //                    "checkDispatchInfoOfTableDesign",
100 //                    "checkDispatchInfoOfFormGridView",
101 //                    "checkDispatchInfoOfDataSourceBrowser",
102 //                    "checkDispatchInfoOfRelationDesign",
103 //                    "checkDispatchInfoOfBasic",
104 //                    "checkDispatchInfoOfStartModule",
105 //                    "checkInterceptorLifeTime",
106 //                    "checkInterception"
107 //                };
108 //    }
109 
110     //-------------------------------------------
111     /** @short  Create the environment for following tests.
112 
113     @descr  create an empty test frame, where we can load
114     different components inside.
115      */
116     @Before public void before()
117     {
118         try
119         {
120             // get uno service manager from global test environment
121             m_xMSF = getMSF();
122 
123             db = new connectivity.tools.HsqlDatabase(m_xMSF);
124 
125             // create desktop
126             m_xDesktop = UnoRuntime.queryInterface(XFrame.class, m_xMSF.createInstance("com.sun.star.frame.Desktop"));
127 
128             m_xFrame = impl_createNewFrame();
129         }
130         catch (java.lang.Throwable ex)
131         {
132             fail("Cant initialize test environment.");
133         }
134     }
135 
136     //-------------------------------------------
137     /** @short  close the environment.
138      */
139     @After public void after()
140     {
141         db.close();
142         impl_closeFrame(m_xFrame);
143         m_xFrame = null;
144     }
145 
146     //-------------------------------------------
147     @Test public void checkDispatchInfoOfWriter()
148     {
149         impl_checkDispatchInfoOfXXX("private:factory/swriter");
150     }
151 
152     //-------------------------------------------
153     @Test public void checkDispatchInfoOfCalc()
154     {
155         impl_checkDispatchInfoOfXXX("private:factory/scalc");
156     }
157 
158     //-------------------------------------------
159     @Test public void checkDispatchInfoOfDraw()
160     {
161         impl_checkDispatchInfoOfXXX("private:factory/sdraw");
162     }
163 
164     //-------------------------------------------
165     @Test public void checkDispatchInfoOfImpress()
166     {
167         impl_checkDispatchInfoOfXXX("private:factory/simpress");
168     }
169 
170     //-------------------------------------------
171     @Test public void checkDispatchInfoOfChart()
172     {
173         impl_checkDispatchInfoOfXXX("private:factory/schart");
174     }
175 
176     //-------------------------------------------
177     @Test public void checkDispatchInfoOfMath()
178     {
179         impl_checkDispatchInfoOfXXX("private:factory/smath");
180     }
181 
182     //-------------------------------------------
183     @Test public void checkDispatchInfoOfDataBase()
184     {
185         impl_checkDispatchInfoOfXXX("private:factory/sdatabase");
186     }
187 
188     //-------------------------------------------
189     @Test public void checkDispatchInfoOfBibliography()
190     {
191         impl_checkDispatchInfoOfXXX(".component:Bibliography/View1");
192     }
193 
194     //-------------------------------------------
195     @Test public void checkDispatchInfoOfQueryDesign()
196     {
197         callDatabaseDispatch(".component:DB/QueryDesign");
198     }
199 
200     //-------------------------------------------
201     @Test public void checkDispatchInfoOfTableDesign()
202     {
203         callDatabaseDispatch(".component:DB/TableDesign");
204     }
205 
206     //-------------------------------------------
207     @Test public void checkDispatchInfoOfFormGridView()
208     {
209         impl_checkDispatchInfoOfXXX(".component:DB/FormGridView");
210     }
211 
212     //-------------------------------------------
213     @Test public void checkDispatchInfoOfDataSourceBrowser()
214     {
215         impl_checkDispatchInfoOfXXX(".component:DB/DataSourceBrowser");
216     }
217 
218     //-------------------------------------------
219     @Test public void checkDispatchInfoOfRelationDesign()
220     {
221         callDatabaseDispatch(".component:DB/RelationDesign");
222     }
223     //-------------------------------------------
224 
225     private void callDatabaseDispatch(String url)
226     {
227         try
228         {
229             final PropertyValue args = new PropertyValue();
230             args.Name = "ActiveConnection";
231             args.Value = (Object) db.defaultConnection();
232 
233             XFrame xFrame = impl_createNewFrame();
234 
235             impl_loadIntoFrame(xFrame, url, new PropertyValue[]
236                     {
237                         args
238                     });
239             impl_checkDispatchInfo(xFrame);
240             impl_closeFrame(xFrame);
241         }
242         catch (java.lang.Exception e)
243         {
244         }
245     }
246 
247     //-------------------------------------------
248     @Test public void checkDispatchInfoOfBasic()
249     {
250         Object aComponent = impl_createUNOComponent("com.sun.star.script.BasicIDE");
251         impl_checkDispatchInfo(aComponent);
252     }
253 
254     //-------------------------------------------
255     @Test public void checkDispatchInfoOfStartModule()
256     {
257         Object aComponent = impl_createUNOComponent("com.sun.star.frame.StartModule");
258         impl_checkDispatchInfo(aComponent);
259     }
260 
261     //-------------------------------------------
262     public void checkInterceptorLifeTime()
263     {
264         // Note: It's important for the following test, that aInterceptor will be hold alive by the uno reference
265         // xInterceptor. Otherwhise we cant check some internal states of aInterceptor at the end of this method, because
266         // it was already killed .-)
267 
268         Interceptor aInterceptor = new Interceptor();
269         XDispatchProviderInterceptor xInterceptor = UnoRuntime.queryInterface(XDispatchProviderInterceptor.class, aInterceptor);
270 
271         XFrame xFrame = impl_createNewFrame();
272         XDispatchProviderInterception xInterception = UnoRuntime.queryInterface(XDispatchProviderInterception.class, xFrame);
273 
274         xInterception.registerDispatchProviderInterceptor(xInterceptor);
275         impl_closeFrame(xFrame);
276 
277         int nRegCount = aInterceptor.getRegistrationCount();
278         boolean bIsRegistered = aInterceptor.isRegistered();
279 
280         System.out.println("registration count = " + nRegCount);
281         System.out.println("is registered ?    = " + bIsRegistered);
282 
283         if (nRegCount < 1)
284         {
285             fail("Interceptor was never registered.");
286         }
287 
288         if (bIsRegistered)
289         {
290             fail("Interceptor was not deregistered automaticly on closing the corresponding frame.");
291         }
292 
293         System.out.println("Destruction of interception chain works as designed .-)");
294     }
295 
296     //-------------------------------------------
297     public void checkInterception()
298     {
299         String[] lDisabledURLs = new String[1];
300         lDisabledURLs[0] = ".uno:Open";
301 
302         System.out.println("create and initialize interceptor ...");
303         Interceptor aInterceptor = new Interceptor();
304         aInterceptor.setURLs4URLs4Blocking(lDisabledURLs);
305 
306         XDispatchProviderInterceptor xInterceptor = UnoRuntime.queryInterface(XDispatchProviderInterceptor.class, aInterceptor);
307 
308         System.out.println("create and initialize frame ...");
309         XFrame xFrame = impl_createNewFrame();
310         impl_loadIntoFrame(xFrame, "private:factory/swriter", null);
311 
312         XDispatchProviderInterception xInterception = UnoRuntime.queryInterface(XDispatchProviderInterception.class, xFrame);
313 
314         System.out.println("register interceptor ...");
315         xInterception.registerDispatchProviderInterceptor(xInterceptor);
316 
317         System.out.println("deregister interceptor ...");
318         xInterception.releaseDispatchProviderInterceptor(xInterceptor);
319     }
320 
321     //-------------------------------------------
322     private void impl_checkDispatchInfoOfXXX(String sXXX)
323     {
324         XFrame xFrame = impl_createNewFrame();
325         impl_loadIntoFrame(xFrame, sXXX, null);
326         impl_checkDispatchInfo(xFrame);
327         impl_closeFrame(xFrame);
328     }
329 
330     //-------------------------------------------
331     /** @short  load an URL into the current test frame.
332      */
333     private void impl_loadIntoFrame(XFrame xFrame, String sURL, PropertyValue args[])
334     {
335         XComponentLoader xLoader = UnoRuntime.queryInterface(XComponentLoader.class, xFrame);
336         if (xLoader == null)
337         {
338             fail("Frame does not provide required interface XComponentLoader.");
339         }
340 
341         XComponent xDoc = null;
342         try
343         {
344             xDoc = xLoader.loadComponentFromURL(sURL, "_self", 0, args);
345         }
346         catch (java.lang.Throwable ex)
347         {
348             xDoc = null;
349         }
350 
351         if (xDoc == null)
352         {
353             fail("Could not load \"" + sURL + "\".");
354         }
355     }
356 
357     //-------------------------------------------
358     /** @short  create an uno implementation directly.
359      */
360     private Object impl_createUNOComponent(String sName)
361     {
362         Object aComponent = null;
363         try
364         {
365             aComponent = m_xMSF.createInstance(sName);
366         }
367         catch (java.lang.Throwable ex)
368         {
369             aComponent = null;
370         }
371 
372         if (aComponent == null)
373         {
374             fail("Could not create UNO component \"" + sName + "\".");
375         }
376         return aComponent;
377     }
378 
379     //-------------------------------------------
380     /** @short  check the interface XDispatchInformationProvider
381     at the specified component.
382      */
383     private void impl_checkDispatchInfo(Object aComponent)
384     {
385         XDispatchInformationProvider xInfoProvider = UnoRuntime.queryInterface(XDispatchInformationProvider.class, aComponent);
386         if (xInfoProvider == null)
387         {
388             // Warning
389             System.out.println("Warning:\tComponent does not provide the [optional!] interface XDispatchInformationProvider.");
390             return;
391         }
392 
393         try
394         {
395             short[] lGroups = xInfoProvider.getSupportedCommandGroups();
396             int c1 = lGroups.length;
397             int i1 = 0;
398             for (i1 = 0; i1 < c1; ++i1)
399             {
400                 short nGroup = lGroups[i1];
401                 DispatchInformation[] lInfos = xInfoProvider.getConfigurableDispatchInformation(nGroup);
402                 int c2 = lInfos.length;
403                 int i2 = 0;
404 
405                 // check for empty lists
406                 // Warning
407                 if (lInfos.length < 1)
408                 {
409                     System.out.println("Warning:\tCould not get any DispatchInformation for group [" + nGroup + "].");
410                 }
411 
412                 // check for duplicates (and by the way, if the info item match the requested group)
413                 HashMap aCheckMap = new HashMap(c2);
414                 for (i2 = 0; i2 < c2; ++i2)
415                 {
416                     DispatchInformation aInfo = lInfos[i2];
417                     if (aInfo.GroupId != nGroup)
418                     {
419                         // Error
420                         fail("At least one DispatchInformation item does not match the requested group.\n\trequested group=[" + nGroup
421                                 + "] returned groupd=[" + aInfo.GroupId + "] command=\"" + aInfo.Command + "\""); // true => dont break this test
422                         continue;
423                     }
424 
425                     if (aCheckMap.containsKey(aInfo.Command))
426                     {
427                         // Error
428                         fail("Found a duplicate item: group=[" + aInfo.GroupId + "] command=\"" + aInfo.Command + "\""); // true => dont break this test
429                         continue;
430                     }
431 
432                     aCheckMap.put(aInfo.Command, aInfo.Command);
433                     System.out.println("\t[" + aInfo.GroupId + "] \"" + aInfo.Command + "\"");
434                 }
435             }
436         }
437         catch (java.lang.Throwable ex)
438         {
439             fail("Exception caught during using XDispatchInformationProvider.");
440             // ex.printStackTrace();
441         }
442     }
443 
444     //-------------------------------------------
445     private synchronized XFrame impl_createNewFrame()
446     {
447         XFrame xFrame = null;
448 
449         try
450         {
451             xFrame = m_xDesktop.findFrame("_blank", 0);
452             xFrame.getContainerWindow().setVisible(true);
453         }
454         catch (java.lang.Throwable ex)
455         {
456             fail("Could not create the frame instance.");
457         }
458 
459         return xFrame;
460     }
461 
462     //-------------------------------------------
463     private synchronized void impl_closeFrame(XFrame xFrame)
464     {
465         XCloseable xClose = UnoRuntime.queryInterface(XCloseable.class, xFrame);
466         try
467         {
468             xClose.close(false);
469         }
470         catch (com.sun.star.util.CloseVetoException exVeto)
471         {
472             fail("Test frame couldn't be closed successfully.");
473         }
474     }
475 
476     private XMultiServiceFactory getMSF()
477     {
478         final XMultiServiceFactory xMSF1 = UnoRuntime.queryInterface(XMultiServiceFactory.class, connection.getComponentContext().getServiceManager());
479         return xMSF1;
480     }
481 
482     // setup and close connections
483     @BeforeClass
484     public static void setUpConnection() throws Exception
485     {
486         System.out.println("setUpConnection()");
487         connection.setUp();
488     }
489 
490     @AfterClass
491     public static void tearDownConnection()
492             throws InterruptedException, com.sun.star.uno.Exception
493     {
494         System.out.println("tearDownConnection()");
495         connection.tearDown();
496     }
497     private static final OfficeConnection connection = new OfficeConnection();
498 }
499