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 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_framework.hxx"
26 
27 //_________________________________________________________________________________________________________________
28 // include own things
29 #include <recording/dispatchrecordersupplier.hxx>
30 #include <threadhelp/writeguard.hxx>
31 #include <threadhelp/readguard.hxx>
32 #include <services.h>
33 
34 //_________________________________________________________________________________________________________________
35 // include interfaces
36 #include <com/sun/star/frame/XRecordableDispatch.hpp>
37 
38 //_________________________________________________________________________________________________________________
39 // include other projects
40 #include <vcl/svapp.hxx>
41 
42 //_________________________________________________________________________________________________________________
43 // namespace
44 
45 namespace framework{
46 
47 //_________________________________________________________________________________________________________________
48 // non exported const
49 
50 //_________________________________________________________________________________________________________________
51 // non exported definitions
52 
53 //_________________________________________________________________________________________________________________
54 // declarations
55 
56 //*****************************************************************************************************************
57 // XInterface, XTypeProvider
58 //*****************************************************************************************************************
DEFINE_XINTERFACE_3(DispatchRecorderSupplier,OWeakObject,DIRECT_INTERFACE (css::lang::XTypeProvider),DIRECT_INTERFACE (css::lang::XServiceInfo),DIRECT_INTERFACE (css::frame::XDispatchRecorderSupplier))59 DEFINE_XINTERFACE_3(
60     DispatchRecorderSupplier,
61     OWeakObject,
62     DIRECT_INTERFACE(css::lang::XTypeProvider),
63     DIRECT_INTERFACE(css::lang::XServiceInfo),
64     DIRECT_INTERFACE(css::frame::XDispatchRecorderSupplier))
65 
66 DEFINE_XTYPEPROVIDER_3(
67     DispatchRecorderSupplier,
68     css::lang::XTypeProvider,
69     css::lang::XServiceInfo,
70     css::frame::XDispatchRecorderSupplier)
71 
72 DEFINE_XSERVICEINFO_MULTISERVICE(
73     DispatchRecorderSupplier,
74     ::cppu::OWeakObject,
75     SERVICENAME_DISPATCHRECORDERSUPPLIER,
76     IMPLEMENTATIONNAME_DISPATCHRECORDERSUPPLIER)
77 
78 DEFINE_INIT_SERVICE(
79     DispatchRecorderSupplier,
80     {
81         /*Attention
82             I think we don't need any mutex or lock here... because we are called by our own static method impl_createInstance()
83             to create a new instance of this class by our own supported service factory.
84             see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations!
85         */
86     }
87 )
88 
89 //_____________________________________________________________________________
90 /**
91     @short  standard constructor to create instance
92     @descr  Because an instance will be initialized by her interface methods
93             it's not necessary to do anything here.
94  */
95 DispatchRecorderSupplier::DispatchRecorderSupplier( const css::uno::Reference< css::lang::XMultiServiceFactory >& xFactory )
96 		//	init baseclasses first!
97 		//	Attention: Don't change order of initialization!
98         : ThreadHelpBase     ( &Application::GetSolarMutex() )
99         , ::cppu::OWeakObject(                               )
100 		//	init member
101         , m_xDispatchRecorder( NULL                          )
102         , m_xFactory         ( xFactory                      )
103 {
104 }
105 
106 //_____________________________________________________________________________
107 /**
108     @short  standard destructor
109     @descr  We are a helper and not a real service. So we don't provide
110             dispose() functionality. This supplier dies by ref count mechanism
111             and should release all internal used ones too.
112  */
~DispatchRecorderSupplier()113 DispatchRecorderSupplier::~DispatchRecorderSupplier()
114 {
115     m_xFactory          = NULL;
116     m_xDispatchRecorder = NULL;
117 }
118 
119 //_____________________________________________________________________________
120 /**
121     @short      set a new dispatch recorder on this supplier
122     @descr      Because there can exist more than one recorder implementations
123                 (to generate java/basic/... scripts from recorded data) it must
124                 be possible to set it on a supplier.
125 
126     @see        getDispatchRecorder()
127 
128     @param      xRecorder
129                 the new recorder to set it
130                 <br><NULL/> isn't recommended, because recording without a
131                 valid recorder can't work. But it's not checked here. So user
132                 of this supplier can decide that without changing this
133                 implementation.
134 
135     @change     09.04.2002 by Andreas Schluens
136  */
setDispatchRecorder(const css::uno::Reference<css::frame::XDispatchRecorder> & xRecorder)137 void SAL_CALL DispatchRecorderSupplier::setDispatchRecorder( const css::uno::Reference< css::frame::XDispatchRecorder >& xRecorder ) throw (css::uno::RuntimeException)
138 {
139     // SAFE =>
140     WriteGuard aWriteLock(m_aLock);
141     m_xDispatchRecorder=xRecorder;
142     // => SAFE
143 }
144 //_____________________________________________________________________________
145 /**
146     @short      provides access to the dispatch recorder of this supplier
147     @descr      Such recorder can be used outside to record dispatches.
148                 But normally he is used internally only. Of course he must be used
149                 from outside to get the recorded data e.g. for saving it as a
150                 script.
151 
152     @see        setDispatchRecorder()
153 
154     @return     the internal used dispatch recorder
155                 <br>May it can be <NULL/> if no one was set before.
156 
157     @change     09.04.2002 by Andreas Schluens
158  */
getDispatchRecorder()159 css::uno::Reference< css::frame::XDispatchRecorder > SAL_CALL DispatchRecorderSupplier::getDispatchRecorder() throw (css::uno::RuntimeException)
160 {
161     // SAFE =>
162     ReadGuard aReadLock(m_aLock);
163     return m_xDispatchRecorder;
164     // => SAFE
165 }
166 
167 //_____________________________________________________________________________
168 /**
169     @short      execute a dispatch request and record it
170     @descr      If given dispatch object provides right recording interface it
171                 will be used. If it's not supported it records the pure dispatch
172                 parameters only. There is no code neither the possibility to
173                 check if recording is enabled or not.
174 
175     @param      aURL            the command URL
176     @param      lArguments      optional arguments (see com.sun.star.document.MediaDescriptor for further informations)
177     @param      xDispatcher     the original dispatch object which should be recorded
178 
179     @change     09.04.2002 by Andreas Schluens
180  */
dispatchAndRecord(const css::util::URL & aURL,const css::uno::Sequence<css::beans::PropertyValue> & lArguments,const css::uno::Reference<css::frame::XDispatch> & xDispatcher)181 void SAL_CALL DispatchRecorderSupplier::dispatchAndRecord( const css::util::URL&                                  aURL        ,
182                                                            const css::uno::Sequence< css::beans::PropertyValue >& lArguments  ,
183                                                            const css::uno::Reference< css::frame::XDispatch >&    xDispatcher ) throw (css::uno::RuntimeException)
184 {
185     // SAFE =>
186     ReadGuard aReadLock(m_aLock);
187     css::uno::Reference< css::frame::XDispatchRecorder > xRecorder = m_xDispatchRecorder;
188     aReadLock.unlock();
189     // => SAFE
190 
191     // clear unspecific situations
192     if (!xDispatcher.is())
193         throw css::uno::RuntimeException(DECLARE_ASCII("specification violation: dispatcher is NULL"), static_cast< ::cppu::OWeakObject* >(this));
194 
195     if (!xRecorder.is())
196         throw css::uno::RuntimeException(DECLARE_ASCII("specification violation: no valid dispatch recorder available"), static_cast< ::cppu::OWeakObject* >(this));
197 
198     // check, if given dispatch supports record functionality by itself...
199     // or must be wrapped.
200     css::uno::Reference< css::frame::XRecordableDispatch > xRecordable(
201         xDispatcher,
202         css::uno::UNO_QUERY);
203 
204     if (xRecordable.is())
205         xRecordable->dispatchAndRecord(aURL,lArguments,xRecorder);
206     else
207     {
208         // There is no reason to wait for information about success
209         // of this request. Because status information of a dispatch
210         // is not guaranteed. So we execute it and record used
211         // parameters only.
212         xDispatcher->dispatch(aURL,lArguments);
213         xRecorder->recordDispatch(aURL,lArguments);
214     }
215 }
216 
217 }	// namespace framework
218