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