diff options
Diffstat (limited to 'framework/source/jobs/job.cxx')
-rw-r--r-- | framework/source/jobs/job.cxx | 944 |
1 files changed, 0 insertions, 944 deletions
diff --git a/framework/source/jobs/job.cxx b/framework/source/jobs/job.cxx deleted file mode 100644 index b25a14cc72..0000000000 --- a/framework/source/jobs/job.cxx +++ /dev/null @@ -1,944 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -// MARKER(update_precomp.py): autogen include statement, do not remove -#include "precompiled_framework.hxx" - -//________________________________ -// my own includes -#include <jobs/job.hxx> -#include <threadhelp/readguard.hxx> -#include <threadhelp/writeguard.hxx> -#include <general.h> -#include <services.h> - -//________________________________ -// interface includes -#include <com/sun/star/task/XJob.hpp> -#include <com/sun/star/task/XAsyncJob.hpp> -#include <com/sun/star/util/XCloseBroadcaster.hpp> -#include <com/sun/star/util/XCloseable.hpp> -#include <com/sun/star/lang/DisposedException.hpp> - -//________________________________ -// includes of other projects -#include <rtl/ustrbuf.hxx> -#include <vcl/svapp.hxx> - -//________________________________ -// namespace - -namespace framework{ - -//________________________________ -// non exported const - -//________________________________ -// non exported definitions - -//________________________________ -// declarations - -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 ) - ) - -DEFINE_XTYPEPROVIDER_4( Job , - css::lang::XTypeProvider , - css::task::XJobListener , - css::frame::XTerminateListener, - css::util::XCloseListener - ) - -//________________________________ -/** - @short standard ctor - @descr It initialize this new instance. But it set some generic parameters here only. - Specialized informations (e.g. the alias or service name ofthis job) will be set - later using the method setJobData(). - - @param xSMGR - reference to the uno service manager - - @param xFrame - reference to the frame, in which environment we run - (May be null!) -*/ -Job::Job( /*IN*/ const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR , - /*IN*/ const css::uno::Reference< css::frame::XFrame >& xFrame ) - : ThreadHelpBase (&Application::GetSolarMutex()) - , ::cppu::OWeakObject ( ) - , m_aJobCfg (xSMGR ) - , m_xSMGR (xSMGR ) - , m_xFrame (xFrame ) - , m_bListenOnDesktop (sal_False ) - , m_bListenOnFrame (sal_False ) - , m_bListenOnModel (sal_False ) - , m_bPendingCloseFrame (sal_False ) - , m_bPendingCloseModel (sal_False ) - , m_eRunState (E_NEW ) -{ -} - -//________________________________ -/** - @short standard ctor - @descr It initialize this new instance. But it set some generic parameters here only. - Specialized informations (e.g. the alias or service name ofthis job) will be set - later using the method setJobData(). - - @param xSMGR - reference to the uno service manager - - @param xModel - reference to the model, in which environment we run - (May be null!) -*/ -Job::Job( /*IN*/ const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR , - /*IN*/ const css::uno::Reference< css::frame::XModel >& xModel ) - : ThreadHelpBase (&Application::GetSolarMutex()) - , ::cppu::OWeakObject ( ) - , m_aJobCfg (xSMGR ) - , m_xSMGR (xSMGR ) - , m_xModel (xModel ) - , m_bListenOnDesktop (sal_False ) - , m_bListenOnFrame (sal_False ) - , m_bListenOnModel (sal_False ) - , m_bPendingCloseFrame (sal_False ) - , m_bPendingCloseModel (sal_False ) - , m_eRunState (E_NEW ) -{ -} - -//________________________________ -/** - @short superflous! - @descr Releasing of memory and reference must be done inside die() call. - Otherwhise it's a bug. -*/ -Job::~Job() -{ -} - -//________________________________ -/** - @short set (or delete) a listener for sending dispatch result events - @descr Because this object is used in a wrapped mode ... the original listener - for such events can't be registered here directly. Because the - listener expect to get the original object given as source of the event. - That's why we get this source here too, to fake(!) it at sending time! - - @param xListener - the original listener for dispatch result events - - @param xSourceFake - our user, which got the registration request for this listener -*/ -void Job::setDispatchResultFake( /*IN*/ const css::uno::Reference< css::frame::XDispatchResultListener >& xListener , - /*IN*/ const css::uno::Reference< css::uno::XInterface >& xSourceFake ) -{ - /* SAFE { */ - WriteGuard aWriteLock(m_aLock); - - // reject dangerous calls - if (m_eRunState != E_NEW) - { - LOG_WARNING("Job::setJobData()", "job may still running or already finished") - return; - } - - m_xResultListener = xListener ; - m_xResultSourceFake = xSourceFake; - aWriteLock.unlock(); - /* } SAFE */ -} - -void Job::setJobData( const JobData& aData ) -{ - /* SAFE { */ - WriteGuard aWriteLock(m_aLock); - - // reject dangerous calls - if (m_eRunState != E_NEW) - { - LOG_WARNING("Job::setJobData()", "job may still running or already finished") - return; - } - - m_aJobCfg = aData; - aWriteLock.unlock(); - /* } SAFE */ -} - -//________________________________ -/** - @short runs the job - @descr It doesn't matter, if the job is an asynchronous or - synchronous one. This method returns only if it was finished - or cancelled. - - @param lDynamicArgs - optional arguments for job execution - In case the represented job is a configured one (which uses static - arguments too) all informations will be merged! -*/ -void Job::execute( /*IN*/ const css::uno::Sequence< css::beans::NamedValue >& lDynamicArgs ) -{ - /* SAFE { */ - WriteGuard aWriteLock(m_aLock); - - // reject dangerous calls - if (m_eRunState != E_NEW) - { - LOG_WARNING("Job::execute()", "job may still running or already finished") - return; - } - - // create the environment and mark this job as running ... - m_eRunState = E_RUNNING; - impl_startListening(); - - css::uno::Reference< css::task::XAsyncJob > xAJob; - css::uno::Reference< css::task::XJob > xSJob; - css::uno::Sequence< css::beans::NamedValue > lJobArgs = impl_generateJobArgs(lDynamicArgs); - - // It's neccessary to hold us self alive! - // Otherwhise we might die by ref count ... - css::uno::Reference< css::task::XJobListener > xThis(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY); - - try - { - // create the job - // We must check for the supported interface on demand! - // But we preferr the synchronous one ... - m_xJob = m_xSMGR->createInstance(m_aJobCfg.getService()); - xSJob = css::uno::Reference< css::task::XJob >(m_xJob, css::uno::UNO_QUERY); - if (!xSJob.is()) - xAJob = css::uno::Reference< css::task::XAsyncJob >(m_xJob, css::uno::UNO_QUERY); - - // execute it asynchron - if (xAJob.is()) - { - m_aAsyncWait.reset(); - aWriteLock.unlock(); - /* } SAFE */ - xAJob->executeAsync(lJobArgs, xThis); - // wait for finishing this job - so this method - // does the same for synchronous and asynchronous jobs! - m_aAsyncWait.wait(); - aWriteLock.lock(); - /* SAFE { */ - // Note: Result handling was already done inside the callback! - } - // execute it synchron - else if (xSJob.is()) - { - aWriteLock.unlock(); - /* } SAFE */ - css::uno::Any aResult = xSJob->execute(lJobArgs); - aWriteLock.lock(); - /* SAFE { */ - impl_reactForJobResult(aResult); - } - } - #if OSL_DEBUG_LEVEL > 0 - catch(const css::uno::Exception& ex) - { - ::rtl::OUStringBuffer sMsg(256); - sMsg.appendAscii("Got exception during job execution. Original Message was:\n\""); - sMsg.append (ex.Message); - sMsg.appendAscii("\""); - LOG_WARNING("Job::execute()", U2B(sMsg.makeStringAndClear()).getStr()) - } - #else - catch(const css::uno::Exception&) - {} - #endif - - // deinitialize the environment and mark this job as finished ... - // but don't overwrite any informations about STOPPED or might DISPOSED jobs! - impl_stopListening(); - if (m_eRunState == E_RUNNING) - m_eRunState = E_STOPPED_OR_FINISHED; - - // If we got a close request from our frame or model ... - // but we disagreed wit that by throwing a veto exception... - // and got the ownership ... - // we have to close the resource frame or model now - - // and to disable ourself! - if (m_bPendingCloseFrame) - { - m_bPendingCloseFrame = sal_False; - css::uno::Reference< css::util::XCloseable > xClose(m_xFrame, css::uno::UNO_QUERY); - if (xClose.is()) - { - try - { - xClose->close(sal_True); - } - catch(const css::util::CloseVetoException&) {} - } - } - - if (m_bPendingCloseModel) - { - m_bPendingCloseModel = sal_False; - css::uno::Reference< css::util::XCloseable > xClose(m_xModel, css::uno::UNO_QUERY); - if (xClose.is()) - { - try - { - xClose->close(sal_True); - } - catch(const css::util::CloseVetoException&) {} - } - } - - aWriteLock.unlock(); - /* SAFE { */ - - // release this instance ... - die(); -} - -//________________________________ -/** - @short kill this job - @descr It doesn't matter if this request is called from inside or - from outside. We release our internal structures and stop - avary activity. After doing so - this instance will not be - useable any longer! Of course we try to handle further requests - carefully. May somehwere else hold a reference to us ... -*/ -void Job::die() -{ - /* SAFE { */ - WriteGuard aWriteLock(m_aLock); - - impl_stopListening(); - - if (m_eRunState != E_DISPOSED) - { - try - { - css::uno::Reference< css::lang::XComponent > xDispose(m_xJob, css::uno::UNO_QUERY); - if (xDispose.is()) - { - xDispose->dispose(); - m_eRunState = E_DISPOSED; - } - } - catch(const css::lang::DisposedException&) - { - m_eRunState = E_DISPOSED; - } - } - - m_xJob = css::uno::Reference< css::uno::XInterface >(); - m_xFrame = css::uno::Reference< css::frame::XFrame >(); - m_xModel = css::uno::Reference< css::frame::XModel >(); - m_xDesktop = css::uno::Reference< css::frame::XDesktop >(); - m_xResultListener = css::uno::Reference< css::frame::XDispatchResultListener >(); - m_xResultSourceFake = css::uno::Reference< css::uno::XInterface >(); - m_bPendingCloseFrame = sal_False; - m_bPendingCloseModel = sal_False; - - aWriteLock.unlock(); - /* SAFE { */ -} - -//________________________________ -/** - @short generates list of arguments for job execute - @descr There exist a set of informations, which can be needed by a job. - a) it's static configuration data (Equals for all jobs. ) - b) it's specific configuration data (Different for every job.) - c) some environment values (e.g. the frame, for which this job was started) - d) any other dynamic data (e.g. parameters of a dispatch() request) - We collect all these informations and generate one list which include all others. - - @param lDynamicArgs - list of dynamic arguments (given by a corresponding dispatch() call) - Can be empty too. - - @return A list which includes all mentioned sub lists. -*/ -css::uno::Sequence< css::beans::NamedValue > Job::impl_generateJobArgs( /*IN*/ const css::uno::Sequence< css::beans::NamedValue >& lDynamicArgs ) -{ - css::uno::Sequence< css::beans::NamedValue > lAllArgs; - - /* SAFE { */ - ReadGuard aReadLock(m_aLock); - - // the real structure of the returned list depends from the environment of this job! - JobData::EMode eMode = m_aJobCfg.getMode(); - - // Create list of environment variables. This list must be part of the - // returned structure everytimes ... but some of its members are opetional! - css::uno::Sequence< css::beans::NamedValue > lEnvArgs(1); - lEnvArgs[0].Name = ::rtl::OUString::createFromAscii(JobData::PROP_ENVTYPE); - lEnvArgs[0].Value <<= m_aJobCfg.getEnvironmentDescriptor(); - - if (m_xFrame.is()) - { - sal_Int32 c = lEnvArgs.getLength(); - lEnvArgs.realloc(c+1); - lEnvArgs[c].Name = ::rtl::OUString::createFromAscii(JobData::PROP_FRAME); - lEnvArgs[c].Value <<= m_xFrame; - } - if (m_xModel.is()) - { - sal_Int32 c = lEnvArgs.getLength(); - lEnvArgs.realloc(c+1); - lEnvArgs[c].Name = ::rtl::OUString::createFromAscii(JobData::PROP_MODEL); - lEnvArgs[c].Value <<= m_xModel; - } - if (eMode==JobData::E_EVENT) - { - sal_Int32 c = lEnvArgs.getLength(); - lEnvArgs.realloc(c+1); - lEnvArgs[c].Name = ::rtl::OUString::createFromAscii(JobData::PROP_EVENTNAME); - lEnvArgs[c].Value <<= m_aJobCfg.getEvent(); - } - - // get the configuration data from the job data container ... if possible - // Means: if this job has any configuration data. Note: only realy - // filled lists will be set to the return structure at the end of this method. - css::uno::Sequence< css::beans::NamedValue > lConfigArgs ; - css::uno::Sequence< css::beans::NamedValue > lJobConfigArgs; - if (eMode==JobData::E_ALIAS || eMode==JobData::E_EVENT) - { - lConfigArgs = m_aJobCfg.getConfig(); - lJobConfigArgs = m_aJobCfg.getJobConfig(); - } - - aReadLock.unlock(); - /* } SAFE */ - - // Add all valid (not empty) lists to the return list - if (lConfigArgs.getLength()>0) - { - sal_Int32 nLength = lAllArgs.getLength(); - lAllArgs.realloc(nLength+1); - lAllArgs[nLength].Name = ::rtl::OUString::createFromAscii(JobData::PROPSET_CONFIG); - lAllArgs[nLength].Value <<= lConfigArgs; - } - if (lJobConfigArgs.getLength()>0) - { - sal_Int32 nLength = lAllArgs.getLength(); - lAllArgs.realloc(nLength+1); - lAllArgs[nLength].Name = ::rtl::OUString::createFromAscii(JobData::PROPSET_OWNCONFIG); - lAllArgs[nLength].Value <<= lJobConfigArgs; - } - if (lEnvArgs.getLength()>0) - { - sal_Int32 nLength = lAllArgs.getLength(); - lAllArgs.realloc(nLength+1); - lAllArgs[nLength].Name = ::rtl::OUString::createFromAscii(JobData::PROPSET_ENVIRONMENT); - lAllArgs[nLength].Value <<= lEnvArgs; - } - if (lDynamicArgs.getLength()>0) - { - sal_Int32 nLength = lAllArgs.getLength(); - lAllArgs.realloc(nLength+1); - lAllArgs[nLength].Name = ::rtl::OUString::createFromAscii(JobData::PROPSET_DYNAMICDATA); - lAllArgs[nLength].Value <<= lDynamicArgs; - } - - return lAllArgs; -} - -//________________________________ -/** - @short analyze the given job result and change the job configuration - @descr Note: Some results can be handled only, if this job has a valid configuration! - For "not configured jobs" (means pure services) they can be ignored. - But these cases are handled by our JobData member. We can call it everytime. - It does the right things automaticly. E.g. if the job has no configuration ... - it does nothing during setJobConfig()! - - @param aResult - the job result for analyzing -*/ -void Job::impl_reactForJobResult( /*IN*/ const css::uno::Any& aResult ) -{ - /* SAFE { */ - WriteGuard aWriteLock(m_aLock); - - // analyze the result set ... - JobResult aAnalyzedResult(aResult); - - // some of the following operations will be supported for different environments - // or different type of jobs only. - JobData::EEnvironment eEnvironment = m_aJobCfg.getEnvironment(); - - // write back the job specific configuration data ... - // If the environment allow it and if this job has a configuration! - if ( - (m_aJobCfg.hasConfig() ) && - (aAnalyzedResult.existPart(JobResult::E_ARGUMENTS)) - ) - { - m_aJobCfg.setJobConfig(aAnalyzedResult.getArguments()); - } - - // disable a job for further executions. - // Note: this option is available inside the environment EXECUTOR only - if ( -// (eEnvironment == JobData::E_EXECUTION ) && - (m_aJobCfg.hasConfig() ) && - (aAnalyzedResult.existPart(JobResult::E_DEACTIVATE)) - ) - { - m_aJobCfg.disableJob(); - } - - // notify any interested listener with the may given result state. - // Note: this option is available inside the environment DISPATCH only - if ( - (eEnvironment == JobData::E_DISPATCH ) && - (m_xResultListener.is() ) && - (aAnalyzedResult.existPart(JobResult::E_DISPATCHRESULT)) - ) - { - m_aJobCfg.setResult(aAnalyzedResult); - // Attention: Because the listener expect that the original object send this event ... - // and we nor the job are the right ones ... - // our user has set itself before. So we can fake this source address! - css::frame::DispatchResultEvent aEvent = aAnalyzedResult.getDispatchResult(); - aEvent.Source = m_xResultSourceFake; - m_xResultListener->dispatchFinished(aEvent); - } - - aWriteLock.unlock(); - /* SAFE { */ -} - -//________________________________ -/** - @short starts listening for office shutdown and closing of our - given target frame (if its a valid reference) - @descr We will reghister ourself as terminate listener - at the global desktop instance. That will hold us - alive and additional we get the information, if the - office whish to shutdown. If then an internal job - is running we will have the chance to supress that - by throwing a veto exception. If our internal wrapped - job finished his work, we can release this listener - connection. - - Further we are listener for closing of the (possible valid) - given frame. We must be shure, that this ressource won't be gone - if our internal job is still running. -*/ -void Job::impl_startListening() -{ - /* SAFE { */ - WriteGuard aWriteLock(m_aLock); - - // listening for office shutdown - if (!m_xDesktop.is() && !m_bListenOnDesktop) - { - try - { - m_xDesktop = css::uno::Reference< css::frame::XDesktop >(m_xSMGR->createInstance(SERVICENAME_DESKTOP), css::uno::UNO_QUERY); - css::uno::Reference< css::frame::XTerminateListener > xThis(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY); - if (m_xDesktop.is()) - { - m_xDesktop->addTerminateListener(xThis); - m_bListenOnDesktop = sal_True; - } - } - catch(css::uno::Exception&) - { - m_xDesktop = css::uno::Reference< css::frame::XDesktop >(); - } - } - - // listening for frame closing - if (m_xFrame.is() && !m_bListenOnFrame) - { - try - { - css::uno::Reference< css::util::XCloseBroadcaster > xCloseable(m_xFrame , css::uno::UNO_QUERY); - css::uno::Reference< css::util::XCloseListener > xThis (static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY); - if (xCloseable.is()) - { - xCloseable->addCloseListener(xThis); - m_bListenOnFrame = sal_True; - } - } - catch(css::uno::Exception&) - { - m_bListenOnFrame = sal_False; - } - } - - // listening for model closing - if (m_xModel.is() && !m_bListenOnModel) - { - try - { - css::uno::Reference< css::util::XCloseBroadcaster > xCloseable(m_xModel , css::uno::UNO_QUERY); - css::uno::Reference< css::util::XCloseListener > xThis (static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY); - if (xCloseable.is()) - { - xCloseable->addCloseListener(xThis); - m_bListenOnModel = sal_True; - } - } - catch(css::uno::Exception&) - { - m_bListenOnModel = sal_False; - } - } - - aWriteLock.unlock(); - /* } SAFE */ -} - -//________________________________ -/** - @short release listener connection for office shutdown - @descr see description of impl_startListening() -*/ -void Job::impl_stopListening() -{ - /* SAFE { */ - WriteGuard aWriteLock(m_aLock); - - // stop listening for office shutdown - if (m_xDesktop.is() && m_bListenOnDesktop) - { - try - { - css::uno::Reference< css::frame::XTerminateListener > xThis(static_cast< ::cppu::OWeakObject* >(this) , css::uno::UNO_QUERY); - m_xDesktop->removeTerminateListener(xThis); - m_xDesktop = css::uno::Reference< css::frame::XDesktop >(); - m_bListenOnDesktop = sal_False; - } - catch(css::uno::Exception&) - { - } - } - - // stop listening for frame closing - if (m_xFrame.is() && m_bListenOnFrame) - { - try - { - css::uno::Reference< css::util::XCloseBroadcaster > xCloseable(m_xFrame , css::uno::UNO_QUERY); - css::uno::Reference< css::util::XCloseListener > xThis (static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY); - if (xCloseable.is()) - { - xCloseable->removeCloseListener(xThis); - m_bListenOnFrame = sal_False; - } - } - catch(css::uno::Exception&) - { - } - } - - // stop listening for model closing - if (m_xModel.is() && m_bListenOnModel) - { - try - { - css::uno::Reference< css::util::XCloseBroadcaster > xCloseable(m_xModel , css::uno::UNO_QUERY); - css::uno::Reference< css::util::XCloseListener > xThis (static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY); - if (xCloseable.is()) - { - xCloseable->removeCloseListener(xThis); - m_bListenOnModel = sal_False; - } - } - catch(css::uno::Exception&) - { - } - } - - aWriteLock.unlock(); - /* } SAFE */ -} - -//________________________________ -/** - @short callback from any asynchronous executed job - - @descr Our execute() method waits for this callback. - We have to react for the possible results here, - to kill the running job and disable the blocked condition - so execute() can be finished too. - - @param xJob - the job, which was running and inform us now - - @param aResult - it's results -*/ -void SAL_CALL Job::jobFinished( /*IN*/ const css::uno::Reference< css::task::XAsyncJob >& xJob , - /*IN*/ const css::uno::Any& aResult ) throw(css::uno::RuntimeException) -{ - /* SAFE { */ - WriteGuard aWriteLock(m_aLock); - - // It's neccessary to check this. - // May this job was cancelled by any other reason - // some milliseconds before. :-) - if (m_xJob.is() && m_xJob==xJob) - { - // react for his results - // (means enable/disable it for further requests - // or save arguments or notify listener ...) - impl_reactForJobResult(aResult); - - // Let the job die! - m_xJob = css::uno::Reference< css::uno::XInterface >(); - } - - // And let the start method "execute()" finishing it's job. - // But do it everytime. So any outside blocking code can finish - // his work too. - m_aAsyncWait.set(); - - aWriteLock.unlock(); - /* } SAFE */ -} - -//________________________________ -/** - @short prevent internal wrapped job against office termination - @descr This event is broadcasted by the desktop instance and ask for an office termination. - If the internal wrapped job is still in progress, we disagree with that by throwing the - right veto exception. If not - we agree. But then we must be aware, that another event - notifyTermination() can follow. Then we have no chance to do the same. Then we have to - accept that and stop our work instandly. - - @param aEvent - describes the broadcaster and must be the desktop instance - - @throw TerminateVetoException - if our internal wrapped job is still running. - */ -void SAL_CALL Job::queryTermination( /*IN*/ const css::lang::EventObject& ) throw(css::frame::TerminationVetoException, - css::uno::RuntimeException ) -{ - /* SAFE { */ - ReadGuard aReadLock(m_aLock); - - - // Otherwhise try to close() it - css::uno::Reference< css::util::XCloseable > xClose(m_xJob, css::uno::UNO_QUERY); - if (xClose.is()) - { - try - { - xClose->close(sal_False); - m_eRunState = E_STOPPED_OR_FINISHED; - } - catch(const css::util::CloseVetoException&) {} - } - - if (m_eRunState != E_STOPPED_OR_FINISHED) - { - css::uno::Reference< css::uno::XInterface > xThis(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY); - throw css::frame::TerminationVetoException(DECLARE_ASCII("job still in progress"), xThis); - } - - aReadLock.unlock(); - /* } SAFE */ -} - - -//________________________________ -/** - @short inform us about office termination - @descr Instead of the method queryTermination(), here is no chance to disagree with that. - We have to accept it and cancel all current processes inside. - It can occure only, if job was not already started if queryTermination() was called here .. - Then we had not throwed a veto exception. But now we must agree with this situation and break - all our internal processes. Its not a good idea to mark this instance as non startable any longer - inside queryTermination() if no job was unning too. Because that would disable this job and may - the office does not realy shutdownm, because another listener has thrown the suitable exception. - - @param aEvent - describes the broadcaster and must be the desktop instance - */ -void SAL_CALL Job::notifyTermination( /*IN*/ const css::lang::EventObject& ) throw(css::uno::RuntimeException) -{ - die(); - // Do nothing else here. Our internal ressources was released ... -} - -//________________________________ -/** - @short prevent internal wrapped job against frame closing - @descr This event is broadcasted by the frame instance and ask for closing. - If the internal wrapped job is still in progress, we disagree with that by throwing the - right veto exception. If not - we agree. But then we must be aware, that another event - notifyClosing() can follow. Then we have no chance to do the same. Then we have to - accept that and stop our work instandly. - - @param aEvent - describes the broadcaster and must be the frame instance - - @param bGetsOwnerShip - If it's set to <sal_True> and we throw the right veto excepion, we have to close this frame later - if our internal processes will be finished. If it's set to <FALSE/> we can ignore it. - - @throw CloseVetoException - if our internal wrapped job is still running. - */ -void SAL_CALL Job::queryClosing( const css::lang::EventObject& aEvent , - sal_Bool bGetsOwnership ) throw(css::util::CloseVetoException, - css::uno::RuntimeException ) -{ - /* SAFE { */ - WriteGuard aWriteLock(m_aLock); - - // do nothing, if no internal job is still running ... - // The frame or model can be closed then successfully. - if (m_eRunState != E_RUNNING) - return; - - // try close() first at the job. - // The job can agree or disagree with this request. - css::uno::Reference< css::util::XCloseable > xClose(m_xJob, css::uno::UNO_QUERY); - if (xClose.is()) - { - xClose->close(bGetsOwnership); - // Here we can say: "this job was stopped successfully". Because - // no veto exception was thrown! - m_eRunState = E_STOPPED_OR_FINISHED; - return; - } - - // try dispose() then - // Here the job has no chance for a veto. - // But we must be aware of an "already disposed exception"... - try - { - css::uno::Reference< css::lang::XComponent > xDispose(m_xJob, css::uno::UNO_QUERY); - if (xDispose.is()) - { - xDispose->dispose(); - m_eRunState = E_DISPOSED; - } - } - catch(const css::lang::DisposedException&) - { - // the job was already disposed by any other mechanism !? - // But it's not interesting for us. For us this job is stopped now. - m_eRunState = E_DISPOSED; - } - - if (m_eRunState != E_DISPOSED) - { - // analyze event source - to find out, which resource called queryClosing() at this - // job wrapper. We must bind a "pending close" request to this resource. - // Closing of the corresponding resource will be done if our internal job finish it's work. - m_bPendingCloseFrame = (m_xFrame.is() && aEvent.Source == m_xFrame); - m_bPendingCloseModel = (m_xModel.is() && aEvent.Source == m_xModel); - - // throw suitable veto exception - because the internal job could not be cancelled. - css::uno::Reference< css::uno::XInterface > xThis(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY); - throw css::util::CloseVetoException(DECLARE_ASCII("job still in progress"), xThis); - } - - // No veto ... - // But don't call die() here or free our internal member. - // This must be done inside notifyClosing() only. Otherwhise the - // might stopped job has no chance to return it's results or - // call us back. We must give him the chance to finish it's work successfully. - - aWriteLock.unlock(); - /* } SAFE */ -} - -//________________________________ -/** - @short inform us about frame closing - @descr Instead of the method queryClosing(), here is no chance to disagree with that. - We have to accept it and cancel all current processes inside. - - @param aEvent - describes the broadcaster and must be the frame or model instance we know - */ -void SAL_CALL Job::notifyClosing( const css::lang::EventObject& ) throw(css::uno::RuntimeException) -{ - die(); - // Do nothing else here. Our internal ressources was released ... -} - -//________________________________ -/** - @short shouldn't be called normaly - @descr But it doesn't matter, who called it. We have to kill our internal - running processes hardly. - - @param aEvent - describe the broadcaster -*/ -void SAL_CALL Job::disposing( const css::lang::EventObject& aEvent ) throw(css::uno::RuntimeException) -{ - /* SAFE { */ - WriteGuard aWriteLock(m_aLock); - - if (m_xDesktop.is() && aEvent.Source == m_xDesktop) - { - m_xDesktop = css::uno::Reference< css::frame::XDesktop >(); - m_bListenOnDesktop = sal_False; - } - else - if (m_xFrame.is() && aEvent.Source == m_xFrame) - { - m_xFrame = css::uno::Reference< css::frame::XFrame >(); - m_bListenOnFrame = sal_False; - } - else - if (m_xModel.is() && aEvent.Source == m_xModel) - { - m_xModel = css::uno::Reference< css::frame::XModel >(); - m_bListenOnModel = sal_False; - } - - aWriteLock.unlock(); - /* } SAFE */ - - die(); - // Do nothing else here. Our internal ressources was released ... -} - -} // namespace framework - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |