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 //_______________________________________________
32 // my own includes
33 #include <dispatch/loaddispatcher.hxx>
34 #include <threadhelp/readguard.hxx>
35 #include <threadhelp/writeguard.hxx>
36 
37 //_______________________________________________
38 // interface includes
39 #include <com/sun/star/frame/DispatchResultState.hpp>
40 
41 //_______________________________________________
42 // includes of other projects
43 
44 //_______________________________________________
45 // namespace
46 
47 namespace framework{
48 
49 namespace css = ::com::sun::star;
50 
51 //_______________________________________________
52 // declarations
53 
54 /*-----------------------------------------------
55     20.08.2003 09:52
56 -----------------------------------------------*/
57 LoadDispatcher::LoadDispatcher(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR       ,
58                                const css::uno::Reference< css::frame::XFrame >&              xOwnerFrame ,
59                                const ::rtl::OUString                                         sTargetName ,
60                                      sal_Int32                                               nSearchFlags)
61     : ThreadHelpBase(            )
62     , m_xSMGR       (xSMGR       )
63     , m_xOwnerFrame (xOwnerFrame )
64     , m_sTarget     (sTargetName )
65     , m_nSearchFlags(nSearchFlags)
66     , m_aLoader     (xSMGR       )
67 {
68 }
69 
70 /*-----------------------------------------------
71     20.08.2003 09:12
72 -----------------------------------------------*/
73 LoadDispatcher::~LoadDispatcher()
74 {
75     m_xSMGR.clear();
76 }
77 
78 /*-----------------------------------------------
79     20.08.2003 09:58
80 -----------------------------------------------*/
81 void SAL_CALL LoadDispatcher::dispatchWithNotification(const css::util::URL&                                             aURL      ,
82                                                        const css::uno::Sequence< css::beans::PropertyValue >&            lArguments,
83                                                        const css::uno::Reference< css::frame::XDispatchResultListener >& xListener )
84     throw(css::uno::RuntimeException)
85 {
86     impl_dispatch( aURL, lArguments, xListener );
87 }
88 
89 /*-----------------------------------------------
90     20.08.2003 09:16
91 -----------------------------------------------*/
92 void SAL_CALL LoadDispatcher::dispatch(const css::util::URL&                                  aURL      ,
93                                        const css::uno::Sequence< css::beans::PropertyValue >& lArguments)
94     throw(css::uno::RuntimeException)
95 {
96     impl_dispatch( aURL, lArguments, css::uno::Reference< css::frame::XDispatchResultListener >() );
97 }
98 
99 /*-----------------------------------------------
100     14.04.2008
101 -----------------------------------------------*/
102 css::uno::Any SAL_CALL LoadDispatcher::dispatchWithReturnValue( const css::util::URL& rURL,
103                                                                 const css::uno::Sequence< css::beans::PropertyValue >& lArguments )
104     throw( css::uno::RuntimeException )
105 {
106     return impl_dispatch( rURL, lArguments, css::uno::Reference< css::frame::XDispatchResultListener >());
107 }
108 
109 /*-----------------------------------------------
110     20.08.2003 10:48
111 -----------------------------------------------*/
112 void SAL_CALL LoadDispatcher::addStatusListener(const css::uno::Reference< css::frame::XStatusListener >& /*xListener*/,
113                                                 const css::util::URL&                                     /*aURL*/     )
114     throw(css::uno::RuntimeException)
115 {
116 }
117 
118 /*-----------------------------------------------
119     20.08.2003 10:49
120 -----------------------------------------------*/
121 void SAL_CALL LoadDispatcher::removeStatusListener(const css::uno::Reference< css::frame::XStatusListener >& /*xListener*/,
122                                                    const css::util::URL&                                     /*aURL*/     )
123     throw(css::uno::RuntimeException)
124 {
125 }
126 
127 /*-----------------------------------------------
128     20.08.2003 09:58
129 -----------------------------------------------*/
130 css::uno::Any LoadDispatcher::impl_dispatch( const css::util::URL& rURL,
131                                              const css::uno::Sequence< css::beans::PropertyValue >& lArguments,
132                                              const css::uno::Reference< css::frame::XDispatchResultListener >& xListener )
133 {
134     // Attention: May be nobody outside hold such temp. dispatch object alive (because
135     // the container in which we resists isnt implemented threadsafe but updated by a timer
136     // and clear our reference ...) we should hold us self alive!
137     css::uno::Reference< css::uno::XInterface > xThis(static_cast< css::frame::XNotifyingDispatch* >(this), css::uno::UNO_QUERY);
138 
139     // SAFE -> ----------------------------------
140     ReadGuard aReadLock(m_aLock);
141 
142     // We are the only client of this load env object ... but
143     // may a dispatch request before is still in progress (?!).
144     // Then we should wait a little bit and block this new request.
145     // In case we run into the timeout, we should reject this new request
146     // and return "FAILED" as result. Otherwhise we can start this new operation.
147     if (!m_aLoader.waitWhileLoading(2000)) // => 2 sec.
148     {
149         if (xListener.is())
150             xListener->dispatchFinished(
151                 css::frame::DispatchResultEvent(xThis, css::frame::DispatchResultState::DONTKNOW, css::uno::Any())); // DONTKNOW? ... not realy started ... not realy failed :-)
152     }
153 
154     css::uno::Reference< css::frame::XFrame > xBaseFrame(m_xOwnerFrame.get(), css::uno::UNO_QUERY);
155     if (!xBaseFrame.is())
156     {
157         if (xListener.is())
158             xListener->dispatchFinished(
159                 css::frame::DispatchResultEvent(xThis, css::frame::DispatchResultState::FAILURE, css::uno::Any()));
160     }
161 
162     // OK ... now the internal loader seems to be useable for new requests
163     // and our owner frame seems to be valid for such operations.
164     // Initialize it with all new but needed properties and start the loading.
165     css::uno::Reference< css::lang::XComponent > xComponent;
166     try
167     {
168         m_aLoader.initializeLoading( rURL.Complete, lArguments, xBaseFrame, m_sTarget, m_nSearchFlags, (LoadEnv::EFeature)(LoadEnv::E_ALLOW_CONTENTHANDLER | LoadEnv::E_WORK_WITH_UI));
169         m_aLoader.startLoading();
170         m_aLoader.waitWhileLoading(); // wait for ever!
171         xComponent = m_aLoader.getTargetComponent();
172 
173         // TODO thinking about asynchronous operations and listener support
174     }
175     catch(const LoadEnvException&)
176         { xComponent.clear(); }
177 
178     if (xListener.is())
179     {
180         if (xComponent.is())
181             xListener->dispatchFinished(
182                 css::frame::DispatchResultEvent(xThis, css::frame::DispatchResultState::SUCCESS, css::uno::Any()));
183         else
184             xListener->dispatchFinished(
185                 css::frame::DispatchResultEvent(xThis, css::frame::DispatchResultState::FAILURE, css::uno::Any()));
186     }
187 
188     // return the model - like loadComponentFromURL()
189     css::uno::Any aRet;
190     if ( xComponent.is () )
191         aRet = css::uno::makeAny( xComponent );
192 
193     aReadLock.unlock();
194     // <- SAFE ----------------------------------
195     return aRet;
196 }
197 
198 } // namespace framework
199