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 #include "sal/config.h"
29 
30 #include "boost/noncopyable.hpp"
31 #include "com/sun/star/awt/AsyncCallback.hpp"
32 #include "com/sun/star/awt/XCallback.hpp"
33 #include "com/sun/star/beans/PropertyState.hpp"
34 #include "com/sun/star/beans/PropertyValue.hpp"
35 #include "com/sun/star/document/MacroExecMode.hpp"
36 #include "com/sun/star/frame/DispatchResultEvent.hpp"
37 #include "com/sun/star/frame/DispatchResultState.hpp"
38 #include "com/sun/star/frame/XComponentLoader.hpp"
39 #include "com/sun/star/frame/XController.hpp"
40 #include "com/sun/star/frame/XDispatchProvider.hpp"
41 #include "com/sun/star/frame/XDispatchResultListener.hpp"
42 #include "com/sun/star/frame/XModel.hpp"
43 #include "com/sun/star/frame/XNotifyingDispatch.hpp"
44 #include "com/sun/star/lang/EventObject.hpp"
45 #include "com/sun/star/uno/Any.hxx"
46 #include "com/sun/star/uno/Reference.hxx"
47 #include "com/sun/star/uno/RuntimeException.hpp"
48 #include "com/sun/star/uno/Sequence.hxx"
49 #include "com/sun/star/util/URL.hpp"
50 #include <preextstl.h>
51 #include "cppuhelper/implbase1.hxx"
52 #include "cppunit/TestAssert.h"
53 #include "cppunit/TestFixture.h"
54 #include "cppunit/extensions/HelperMacros.h"
55 #include "cppunit/plugin/TestPlugIn.h"
56 #include <postextstl.h>
57 #include "osl/conditn.hxx"
58 #include "osl/diagnose.h"
59 #include "rtl/ustring.h"
60 #include "rtl/ustring.hxx"
61 #include "test/gettestargument.hxx"
62 #include "test/officeconnection.hxx"
63 #include "test/oustringostreaminserter.hxx"
64 #include "test/toabsolutefileurl.hxx"
65 
66 namespace {
67 
68 namespace css = com::sun::star;
69 
70 struct Result: private boost::noncopyable {
71     osl::Condition condition;
72     bool success;
73     rtl::OUString result;
74 };
75 
76 class Listener:
77     public cppu::WeakImplHelper1< css::frame::XDispatchResultListener >
78 {
79 public:
80     Listener(Result * result): result_(result) { OSL_ASSERT(result != 0); }
81 
82 private:
83     virtual void SAL_CALL disposing(css::lang::EventObject const &)
84         throw (css::uno::RuntimeException) {}
85 
86     virtual void SAL_CALL dispatchFinished(
87         css::frame::DispatchResultEvent const & Result)
88         throw (css::uno::RuntimeException);
89 
90     Result * result_;
91 };
92 
93 void Listener::dispatchFinished(css::frame::DispatchResultEvent const & Result)
94     throw (css::uno::RuntimeException)
95 {
96     result_->success =
97         (Result.State == css::frame::DispatchResultState::SUCCESS) &&
98         (Result.Result >>= result_->result);
99     result_->condition.set();
100 }
101 
102 class Callback: public cppu::WeakImplHelper1< css::awt::XCallback > {
103 public:
104     Callback(
105         css::uno::Reference< css::frame::XNotifyingDispatch > const & dispatch,
106         css::util::URL const & url,
107         css::uno::Sequence< css::beans::PropertyValue > const & arguments,
108         css::uno::Reference< css::frame::XDispatchResultListener > const &
109             listener):
110         dispatch_(dispatch), url_(url), arguments_(arguments),
111         listener_(listener)
112     { OSL_ASSERT(dispatch.is()); }
113 
114 private:
115     virtual void SAL_CALL notify(css::uno::Any const &)
116         throw (css::uno::RuntimeException)
117     { dispatch_->dispatchWithNotification(url_, arguments_, listener_); }
118 
119     css::uno::Reference< css::frame::XNotifyingDispatch > dispatch_;
120     css::util::URL url_;
121     css::uno::Sequence< css::beans::PropertyValue > arguments_;
122     css::uno::Reference< css::frame::XDispatchResultListener > listener_;
123 };
124 
125 class Test: public CppUnit::TestFixture {
126 public:
127     virtual void setUp();
128 
129     virtual void tearDown();
130 
131 private:
132     CPPUNIT_TEST_SUITE(Test);
133     CPPUNIT_TEST(test);
134     CPPUNIT_TEST_SUITE_END();
135 
136     void test();
137 
138     test::OfficeConnection connection_;
139 };
140 
141 void Test::setUp() {
142     connection_.setUp();
143 }
144 
145 void Test::tearDown() {
146     connection_.tearDown();
147 }
148 
149 void Test::test() {
150     rtl::OUString doc;
151     CPPUNIT_ASSERT(
152         test::getTestArgument(
153             rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("smoketest.doc")), &doc));
154     css::uno::Sequence< css::beans::PropertyValue > args(2);
155     args[0].Name = rtl::OUString(
156         RTL_CONSTASCII_USTRINGPARAM("MacroExecutionMode"));
157     args[0].Handle = -1;
158     args[0].Value <<=
159         com::sun::star::document::MacroExecMode::ALWAYS_EXECUTE_NO_WARN;
160     args[0].State = css::beans::PropertyState_DIRECT_VALUE;
161     args[1].Name = rtl::OUString(
162         RTL_CONSTASCII_USTRINGPARAM("ReadOnly"));
163     args[1].Handle = -1;
164     args[1].Value <<= sal_True;
165     args[1].State = css::beans::PropertyState_DIRECT_VALUE;
166     css::util::URL url;
167     url.Complete = rtl::OUString(
168         RTL_CONSTASCII_USTRINGPARAM(
169             "vnd.sun.star.script:Standard.Global.StartTestWithDefaultOptions?"
170             "language=Basic&location=document"));
171     css::uno::Reference< css::frame::XNotifyingDispatch > disp(
172         css::uno::Reference< css::frame::XDispatchProvider >(
173             css::uno::Reference< css::frame::XController >(
174                 css::uno::Reference< css::frame::XModel >(
175                     css::uno::Reference< css::frame::XComponentLoader >(
176                         (connection_.getComponentContext()->
177                          getServiceManager()->createInstanceWithContext(
178                              rtl::OUString(
179                                  RTL_CONSTASCII_USTRINGPARAM(
180                                      "com.sun.star.frame.Desktop")),
181                              connection_.getComponentContext())),
182                         css::uno::UNO_QUERY_THROW)->loadComponentFromURL(
183                             test::toAbsoluteFileUrl(doc),
184                             rtl::OUString(
185                                 RTL_CONSTASCII_USTRINGPARAM("_default")),
186                             0, args),
187                     css::uno::UNO_QUERY_THROW)->getCurrentController(),
188                 css::uno::UNO_SET_THROW)->getFrame(),
189             css::uno::UNO_QUERY_THROW)->queryDispatch(
190                 url, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_self")), 0),
191         css::uno::UNO_QUERY_THROW);
192     Result result;
193     // Shifted to main thread to work around potential deadlocks (i112867):
194     com::sun::star::awt::AsyncCallback::create(
195         connection_.getComponentContext())->addCallback(
196             new Callback(
197                 disp, url, css::uno::Sequence< css::beans::PropertyValue >(),
198                 new Listener(&result)),
199             css::uno::Any());
200     result.condition.wait();
201     CPPUNIT_ASSERT(result.success);
202     CPPUNIT_ASSERT_EQUAL(rtl::OUString(), result.result);
203 }
204 
205 CPPUNIT_TEST_SUITE_REGISTRATION(Test);
206 
207 }
208 
209 CPPUNIT_PLUGIN_IMPLEMENT();
210