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