diff options
author | Vladimir Glazounov <vg@openoffice.org> | 2003-05-22 07:38:04 +0000 |
---|---|---|
committer | Vladimir Glazounov <vg@openoffice.org> | 2003-05-22 07:38:04 +0000 |
commit | 36111eaa31c7be7f268cc3507804f98f70cc79f9 (patch) | |
tree | 9d40a4995a9cd7a945575765adbb7fe0e79384c2 /framework/source | |
parent | 79bf12e847de49c97293c960600db03adc877acc (diff) |
INTEGRATION: CWS os9 (1.3.8); FILE MERGED
2003/05/06 12:59:20 as 1.3.8.3: #107420# implement support for XCloseable/XComponent
2003/05/02 06:58:37 os 1.3.8.2: Syntax corrected ('.' <->'::' )
2003/04/29 09:43:29 as 1.3.8.1: #107420# bind event broadcaster to job execution
Diffstat (limited to 'framework/source')
-rw-r--r-- | framework/source/jobs/jobexecutor.cxx | 250 |
1 files changed, 219 insertions, 31 deletions
diff --git a/framework/source/jobs/jobexecutor.cxx b/framework/source/jobs/jobexecutor.cxx index 901322c33e31..3c124db4d7a7 100644 --- a/framework/source/jobs/jobexecutor.cxx +++ b/framework/source/jobs/jobexecutor.cxx @@ -2,9 +2,9 @@ * * $RCSfile: jobexecutor.cxx,v $ * - * $Revision: 1.3 $ + * $Revision: 1.4 $ * - * last change: $Author: hr $ $Date: 2003-04-04 17:17:12 $ + * last change: $Author: vg $ $Date: 2003-05-22 08:38:04 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -74,8 +74,12 @@ #include <jobs/joburl.hxx> #endif -#ifndef __FRAMEWORK_CONFIG_CONFIGACCESS_HXX_ -#include <jobs/configaccess.hxx> +#ifndef __FRAMEWORK_CLASS_CONVERTER_HXX_ +#include <classes/converter.hxx> +#endif + +#ifndef __FRAMEWORK_THREADHELP_TRANSACTIONGUARD_HXX_ +#include <threadhelp/transactionguard.hxx> #endif #ifndef __FRAMEWORK_THREADHELP_READGUARD_HXX_ @@ -101,6 +105,14 @@ #include <com/sun/star/beans/XPropertySet.hpp> #endif +#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_ +#include <com/sun/star/container/XNameAccess.hpp> +#endif + +#ifndef _COM_SUN_STAR_CONTAINER_XCONTAINER_HPP_ +#include <com/sun/star/container/XContainer.hpp> +#endif + //________________________________ // includes of other projects @@ -130,24 +142,30 @@ namespace framework{ //________________________________ // declarations -DEFINE_XINTERFACE_3( JobExecutor , - OWeakObject , - DIRECT_INTERFACE(css::lang::XTypeProvider), - DIRECT_INTERFACE(css::lang::XServiceInfo ), - DIRECT_INTERFACE(css::task::XJobExecutor ) +DEFINE_XINTERFACE_6( JobExecutor , + OWeakObject , + DIRECT_INTERFACE(css::lang::XTypeProvider ), + DIRECT_INTERFACE(css::lang::XServiceInfo ), + DIRECT_INTERFACE(css::task::XJobExecutor ), + DIRECT_INTERFACE(css::container::XContainerListener ), + DIRECT_INTERFACE(css::document::XEventListener ), + DERIVED_INTERFACE(css::lang::XEventListener,css::document::XEventListener) ) -DEFINE_XTYPEPROVIDER_3( JobExecutor , - css::lang::XTypeProvider, - css::lang::XServiceInfo , - css::task::XJobExecutor +DEFINE_XTYPEPROVIDER_6( JobExecutor , + css::lang::XTypeProvider , + css::lang::XServiceInfo , + css::task::XJobExecutor , + css::container::XContainerListener, + css::document::XEventListener , + css::lang::XEventListener ) -DEFINE_XSERVICEINFO_MULTISERVICE( JobExecutor , - ::cppu::OWeakObject , - SERVICENAME_JOBEXECUTOR , - IMPLEMENTATIONNAME_JOBEXECUTOR - ) +DEFINE_XSERVICEINFO_ONEINSTANCESERVICE( JobExecutor , + ::cppu::OWeakObject , + SERVICENAME_JOBEXECUTOR , + IMPLEMENTATIONNAME_JOBEXECUTOR + ) DEFINE_INIT_SERVICE( JobExecutor, { @@ -156,28 +174,58 @@ DEFINE_INIT_SERVICE( JobExecutor, to create a new instance of this class by our own supported service factory. see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations! */ + // read the list of all currently registered events inside configuration. + // e.g. "/org.openoffice.Office.Jobs/Events/<event name>" + // We need it later to check if an incoming event request can be executed successfully + // or must be rejected. It's an optimization! Of course we must implement updating of this + // list too ... Be listener at the configuration. + + m_aConfig.open(ConfigAccess::E_READONLY); + if (m_aConfig.getMode() == ConfigAccess::E_READONLY) + { + css::uno::Reference< css::container::XNameAccess > xRegistry(m_aConfig.cfg(), css::uno::UNO_QUERY); + if (xRegistry.is()) + m_lEvents = Converter::convert_seqOUString2OUStringList(xRegistry->getElementNames()); + + css::uno::Reference< css::container::XContainer > xNotifier(m_aConfig.cfg(), css::uno::UNO_QUERY); + if (xNotifier.is()) + { + css::uno::Reference< css::container::XContainerListener > xThis(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY); + xNotifier->addContainerListener(xThis); + } + + // don't close cfg here! + // It will be done inside disposing ... + } } ) //________________________________ + /** @short standard ctor @descr It initialize this new instance. @param xSMGR reference to the uno service manager -*/ + */ JobExecutor::JobExecutor( /*IN*/ const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ) - : ThreadHelpBase(&Application::GetSolarMutex()) - , m_xSMGR (xSMGR ) + : ThreadHelpBase (&Application::GetSolarMutex() ) + , ::cppu::OWeakObject ( ) + , m_xSMGR (xSMGR ) + , m_aConfig (xSMGR, ::rtl::OUString::createFromAscii(JobData::EVENTCFG_ROOT) ) { + // Don't do any reference related code here! Do it inside special + // impl_ method() ... see DEFINE_INIT_SERVICE() macro for further informations. } JobExecutor::~JobExecutor() { + LOG_ASSERT(m_aConfig.getMode() == ConfigAccess::E_CLOSED, "JobExecutor::~JobExecutor()\nConfiguration don't send dispoing() message!\n") } //________________________________ + /** @short implementation of XJobExecutor interface @descr We use the given event to locate any registered job inside our configuration @@ -186,15 +234,23 @@ JobExecutor::~JobExecutor() @param sEvent is used to locate registered jobs -*/ + */ void SAL_CALL JobExecutor::trigger( const ::rtl::OUString& sEvent ) throw(css::uno::RuntimeException) { + /* SAFE { */ + ReadGuard aReadLock(m_aLock); + + // Optimization! + // Check if the given event name exist inside configuration and reject wrong requests. + // This optimization supress using of the cfg api for getting event and job descriptions ... + if (m_lEvents.find(sEvent) == m_lEvents.end()) + return; + // get list of all enabled jobs // The called static helper methods read it from the configuration and // filter disabled jobs using it's time stamp values. - /* SAFE { */ - ReadGuard aReadLock(m_aLock); css::uno::Sequence< ::rtl::OUString > lJobs = JobData::getEnabledJobsForEvent(m_xSMGR, sEvent); + aReadLock.unlock(); /* } SAFE */ @@ -221,16 +277,148 @@ void SAL_CALL JobExecutor::trigger( const ::rtl::OUString& sEvent ) throw(css::u aReadLock.unlock(); /* } SAFE */ - try + pJob->execute(css::uno::Sequence< css::beans::NamedValue >()); + } +} + +//________________________________ + +void SAL_CALL JobExecutor::notifyEvent( const css::document::EventObject& aEvent ) throw(css::uno::RuntimeException) +{ + /* SAFE { */ + ReadGuard aReadLock(m_aLock); + + // Optimization! + // Check if the given event name exist inside configuration and reject wrong requests. + // This optimization supress using of the cfg api for getting event and job descriptions ... + if (m_lEvents.find(aEvent.EventName) == m_lEvents.end()) + return; + + // get list of all enabled jobs + // The called static helper methods read it from the configuration and + // filter disabled jobs using it's time stamp values. + css::uno::Sequence< ::rtl::OUString > lJobs = JobData::getEnabledJobsForEvent(m_xSMGR, aEvent.EventName); + + // Special feature: If the events "OnNew" or "OnLoad" occures - we generate our own event "onDocumentOpened". + if ( + (aEvent.EventName.equalsAscii("OnNew") ) || + (aEvent.EventName.equalsAscii("OnLoad")) + ) + { + css::uno::Sequence< ::rtl::OUString > lAdditionalJobs = JobData::getEnabledJobsForEvent(m_xSMGR, DECLARE_ASCII("onDocumentOpened")); + sal_Int32 count = lAdditionalJobs.getLength(); + if (count > 0) { - pJob->execute(css::uno::Sequence< css::beans::NamedValue >()); + sal_Int32 dest = lJobs.getLength(); + sal_Int32 source = 0; + lJobs.realloc(dest+count); + while(source < count) + { + lJobs[dest] = lAdditionalJobs[source]; + ++source; + ++dest; + } } - #ifdef ENABLE_WARNINGS - catch(const css::uno::Exception& exAny) {LOG_EXCEPTION("JobExecutor::trigger()", "catched on execute job", exAny.Message)} - #else - catch(const css::uno::Exception&) {} - #endif // ENABLE_WARNINGS } + + aReadLock.unlock(); + /* } SAFE */ + + // step over all enabled jobs and execute it + sal_Int32 c = lJobs.getLength(); + for (sal_Int32 j=0; j<c; ++j) + { + /* SAFE { */ + aReadLock.lock(); + + JobData aCfg(m_xSMGR); + aCfg.setEvent(aEvent.EventName, lJobs[j]); + aCfg.setEnvironment(JobData::E_DOCUMENTEVENT); + + /*Attention! + Jobs implements interfaces and dies by ref count! + And freeing of such uno object is done by uno itself. + So we have to use dynamic memory everytimes. + */ + css::uno::Reference< css::frame::XModel > xModel(aEvent.Source, css::uno::UNO_QUERY); + Job* pJob = new Job(m_xSMGR, xModel); + css::uno::Reference< css::uno::XInterface > xJob(static_cast< ::cppu::OWeakObject* >(pJob), css::uno::UNO_QUERY); + pJob->setJobData(aCfg); + + aReadLock.unlock(); + /* } SAFE */ + + pJob->execute(css::uno::Sequence< css::beans::NamedValue >()); + } +} + +//________________________________ + +void SAL_CALL JobExecutor::elementInserted( const css::container::ContainerEvent& aEvent ) throw(css::uno::RuntimeException) +{ + ::rtl::OUString sValue; + if (aEvent.Accessor >>= sValue) + { + ::rtl::OUString sEvent = ::utl::extractFirstFromConfigurationPath(sValue); + if (sEvent.getLength() > 0) + { + OUStringList::iterator pEvent = m_lEvents.find(sEvent); + if (pEvent == m_lEvents.end()) + m_lEvents.push_back(sEvent); + } + } +} + +void SAL_CALL JobExecutor::elementRemoved ( const css::container::ContainerEvent& aEvent ) throw(css::uno::RuntimeException) +{ + ::rtl::OUString sValue; + if (aEvent.Accessor >>= sValue) + { + ::rtl::OUString sEvent = ::utl::extractFirstFromConfigurationPath(sValue); + if (sEvent.getLength() > 0) + { + OUStringList::iterator pEvent = m_lEvents.find(sEvent); + if (pEvent != m_lEvents.end()) + m_lEvents.erase(pEvent); + } + } +} + +void SAL_CALL JobExecutor::elementReplaced( const css::container::ContainerEvent& aEvent ) throw(css::uno::RuntimeException) +{ + // I'm not interested on changed items :-) +} + +//________________________________ + +/** @short the used cfg changes notifier wish to be released in its reference. + + @descr We close our internal used configuration instance to + free this reference. + + @attention For the special feature "bind global document event broadcaster to job execution" + this job executor instance was registered from outside code as + css.document.XEventListener. So it can be, that this disposing call comes from + the global event broadcaster service. But we don't hold any reference to this service + which can or must be released. Because this broadcaster itself is an one instance service + too, we can ignore this request. On the other side we must relase our internal CFG + reference ... SOLUTION => check the given event source and react only, if it's our internal + hold configuration object! + */ +void SAL_CALL JobExecutor::disposing( const css::lang::EventObject& aEvent ) throw(css::uno::RuntimeException) +{ + /* SAFE { */ + ReadGuard aReadLock(m_aLock); + css::uno::Reference< css::uno::XInterface > xCFG(m_aConfig.cfg(), css::uno::UNO_QUERY); + if ( + (xCFG == aEvent.Source ) && + (m_aConfig.getMode() != ConfigAccess::E_CLOSED) + ) + { + m_aConfig.close(); + } + aReadLock.unlock(); + /* } SAFE */ } } // namespace framework |