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