From ecc7ab4b75d4fe46e4f6d51018506f7ceb745f44 Mon Sep 17 00:00:00 2001 From: Carsten Driesner Date: Thu, 4 Nov 2010 15:43:13 +0100 Subject: fwk160: #i107568# Jobs service enhancement to instantiate services only on matching application module context --- framework/inc/jobs/jobdata.hxx | 10 ++++++++++ framework/inc/jobs/jobdispatch.hxx | 3 +++ framework/inc/jobs/jobexecutor.hxx | 4 ++++ framework/source/jobs/jobdata.cxx | 30 ++++++++++++++++++++++++++-- framework/source/jobs/jobdispatch.cxx | 37 ++++++++++++++++++++++++++--------- framework/source/jobs/jobexecutor.cxx | 18 +++++++++++++++++ 6 files changed, 91 insertions(+), 11 deletions(-) (limited to 'framework') diff --git a/framework/inc/jobs/jobdata.hxx b/framework/inc/jobs/jobdata.hxx index 21aa027cc874..e9cc79030770 100644 --- a/framework/inc/jobs/jobdata.hxx +++ b/framework/inc/jobs/jobdata.hxx @@ -80,6 +80,8 @@ class JobData : private ThreadHelpBase static const sal_Char* JOBCFG_PROP_ARGUMENTS; /// define the cfg key "Service" of a job relativ to JOBCFG_ROOT/ static const sal_Char* JOBCFG_PROP_SERVICE; + /// define the cfg key "Context" of a job relativ to JOBCFG_ROOT/ + static const sal_Char* JOBCFG_PROP_CONTEXT; /// specifies the root package and key to find event registrations static const sal_Char* EVENTCFG_ROOT; @@ -105,6 +107,7 @@ class JobData : private ThreadHelpBase static const sal_Char* PROP_FRAME; static const sal_Char* PROP_MODEL; static const sal_Char* PROP_SERVICE; + static const sal_Char* PROP_CONTEXT; //___________________________________ // structs @@ -209,6 +212,12 @@ class JobData : private ThreadHelpBase */ ::rtl::OUString m_sService; + /** + the module context list of this job. + It's readed from the configuration. Don't set it from outside! + */ + ::rtl::OUString m_sContext; + /** a job can be registered for an event. It can be an empty value! But it will be set from outside any times. @@ -255,6 +264,7 @@ class JobData : private ThreadHelpBase css::uno::Sequence< css::beans::NamedValue > getJobConfig () const; sal_Bool hasConfig () const; + sal_Bool hasCorrectContext ( const ::rtl::OUString& rModuleIdent ) const; void setEnvironment ( EEnvironment eEnvironment ); void setAlias ( const ::rtl::OUString& sAlias ); diff --git a/framework/inc/jobs/jobdispatch.hxx b/framework/inc/jobs/jobdispatch.hxx index 85e501e866e1..49b6b31b8cac 100644 --- a/framework/inc/jobs/jobdispatch.hxx +++ b/framework/inc/jobs/jobdispatch.hxx @@ -101,6 +101,9 @@ class JobDispatch : public css::lang::XTypeProvider /** reference to the frame, inside which this dispatch is used */ css::uno::Reference< css::frame::XFrame > m_xFrame; + /** name of module (writer, impress etc.) the frame is for */ + ::rtl::OUString m_sModuleIdentifier; + //___________________________________ // native interface methods diff --git a/framework/inc/jobs/jobexecutor.hxx b/framework/inc/jobs/jobexecutor.hxx index ead1022df2ec..955b2978f791 100644 --- a/framework/inc/jobs/jobexecutor.hxx +++ b/framework/inc/jobs/jobexecutor.hxx @@ -48,6 +48,7 @@ #include #include #include +#include //_______________________________________ // other includes @@ -85,6 +86,9 @@ class JobExecutor : public css::lang::XTypeProvider /** reference to the uno service manager */ css::uno::Reference< css::lang::XMultiServiceFactory > m_xSMGR; + /** reference to the module info service */ + css::uno::Reference< css::frame::XModuleManager > m_xModuleManager; + /** cached list of all registered event names of cfg for call optimization. */ OUStringList m_lEvents; diff --git a/framework/source/jobs/jobdata.cxx b/framework/source/jobs/jobdata.cxx index 4acbce44f831..4d7051231513 100644 --- a/framework/source/jobs/jobdata.cxx +++ b/framework/source/jobs/jobdata.cxx @@ -1,4 +1,4 @@ - /************************************************************************* +/************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -61,6 +61,7 @@ namespace framework{ const sal_Char* JobData::JOBCFG_ROOT = "/org.openoffice.Office.Jobs/Jobs/" ; const sal_Char* JobData::JOBCFG_PROP_SERVICE = "Service" ; +const sal_Char* JobData::JOBCFG_PROP_CONTEXT = "Context" ; const sal_Char* JobData::JOBCFG_PROP_ARGUMENTS = "Arguments" ; const sal_Char* JobData::EVENTCFG_ROOT = "/org.openoffice.Office.Jobs/Events/" ; @@ -79,6 +80,7 @@ const sal_Char* JobData::PROP_ENVTYPE = "EnvType" const sal_Char* JobData::PROP_FRAME = "Frame" ; const sal_Char* JobData::PROP_MODEL = "Model" ; const sal_Char* JobData::PROP_SERVICE = "Service" ; +const sal_Char* JobData::PROP_CONTEXT = "Context" ; //________________________________ // non exported definitions @@ -139,6 +141,7 @@ void JobData::operator=( const JobData& rCopy ) m_eEnvironment = rCopy.m_eEnvironment ; m_sAlias = rCopy.m_sAlias ; m_sService = rCopy.m_sService ; + m_sContext = rCopy.m_sContext ; m_sEvent = rCopy.m_sEvent ; m_lArguments = rCopy.m_lArguments ; m_aLastExecutionResult = rCopy.m_aLastExecutionResult; @@ -201,6 +204,10 @@ void JobData::setAlias( const ::rtl::OUString& sAlias ) aValue = xJobProperties->getPropertyValue(::rtl::OUString::createFromAscii(JOBCFG_PROP_SERVICE)); aValue >>= m_sService; + // read module context list + aValue = xJobProperties->getPropertyValue(::rtl::OUString::createFromAscii(JOBCFG_PROP_CONTEXT)); + aValue >>= m_sContext; + // read whole argument list aValue = xJobProperties->getPropertyValue(::rtl::OUString::createFromAscii(JOBCFG_PROP_ARGUMENTS)); css::uno::Reference< css::container::XNameAccess > xArgumentList; @@ -477,7 +484,7 @@ css::uno::Sequence< css::beans::NamedValue > JobData::getConfig() const css::uno::Sequence< css::beans::NamedValue > lConfig; if (m_eMode==E_ALIAS) { - lConfig.realloc(2); + lConfig.realloc(3); sal_Int32 i = 0; lConfig[i].Name = ::rtl::OUString::createFromAscii(PROP_ALIAS); @@ -487,6 +494,10 @@ css::uno::Sequence< css::beans::NamedValue > JobData::getConfig() const lConfig[i].Name = ::rtl::OUString::createFromAscii(PROP_SERVICE); lConfig[i].Value <<= m_sService; ++i; + + lConfig[i].Name = ::rtl::OUString::createFromAscii(PROP_CONTEXT); + lConfig[i].Value <<= m_sContext; + ++i; } aReadLock.unlock(); /* } SAFE */ @@ -607,6 +618,20 @@ void JobData::appendEnabledJobsForEvent( const css::uno::Reference< css::lang::X } } +//________________________________ +/** + */ +sal_Bool JobData::hasCorrectContext(const ::rtl::OUString& rModuleIdent) const +{ + if ( m_sContext.getLength() == 0 ) + return sal_True; + + if ( rModuleIdent.getLength() > 0 ) + return ( m_sContext.equals( rModuleIdent )); + + return sal_False; +} + //________________________________ /** */ @@ -705,6 +730,7 @@ void JobData::impl_reset() m_eEnvironment = E_UNKNOWN_ENVIRONMENT; m_sAlias = ::rtl::OUString(); m_sService = ::rtl::OUString(); + m_sContext = ::rtl::OUString(); m_sEvent = ::rtl::OUString(); m_lArguments = css::uno::Sequence< css::beans::NamedValue >(); aWriteLock.unlock(); diff --git a/framework/source/jobs/jobdispatch.cxx b/framework/source/jobs/jobdispatch.cxx index b2c5399d0216..afc0abada7c1 100644 --- a/framework/source/jobs/jobdispatch.cxx +++ b/framework/source/jobs/jobdispatch.cxx @@ -44,6 +44,7 @@ // interface includes #include #include +#include //________________________________ // includes of other projects @@ -145,7 +146,20 @@ void SAL_CALL JobDispatch::initialize( const css::uno::Sequence< css::uno::Any > for (int a=0; a>= m_xFrame; + + css::uno::Reference< css::frame::XModuleManager > xModuleManager( + m_xSMGR->createInstance( + SERVICENAME_MODULEMANAGER ), + css::uno::UNO_QUERY_THROW ); + try + { + m_sModuleIdentifier = xModuleManager->identify( m_xFrame ); + } + catch( css::uno::Exception& ) + {} + } } aWriteLock.unlock(); @@ -289,16 +303,8 @@ void JobDispatch::impl_dispatchEvent( /*IN*/ const ::rtl::OUString& // But a may given listener will know something ... // I think this operaton was finished successfully. // It's not realy an error, if no registered jobs could be located. - if (lJobs.getLength()<1 && xListener.is()) - { - css::frame::DispatchResultEvent aEvent; - aEvent.Source = xThis; - aEvent.State = css::frame::DispatchResultState::SUCCESS; - xListener->dispatchFinished(aEvent); - return; - } - // Step over all found jobs and execute it + int nExecutedJobs=0; for (int j=0; jsetDispatchResultFake(xListener, xThis); pJob->execute(Converter::convert_seqPropVal2seqNamedVal(lArgs)); + ++nExecutedJobs; + } + + if (nExecutedJobs<1 && xListener.is()) + { + css::frame::DispatchResultEvent aEvent; + aEvent.Source = xThis; + aEvent.State = css::frame::DispatchResultState::SUCCESS; + xListener->dispatchFinished(aEvent); } } diff --git a/framework/source/jobs/jobexecutor.cxx b/framework/source/jobs/jobexecutor.cxx index e3a6122d4938..f33d88216566 100644 --- a/framework/source/jobs/jobexecutor.cxx +++ b/framework/source/jobs/jobexecutor.cxx @@ -98,6 +98,11 @@ DEFINE_XSERVICEINFO_ONEINSTANCESERVICE( JobExecutor , DEFINE_INIT_SERVICE( JobExecutor, { + m_xModuleManager = css::uno::Reference< css::frame::XModuleManager >( + m_xSMGR->createInstance( + SERVICENAME_MODULEMANAGER ), + css::uno::UNO_QUERY_THROW ); + /*Attention I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance() to create a new instance of this class by our own supported service factory. @@ -142,6 +147,7 @@ JobExecutor::JobExecutor( /*IN*/ const css::uno::Reference< css::lang::XMultiSer : ThreadHelpBase (&Application::GetSolarMutex() ) , ::cppu::OWeakObject ( ) , m_xSMGR (xSMGR ) + , m_xModuleManager ( ) , m_aConfig (xSMGR, ::rtl::OUString::createFromAscii(JobData::EVENTCFG_ROOT) ) { // Don't do any reference related code here! Do it inside special @@ -233,6 +239,15 @@ void SAL_CALL JobExecutor::notifyEvent( const css::document::EventObject& aEvent // This optimization supress using of the cfg api for getting event and job descriptions. // see using of m_lEvents.find() below ... + // retrieve event context from event source + rtl::OUString aModuleIdentifier; + try + { + aModuleIdentifier = m_xModuleManager->identify( aEvent.Source ); + } + catch( css::uno::Exception& ) + {} + // Special feature: If the events "OnNew" or "OnLoad" occures - we generate our own event "onDocumentOpened". if ( (aEvent.EventName.equals(EVENT_ON_NEW )) || @@ -275,6 +290,9 @@ void SAL_CALL JobExecutor::notifyEvent( const css::document::EventObject& aEvent aCfg.setEvent(rBinding.m_sDocEvent, rBinding.m_sJobName); aCfg.setEnvironment(JobData::E_DOCUMENTEVENT); + if (!aCfg.hasCorrectContext(aModuleIdentifier)) + continue; + /*Attention! Jobs implements interfaces and dies by ref count! And freeing of such uno object is done by uno itself. -- cgit From cc707fd9b308f07bbebdf83dae3a8b1ef6168d48 Mon Sep 17 00:00:00 2001 From: Carsten Driesner Date: Thu, 4 Nov 2010 17:17:08 +0100 Subject: fwk160: #i107568# Revised hasContext() implementation to fix problem described in the issue --- framework/source/jobs/jobdata.cxx | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'framework') diff --git a/framework/source/jobs/jobdata.cxx b/framework/source/jobs/jobdata.cxx index 4d7051231513..feb1e4bb52f9 100644 --- a/framework/source/jobs/jobdata.cxx +++ b/framework/source/jobs/jobdata.cxx @@ -623,11 +623,21 @@ void JobData::appendEnabledJobsForEvent( const css::uno::Reference< css::lang::X */ sal_Bool JobData::hasCorrectContext(const ::rtl::OUString& rModuleIdent) const { - if ( m_sContext.getLength() == 0 ) + sal_Int32 nContextLen = m_sContext.getLength(); + sal_Int32 nModuleIdLen = rModuleIdent.getLength(); + + if ( nContextLen == 0 ) return sal_True; - if ( rModuleIdent.getLength() > 0 ) - return ( m_sContext.equals( rModuleIdent )); + if ( nModuleIdLen > 0 ) + { + sal_Int32 nIndex = m_sContext.indexOf( rModuleIdent ); + if ( nIndex >= 0 && ( nIndex+nModuleIdLen <= nContextLen )) + { + ::rtl::OUString sContextModule = m_sContext.copy( nIndex, nModuleIdLen ); + return sContextModule.equals( rModuleIdent ); + } + } return sal_False; } -- cgit