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 "precompiled_desktop.hxx"
29 #include "sal/config.h"
30 
31 #include "boost/noncopyable.hpp"
32 #include "com/sun/star/awt/MessageBoxButtons.hpp"
33 #include "com/sun/star/awt/Rectangle.hpp"
34 #include "com/sun/star/awt/XMessageBox.hpp"
35 #include "com/sun/star/awt/XMessageBoxFactory.hpp"
36 #include "com/sun/star/awt/XWindowPeer.hpp"
37 #include "com/sun/star/beans/PropertyValue.hpp"
38 #include "com/sun/star/frame/DispatchDescriptor.hpp"
39 #include "com/sun/star/frame/XDesktop.hpp"
40 #include "com/sun/star/frame/XDispatch.hpp"
41 #include "com/sun/star/frame/XDispatchProvider.hpp"
42 #include "com/sun/star/frame/XFrame.hpp"
43 #include "com/sun/star/frame/XStatusListener.hpp"
44 #include "com/sun/star/lang/XComponent.hpp"
45 #include "com/sun/star/lang/XMultiComponentFactory.hpp"
46 #include "com/sun/star/lang/XServiceInfo.hpp"
47 #include "com/sun/star/registry/XRegistryKey.hpp"
48 #include "com/sun/star/uno/DeploymentException.hpp"
49 #include "com/sun/star/uno/Exception.hpp"
50 #include "com/sun/star/uno/Reference.hxx"
51 #include "com/sun/star/uno/RuntimeException.hpp"
52 #include "com/sun/star/uno/Sequence.hxx"
53 #include "com/sun/star/uno/XComponentContext.hpp"
54 #include "com/sun/star/uno/XInterface.hpp"
55 #include "com/sun/star/util/URL.hpp"
56 #include "cppuhelper/factory.hxx"
57 #include "cppuhelper/implbase2.hxx"
58 #include "cppuhelper/implementationentry.hxx"
59 #include "cppuhelper/weak.hxx"
60 #include "osl/diagnose.h"
61 #include "rtl/textenc.h"
62 #include "rtl/ustring.h"
63 #include "rtl/ustring.hxx"
64 #include "sal/types.h"
65 #include "uno/lbnames.h"
66 
67 namespace {
68 
69 namespace css = com::sun::star;
70 
71 class Provider:
72     public cppu::WeakImplHelper2<
73         css::lang::XServiceInfo, css::frame::XDispatchProvider >,
74     private boost::noncopyable
75 {
76 public:
77     static css::uno::Reference< css::uno::XInterface > SAL_CALL static_create(
78         css::uno::Reference< css::uno::XComponentContext > const & xContext)
79         SAL_THROW((css::uno::Exception))
80     { return static_cast< cppu::OWeakObject * >(new Provider(xContext)); }
81 
82     static rtl::OUString SAL_CALL static_getImplementationName();
83 
84     static css::uno::Sequence< rtl::OUString > SAL_CALL
85     static_getSupportedServiceNames();
86 
87 private:
88     Provider(
89         css::uno::Reference< css::uno::XComponentContext > const & context):
90         context_(context) { OSL_ASSERT(context.is()); }
91 
92     virtual ~Provider() {}
93 
94     virtual rtl::OUString SAL_CALL getImplementationName()
95         throw (css::uno::RuntimeException)
96     { return static_getImplementationName(); }
97 
98     virtual sal_Bool SAL_CALL supportsService(rtl::OUString const & ServiceName)
99         throw (css::uno::RuntimeException)
100     { return ServiceName == getSupportedServiceNames()[0]; } //TODO
101 
102     virtual css::uno::Sequence< rtl::OUString > SAL_CALL
103     getSupportedServiceNames() throw (css::uno::RuntimeException)
104     { return static_getSupportedServiceNames(); }
105 
106     virtual css::uno::Reference< css::frame::XDispatch > SAL_CALL queryDispatch(
107         css::util::URL const &, rtl::OUString const &, sal_Int32)
108         throw (css::uno::RuntimeException);
109 
110     virtual css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > >
111     SAL_CALL queryDispatches(
112         css::uno::Sequence< css::frame::DispatchDescriptor > const & Requests)
113         throw (css::uno::RuntimeException);
114 
115     css::uno::Reference< css::uno::XComponentContext > context_;
116 };
117 
118 rtl::OUString Provider::static_getImplementationName() {
119     return rtl::OUString(
120         RTL_CONSTASCII_USTRINGPARAM(
121             "com.sun.star.comp.test.deployment.active_native"));
122 }
123 
124 css::uno::Sequence< rtl::OUString > Provider::static_getSupportedServiceNames()
125 {
126     rtl::OUString name(
127         RTL_CONSTASCII_USTRINGPARAM(
128             "com.sun.star.test.deployment.active_native"));
129     return css::uno::Sequence< rtl::OUString >(&name, 1);
130 }
131 
132 css::uno::Reference< css::frame::XDispatch > Provider::queryDispatch(
133     css::util::URL const &, rtl::OUString const &, sal_Int32)
134     throw (css::uno::RuntimeException)
135 {
136     css::uno::Reference< css::frame::XDispatch > dispatch;
137     if (!(context_->getValueByName(
138               rtl::OUString(
139                   RTL_CONSTASCII_USTRINGPARAM(
140                       "/singletons/com.sun.star.test.deployment."
141                       "active_native_singleton"))) >>=
142           dispatch) ||
143         !dispatch.is())
144     {
145         throw css::uno::DeploymentException(
146             rtl::OUString(
147                 RTL_CONSTASCII_USTRINGPARAM(
148                     "component context fails to supply singleton"
149                     " com.sun.star.test.deployment.active_native_singleton of"
150                     " type com.sun.star.frame.XDispatch")),
151             context_);
152     }
153     return dispatch;
154 }
155 
156 css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > >
157 Provider::queryDispatches(
158     css::uno::Sequence< css::frame::DispatchDescriptor > const & Requests)
159     throw (css::uno::RuntimeException)
160 {
161     css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > s(
162         Requests.getLength());
163     for (sal_Int32 i = 0; i < s.getLength(); ++i) {
164         s[i] = queryDispatch(
165             Requests[i].FeatureURL, Requests[i].FrameName,
166             Requests[i].SearchFlags);
167     }
168     return s;
169 }
170 
171 class Dispatch:
172     public cppu::WeakImplHelper2<
173         css::lang::XServiceInfo, css::frame::XDispatch >,
174     private boost::noncopyable
175 {
176 public:
177     static css::uno::Reference< css::uno::XInterface > SAL_CALL static_create(
178         css::uno::Reference< css::uno::XComponentContext > const & xContext)
179         SAL_THROW((css::uno::Exception))
180     { return static_cast< cppu::OWeakObject * >(new Dispatch(xContext)); }
181 
182     static rtl::OUString SAL_CALL static_getImplementationName();
183 
184     static css::uno::Sequence< rtl::OUString > SAL_CALL
185     static_getSupportedServiceNames()
186     { return css::uno::Sequence< rtl::OUString >(); }
187 
188 private:
189     Dispatch(
190         css::uno::Reference< css::uno::XComponentContext > const & context):
191         context_(context) { OSL_ASSERT(context.is()); }
192 
193     virtual ~Dispatch() {}
194 
195     virtual rtl::OUString SAL_CALL getImplementationName()
196         throw (css::uno::RuntimeException)
197     { return static_getImplementationName(); }
198 
199     virtual sal_Bool SAL_CALL supportsService(rtl::OUString const &)
200         throw (css::uno::RuntimeException)
201     { return false; } //TODO
202 
203     virtual css::uno::Sequence< rtl::OUString > SAL_CALL
204     getSupportedServiceNames() throw (css::uno::RuntimeException)
205     { return static_getSupportedServiceNames(); }
206 
207     virtual void SAL_CALL dispatch(
208         css::util::URL const &,
209         css::uno::Sequence< css::beans::PropertyValue > const &)
210         throw (css::uno::RuntimeException);
211 
212     virtual void SAL_CALL addStatusListener(
213         css::uno::Reference< css::frame::XStatusListener > const &,
214         css::util::URL const &)
215         throw (css::uno::RuntimeException)
216     {}
217 
218     virtual void SAL_CALL removeStatusListener(
219         css::uno::Reference< css::frame::XStatusListener > const &,
220         css::util::URL const &)
221         throw (css::uno::RuntimeException)
222     {}
223 
224     css::uno::Reference< css::uno::XComponentContext > context_;
225 };
226 
227 rtl::OUString Dispatch::static_getImplementationName() {
228     return rtl::OUString(
229         RTL_CONSTASCII_USTRINGPARAM(
230             "com.sun.star.comp.test.deployment.active_native_singleton"));
231 }
232 
233 void Dispatch::dispatch(
234     css::util::URL const &,
235     css::uno::Sequence< css::beans::PropertyValue > const &)
236     throw (css::uno::RuntimeException)
237 {
238     css::uno::Reference< css::lang::XMultiComponentFactory > smgr(
239         context_->getServiceManager(), css::uno::UNO_SET_THROW);
240     css::uno::Reference< css::awt::XMessageBox > box(
241         css::uno::Reference< css::awt::XMessageBoxFactory >(
242             smgr->createInstanceWithContext(
243                 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
244                                   "com.sun.star.awt.Toolkit")), context_),
245             css::uno::UNO_QUERY_THROW)->createMessageBox(
246                 css::uno::Reference< css::awt::XWindowPeer >(
247                     css::uno::Reference< css::frame::XFrame >(
248                         css::uno::Reference< css::frame::XDesktop >(
249                             smgr->createInstanceWithContext(
250                                 rtl::OUString(
251                                     RTL_CONSTASCII_USTRINGPARAM(
252                                         "com.sun.star.frame.Desktop")),
253                                 context_),
254                             css::uno::UNO_QUERY_THROW)->getCurrentFrame(),
255                         css::uno::UNO_SET_THROW)->getComponentWindow(),
256                     css::uno::UNO_QUERY_THROW),
257                 css::awt::Rectangle(),
258                 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("infobox")),
259                 css::awt::MessageBoxButtons::BUTTONS_OK,
260                 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("active")),
261                 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("native"))),
262         css::uno::UNO_SET_THROW);
263     box->execute();
264     css::uno::Reference< css::lang::XComponent >(
265         box, css::uno::UNO_QUERY_THROW)->dispose();
266 }
267 
268 static cppu::ImplementationEntry const services[] = {
269     { &Provider::static_create, &Provider::static_getImplementationName,
270       &Provider::static_getSupportedServiceNames,
271       &cppu::createSingleComponentFactory, 0, 0 },
272     { &Dispatch::static_create, &Dispatch::static_getImplementationName,
273       &Dispatch::static_getSupportedServiceNames,
274       &cppu::createSingleComponentFactory, 0, 0 },
275     { 0, 0, 0, 0, 0, 0 }
276 };
277 
278 }
279 
280 extern "C" void * SAL_CALL component_getFactory(
281     char const * pImplName, void * pServiceManager, void * pRegistryKey)
282 {
283     return cppu::component_getFactoryHelper(
284         pImplName, pServiceManager, pRegistryKey, services);
285 }
286 
287 extern "C" void SAL_CALL component_getImplementationEnvironment(
288     char const ** ppEnvTypeName, uno_Environment **)
289 {
290     *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
291 }
292 
293 extern "C" sal_Bool SAL_CALL component_writeInfo(
294     void * pServiceManager, void * pRegistryKey)
295 {
296     if (!component_writeInfoHelper(pServiceManager, pRegistryKey, services)) {
297         return false;
298     }
299     try {
300         css::uno::Reference< css::registry::XRegistryKey >(
301             (css::uno::Reference< css::registry::XRegistryKey >(
302                 static_cast< css::registry::XRegistryKey * >(pRegistryKey))->
303              createKey(
304                  rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/")) +
305                  Dispatch::static_getImplementationName() +
306                  rtl::OUString(
307                      RTL_CONSTASCII_USTRINGPARAM(
308                          "/UNO/SINGLETONS/com.sun.star.test.deployment."
309                          "active_native_singleton")))),
310             css::uno::UNO_SET_THROW)->
311             setStringValue(Dispatch::static_getImplementationName());
312     } catch (css::uno::Exception & e) {
313         (void) e;
314         OSL_TRACE(
315             "active_native component_writeInfo exception: %s",
316             rtl::OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8).getStr());
317         return false;
318     }
319     return true;
320 }
321