1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski *
3*b1cdbd2cSJim Jagielski * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski * or more contributor license agreements. See the NOTICE file
5*b1cdbd2cSJim Jagielski * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski * regarding copyright ownership. The ASF licenses this file
7*b1cdbd2cSJim Jagielski * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski * with the License. You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski *
11*b1cdbd2cSJim Jagielski * http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski *
13*b1cdbd2cSJim Jagielski * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski * KIND, either express or implied. See the License for the
17*b1cdbd2cSJim Jagielski * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski * under the License.
19*b1cdbd2cSJim Jagielski *
20*b1cdbd2cSJim Jagielski *************************************************************/
21*b1cdbd2cSJim Jagielski
22*b1cdbd2cSJim Jagielski
23*b1cdbd2cSJim Jagielski
24*b1cdbd2cSJim Jagielski // MARKER(update_precomp.py): autogen include statement, do not remove
25*b1cdbd2cSJim Jagielski #include "precompiled_framework.hxx"
26*b1cdbd2cSJim Jagielski
27*b1cdbd2cSJim Jagielski //________________________________
28*b1cdbd2cSJim Jagielski // my own includes
29*b1cdbd2cSJim Jagielski #include <jobs/job.hxx>
30*b1cdbd2cSJim Jagielski #include <threadhelp/readguard.hxx>
31*b1cdbd2cSJim Jagielski #include <threadhelp/writeguard.hxx>
32*b1cdbd2cSJim Jagielski #include <general.h>
33*b1cdbd2cSJim Jagielski #include <services.h>
34*b1cdbd2cSJim Jagielski
35*b1cdbd2cSJim Jagielski //________________________________
36*b1cdbd2cSJim Jagielski // interface includes
37*b1cdbd2cSJim Jagielski #include <com/sun/star/task/XJob.hpp>
38*b1cdbd2cSJim Jagielski #include <com/sun/star/task/XAsyncJob.hpp>
39*b1cdbd2cSJim Jagielski #include <com/sun/star/util/XCloseBroadcaster.hpp>
40*b1cdbd2cSJim Jagielski #include <com/sun/star/util/XCloseable.hpp>
41*b1cdbd2cSJim Jagielski #include <com/sun/star/lang/DisposedException.hpp>
42*b1cdbd2cSJim Jagielski
43*b1cdbd2cSJim Jagielski //________________________________
44*b1cdbd2cSJim Jagielski // includes of other projects
45*b1cdbd2cSJim Jagielski #include <rtl/ustrbuf.hxx>
46*b1cdbd2cSJim Jagielski #include <vcl/svapp.hxx>
47*b1cdbd2cSJim Jagielski
48*b1cdbd2cSJim Jagielski //________________________________
49*b1cdbd2cSJim Jagielski // namespace
50*b1cdbd2cSJim Jagielski
51*b1cdbd2cSJim Jagielski namespace framework{
52*b1cdbd2cSJim Jagielski
53*b1cdbd2cSJim Jagielski //________________________________
54*b1cdbd2cSJim Jagielski // non exported const
55*b1cdbd2cSJim Jagielski
56*b1cdbd2cSJim Jagielski //________________________________
57*b1cdbd2cSJim Jagielski // non exported definitions
58*b1cdbd2cSJim Jagielski
59*b1cdbd2cSJim Jagielski //________________________________
60*b1cdbd2cSJim Jagielski // declarations
61*b1cdbd2cSJim Jagielski
DEFINE_XINTERFACE_4(Job,OWeakObject,DIRECT_INTERFACE (css::lang::XTypeProvider),DIRECT_INTERFACE (css::task::XJobListener),DIRECT_INTERFACE (css::frame::XTerminateListener),DIRECT_INTERFACE (css::util::XCloseListener))62*b1cdbd2cSJim Jagielski DEFINE_XINTERFACE_4( Job ,
63*b1cdbd2cSJim Jagielski OWeakObject ,
64*b1cdbd2cSJim Jagielski DIRECT_INTERFACE(css::lang::XTypeProvider ),
65*b1cdbd2cSJim Jagielski DIRECT_INTERFACE(css::task::XJobListener ),
66*b1cdbd2cSJim Jagielski DIRECT_INTERFACE(css::frame::XTerminateListener),
67*b1cdbd2cSJim Jagielski DIRECT_INTERFACE(css::util::XCloseListener )
68*b1cdbd2cSJim Jagielski )
69*b1cdbd2cSJim Jagielski
70*b1cdbd2cSJim Jagielski DEFINE_XTYPEPROVIDER_4( Job ,
71*b1cdbd2cSJim Jagielski css::lang::XTypeProvider ,
72*b1cdbd2cSJim Jagielski css::task::XJobListener ,
73*b1cdbd2cSJim Jagielski css::frame::XTerminateListener,
74*b1cdbd2cSJim Jagielski css::util::XCloseListener
75*b1cdbd2cSJim Jagielski )
76*b1cdbd2cSJim Jagielski
77*b1cdbd2cSJim Jagielski //________________________________
78*b1cdbd2cSJim Jagielski /**
79*b1cdbd2cSJim Jagielski @short standard ctor
80*b1cdbd2cSJim Jagielski @descr It initialize this new instance. But it set some generic parameters here only.
81*b1cdbd2cSJim Jagielski Specialized informations (e.g. the alias or service name ofthis job) will be set
82*b1cdbd2cSJim Jagielski later using the method setJobData().
83*b1cdbd2cSJim Jagielski
84*b1cdbd2cSJim Jagielski @param xSMGR
85*b1cdbd2cSJim Jagielski reference to the uno service manager
86*b1cdbd2cSJim Jagielski
87*b1cdbd2cSJim Jagielski @param xFrame
88*b1cdbd2cSJim Jagielski reference to the frame, in which environment we run
89*b1cdbd2cSJim Jagielski (May be null!)
90*b1cdbd2cSJim Jagielski */
91*b1cdbd2cSJim Jagielski Job::Job( /*IN*/ const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
92*b1cdbd2cSJim Jagielski /*IN*/ const css::uno::Reference< css::frame::XFrame >& xFrame )
93*b1cdbd2cSJim Jagielski : ThreadHelpBase (&Application::GetSolarMutex())
94*b1cdbd2cSJim Jagielski , ::cppu::OWeakObject ( )
95*b1cdbd2cSJim Jagielski , m_aJobCfg (xSMGR )
96*b1cdbd2cSJim Jagielski , m_xSMGR (xSMGR )
97*b1cdbd2cSJim Jagielski , m_xFrame (xFrame )
98*b1cdbd2cSJim Jagielski , m_bListenOnDesktop (sal_False )
99*b1cdbd2cSJim Jagielski , m_bListenOnFrame (sal_False )
100*b1cdbd2cSJim Jagielski , m_bListenOnModel (sal_False )
101*b1cdbd2cSJim Jagielski , m_bPendingCloseFrame (sal_False )
102*b1cdbd2cSJim Jagielski , m_bPendingCloseModel (sal_False )
103*b1cdbd2cSJim Jagielski , m_eRunState (E_NEW )
104*b1cdbd2cSJim Jagielski {
105*b1cdbd2cSJim Jagielski }
106*b1cdbd2cSJim Jagielski
107*b1cdbd2cSJim Jagielski //________________________________
108*b1cdbd2cSJim Jagielski /**
109*b1cdbd2cSJim Jagielski @short standard ctor
110*b1cdbd2cSJim Jagielski @descr It initialize this new instance. But it set some generic parameters here only.
111*b1cdbd2cSJim Jagielski Specialized informations (e.g. the alias or service name ofthis job) will be set
112*b1cdbd2cSJim Jagielski later using the method setJobData().
113*b1cdbd2cSJim Jagielski
114*b1cdbd2cSJim Jagielski @param xSMGR
115*b1cdbd2cSJim Jagielski reference to the uno service manager
116*b1cdbd2cSJim Jagielski
117*b1cdbd2cSJim Jagielski @param xModel
118*b1cdbd2cSJim Jagielski reference to the model, in which environment we run
119*b1cdbd2cSJim Jagielski (May be null!)
120*b1cdbd2cSJim Jagielski */
Job(const css::uno::Reference<css::lang::XMultiServiceFactory> & xSMGR,const css::uno::Reference<css::frame::XModel> & xModel)121*b1cdbd2cSJim Jagielski Job::Job( /*IN*/ const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
122*b1cdbd2cSJim Jagielski /*IN*/ const css::uno::Reference< css::frame::XModel >& xModel )
123*b1cdbd2cSJim Jagielski : ThreadHelpBase (&Application::GetSolarMutex())
124*b1cdbd2cSJim Jagielski , ::cppu::OWeakObject ( )
125*b1cdbd2cSJim Jagielski , m_aJobCfg (xSMGR )
126*b1cdbd2cSJim Jagielski , m_xSMGR (xSMGR )
127*b1cdbd2cSJim Jagielski , m_xModel (xModel )
128*b1cdbd2cSJim Jagielski , m_bListenOnDesktop (sal_False )
129*b1cdbd2cSJim Jagielski , m_bListenOnFrame (sal_False )
130*b1cdbd2cSJim Jagielski , m_bListenOnModel (sal_False )
131*b1cdbd2cSJim Jagielski , m_bPendingCloseFrame (sal_False )
132*b1cdbd2cSJim Jagielski , m_bPendingCloseModel (sal_False )
133*b1cdbd2cSJim Jagielski , m_eRunState (E_NEW )
134*b1cdbd2cSJim Jagielski {
135*b1cdbd2cSJim Jagielski }
136*b1cdbd2cSJim Jagielski
137*b1cdbd2cSJim Jagielski //________________________________
138*b1cdbd2cSJim Jagielski /**
139*b1cdbd2cSJim Jagielski @short superflous!
140*b1cdbd2cSJim Jagielski @descr Releasing of memory and reference must be done inside die() call.
141*b1cdbd2cSJim Jagielski Otherwhise it's a bug.
142*b1cdbd2cSJim Jagielski */
~Job()143*b1cdbd2cSJim Jagielski Job::~Job()
144*b1cdbd2cSJim Jagielski {
145*b1cdbd2cSJim Jagielski }
146*b1cdbd2cSJim Jagielski
147*b1cdbd2cSJim Jagielski //________________________________
148*b1cdbd2cSJim Jagielski /**
149*b1cdbd2cSJim Jagielski @short set (or delete) a listener for sending dispatch result events
150*b1cdbd2cSJim Jagielski @descr Because this object is used in a wrapped mode ... the original listener
151*b1cdbd2cSJim Jagielski for such events can't be registered here directly. Because the
152*b1cdbd2cSJim Jagielski listener expect to get the original object given as source of the event.
153*b1cdbd2cSJim Jagielski That's why we get this source here too, to fake(!) it at sending time!
154*b1cdbd2cSJim Jagielski
155*b1cdbd2cSJim Jagielski @param xListener
156*b1cdbd2cSJim Jagielski the original listener for dispatch result events
157*b1cdbd2cSJim Jagielski
158*b1cdbd2cSJim Jagielski @param xSourceFake
159*b1cdbd2cSJim Jagielski our user, which got the registration request for this listener
160*b1cdbd2cSJim Jagielski */
setDispatchResultFake(const css::uno::Reference<css::frame::XDispatchResultListener> & xListener,const css::uno::Reference<css::uno::XInterface> & xSourceFake)161*b1cdbd2cSJim Jagielski void Job::setDispatchResultFake( /*IN*/ const css::uno::Reference< css::frame::XDispatchResultListener >& xListener ,
162*b1cdbd2cSJim Jagielski /*IN*/ const css::uno::Reference< css::uno::XInterface >& xSourceFake )
163*b1cdbd2cSJim Jagielski {
164*b1cdbd2cSJim Jagielski /* SAFE { */
165*b1cdbd2cSJim Jagielski WriteGuard aWriteLock(m_aLock);
166*b1cdbd2cSJim Jagielski
167*b1cdbd2cSJim Jagielski // reject dangerous calls
168*b1cdbd2cSJim Jagielski if (m_eRunState != E_NEW)
169*b1cdbd2cSJim Jagielski {
170*b1cdbd2cSJim Jagielski LOG_WARNING("Job::setJobData()", "job may still running or already finished")
171*b1cdbd2cSJim Jagielski return;
172*b1cdbd2cSJim Jagielski }
173*b1cdbd2cSJim Jagielski
174*b1cdbd2cSJim Jagielski m_xResultListener = xListener ;
175*b1cdbd2cSJim Jagielski m_xResultSourceFake = xSourceFake;
176*b1cdbd2cSJim Jagielski aWriteLock.unlock();
177*b1cdbd2cSJim Jagielski /* } SAFE */
178*b1cdbd2cSJim Jagielski }
179*b1cdbd2cSJim Jagielski
setJobData(const JobData & aData)180*b1cdbd2cSJim Jagielski void Job::setJobData( const JobData& aData )
181*b1cdbd2cSJim Jagielski {
182*b1cdbd2cSJim Jagielski /* SAFE { */
183*b1cdbd2cSJim Jagielski WriteGuard aWriteLock(m_aLock);
184*b1cdbd2cSJim Jagielski
185*b1cdbd2cSJim Jagielski // reject dangerous calls
186*b1cdbd2cSJim Jagielski if (m_eRunState != E_NEW)
187*b1cdbd2cSJim Jagielski {
188*b1cdbd2cSJim Jagielski LOG_WARNING("Job::setJobData()", "job may still running or already finished")
189*b1cdbd2cSJim Jagielski return;
190*b1cdbd2cSJim Jagielski }
191*b1cdbd2cSJim Jagielski
192*b1cdbd2cSJim Jagielski m_aJobCfg = aData;
193*b1cdbd2cSJim Jagielski aWriteLock.unlock();
194*b1cdbd2cSJim Jagielski /* } SAFE */
195*b1cdbd2cSJim Jagielski }
196*b1cdbd2cSJim Jagielski
197*b1cdbd2cSJim Jagielski //________________________________
198*b1cdbd2cSJim Jagielski /**
199*b1cdbd2cSJim Jagielski @short runs the job
200*b1cdbd2cSJim Jagielski @descr It doesn't matter, if the job is an asynchronous or
201*b1cdbd2cSJim Jagielski synchronous one. This method returns only if it was finished
202*b1cdbd2cSJim Jagielski or cancelled.
203*b1cdbd2cSJim Jagielski
204*b1cdbd2cSJim Jagielski @param lDynamicArgs
205*b1cdbd2cSJim Jagielski optional arguments for job execution
206*b1cdbd2cSJim Jagielski In case the represented job is a configured one (which uses static
207*b1cdbd2cSJim Jagielski arguments too) all informations will be merged!
208*b1cdbd2cSJim Jagielski */
execute(const css::uno::Sequence<css::beans::NamedValue> & lDynamicArgs)209*b1cdbd2cSJim Jagielski void Job::execute( /*IN*/ const css::uno::Sequence< css::beans::NamedValue >& lDynamicArgs )
210*b1cdbd2cSJim Jagielski {
211*b1cdbd2cSJim Jagielski /* SAFE { */
212*b1cdbd2cSJim Jagielski WriteGuard aWriteLock(m_aLock);
213*b1cdbd2cSJim Jagielski
214*b1cdbd2cSJim Jagielski // reject dangerous calls
215*b1cdbd2cSJim Jagielski if (m_eRunState != E_NEW)
216*b1cdbd2cSJim Jagielski {
217*b1cdbd2cSJim Jagielski LOG_WARNING("Job::execute()", "job may still running or already finished")
218*b1cdbd2cSJim Jagielski return;
219*b1cdbd2cSJim Jagielski }
220*b1cdbd2cSJim Jagielski
221*b1cdbd2cSJim Jagielski // create the environment and mark this job as running ...
222*b1cdbd2cSJim Jagielski m_eRunState = E_RUNNING;
223*b1cdbd2cSJim Jagielski impl_startListening();
224*b1cdbd2cSJim Jagielski
225*b1cdbd2cSJim Jagielski css::uno::Reference< css::task::XAsyncJob > xAJob;
226*b1cdbd2cSJim Jagielski css::uno::Reference< css::task::XJob > xSJob;
227*b1cdbd2cSJim Jagielski css::uno::Sequence< css::beans::NamedValue > lJobArgs = impl_generateJobArgs(lDynamicArgs);
228*b1cdbd2cSJim Jagielski
229*b1cdbd2cSJim Jagielski // It's neccessary to hold us self alive!
230*b1cdbd2cSJim Jagielski // Otherwhise we might die by ref count ...
231*b1cdbd2cSJim Jagielski css::uno::Reference< css::task::XJobListener > xThis(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
232*b1cdbd2cSJim Jagielski
233*b1cdbd2cSJim Jagielski try
234*b1cdbd2cSJim Jagielski {
235*b1cdbd2cSJim Jagielski // create the job
236*b1cdbd2cSJim Jagielski // We must check for the supported interface on demand!
237*b1cdbd2cSJim Jagielski // But we preferr the synchronous one ...
238*b1cdbd2cSJim Jagielski m_xJob = m_xSMGR->createInstance(m_aJobCfg.getService());
239*b1cdbd2cSJim Jagielski xSJob = css::uno::Reference< css::task::XJob >(m_xJob, css::uno::UNO_QUERY);
240*b1cdbd2cSJim Jagielski if (!xSJob.is())
241*b1cdbd2cSJim Jagielski xAJob = css::uno::Reference< css::task::XAsyncJob >(m_xJob, css::uno::UNO_QUERY);
242*b1cdbd2cSJim Jagielski
243*b1cdbd2cSJim Jagielski // execute it asynchron
244*b1cdbd2cSJim Jagielski if (xAJob.is())
245*b1cdbd2cSJim Jagielski {
246*b1cdbd2cSJim Jagielski m_aAsyncWait.reset();
247*b1cdbd2cSJim Jagielski aWriteLock.unlock();
248*b1cdbd2cSJim Jagielski /* } SAFE */
249*b1cdbd2cSJim Jagielski xAJob->executeAsync(lJobArgs, xThis);
250*b1cdbd2cSJim Jagielski // wait for finishing this job - so this method
251*b1cdbd2cSJim Jagielski // does the same for synchronous and asynchronous jobs!
252*b1cdbd2cSJim Jagielski m_aAsyncWait.wait();
253*b1cdbd2cSJim Jagielski aWriteLock.lock();
254*b1cdbd2cSJim Jagielski /* SAFE { */
255*b1cdbd2cSJim Jagielski // Note: Result handling was already done inside the callback!
256*b1cdbd2cSJim Jagielski }
257*b1cdbd2cSJim Jagielski // execute it synchron
258*b1cdbd2cSJim Jagielski else if (xSJob.is())
259*b1cdbd2cSJim Jagielski {
260*b1cdbd2cSJim Jagielski aWriteLock.unlock();
261*b1cdbd2cSJim Jagielski /* } SAFE */
262*b1cdbd2cSJim Jagielski css::uno::Any aResult = xSJob->execute(lJobArgs);
263*b1cdbd2cSJim Jagielski aWriteLock.lock();
264*b1cdbd2cSJim Jagielski /* SAFE { */
265*b1cdbd2cSJim Jagielski impl_reactForJobResult(aResult);
266*b1cdbd2cSJim Jagielski }
267*b1cdbd2cSJim Jagielski }
268*b1cdbd2cSJim Jagielski #if OSL_DEBUG_LEVEL > 0
269*b1cdbd2cSJim Jagielski catch(const css::uno::Exception& ex)
270*b1cdbd2cSJim Jagielski {
271*b1cdbd2cSJim Jagielski ::rtl::OUStringBuffer sMsg(256);
272*b1cdbd2cSJim Jagielski sMsg.appendAscii("Got exception during job execution. Original Message was:\n\"");
273*b1cdbd2cSJim Jagielski sMsg.append (ex.Message);
274*b1cdbd2cSJim Jagielski sMsg.appendAscii("\"");
275*b1cdbd2cSJim Jagielski LOG_WARNING("Job::execute()", U2B(sMsg.makeStringAndClear()).getStr())
276*b1cdbd2cSJim Jagielski }
277*b1cdbd2cSJim Jagielski #else
278*b1cdbd2cSJim Jagielski catch(const css::uno::Exception&)
279*b1cdbd2cSJim Jagielski {}
280*b1cdbd2cSJim Jagielski #endif
281*b1cdbd2cSJim Jagielski
282*b1cdbd2cSJim Jagielski // deinitialize the environment and mark this job as finished ...
283*b1cdbd2cSJim Jagielski // but don't overwrite any informations about STOPPED or might DISPOSED jobs!
284*b1cdbd2cSJim Jagielski impl_stopListening();
285*b1cdbd2cSJim Jagielski if (m_eRunState == E_RUNNING)
286*b1cdbd2cSJim Jagielski m_eRunState = E_STOPPED_OR_FINISHED;
287*b1cdbd2cSJim Jagielski
288*b1cdbd2cSJim Jagielski // If we got a close request from our frame or model ...
289*b1cdbd2cSJim Jagielski // but we disagreed wit that by throwing a veto exception...
290*b1cdbd2cSJim Jagielski // and got the ownership ...
291*b1cdbd2cSJim Jagielski // we have to close the resource frame or model now -
292*b1cdbd2cSJim Jagielski // and to disable ourself!
293*b1cdbd2cSJim Jagielski if (m_bPendingCloseFrame)
294*b1cdbd2cSJim Jagielski {
295*b1cdbd2cSJim Jagielski m_bPendingCloseFrame = sal_False;
296*b1cdbd2cSJim Jagielski css::uno::Reference< css::util::XCloseable > xClose(m_xFrame, css::uno::UNO_QUERY);
297*b1cdbd2cSJim Jagielski if (xClose.is())
298*b1cdbd2cSJim Jagielski {
299*b1cdbd2cSJim Jagielski try
300*b1cdbd2cSJim Jagielski {
301*b1cdbd2cSJim Jagielski xClose->close(sal_True);
302*b1cdbd2cSJim Jagielski }
303*b1cdbd2cSJim Jagielski catch(const css::util::CloseVetoException&) {}
304*b1cdbd2cSJim Jagielski }
305*b1cdbd2cSJim Jagielski }
306*b1cdbd2cSJim Jagielski
307*b1cdbd2cSJim Jagielski if (m_bPendingCloseModel)
308*b1cdbd2cSJim Jagielski {
309*b1cdbd2cSJim Jagielski m_bPendingCloseModel = sal_False;
310*b1cdbd2cSJim Jagielski css::uno::Reference< css::util::XCloseable > xClose(m_xModel, css::uno::UNO_QUERY);
311*b1cdbd2cSJim Jagielski if (xClose.is())
312*b1cdbd2cSJim Jagielski {
313*b1cdbd2cSJim Jagielski try
314*b1cdbd2cSJim Jagielski {
315*b1cdbd2cSJim Jagielski xClose->close(sal_True);
316*b1cdbd2cSJim Jagielski }
317*b1cdbd2cSJim Jagielski catch(const css::util::CloseVetoException&) {}
318*b1cdbd2cSJim Jagielski }
319*b1cdbd2cSJim Jagielski }
320*b1cdbd2cSJim Jagielski
321*b1cdbd2cSJim Jagielski aWriteLock.unlock();
322*b1cdbd2cSJim Jagielski /* SAFE { */
323*b1cdbd2cSJim Jagielski
324*b1cdbd2cSJim Jagielski // release this instance ...
325*b1cdbd2cSJim Jagielski die();
326*b1cdbd2cSJim Jagielski }
327*b1cdbd2cSJim Jagielski
328*b1cdbd2cSJim Jagielski //________________________________
329*b1cdbd2cSJim Jagielski /**
330*b1cdbd2cSJim Jagielski @short kill this job
331*b1cdbd2cSJim Jagielski @descr It doesn't matter if this request is called from inside or
332*b1cdbd2cSJim Jagielski from outside. We release our internal structures and stop
333*b1cdbd2cSJim Jagielski avary activity. After doing so - this instance will not be
334*b1cdbd2cSJim Jagielski useable any longer! Of course we try to handle further requests
335*b1cdbd2cSJim Jagielski carefully. May somehwere else hold a reference to us ...
336*b1cdbd2cSJim Jagielski */
die()337*b1cdbd2cSJim Jagielski void Job::die()
338*b1cdbd2cSJim Jagielski {
339*b1cdbd2cSJim Jagielski /* SAFE { */
340*b1cdbd2cSJim Jagielski WriteGuard aWriteLock(m_aLock);
341*b1cdbd2cSJim Jagielski
342*b1cdbd2cSJim Jagielski impl_stopListening();
343*b1cdbd2cSJim Jagielski
344*b1cdbd2cSJim Jagielski if (m_eRunState != E_DISPOSED)
345*b1cdbd2cSJim Jagielski {
346*b1cdbd2cSJim Jagielski try
347*b1cdbd2cSJim Jagielski {
348*b1cdbd2cSJim Jagielski css::uno::Reference< css::lang::XComponent > xDispose(m_xJob, css::uno::UNO_QUERY);
349*b1cdbd2cSJim Jagielski if (xDispose.is())
350*b1cdbd2cSJim Jagielski {
351*b1cdbd2cSJim Jagielski xDispose->dispose();
352*b1cdbd2cSJim Jagielski m_eRunState = E_DISPOSED;
353*b1cdbd2cSJim Jagielski }
354*b1cdbd2cSJim Jagielski }
355*b1cdbd2cSJim Jagielski catch(const css::lang::DisposedException&)
356*b1cdbd2cSJim Jagielski {
357*b1cdbd2cSJim Jagielski m_eRunState = E_DISPOSED;
358*b1cdbd2cSJim Jagielski }
359*b1cdbd2cSJim Jagielski }
360*b1cdbd2cSJim Jagielski
361*b1cdbd2cSJim Jagielski m_xJob = css::uno::Reference< css::uno::XInterface >();
362*b1cdbd2cSJim Jagielski m_xFrame = css::uno::Reference< css::frame::XFrame >();
363*b1cdbd2cSJim Jagielski m_xModel = css::uno::Reference< css::frame::XModel >();
364*b1cdbd2cSJim Jagielski m_xDesktop = css::uno::Reference< css::frame::XDesktop >();
365*b1cdbd2cSJim Jagielski m_xResultListener = css::uno::Reference< css::frame::XDispatchResultListener >();
366*b1cdbd2cSJim Jagielski m_xResultSourceFake = css::uno::Reference< css::uno::XInterface >();
367*b1cdbd2cSJim Jagielski m_bPendingCloseFrame = sal_False;
368*b1cdbd2cSJim Jagielski m_bPendingCloseModel = sal_False;
369*b1cdbd2cSJim Jagielski
370*b1cdbd2cSJim Jagielski aWriteLock.unlock();
371*b1cdbd2cSJim Jagielski /* SAFE { */
372*b1cdbd2cSJim Jagielski }
373*b1cdbd2cSJim Jagielski
374*b1cdbd2cSJim Jagielski //________________________________
375*b1cdbd2cSJim Jagielski /**
376*b1cdbd2cSJim Jagielski @short generates list of arguments for job execute
377*b1cdbd2cSJim Jagielski @descr There exist a set of informations, which can be needed by a job.
378*b1cdbd2cSJim Jagielski a) it's static configuration data (Equals for all jobs. )
379*b1cdbd2cSJim Jagielski b) it's specific configuration data (Different for every job.)
380*b1cdbd2cSJim Jagielski c) some environment values (e.g. the frame, for which this job was started)
381*b1cdbd2cSJim Jagielski d) any other dynamic data (e.g. parameters of a dispatch() request)
382*b1cdbd2cSJim Jagielski We collect all these informations and generate one list which include all others.
383*b1cdbd2cSJim Jagielski
384*b1cdbd2cSJim Jagielski @param lDynamicArgs
385*b1cdbd2cSJim Jagielski list of dynamic arguments (given by a corresponding dispatch() call)
386*b1cdbd2cSJim Jagielski Can be empty too.
387*b1cdbd2cSJim Jagielski
388*b1cdbd2cSJim Jagielski @return A list which includes all mentioned sub lists.
389*b1cdbd2cSJim Jagielski */
impl_generateJobArgs(const css::uno::Sequence<css::beans::NamedValue> & lDynamicArgs)390*b1cdbd2cSJim Jagielski css::uno::Sequence< css::beans::NamedValue > Job::impl_generateJobArgs( /*IN*/ const css::uno::Sequence< css::beans::NamedValue >& lDynamicArgs )
391*b1cdbd2cSJim Jagielski {
392*b1cdbd2cSJim Jagielski css::uno::Sequence< css::beans::NamedValue > lAllArgs;
393*b1cdbd2cSJim Jagielski
394*b1cdbd2cSJim Jagielski /* SAFE { */
395*b1cdbd2cSJim Jagielski ReadGuard aReadLock(m_aLock);
396*b1cdbd2cSJim Jagielski
397*b1cdbd2cSJim Jagielski // the real structure of the returned list depends from the environment of this job!
398*b1cdbd2cSJim Jagielski JobData::EMode eMode = m_aJobCfg.getMode();
399*b1cdbd2cSJim Jagielski
400*b1cdbd2cSJim Jagielski // Create list of environment variables. This list must be part of the
401*b1cdbd2cSJim Jagielski // returned structure everytimes ... but some of its members are opetional!
402*b1cdbd2cSJim Jagielski css::uno::Sequence< css::beans::NamedValue > lEnvArgs(1);
403*b1cdbd2cSJim Jagielski lEnvArgs[0].Name = ::rtl::OUString::createFromAscii(JobData::PROP_ENVTYPE);
404*b1cdbd2cSJim Jagielski lEnvArgs[0].Value <<= m_aJobCfg.getEnvironmentDescriptor();
405*b1cdbd2cSJim Jagielski
406*b1cdbd2cSJim Jagielski if (m_xFrame.is())
407*b1cdbd2cSJim Jagielski {
408*b1cdbd2cSJim Jagielski sal_Int32 c = lEnvArgs.getLength();
409*b1cdbd2cSJim Jagielski lEnvArgs.realloc(c+1);
410*b1cdbd2cSJim Jagielski lEnvArgs[c].Name = ::rtl::OUString::createFromAscii(JobData::PROP_FRAME);
411*b1cdbd2cSJim Jagielski lEnvArgs[c].Value <<= m_xFrame;
412*b1cdbd2cSJim Jagielski }
413*b1cdbd2cSJim Jagielski if (m_xModel.is())
414*b1cdbd2cSJim Jagielski {
415*b1cdbd2cSJim Jagielski sal_Int32 c = lEnvArgs.getLength();
416*b1cdbd2cSJim Jagielski lEnvArgs.realloc(c+1);
417*b1cdbd2cSJim Jagielski lEnvArgs[c].Name = ::rtl::OUString::createFromAscii(JobData::PROP_MODEL);
418*b1cdbd2cSJim Jagielski lEnvArgs[c].Value <<= m_xModel;
419*b1cdbd2cSJim Jagielski }
420*b1cdbd2cSJim Jagielski if (eMode==JobData::E_EVENT)
421*b1cdbd2cSJim Jagielski {
422*b1cdbd2cSJim Jagielski sal_Int32 c = lEnvArgs.getLength();
423*b1cdbd2cSJim Jagielski lEnvArgs.realloc(c+1);
424*b1cdbd2cSJim Jagielski lEnvArgs[c].Name = ::rtl::OUString::createFromAscii(JobData::PROP_EVENTNAME);
425*b1cdbd2cSJim Jagielski lEnvArgs[c].Value <<= m_aJobCfg.getEvent();
426*b1cdbd2cSJim Jagielski }
427*b1cdbd2cSJim Jagielski
428*b1cdbd2cSJim Jagielski // get the configuration data from the job data container ... if possible
429*b1cdbd2cSJim Jagielski // Means: if this job has any configuration data. Note: only realy
430*b1cdbd2cSJim Jagielski // filled lists will be set to the return structure at the end of this method.
431*b1cdbd2cSJim Jagielski css::uno::Sequence< css::beans::NamedValue > lConfigArgs ;
432*b1cdbd2cSJim Jagielski css::uno::Sequence< css::beans::NamedValue > lJobConfigArgs;
433*b1cdbd2cSJim Jagielski if (eMode==JobData::E_ALIAS || eMode==JobData::E_EVENT)
434*b1cdbd2cSJim Jagielski {
435*b1cdbd2cSJim Jagielski lConfigArgs = m_aJobCfg.getConfig();
436*b1cdbd2cSJim Jagielski lJobConfigArgs = m_aJobCfg.getJobConfig();
437*b1cdbd2cSJim Jagielski }
438*b1cdbd2cSJim Jagielski
439*b1cdbd2cSJim Jagielski aReadLock.unlock();
440*b1cdbd2cSJim Jagielski /* } SAFE */
441*b1cdbd2cSJim Jagielski
442*b1cdbd2cSJim Jagielski // Add all valid (not empty) lists to the return list
443*b1cdbd2cSJim Jagielski if (lConfigArgs.getLength()>0)
444*b1cdbd2cSJim Jagielski {
445*b1cdbd2cSJim Jagielski sal_Int32 nLength = lAllArgs.getLength();
446*b1cdbd2cSJim Jagielski lAllArgs.realloc(nLength+1);
447*b1cdbd2cSJim Jagielski lAllArgs[nLength].Name = ::rtl::OUString::createFromAscii(JobData::PROPSET_CONFIG);
448*b1cdbd2cSJim Jagielski lAllArgs[nLength].Value <<= lConfigArgs;
449*b1cdbd2cSJim Jagielski }
450*b1cdbd2cSJim Jagielski if (lJobConfigArgs.getLength()>0)
451*b1cdbd2cSJim Jagielski {
452*b1cdbd2cSJim Jagielski sal_Int32 nLength = lAllArgs.getLength();
453*b1cdbd2cSJim Jagielski lAllArgs.realloc(nLength+1);
454*b1cdbd2cSJim Jagielski lAllArgs[nLength].Name = ::rtl::OUString::createFromAscii(JobData::PROPSET_OWNCONFIG);
455*b1cdbd2cSJim Jagielski lAllArgs[nLength].Value <<= lJobConfigArgs;
456*b1cdbd2cSJim Jagielski }
457*b1cdbd2cSJim Jagielski if (lEnvArgs.getLength()>0)
458*b1cdbd2cSJim Jagielski {
459*b1cdbd2cSJim Jagielski sal_Int32 nLength = lAllArgs.getLength();
460*b1cdbd2cSJim Jagielski lAllArgs.realloc(nLength+1);
461*b1cdbd2cSJim Jagielski lAllArgs[nLength].Name = ::rtl::OUString::createFromAscii(JobData::PROPSET_ENVIRONMENT);
462*b1cdbd2cSJim Jagielski lAllArgs[nLength].Value <<= lEnvArgs;
463*b1cdbd2cSJim Jagielski }
464*b1cdbd2cSJim Jagielski if (lDynamicArgs.getLength()>0)
465*b1cdbd2cSJim Jagielski {
466*b1cdbd2cSJim Jagielski sal_Int32 nLength = lAllArgs.getLength();
467*b1cdbd2cSJim Jagielski lAllArgs.realloc(nLength+1);
468*b1cdbd2cSJim Jagielski lAllArgs[nLength].Name = ::rtl::OUString::createFromAscii(JobData::PROPSET_DYNAMICDATA);
469*b1cdbd2cSJim Jagielski lAllArgs[nLength].Value <<= lDynamicArgs;
470*b1cdbd2cSJim Jagielski }
471*b1cdbd2cSJim Jagielski
472*b1cdbd2cSJim Jagielski return lAllArgs;
473*b1cdbd2cSJim Jagielski }
474*b1cdbd2cSJim Jagielski
475*b1cdbd2cSJim Jagielski //________________________________
476*b1cdbd2cSJim Jagielski /**
477*b1cdbd2cSJim Jagielski @short analyze the given job result and change the job configuration
478*b1cdbd2cSJim Jagielski @descr Note: Some results can be handled only, if this job has a valid configuration!
479*b1cdbd2cSJim Jagielski For "not configured jobs" (means pure services) they can be ignored.
480*b1cdbd2cSJim Jagielski But these cases are handled by our JobData member. We can call it everytime.
481*b1cdbd2cSJim Jagielski It does the right things automaticly. E.g. if the job has no configuration ...
482*b1cdbd2cSJim Jagielski it does nothing during setJobConfig()!
483*b1cdbd2cSJim Jagielski
484*b1cdbd2cSJim Jagielski @param aResult
485*b1cdbd2cSJim Jagielski the job result for analyzing
486*b1cdbd2cSJim Jagielski */
impl_reactForJobResult(const css::uno::Any & aResult)487*b1cdbd2cSJim Jagielski void Job::impl_reactForJobResult( /*IN*/ const css::uno::Any& aResult )
488*b1cdbd2cSJim Jagielski {
489*b1cdbd2cSJim Jagielski /* SAFE { */
490*b1cdbd2cSJim Jagielski WriteGuard aWriteLock(m_aLock);
491*b1cdbd2cSJim Jagielski
492*b1cdbd2cSJim Jagielski // analyze the result set ...
493*b1cdbd2cSJim Jagielski JobResult aAnalyzedResult(aResult);
494*b1cdbd2cSJim Jagielski
495*b1cdbd2cSJim Jagielski // some of the following operations will be supported for different environments
496*b1cdbd2cSJim Jagielski // or different type of jobs only.
497*b1cdbd2cSJim Jagielski JobData::EEnvironment eEnvironment = m_aJobCfg.getEnvironment();
498*b1cdbd2cSJim Jagielski
499*b1cdbd2cSJim Jagielski // write back the job specific configuration data ...
500*b1cdbd2cSJim Jagielski // If the environment allow it and if this job has a configuration!
501*b1cdbd2cSJim Jagielski if (
502*b1cdbd2cSJim Jagielski (m_aJobCfg.hasConfig() ) &&
503*b1cdbd2cSJim Jagielski (aAnalyzedResult.existPart(JobResult::E_ARGUMENTS))
504*b1cdbd2cSJim Jagielski )
505*b1cdbd2cSJim Jagielski {
506*b1cdbd2cSJim Jagielski m_aJobCfg.setJobConfig(aAnalyzedResult.getArguments());
507*b1cdbd2cSJim Jagielski }
508*b1cdbd2cSJim Jagielski
509*b1cdbd2cSJim Jagielski // disable a job for further executions.
510*b1cdbd2cSJim Jagielski // Note: this option is available inside the environment EXECUTOR only
511*b1cdbd2cSJim Jagielski if (
512*b1cdbd2cSJim Jagielski // (eEnvironment == JobData::E_EXECUTION ) &&
513*b1cdbd2cSJim Jagielski (m_aJobCfg.hasConfig() ) &&
514*b1cdbd2cSJim Jagielski (aAnalyzedResult.existPart(JobResult::E_DEACTIVATE))
515*b1cdbd2cSJim Jagielski )
516*b1cdbd2cSJim Jagielski {
517*b1cdbd2cSJim Jagielski m_aJobCfg.disableJob();
518*b1cdbd2cSJim Jagielski }
519*b1cdbd2cSJim Jagielski
520*b1cdbd2cSJim Jagielski // notify any interested listener with the may given result state.
521*b1cdbd2cSJim Jagielski // Note: this option is available inside the environment DISPATCH only
522*b1cdbd2cSJim Jagielski if (
523*b1cdbd2cSJim Jagielski (eEnvironment == JobData::E_DISPATCH ) &&
524*b1cdbd2cSJim Jagielski (m_xResultListener.is() ) &&
525*b1cdbd2cSJim Jagielski (aAnalyzedResult.existPart(JobResult::E_DISPATCHRESULT))
526*b1cdbd2cSJim Jagielski )
527*b1cdbd2cSJim Jagielski {
528*b1cdbd2cSJim Jagielski m_aJobCfg.setResult(aAnalyzedResult);
529*b1cdbd2cSJim Jagielski // Attention: Because the listener expect that the original object send this event ...
530*b1cdbd2cSJim Jagielski // and we nor the job are the right ones ...
531*b1cdbd2cSJim Jagielski // our user has set itself before. So we can fake this source address!
532*b1cdbd2cSJim Jagielski css::frame::DispatchResultEvent aEvent = aAnalyzedResult.getDispatchResult();
533*b1cdbd2cSJim Jagielski aEvent.Source = m_xResultSourceFake;
534*b1cdbd2cSJim Jagielski m_xResultListener->dispatchFinished(aEvent);
535*b1cdbd2cSJim Jagielski }
536*b1cdbd2cSJim Jagielski
537*b1cdbd2cSJim Jagielski aWriteLock.unlock();
538*b1cdbd2cSJim Jagielski /* SAFE { */
539*b1cdbd2cSJim Jagielski }
540*b1cdbd2cSJim Jagielski
541*b1cdbd2cSJim Jagielski //________________________________
542*b1cdbd2cSJim Jagielski /**
543*b1cdbd2cSJim Jagielski @short starts listening for office shutdown and closing of our
544*b1cdbd2cSJim Jagielski given target frame (if its a valid reference)
545*b1cdbd2cSJim Jagielski @descr We will reghister ourself as terminate listener
546*b1cdbd2cSJim Jagielski at the global desktop instance. That will hold us
547*b1cdbd2cSJim Jagielski alive and additional we get the information, if the
548*b1cdbd2cSJim Jagielski office whish to shutdown. If then an internal job
549*b1cdbd2cSJim Jagielski is running we will have the chance to supress that
550*b1cdbd2cSJim Jagielski by throwing a veto exception. If our internal wrapped
551*b1cdbd2cSJim Jagielski job finished his work, we can release this listener
552*b1cdbd2cSJim Jagielski connection.
553*b1cdbd2cSJim Jagielski
554*b1cdbd2cSJim Jagielski Further we are listener for closing of the (possible valid)
555*b1cdbd2cSJim Jagielski given frame. We must be shure, that this ressource won't be gone
556*b1cdbd2cSJim Jagielski if our internal job is still running.
557*b1cdbd2cSJim Jagielski */
impl_startListening()558*b1cdbd2cSJim Jagielski void Job::impl_startListening()
559*b1cdbd2cSJim Jagielski {
560*b1cdbd2cSJim Jagielski /* SAFE { */
561*b1cdbd2cSJim Jagielski WriteGuard aWriteLock(m_aLock);
562*b1cdbd2cSJim Jagielski
563*b1cdbd2cSJim Jagielski // listening for office shutdown
564*b1cdbd2cSJim Jagielski if (!m_xDesktop.is() && !m_bListenOnDesktop)
565*b1cdbd2cSJim Jagielski {
566*b1cdbd2cSJim Jagielski try
567*b1cdbd2cSJim Jagielski {
568*b1cdbd2cSJim Jagielski m_xDesktop = css::uno::Reference< css::frame::XDesktop >(m_xSMGR->createInstance(SERVICENAME_DESKTOP), css::uno::UNO_QUERY);
569*b1cdbd2cSJim Jagielski css::uno::Reference< css::frame::XTerminateListener > xThis(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
570*b1cdbd2cSJim Jagielski if (m_xDesktop.is())
571*b1cdbd2cSJim Jagielski {
572*b1cdbd2cSJim Jagielski m_xDesktop->addTerminateListener(xThis);
573*b1cdbd2cSJim Jagielski m_bListenOnDesktop = sal_True;
574*b1cdbd2cSJim Jagielski }
575*b1cdbd2cSJim Jagielski }
576*b1cdbd2cSJim Jagielski catch(css::uno::Exception&)
577*b1cdbd2cSJim Jagielski {
578*b1cdbd2cSJim Jagielski m_xDesktop = css::uno::Reference< css::frame::XDesktop >();
579*b1cdbd2cSJim Jagielski }
580*b1cdbd2cSJim Jagielski }
581*b1cdbd2cSJim Jagielski
582*b1cdbd2cSJim Jagielski // listening for frame closing
583*b1cdbd2cSJim Jagielski if (m_xFrame.is() && !m_bListenOnFrame)
584*b1cdbd2cSJim Jagielski {
585*b1cdbd2cSJim Jagielski try
586*b1cdbd2cSJim Jagielski {
587*b1cdbd2cSJim Jagielski css::uno::Reference< css::util::XCloseBroadcaster > xCloseable(m_xFrame , css::uno::UNO_QUERY);
588*b1cdbd2cSJim Jagielski css::uno::Reference< css::util::XCloseListener > xThis (static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
589*b1cdbd2cSJim Jagielski if (xCloseable.is())
590*b1cdbd2cSJim Jagielski {
591*b1cdbd2cSJim Jagielski xCloseable->addCloseListener(xThis);
592*b1cdbd2cSJim Jagielski m_bListenOnFrame = sal_True;
593*b1cdbd2cSJim Jagielski }
594*b1cdbd2cSJim Jagielski }
595*b1cdbd2cSJim Jagielski catch(css::uno::Exception&)
596*b1cdbd2cSJim Jagielski {
597*b1cdbd2cSJim Jagielski m_bListenOnFrame = sal_False;
598*b1cdbd2cSJim Jagielski }
599*b1cdbd2cSJim Jagielski }
600*b1cdbd2cSJim Jagielski
601*b1cdbd2cSJim Jagielski // listening for model closing
602*b1cdbd2cSJim Jagielski if (m_xModel.is() && !m_bListenOnModel)
603*b1cdbd2cSJim Jagielski {
604*b1cdbd2cSJim Jagielski try
605*b1cdbd2cSJim Jagielski {
606*b1cdbd2cSJim Jagielski css::uno::Reference< css::util::XCloseBroadcaster > xCloseable(m_xModel , css::uno::UNO_QUERY);
607*b1cdbd2cSJim Jagielski css::uno::Reference< css::util::XCloseListener > xThis (static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
608*b1cdbd2cSJim Jagielski if (xCloseable.is())
609*b1cdbd2cSJim Jagielski {
610*b1cdbd2cSJim Jagielski xCloseable->addCloseListener(xThis);
611*b1cdbd2cSJim Jagielski m_bListenOnModel = sal_True;
612*b1cdbd2cSJim Jagielski }
613*b1cdbd2cSJim Jagielski }
614*b1cdbd2cSJim Jagielski catch(css::uno::Exception&)
615*b1cdbd2cSJim Jagielski {
616*b1cdbd2cSJim Jagielski m_bListenOnModel = sal_False;
617*b1cdbd2cSJim Jagielski }
618*b1cdbd2cSJim Jagielski }
619*b1cdbd2cSJim Jagielski
620*b1cdbd2cSJim Jagielski aWriteLock.unlock();
621*b1cdbd2cSJim Jagielski /* } SAFE */
622*b1cdbd2cSJim Jagielski }
623*b1cdbd2cSJim Jagielski
624*b1cdbd2cSJim Jagielski //________________________________
625*b1cdbd2cSJim Jagielski /**
626*b1cdbd2cSJim Jagielski @short release listener connection for office shutdown
627*b1cdbd2cSJim Jagielski @descr see description of impl_startListening()
628*b1cdbd2cSJim Jagielski */
impl_stopListening()629*b1cdbd2cSJim Jagielski void Job::impl_stopListening()
630*b1cdbd2cSJim Jagielski {
631*b1cdbd2cSJim Jagielski /* SAFE { */
632*b1cdbd2cSJim Jagielski WriteGuard aWriteLock(m_aLock);
633*b1cdbd2cSJim Jagielski
634*b1cdbd2cSJim Jagielski // stop listening for office shutdown
635*b1cdbd2cSJim Jagielski if (m_xDesktop.is() && m_bListenOnDesktop)
636*b1cdbd2cSJim Jagielski {
637*b1cdbd2cSJim Jagielski try
638*b1cdbd2cSJim Jagielski {
639*b1cdbd2cSJim Jagielski css::uno::Reference< css::frame::XTerminateListener > xThis(static_cast< ::cppu::OWeakObject* >(this) , css::uno::UNO_QUERY);
640*b1cdbd2cSJim Jagielski m_xDesktop->removeTerminateListener(xThis);
641*b1cdbd2cSJim Jagielski m_xDesktop = css::uno::Reference< css::frame::XDesktop >();
642*b1cdbd2cSJim Jagielski m_bListenOnDesktop = sal_False;
643*b1cdbd2cSJim Jagielski }
644*b1cdbd2cSJim Jagielski catch(css::uno::Exception&)
645*b1cdbd2cSJim Jagielski {
646*b1cdbd2cSJim Jagielski }
647*b1cdbd2cSJim Jagielski }
648*b1cdbd2cSJim Jagielski
649*b1cdbd2cSJim Jagielski // stop listening for frame closing
650*b1cdbd2cSJim Jagielski if (m_xFrame.is() && m_bListenOnFrame)
651*b1cdbd2cSJim Jagielski {
652*b1cdbd2cSJim Jagielski try
653*b1cdbd2cSJim Jagielski {
654*b1cdbd2cSJim Jagielski css::uno::Reference< css::util::XCloseBroadcaster > xCloseable(m_xFrame , css::uno::UNO_QUERY);
655*b1cdbd2cSJim Jagielski css::uno::Reference< css::util::XCloseListener > xThis (static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
656*b1cdbd2cSJim Jagielski if (xCloseable.is())
657*b1cdbd2cSJim Jagielski {
658*b1cdbd2cSJim Jagielski xCloseable->removeCloseListener(xThis);
659*b1cdbd2cSJim Jagielski m_bListenOnFrame = sal_False;
660*b1cdbd2cSJim Jagielski }
661*b1cdbd2cSJim Jagielski }
662*b1cdbd2cSJim Jagielski catch(css::uno::Exception&)
663*b1cdbd2cSJim Jagielski {
664*b1cdbd2cSJim Jagielski }
665*b1cdbd2cSJim Jagielski }
666*b1cdbd2cSJim Jagielski
667*b1cdbd2cSJim Jagielski // stop listening for model closing
668*b1cdbd2cSJim Jagielski if (m_xModel.is() && m_bListenOnModel)
669*b1cdbd2cSJim Jagielski {
670*b1cdbd2cSJim Jagielski try
671*b1cdbd2cSJim Jagielski {
672*b1cdbd2cSJim Jagielski css::uno::Reference< css::util::XCloseBroadcaster > xCloseable(m_xModel , css::uno::UNO_QUERY);
673*b1cdbd2cSJim Jagielski css::uno::Reference< css::util::XCloseListener > xThis (static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
674*b1cdbd2cSJim Jagielski if (xCloseable.is())
675*b1cdbd2cSJim Jagielski {
676*b1cdbd2cSJim Jagielski xCloseable->removeCloseListener(xThis);
677*b1cdbd2cSJim Jagielski m_bListenOnModel = sal_False;
678*b1cdbd2cSJim Jagielski }
679*b1cdbd2cSJim Jagielski }
680*b1cdbd2cSJim Jagielski catch(css::uno::Exception&)
681*b1cdbd2cSJim Jagielski {
682*b1cdbd2cSJim Jagielski }
683*b1cdbd2cSJim Jagielski }
684*b1cdbd2cSJim Jagielski
685*b1cdbd2cSJim Jagielski aWriteLock.unlock();
686*b1cdbd2cSJim Jagielski /* } SAFE */
687*b1cdbd2cSJim Jagielski }
688*b1cdbd2cSJim Jagielski
689*b1cdbd2cSJim Jagielski //________________________________
690*b1cdbd2cSJim Jagielski /**
691*b1cdbd2cSJim Jagielski @short callback from any asynchronous executed job
692*b1cdbd2cSJim Jagielski
693*b1cdbd2cSJim Jagielski @descr Our execute() method waits for this callback.
694*b1cdbd2cSJim Jagielski We have to react for the possible results here,
695*b1cdbd2cSJim Jagielski to kill the running job and disable the blocked condition
696*b1cdbd2cSJim Jagielski so execute() can be finished too.
697*b1cdbd2cSJim Jagielski
698*b1cdbd2cSJim Jagielski @param xJob
699*b1cdbd2cSJim Jagielski the job, which was running and inform us now
700*b1cdbd2cSJim Jagielski
701*b1cdbd2cSJim Jagielski @param aResult
702*b1cdbd2cSJim Jagielski it's results
703*b1cdbd2cSJim Jagielski */
jobFinished(const css::uno::Reference<css::task::XAsyncJob> & xJob,const css::uno::Any & aResult)704*b1cdbd2cSJim Jagielski void SAL_CALL Job::jobFinished( /*IN*/ const css::uno::Reference< css::task::XAsyncJob >& xJob ,
705*b1cdbd2cSJim Jagielski /*IN*/ const css::uno::Any& aResult ) throw(css::uno::RuntimeException)
706*b1cdbd2cSJim Jagielski {
707*b1cdbd2cSJim Jagielski /* SAFE { */
708*b1cdbd2cSJim Jagielski WriteGuard aWriteLock(m_aLock);
709*b1cdbd2cSJim Jagielski
710*b1cdbd2cSJim Jagielski // It's neccessary to check this.
711*b1cdbd2cSJim Jagielski // May this job was cancelled by any other reason
712*b1cdbd2cSJim Jagielski // some milliseconds before. :-)
713*b1cdbd2cSJim Jagielski if (m_xJob.is() && m_xJob==xJob)
714*b1cdbd2cSJim Jagielski {
715*b1cdbd2cSJim Jagielski // react for his results
716*b1cdbd2cSJim Jagielski // (means enable/disable it for further requests
717*b1cdbd2cSJim Jagielski // or save arguments or notify listener ...)
718*b1cdbd2cSJim Jagielski impl_reactForJobResult(aResult);
719*b1cdbd2cSJim Jagielski
720*b1cdbd2cSJim Jagielski // Let the job die!
721*b1cdbd2cSJim Jagielski m_xJob = css::uno::Reference< css::uno::XInterface >();
722*b1cdbd2cSJim Jagielski }
723*b1cdbd2cSJim Jagielski
724*b1cdbd2cSJim Jagielski // And let the start method "execute()" finishing it's job.
725*b1cdbd2cSJim Jagielski // But do it everytime. So any outside blocking code can finish
726*b1cdbd2cSJim Jagielski // his work too.
727*b1cdbd2cSJim Jagielski m_aAsyncWait.set();
728*b1cdbd2cSJim Jagielski
729*b1cdbd2cSJim Jagielski aWriteLock.unlock();
730*b1cdbd2cSJim Jagielski /* } SAFE */
731*b1cdbd2cSJim Jagielski }
732*b1cdbd2cSJim Jagielski
733*b1cdbd2cSJim Jagielski //________________________________
734*b1cdbd2cSJim Jagielski /**
735*b1cdbd2cSJim Jagielski @short prevent internal wrapped job against office termination
736*b1cdbd2cSJim Jagielski @descr This event is broadcasted by the desktop instance and ask for an office termination.
737*b1cdbd2cSJim Jagielski If the internal wrapped job is still in progress, we disagree with that by throwing the
738*b1cdbd2cSJim Jagielski right veto exception. If not - we agree. But then we must be aware, that another event
739*b1cdbd2cSJim Jagielski notifyTermination() can follow. Then we have no chance to do the same. Then we have to
740*b1cdbd2cSJim Jagielski accept that and stop our work instandly.
741*b1cdbd2cSJim Jagielski
742*b1cdbd2cSJim Jagielski @param aEvent
743*b1cdbd2cSJim Jagielski describes the broadcaster and must be the desktop instance
744*b1cdbd2cSJim Jagielski
745*b1cdbd2cSJim Jagielski @throw TerminateVetoException
746*b1cdbd2cSJim Jagielski if our internal wrapped job is still running.
747*b1cdbd2cSJim Jagielski */
queryTermination(const css::lang::EventObject &)748*b1cdbd2cSJim Jagielski void SAL_CALL Job::queryTermination( /*IN*/ const css::lang::EventObject& ) throw(css::frame::TerminationVetoException,
749*b1cdbd2cSJim Jagielski css::uno::RuntimeException )
750*b1cdbd2cSJim Jagielski {
751*b1cdbd2cSJim Jagielski /* SAFE { */
752*b1cdbd2cSJim Jagielski ReadGuard aReadLock(m_aLock);
753*b1cdbd2cSJim Jagielski
754*b1cdbd2cSJim Jagielski // don't disagree with this request if job was already stopped or finished it's work
755*b1cdbd2cSJim Jagielski // if (m_eRunState != E_RUNNING)
756*b1cdbd2cSJim Jagielski // return;
757*b1cdbd2cSJim Jagielski
758*b1cdbd2cSJim Jagielski // Otherwhise try to close() it
759*b1cdbd2cSJim Jagielski css::uno::Reference< css::util::XCloseable > xClose(m_xJob, css::uno::UNO_QUERY);
760*b1cdbd2cSJim Jagielski if (xClose.is())
761*b1cdbd2cSJim Jagielski {
762*b1cdbd2cSJim Jagielski try
763*b1cdbd2cSJim Jagielski {
764*b1cdbd2cSJim Jagielski xClose->close(sal_False);
765*b1cdbd2cSJim Jagielski m_eRunState = E_STOPPED_OR_FINISHED;
766*b1cdbd2cSJim Jagielski }
767*b1cdbd2cSJim Jagielski catch(const css::util::CloseVetoException&) {}
768*b1cdbd2cSJim Jagielski }
769*b1cdbd2cSJim Jagielski
770*b1cdbd2cSJim Jagielski if (m_eRunState != E_STOPPED_OR_FINISHED)
771*b1cdbd2cSJim Jagielski {
772*b1cdbd2cSJim Jagielski css::uno::Reference< css::uno::XInterface > xThis(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
773*b1cdbd2cSJim Jagielski throw css::frame::TerminationVetoException(DECLARE_ASCII("job still in progress"), xThis);
774*b1cdbd2cSJim Jagielski }
775*b1cdbd2cSJim Jagielski
776*b1cdbd2cSJim Jagielski aReadLock.unlock();
777*b1cdbd2cSJim Jagielski /* } SAFE */
778*b1cdbd2cSJim Jagielski }
779*b1cdbd2cSJim Jagielski
780*b1cdbd2cSJim Jagielski
781*b1cdbd2cSJim Jagielski //________________________________
782*b1cdbd2cSJim Jagielski /**
783*b1cdbd2cSJim Jagielski @short inform us about office termination
784*b1cdbd2cSJim Jagielski @descr Instead of the method queryTermination(), here is no chance to disagree with that.
785*b1cdbd2cSJim Jagielski We have to accept it and cancel all current processes inside.
786*b1cdbd2cSJim Jagielski It can occure only, if job was not already started if queryTermination() was called here ..
787*b1cdbd2cSJim Jagielski Then we had not throwed a veto exception. But now we must agree with this situation and break
788*b1cdbd2cSJim Jagielski all our internal processes. Its not a good idea to mark this instance as non startable any longer
789*b1cdbd2cSJim Jagielski inside queryTermination() if no job was unning too. Because that would disable this job and may
790*b1cdbd2cSJim Jagielski the office does not realy shutdownm, because another listener has thrown the suitable exception.
791*b1cdbd2cSJim Jagielski
792*b1cdbd2cSJim Jagielski @param aEvent
793*b1cdbd2cSJim Jagielski describes the broadcaster and must be the desktop instance
794*b1cdbd2cSJim Jagielski */
notifyTermination(const css::lang::EventObject &)795*b1cdbd2cSJim Jagielski void SAL_CALL Job::notifyTermination( /*IN*/ const css::lang::EventObject& ) throw(css::uno::RuntimeException)
796*b1cdbd2cSJim Jagielski {
797*b1cdbd2cSJim Jagielski die();
798*b1cdbd2cSJim Jagielski // Do nothing else here. Our internal ressources was released ...
799*b1cdbd2cSJim Jagielski }
800*b1cdbd2cSJim Jagielski
801*b1cdbd2cSJim Jagielski //________________________________
802*b1cdbd2cSJim Jagielski /**
803*b1cdbd2cSJim Jagielski @short prevent internal wrapped job against frame closing
804*b1cdbd2cSJim Jagielski @descr This event is broadcasted by the frame instance and ask for closing.
805*b1cdbd2cSJim Jagielski If the internal wrapped job is still in progress, we disagree with that by throwing the
806*b1cdbd2cSJim Jagielski right veto exception. If not - we agree. But then we must be aware, that another event
807*b1cdbd2cSJim Jagielski notifyClosing() can follow. Then we have no chance to do the same. Then we have to
808*b1cdbd2cSJim Jagielski accept that and stop our work instandly.
809*b1cdbd2cSJim Jagielski
810*b1cdbd2cSJim Jagielski @param aEvent
811*b1cdbd2cSJim Jagielski describes the broadcaster and must be the frame instance
812*b1cdbd2cSJim Jagielski
813*b1cdbd2cSJim Jagielski @param bGetsOwnerShip
814*b1cdbd2cSJim Jagielski If it's set to <sal_True> and we throw the right veto excepion, we have to close this frame later
815*b1cdbd2cSJim Jagielski if our internal processes will be finished. If it's set to <FALSE/> we can ignore it.
816*b1cdbd2cSJim Jagielski
817*b1cdbd2cSJim Jagielski @throw CloseVetoException
818*b1cdbd2cSJim Jagielski if our internal wrapped job is still running.
819*b1cdbd2cSJim Jagielski */
queryClosing(const css::lang::EventObject & aEvent,sal_Bool bGetsOwnership)820*b1cdbd2cSJim Jagielski void SAL_CALL Job::queryClosing( const css::lang::EventObject& aEvent ,
821*b1cdbd2cSJim Jagielski sal_Bool bGetsOwnership ) throw(css::util::CloseVetoException,
822*b1cdbd2cSJim Jagielski css::uno::RuntimeException )
823*b1cdbd2cSJim Jagielski {
824*b1cdbd2cSJim Jagielski /* SAFE { */
825*b1cdbd2cSJim Jagielski WriteGuard aWriteLock(m_aLock);
826*b1cdbd2cSJim Jagielski
827*b1cdbd2cSJim Jagielski // do nothing, if no internal job is still running ...
828*b1cdbd2cSJim Jagielski // The frame or model can be closed then successfully.
829*b1cdbd2cSJim Jagielski if (m_eRunState != E_RUNNING)
830*b1cdbd2cSJim Jagielski return;
831*b1cdbd2cSJim Jagielski
832*b1cdbd2cSJim Jagielski // try close() first at the job.
833*b1cdbd2cSJim Jagielski // The job can agree or disagree with this request.
834*b1cdbd2cSJim Jagielski css::uno::Reference< css::util::XCloseable > xClose(m_xJob, css::uno::UNO_QUERY);
835*b1cdbd2cSJim Jagielski if (xClose.is())
836*b1cdbd2cSJim Jagielski {
837*b1cdbd2cSJim Jagielski xClose->close(bGetsOwnership);
838*b1cdbd2cSJim Jagielski // Here we can say: "this job was stopped successfully". Because
839*b1cdbd2cSJim Jagielski // no veto exception was thrown!
840*b1cdbd2cSJim Jagielski m_eRunState = E_STOPPED_OR_FINISHED;
841*b1cdbd2cSJim Jagielski return;
842*b1cdbd2cSJim Jagielski }
843*b1cdbd2cSJim Jagielski
844*b1cdbd2cSJim Jagielski // try dispose() then
845*b1cdbd2cSJim Jagielski // Here the job has no chance for a veto.
846*b1cdbd2cSJim Jagielski // But we must be aware of an "already disposed exception"...
847*b1cdbd2cSJim Jagielski try
848*b1cdbd2cSJim Jagielski {
849*b1cdbd2cSJim Jagielski css::uno::Reference< css::lang::XComponent > xDispose(m_xJob, css::uno::UNO_QUERY);
850*b1cdbd2cSJim Jagielski if (xDispose.is())
851*b1cdbd2cSJim Jagielski {
852*b1cdbd2cSJim Jagielski xDispose->dispose();
853*b1cdbd2cSJim Jagielski m_eRunState = E_DISPOSED;
854*b1cdbd2cSJim Jagielski }
855*b1cdbd2cSJim Jagielski }
856*b1cdbd2cSJim Jagielski catch(const css::lang::DisposedException&)
857*b1cdbd2cSJim Jagielski {
858*b1cdbd2cSJim Jagielski // the job was already disposed by any other mechanism !?
859*b1cdbd2cSJim Jagielski // But it's not interesting for us. For us this job is stopped now.
860*b1cdbd2cSJim Jagielski m_eRunState = E_DISPOSED;
861*b1cdbd2cSJim Jagielski }
862*b1cdbd2cSJim Jagielski
863*b1cdbd2cSJim Jagielski if (m_eRunState != E_DISPOSED)
864*b1cdbd2cSJim Jagielski {
865*b1cdbd2cSJim Jagielski // analyze event source - to find out, which resource called queryClosing() at this
866*b1cdbd2cSJim Jagielski // job wrapper. We must bind a "pending close" request to this resource.
867*b1cdbd2cSJim Jagielski // Closing of the corresponding resource will be done if our internal job finish it's work.
868*b1cdbd2cSJim Jagielski m_bPendingCloseFrame = (m_xFrame.is() && aEvent.Source == m_xFrame);
869*b1cdbd2cSJim Jagielski m_bPendingCloseModel = (m_xModel.is() && aEvent.Source == m_xModel);
870*b1cdbd2cSJim Jagielski
871*b1cdbd2cSJim Jagielski // throw suitable veto exception - because the internal job could not be cancelled.
872*b1cdbd2cSJim Jagielski css::uno::Reference< css::uno::XInterface > xThis(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
873*b1cdbd2cSJim Jagielski throw css::util::CloseVetoException(DECLARE_ASCII("job still in progress"), xThis);
874*b1cdbd2cSJim Jagielski }
875*b1cdbd2cSJim Jagielski
876*b1cdbd2cSJim Jagielski // No veto ...
877*b1cdbd2cSJim Jagielski // But don't call die() here or free our internal member.
878*b1cdbd2cSJim Jagielski // This must be done inside notifyClosing() only. Otherwhise the
879*b1cdbd2cSJim Jagielski // might stopped job has no chance to return it's results or
880*b1cdbd2cSJim Jagielski // call us back. We must give him the chance to finish it's work successfully.
881*b1cdbd2cSJim Jagielski
882*b1cdbd2cSJim Jagielski aWriteLock.unlock();
883*b1cdbd2cSJim Jagielski /* } SAFE */
884*b1cdbd2cSJim Jagielski }
885*b1cdbd2cSJim Jagielski
886*b1cdbd2cSJim Jagielski //________________________________
887*b1cdbd2cSJim Jagielski /**
888*b1cdbd2cSJim Jagielski @short inform us about frame closing
889*b1cdbd2cSJim Jagielski @descr Instead of the method queryClosing(), here is no chance to disagree with that.
890*b1cdbd2cSJim Jagielski We have to accept it and cancel all current processes inside.
891*b1cdbd2cSJim Jagielski
892*b1cdbd2cSJim Jagielski @param aEvent
893*b1cdbd2cSJim Jagielski describes the broadcaster and must be the frame or model instance we know
894*b1cdbd2cSJim Jagielski */
notifyClosing(const css::lang::EventObject &)895*b1cdbd2cSJim Jagielski void SAL_CALL Job::notifyClosing( const css::lang::EventObject& ) throw(css::uno::RuntimeException)
896*b1cdbd2cSJim Jagielski {
897*b1cdbd2cSJim Jagielski die();
898*b1cdbd2cSJim Jagielski // Do nothing else here. Our internal ressources was released ...
899*b1cdbd2cSJim Jagielski }
900*b1cdbd2cSJim Jagielski
901*b1cdbd2cSJim Jagielski //________________________________
902*b1cdbd2cSJim Jagielski /**
903*b1cdbd2cSJim Jagielski @short shouldn't be called normaly
904*b1cdbd2cSJim Jagielski @descr But it doesn't matter, who called it. We have to kill our internal
905*b1cdbd2cSJim Jagielski running processes hardly.
906*b1cdbd2cSJim Jagielski
907*b1cdbd2cSJim Jagielski @param aEvent
908*b1cdbd2cSJim Jagielski describe the broadcaster
909*b1cdbd2cSJim Jagielski */
disposing(const css::lang::EventObject & aEvent)910*b1cdbd2cSJim Jagielski void SAL_CALL Job::disposing( const css::lang::EventObject& aEvent ) throw(css::uno::RuntimeException)
911*b1cdbd2cSJim Jagielski {
912*b1cdbd2cSJim Jagielski /* SAFE { */
913*b1cdbd2cSJim Jagielski WriteGuard aWriteLock(m_aLock);
914*b1cdbd2cSJim Jagielski
915*b1cdbd2cSJim Jagielski if (m_xDesktop.is() && aEvent.Source == m_xDesktop)
916*b1cdbd2cSJim Jagielski {
917*b1cdbd2cSJim Jagielski m_xDesktop = css::uno::Reference< css::frame::XDesktop >();
918*b1cdbd2cSJim Jagielski m_bListenOnDesktop = sal_False;
919*b1cdbd2cSJim Jagielski }
920*b1cdbd2cSJim Jagielski else
921*b1cdbd2cSJim Jagielski if (m_xFrame.is() && aEvent.Source == m_xFrame)
922*b1cdbd2cSJim Jagielski {
923*b1cdbd2cSJim Jagielski m_xFrame = css::uno::Reference< css::frame::XFrame >();
924*b1cdbd2cSJim Jagielski m_bListenOnFrame = sal_False;
925*b1cdbd2cSJim Jagielski }
926*b1cdbd2cSJim Jagielski else
927*b1cdbd2cSJim Jagielski if (m_xModel.is() && aEvent.Source == m_xModel)
928*b1cdbd2cSJim Jagielski {
929*b1cdbd2cSJim Jagielski m_xModel = css::uno::Reference< css::frame::XModel >();
930*b1cdbd2cSJim Jagielski m_bListenOnModel = sal_False;
931*b1cdbd2cSJim Jagielski }
932*b1cdbd2cSJim Jagielski
933*b1cdbd2cSJim Jagielski aWriteLock.unlock();
934*b1cdbd2cSJim Jagielski /* } SAFE */
935*b1cdbd2cSJim Jagielski
936*b1cdbd2cSJim Jagielski die();
937*b1cdbd2cSJim Jagielski // Do nothing else here. Our internal ressources was released ...
938*b1cdbd2cSJim Jagielski }
939*b1cdbd2cSJim Jagielski
940*b1cdbd2cSJim Jagielski } // namespace framework
941