Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <services/dispatchhelper.hxx>
30 : : #include <threadhelp/readguard.hxx>
31 : : #include <threadhelp/writeguard.hxx>
32 : : #include <services.h>
33 : :
34 : : #include <com/sun/star/util/URLTransformer.hpp>
35 : : #include <com/sun/star/util/XURLTransformer.hpp>
36 : : #include <com/sun/star/frame/XNotifyingDispatch.hpp>
37 : :
38 : : #include <comphelper/componentcontext.hxx>
39 : :
40 : : namespace framework{
41 : :
42 : : //_______________________________________________
43 : : // XInterface, XTypeProvider, XServiceInfo
44 : :
45 [ + - ][ + - ]: 42 : DEFINE_XSERVICEINFO_MULTISERVICE(DispatchHelper ,
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ # # ]
[ # # ]
46 : : ::cppu::OWeakObject ,
47 : : SERVICENAME_DISPATCHHELPER ,
48 : : IMPLEMENTATIONNAME_DISPATCHHELPER)
49 : :
50 : 4 : DEFINE_INIT_SERVICE( DispatchHelper, {} )
51 : :
52 : : //_______________________________________________
53 : :
54 : : /** ctor.
55 : :
56 : : @param xSMGR the global uno service manager, which can be used to create own needed services.
57 : : */
58 : 4 : DispatchHelper::DispatchHelper( const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR )
59 : : : ThreadHelpBase( )
60 : : // Init member
61 [ + - ][ + - ]: 4 : , m_xSMGR (xSMGR)
62 : : {
63 : 4 : }
64 : :
65 : : //_______________________________________________
66 : :
67 : : /** dtor.
68 : : */
69 [ + - ][ + - ]: 4 : DispatchHelper::~DispatchHelper()
70 : : {
71 [ - + ]: 8 : }
72 : :
73 : : //_______________________________________________
74 : :
75 : : /** capsulate all steps of a dispatch request and provide so an easy way for dispatches.
76 : :
77 : : @param xDispatchProvider
78 : : identifies the object, which provides may be valid dispatch objects for this execute.
79 : :
80 : : @param sURL
81 : : describes the requested feature.
82 : :
83 : : @param sTargetFrameName
84 : : points to the frame, which must be used (or may be created) for this dispatch.
85 : :
86 : : @param nSearchFlags
87 : : in case the <var>sTargetFrameName</var> isn't unique, these flags regulate further searches.
88 : :
89 : : @param lArguments
90 : : optional arguments for this request.
91 : :
92 : : @return An Any which capsulate a possible result of the internal wrapped dispatch.
93 : : */
94 : 8 : css::uno::Any SAL_CALL DispatchHelper::executeDispatch(
95 : : const css::uno::Reference< css::frame::XDispatchProvider >& xDispatchProvider ,
96 : : const ::rtl::OUString& sURL ,
97 : : const ::rtl::OUString& sTargetFrameName ,
98 : : sal_Int32 nSearchFlags ,
99 : : const css::uno::Sequence< css::beans::PropertyValue >& lArguments )
100 : : throw(css::uno::RuntimeException)
101 : : {
102 [ + - ]: 8 : css::uno::Reference< css::uno::XInterface > xTHIS(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
103 : :
104 : : // check for valid parameters
105 [ - + ]: 16 : if (
[ + - - + ]
106 : 8 : (!xDispatchProvider.is()) ||
107 : 8 : (sURL.isEmpty() )
108 : : )
109 : : {
110 : 0 : return css::uno::Any();
111 : : }
112 : :
113 : : // parse given URL
114 : : /* SAFE { */
115 [ + - ]: 8 : ReadGuard aReadLock(m_aLock);
116 [ + - ][ + - ]: 8 : css::uno::Reference< css::util::XURLTransformer > xParser(css::util::URLTransformer::create(::comphelper::ComponentContext(m_xSMGR).getUNOContext()) );
[ + - ][ + - ]
117 [ + - ]: 8 : aReadLock.unlock();
118 : : /* } SAFE */
119 : :
120 : 8 : css::util::URL aURL;
121 : 8 : aURL.Complete = sURL;
122 [ + - ][ + - ]: 8 : xParser->parseStrict(aURL);
123 : :
124 : : // search dispatcher
125 [ + - ][ + - ]: 8 : css::uno::Reference< css::frame::XDispatch > xDispatch = xDispatchProvider->queryDispatch(aURL, sTargetFrameName, nSearchFlags);
126 [ + - ]: 8 : css::uno::Reference< css::frame::XNotifyingDispatch > xNotifyDispatch (xDispatch, css::uno::UNO_QUERY);
127 : :
128 : : // make sure that synchronous execution is used (if possible)
129 [ + - ]: 8 : css::uno::Sequence< css::beans::PropertyValue > aArguments( lArguments );
130 : 8 : sal_Int32 nLength = lArguments.getLength();
131 [ + - ]: 8 : aArguments.realloc( nLength + 1 );
132 [ + - ]: 8 : aArguments[ nLength ].Name = ::rtl::OUString("SynchronMode");
133 [ + - ][ + - ]: 8 : aArguments[ nLength ].Value <<= (sal_Bool) sal_True;
134 : :
135 : 8 : css::uno::Any aResult;
136 [ + - ]: 8 : if (xNotifyDispatch.is())
137 : : {
138 : : // dispatch it with guaranteed notification
139 : : // Here we can hope for a result ... instead of the normal dispatch.
140 [ + - ]: 8 : css::uno::Reference< css::frame::XDispatchResultListener > xListener(xTHIS, css::uno::UNO_QUERY);
141 : : /* SAFE { */
142 [ + - ]: 8 : WriteGuard aWriteLock(m_aLock);
143 [ + - ][ + - ]: 8 : m_xBroadcaster = css::uno::Reference< css::uno::XInterface >(xNotifyDispatch, css::uno::UNO_QUERY);
144 : 8 : m_aResult = css::uno::Any();
145 [ + - ]: 8 : m_aBlock.reset();
146 [ + - ]: 8 : aWriteLock.unlock();
147 : : /* } SAFE */
148 : :
149 : : // dispatch it and wait for a notification
150 : : // TODO/MBA: waiting in main thread?!
151 [ + - ][ + - ]: 8 : xNotifyDispatch->dispatchWithNotification(aURL, aArguments, xListener);
152 [ + - ]: 8 : aResult = m_aResult;
153 : : }
154 : : else
155 [ # # ]: 0 : if (xDispatch.is())
156 : : {
157 : : // dispatch it without any chance to get a result
158 [ # # ][ # # ]: 0 : xDispatch->dispatch( aURL, aArguments );
159 : : }
160 : :
161 [ + - ][ + - ]: 8 : return aResult;
162 : : }
163 : :
164 : : //_______________________________________________
165 : :
166 : : /** callback for started dispatch with guaranteed notifications.
167 : :
168 : : We must save the result, so the method executeDispatch() can return it.
169 : : Further we must release the broadcaster (otherwhise it can't die)
170 : : and unblock the waiting executeDispatch() request.
171 : :
172 : : @param aResult
173 : : describes the result of the dispatch operation
174 : : */
175 : 8 : void SAL_CALL DispatchHelper::dispatchFinished( const css::frame::DispatchResultEvent& aResult )
176 : : throw(css::uno::RuntimeException)
177 : : {
178 : : /* SAFE { */
179 [ + - ]: 8 : WriteGuard aWriteLock(m_aLock);
180 : :
181 [ + - ]: 8 : m_aResult <<= aResult;
182 [ + - ]: 8 : m_aBlock.set();
183 [ + - ]: 8 : m_xBroadcaster.clear();
184 : :
185 : : /* } SAFE */
186 : 8 : }
187 : :
188 : : //_______________________________________________
189 : :
190 : : /** we has to realease our broadcaster reference.
191 : :
192 : : @param aEvent
193 : : describe the source of this event and MUST be our save broadcaster!
194 : : */
195 : 0 : void SAL_CALL DispatchHelper::disposing( const css::lang::EventObject& )
196 : : throw(css::uno::RuntimeException)
197 : : {
198 : : /* SAFE { */
199 [ # # ]: 0 : WriteGuard aWriteLock(m_aLock);
200 : :
201 : 0 : m_aResult.clear();
202 [ # # ]: 0 : m_aBlock.set();
203 [ # # ]: 0 : m_xBroadcaster.clear();
204 : :
205 : : /* } SAFE */
206 : 0 : }
207 : :
208 : : }
209 : :
210 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|