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 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_framework.hxx"
30 //_________________________________________________________________________________________________________________
31 //	my own includes
32 //_________________________________________________________________________________________________________________
33 
34 #ifndef __FRAMEWORK_DISPATCH_OXT_HANDLER_HXX_
35 #include <dispatch/oxt_handler.hxx>
36 #endif
37 
38 #ifndef __FRAMEWORK_THREADHELP_TRANSACTIONGUARD_HXX_
39 #include <threadhelp/transactionguard.hxx>
40 #endif
41 
42 #ifndef __FRAMEWORK_THREADHELP_WRITEGUARD_HXX_
43 #include <threadhelp/writeguard.hxx>
44 #endif
45 
46 #ifndef __FRAMEWORK_THREADHELP_READGUARD_HXX_
47 #include <threadhelp/readguard.hxx>
48 #endif
49 
50 #ifndef __FRAMEWORK_MACROS_DEBUG_HXX_
51 #include <macros/debug.hxx>
52 #endif
53 
54 #ifndef __FRAMEWORK_SERVICES_H_
55 #include <services.h>
56 #endif
57 
58 #ifndef __COMPHELPER_MEDIADESCRIPTOR_HXX_
59 #include <comphelper/mediadescriptor.hxx>
60 #endif
61 
62 //_________________________________________________________________________________________________________________
63 //	interface includes
64 //_________________________________________________________________________________________________________________
65 
66 #include <com/sun/star/io/XInputStream.hpp>
67 #include <com/sun/star/frame/DispatchResultState.hpp>
68 #include <com/sun/star/task/XJobExecutor.hpp>
69 
70 //_________________________________________________________________________________________________________________
71 //	includes of other projects
72 //_________________________________________________________________________________________________________________
73 
74 #ifndef _COMPHELPER_SEQUENCEASHASHMAP_HXX_
75 #include <comphelper/sequenceashashmap.hxx>
76 #endif
77 
78 #ifndef _RTL_USTRBUF_HXX_
79 #include <rtl/ustrbuf.hxx>
80 #endif
81 
82 //_________________________________________________________________________________________________________________
83 //	namespace
84 //_________________________________________________________________________________________________________________
85 
86 namespace framework{
87 
88 //_________________________________________________________________________________________________________________
89 //	non exported const
90 //_________________________________________________________________________________________________________________
91 
92 //_________________________________________________________________________________________________________________
93 //	non exported definitions
94 //_________________________________________________________________________________________________________________
95 
96 #define UNISTRING(s) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s))
97 
98 //_________________________________________________________________________________________________________________
99 //	declarations
100 //_________________________________________________________________________________________________________________
101 
102 //*****************************************************************************************************************
103 //  XInterface, XTypeProvider, XServiceInfo
104 //*****************************************************************************************************************
105 DEFINE_XINTERFACE_5                 (   Oxt_Handler                                                ,
106                                         OWeakObject                                                ,
107                                         DIRECT_INTERFACE( css::lang::XTypeProvider                ),
108                                         DIRECT_INTERFACE( css::lang::XServiceInfo                 ),
109                                         DIRECT_INTERFACE( css::frame::XNotifyingDispatch          ),
110                                         DIRECT_INTERFACE( css::frame::XDispatch                   ),
111                                         DIRECT_INTERFACE( css::document::XExtendedFilterDetection )
112                                     )
113 
114 DEFINE_XTYPEPROVIDER_5              (   Oxt_Handler                                                ,
115                                         css::lang::XTypeProvider                                   ,
116                                         css::lang::XServiceInfo                                    ,
117                                         css::frame::XNotifyingDispatch                             ,
118                                         css::frame::XDispatch                                      ,
119                                         css::document::XExtendedFilterDetection
120                                     )
121 
122 DEFINE_XSERVICEINFO_MULTISERVICE    (   Oxt_Handler                                                ,
123                                         ::cppu::OWeakObject                                        ,
124                                         SERVICENAME_CONTENTHANDLER                                 ,
125                                         IMPLEMENTATIONNAME_OXT_HANDLER
126 									)
127 
128 DEFINE_INIT_SERVICE                 (   Oxt_Handler,
129                                         {
130                                         }
131                                     )
132 
133 /*-************************************************************************************************************//**
134     @short      standard ctor
135     @descr      These initialize a new instance of this class with needed informations for work.
136 
137     @seealso    using at owner
138 
139     @param      "xFactory", reference to service manager for creation of new services
140     @return     -
141 
142     @onerror    Show an assertion and do nothing else.
143     @threadsafe yes
144 *//*-*************************************************************************************************************/
145 Oxt_Handler::Oxt_Handler( const css::uno::Reference< css::lang::XMultiServiceFactory >& xFactory )
146 		//	Init baseclasses first
147         :   ThreadHelpBase      (          )
148         ,   ::cppu::OWeakObject (          )
149         // Init member
150         ,   m_xFactory          ( xFactory )
151 {
152 }
153 
154 /*-************************************************************************************************************//**
155     @short      standard dtor
156     @descr      -
157 
158     @seealso    -
159 
160     @param      -
161     @return     -
162 
163     @onerror    -
164     @threadsafe -
165 *//*-*************************************************************************************************************/
166 Oxt_Handler::~Oxt_Handler()
167 {
168     if ( m_xListener.is() )
169     {
170         css::frame::DispatchResultEvent aEvent;
171         aEvent.State = css::frame::DispatchResultState::FAILURE;
172         m_xListener->dispatchFinished( aEvent );
173         m_xListener = css::uno::Reference< css::frame::XDispatchResultListener >();
174     }
175 }
176 
177 /*-************************************************************************************************************//**
178     @interface  ::com::sun::star::frame::XDispatch
179 
180     @short      try to load audio file
181     @descr      This method try to load given audio file by URL and play it. We use vcl/Sound class to do that.
182                 Playing of sound is asynchron everytime.
183 
184     @attention  We must hold us alive by ourself ... because we use async. vcl sound player ... but playing is started
185                 in async interface call "dispatch()" too. And caller forget us imediatly. But then our uno ref count
186                 will decreased to 0 and will die. The only solution is to use own reference to our implementation.
187                 But we do it for realy started jobs only and release it during call back of vcl.
188 
189     @seealso    class vcl/Sound
190     @seealso    method implts_PlayerNotify()
191 
192     @param      "aURL"      , URL to dispatch.
193     @param      "lArguments", list of optional arguments.
194     @return     -
195 
196     @onerror    We do nothing.
197     @threadsafe yes
198 *//*-*************************************************************************************************************/
199 void SAL_CALL Oxt_Handler::dispatchWithNotification( const css::util::URL& aURL,
200                                                      const css::uno::Sequence< css::beans::PropertyValue >&            /*lArguments*/,
201                                                      const css::uno::Reference< css::frame::XDispatchResultListener >& xListener )
202     throw( css::uno::RuntimeException )
203 {
204     // SAFE {
205     ResetableGuard aLock( m_aLock );
206 
207     rtl::OUString sServiceName = UNISTRING( "com.sun.star.deployment.ui.PackageManagerDialog" );
208     css::uno::Sequence< css::uno::Any > lParams(1);
209     lParams[0] <<= aURL.Main;
210 
211     css::uno::Reference< css::uno::XInterface > xService;
212 
213     xService = m_xFactory->createInstanceWithArguments( sServiceName, lParams );
214     css::uno::Reference< css::task::XJobExecutor > xExecuteable( xService, css::uno::UNO_QUERY );
215     if ( xExecuteable.is() )
216         xExecuteable->trigger( rtl::OUString() );
217 
218     if ( xListener.is() )
219     {
220         css::frame::DispatchResultEvent aEvent;
221         aEvent.State = css::frame::DispatchResultState::SUCCESS;
222         xListener->dispatchFinished( aEvent );
223     }
224 
225 /*
226     // Try to initialize player.
227     m_xListener = xListener;
228     if (m_aPlayer.SetSoundName(aURL.Complete))
229     {
230         // OK- we can start async playing ...
231         // Count this request and initialize self-holder against dieing by uno ref count ...
232         m_xSelfHold = css::uno::Reference< css::uno::XInterface >(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
233         m_aPlayer.Play();
234     }
235 */
236     // } SAFE
237     aLock.unlock();
238 }
239 
240 void SAL_CALL Oxt_Handler::dispatch( const css::util::URL&                                  aURL       ,
241                                      const css::uno::Sequence< css::beans::PropertyValue >& lArguments )
242     throw( css::uno::RuntimeException )
243 {
244     dispatchWithNotification( aURL, lArguments, css::uno::Reference< css::frame::XDispatchResultListener >() );
245 }
246 
247 /*-************************************************************************************************************//**
248     @interface  ::com::sun::star::document::XExtendedFilterDetection
249 
250     @short      try to detect file (given as argument included in "lDescriptor")
251     @descr      We try to detect, if given file could be handled by this class and is a well known one.
252                 If it is - we return right internal type name - otherwise we return nothing!
253                 So call can search for another detect service and ask him too.
254 
255     @attention  a) We don't need any mutex here ... because we don't use any member!
256                 b) Dont' use internal player instance "m_pPlayer" to detect given sound file!
257                    It's not neccessary to do that ... and we can use temp. variable to do the same.
258                    This way is easy - we don't must synchronize it with currently played sounds!
259                    Another reason to do so ... We are a listener on our internal ma_Player object.
260                    If you would call "IsSoundFile()" on this instance, he would call us back and
261                    we make some uneccssary things ...
262 
263     @seealso    -
264 
265     @param      "lDescriptor", description of file to detect
266     @return     Internal type name which match this file ... or nothing if it is unknown.
267 
268     @onerror    We return nothing.
269     @threadsafe yes
270 *//*-*************************************************************************************************************/
271 ::rtl::OUString SAL_CALL Oxt_Handler::detect( css::uno::Sequence< css::beans::PropertyValue >& lDescriptor )
272     throw( css::uno::RuntimeException )
273 {
274     // Our default is "nothing". So we can return it, if detection failed or fily type is realy unknown.
275     ::rtl::OUString sTypeName;
276 
277     // Analyze given descriptor to find filename or input stream or ...
278     ::comphelper::MediaDescriptor aDescriptor( lDescriptor );
279     ::rtl::OUString               sURL       = aDescriptor.getUnpackedValueOrDefault( ::comphelper::MediaDescriptor::PROP_URL(), ::rtl::OUString() );
280 
281     long nLength = sURL.getLength();
282     if ( ( nLength > 4 ) && sURL.matchIgnoreAsciiCase( UNISTRING(".oxt"), nLength-4 ) )
283     {
284         // "IsSoundFile" idffer between different "wav" and "au" file versions ...
285         // couldn't return this information ... because: He use the OS to detect it!
286         // I think we can the following ones:
287         //  a) look for given extension of url to map our type decision HARD CODED!!!
288         //  b) return preferred type every time... it's easy :-)
289         sTypeName = ::rtl::OUString::createFromAscii("oxt_OpenOffice_Extension");
290         aDescriptor[::comphelper::MediaDescriptor::PROP_TYPENAME()] <<= sTypeName;
291         aDescriptor >> lDescriptor;
292     }
293 
294     // Return our decision.
295     return sTypeName;
296 }
297 
298 } // namespace framework
299