LCOV - code coverage report
Current view: top level - libreoffice/framework/source/jobs - jobdispatch.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 1 114 0.9 %
Date: 2012-12-27 Functions: 1 26 3.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <jobs/jobdispatch.hxx>
      21             : #include <jobs/joburl.hxx>
      22             : #include <jobs/job.hxx>
      23             : #include <threadhelp/readguard.hxx>
      24             : #include <threadhelp/writeguard.hxx>
      25             : #include <threadhelp/resetableguard.hxx>
      26             : #include <classes/converter.hxx>
      27             : #include <general.h>
      28             : #include <services.h>
      29             : 
      30             : #include <com/sun/star/beans/XPropertySet.hpp>
      31             : #include <com/sun/star/frame/DispatchResultState.hpp>
      32             : #include <com/sun/star/frame/ModuleManager.hpp>
      33             : 
      34             : #include <rtl/ustrbuf.hxx>
      35             : #include <vcl/svapp.hxx>
      36             : 
      37             : namespace framework{
      38             : 
      39           0 : DEFINE_XINTERFACE_6( JobDispatch                                     ,
      40             :                      OWeakObject                                     ,
      41             :                      DIRECT_INTERFACE(css::lang::XTypeProvider      ),
      42             :                      DIRECT_INTERFACE(css::frame::XDispatchProvider ),
      43             :                      DIRECT_INTERFACE(css::lang::XInitialization ),
      44             :                      DIRECT_INTERFACE(css::lang::XServiceInfo),
      45             :                      DIRECT_INTERFACE(css::frame::XNotifyingDispatch),
      46             :                      DIRECT_INTERFACE(css::frame::XDispatch         )
      47             :                    )
      48             : 
      49           0 : DEFINE_XTYPEPROVIDER_6( JobDispatch                   ,
      50             :                         css::lang::XTypeProvider      ,
      51             :                         css::frame::XDispatchProvider ,
      52             :                         css::frame::XNotifyingDispatch,
      53             :                         css::lang::XInitialization,
      54             :                         css::lang::XServiceInfo,
      55             :                         css::frame::XDispatch
      56             :                       )
      57             : 
      58         183 : DEFINE_XSERVICEINFO_MULTISERVICE( JobDispatch                   ,
      59             :                                   ::cppu::OWeakObject           ,
      60             :                                   SERVICENAME_PROTOCOLHANDLER   ,
      61             :                                   IMPLEMENTATIONNAME_JOBDISPATCH
      62             :                                 )
      63             : 
      64           0 : DEFINE_INIT_SERVICE( JobDispatch,
      65             :                      {
      66             :                          /*Attention
      67             :                              I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance()
      68             :                              to create a new instance of this class by our own supported service factory.
      69             :                              see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations!
      70             :                          */
      71             :                      }
      72             :                    )
      73             : 
      74             : //________________________________
      75             : /**
      76             :     @short      standard ctor
      77             :     @descr      It initialize this new instance.
      78             : 
      79             :     @param      xSMGR
      80             :                     reference to the uno service manager
      81             : */
      82           0 : JobDispatch::JobDispatch( /*IN*/ const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR )
      83           0 :     : ThreadHelpBase(&Application::GetSolarMutex())
      84             :     , OWeakObject   (                             )
      85           0 :     , m_xSMGR       (xSMGR                        )
      86             : {
      87           0 : }
      88             : 
      89             : //________________________________
      90             : /**
      91             :     @short  let this instance die
      92             :     @descr  We have to release all used resources and free used memory.
      93             : */
      94           0 : JobDispatch::~JobDispatch()
      95             : {
      96             :     // release all used resources
      97           0 :     m_xSMGR  = css::uno::Reference< css::lang::XMultiServiceFactory >();
      98           0 :     m_xFrame = css::uno::Reference< css::frame::XFrame >();
      99           0 : }
     100             : 
     101             : //________________________________
     102             : /**
     103             :     @short  implementation of XInitalization
     104             :     @descr  A protocol handler can provide this functionality, if it wish to get additional informations
     105             :             about the context it runs. In this case the frame reference would be given by the outside code.
     106             : 
     107             :     @param  lArguments
     108             :                 the list of initialization arguments
     109             :                 First parameter should be the frame reference we need.
     110             : */
     111           0 : void SAL_CALL JobDispatch::initialize( const css::uno::Sequence< css::uno::Any >& lArguments ) throw(css::uno::Exception       ,
     112             :                                                                                                      css::uno::RuntimeException)
     113             : {
     114             :     /* SAFE { */
     115           0 :     WriteGuard aWriteLock(m_aLock);
     116             : 
     117           0 :     for (int a=0; a<lArguments.getLength(); ++a)
     118             :     {
     119           0 :         if (a==0)
     120             :         {
     121           0 :             lArguments[a] >>= m_xFrame;
     122             : 
     123             :             css::uno::Reference< css::frame::XModuleManager2 > xModuleManager =
     124           0 :                 css::frame::ModuleManager::create(comphelper::getComponentContext(m_xSMGR));
     125             :             try
     126             :             {
     127           0 :                 m_sModuleIdentifier = xModuleManager->identify( m_xFrame );
     128             :             }
     129           0 :             catch( const css::uno::Exception& )
     130           0 :             {}
     131             :         }
     132             :     }
     133             : 
     134           0 :     aWriteLock.unlock();
     135             :     /* } SAFE */
     136           0 : }
     137             : 
     138             : //________________________________
     139             : /**
     140             :     @short  implementation of XDispatchProvider::queryDispatches()
     141             :     @descr  Every protocol handler will be asked for his agreement, if an URL was queried
     142             :             for which this handler is registered. It's the chance for this handler to validate
     143             :             the given URL and return a dispatch object (may be itself) or not.
     144             : 
     145             :     @param  aURL
     146             :                 the queried URL, which should be checked
     147             : 
     148             :     @param  sTargetFrameName
     149             :                 describes the target frame, in which context this handler will be used
     150             :                 Is mostly set to "", "_self", "_blank", "_default" or a non special one
     151             :                 using SELF/CREATE as search flags.
     152             : 
     153             :     @param  nSearchFlags
     154             :                 Can be SELF or CREATE only and are set only if sTargetFrameName isn't a special target
     155             : */
     156           0 : css::uno::Reference< css::frame::XDispatch > SAL_CALL JobDispatch::queryDispatch( /*IN*/ const css::util::URL&  aURL             ,
     157             :                                                                                   /*IN*/ const ::rtl::OUString& /*sTargetFrameName*/ ,
     158             :                                                                                   /*IN*/       sal_Int32        /*nSearchFlags*/     ) throw(css::uno::RuntimeException)
     159             : {
     160           0 :     css::uno::Reference< css::frame::XDispatch > xDispatch;
     161             : 
     162           0 :     JobURL aAnalyzedURL(aURL.Complete);
     163           0 :     if (aAnalyzedURL.isValid())
     164           0 :         xDispatch = css::uno::Reference< css::frame::XDispatch >( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
     165             : 
     166           0 :     return xDispatch;
     167             : }
     168             : 
     169             : //________________________________
     170             : /**
     171             :     @short  implementation of XDispatchProvider::queryDispatches()
     172             :     @descr  It's an optimized access for remote, so you can ask for
     173             :             multiple dispatch objects at the same time.
     174             : 
     175             :     @param  lDescriptor
     176             :                 a list of queryDispatch() parameter
     177             : 
     178             :     @return A list of corresponding dispatch objects.
     179             :             NULL references are not skipped. Every result
     180             :             match to one given descriptor item.
     181             : */
     182           0 : css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > SAL_CALL JobDispatch::queryDispatches( const css::uno::Sequence< css::frame::DispatchDescriptor >& lDescriptor ) throw(css::uno::RuntimeException)
     183             : {
     184             :     // don't pack resulting list!
     185           0 :     sal_Int32 nCount = lDescriptor.getLength();
     186           0 :     css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > lDispatches(nCount);
     187             : 
     188           0 :     for (sal_Int32 i=0; i<nCount; ++i)
     189           0 :         lDispatches[i] = queryDispatch( lDescriptor[i].FeatureURL  ,
     190           0 :                                         lDescriptor[i].FrameName   ,
     191           0 :                                         lDescriptor[i].SearchFlags );
     192           0 :     return lDispatches;
     193             : }
     194             : 
     195             : //________________________________
     196             : /**
     197             :     @short  implementation of XNotifyingDispatch::dispatchWithNotification()
     198             :     @descr  It creates the job service implementation and call execute on it.
     199             :             Further it starts the life time control of it. (important for async job)
     200             :             For synchonrous job we react for the returned result directly ... for asynchronous
     201             :             ones we do it later inside our callback method. But we use the same impl method
     202             :             doing that to share the code. (see impl_finishJob())
     203             : 
     204             :             If a job is already running, (it can only occure for asynchronous jobs)
     205             :             don't start the same job a second time. Queue in the given dispatch parameter
     206             :             and return immediatly. If the current running job call us back, we will start this
     207             :             new dispatch request.
     208             :             If no job is running - queue the parameter too! But then start the new job immediatly.
     209             :             We have to queue it every time - because it hold us alive by ref count!
     210             : 
     211             :     @param  aURL
     212             :                 describe the job(s), which should be started
     213             : 
     214             :     @param  lArgs
     215             :                 optional arguments for this request
     216             : 
     217             :     @param  xListener
     218             :                 an interested listener for possible results of this operation
     219             : */
     220           0 : void SAL_CALL JobDispatch::dispatchWithNotification( /*IN*/ const css::util::URL&                                             aURL      ,
     221             :                                                      /*IN*/ const css::uno::Sequence< css::beans::PropertyValue >&            lArgs     ,
     222             :                                                      /*IN*/ const css::uno::Reference< css::frame::XDispatchResultListener >& xListener ) throw(css::uno::RuntimeException)
     223             : {
     224           0 :     JobURL aAnalyzedURL(aURL.Complete);
     225           0 :     if (aAnalyzedURL.isValid())
     226             :     {
     227           0 :         ::rtl::OUString sRequest;
     228           0 :         if (aAnalyzedURL.getEvent(sRequest))
     229           0 :             impl_dispatchEvent(sRequest, lArgs, xListener);
     230             :         else
     231           0 :         if (aAnalyzedURL.getService(sRequest))
     232           0 :             impl_dispatchService(sRequest, lArgs, xListener);
     233             :         else
     234           0 :         if (aAnalyzedURL.getAlias(sRequest))
     235           0 :             impl_dispatchAlias(sRequest, lArgs, xListener);
     236           0 :     }
     237           0 : }
     238             : 
     239             : //________________________________
     240             : /**
     241             :     @short  dispatch an event
     242             :     @descr  We search all registered jobs for this event and execute it.
     243             :             After doing so, we inform the given listener about the results.
     244             :             (There will be one notify for every executed job!)
     245             : 
     246             :     @param  sEvent
     247             :                 the event, for which jobs can be registered
     248             : 
     249             :     @param  lArgs
     250             :                 optional arguments for this request
     251             :                 Currently not used!
     252             : 
     253             :     @param  xListener
     254             :                 an interested listener for possible results of this operation
     255             : */
     256           0 : void JobDispatch::impl_dispatchEvent( /*IN*/ const ::rtl::OUString&                                            sEvent    ,
     257             :                                       /*IN*/ const css::uno::Sequence< css::beans::PropertyValue >&            lArgs     ,
     258             :                                       /*IN*/ const css::uno::Reference< css::frame::XDispatchResultListener >& xListener )
     259             : {
     260             :     // get list of all enabled jobs
     261             :     // The called static helper methods read it from the configuration and
     262             :     // filter disabled jobs using it's time stamp values.
     263             :     /* SAFE { */
     264           0 :     ReadGuard aReadLock(m_aLock);
     265           0 :     css::uno::Sequence< ::rtl::OUString > lJobs = JobData::getEnabledJobsForEvent(comphelper::getComponentContext(m_xSMGR), sEvent);
     266           0 :     aReadLock.unlock();
     267             :     /* } SAFE */
     268             : 
     269           0 :     css::uno::Reference< css::frame::XDispatchResultListener > xThis( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
     270             : 
     271             :     // no jobs ... no execution
     272             :     // But a may given listener will know something ...
     273             :     // I think this operaton was finished successfully.
     274             :     // It's not realy an error, if no registered jobs could be located.
     275             :     // Step over all found jobs and execute it
     276           0 :     int nExecutedJobs=0;
     277           0 :     for (int j=0; j<lJobs.getLength(); ++j)
     278             :     {
     279             :         /* SAFE { */
     280           0 :         aReadLock.lock();
     281             : 
     282           0 :         JobData aCfg(comphelper::getComponentContext(m_xSMGR));
     283           0 :         aCfg.setEvent(sEvent, lJobs[j]);
     284           0 :         aCfg.setEnvironment(JobData::E_DISPATCH);
     285           0 :         const bool bIsEnabled=aCfg.hasCorrectContext(m_sModuleIdentifier);
     286             : 
     287             :         /*Attention!
     288             :             Jobs implements interfaces and dies by ref count!
     289             :             And freeing of such uno object is done by uno itself.
     290             :             So we have to use dynamic memory everytimes.
     291             :          */
     292           0 :         Job* pJob = new Job(m_xSMGR, m_xFrame);
     293           0 :         css::uno::Reference< css::uno::XInterface > xJob(static_cast< ::cppu::OWeakObject* >(pJob), css::uno::UNO_QUERY);
     294           0 :         pJob->setJobData(aCfg);
     295             : 
     296           0 :         aReadLock.unlock();
     297             :         /* } SAFE */
     298             : 
     299           0 :         if (!bIsEnabled)
     300           0 :             continue;
     301             : 
     302             :         // Special mode for listener.
     303             :         // We dont notify it directly here. We delegate that
     304             :         // to the job implementation. But we must set ourself there too.
     305             :         // Because this job must fake the source address of the event.
     306             :         // Otherwise the listener may ignore it.
     307           0 :         if (xListener.is())
     308           0 :             pJob->setDispatchResultFake(xListener, xThis);
     309           0 :         pJob->execute(Converter::convert_seqPropVal2seqNamedVal(lArgs));
     310           0 :         ++nExecutedJobs;
     311           0 :     }
     312             : 
     313           0 :     if (nExecutedJobs<1 && xListener.is())
     314             :     {
     315           0 :         css::frame::DispatchResultEvent aEvent;
     316           0 :         aEvent.Source = xThis;
     317           0 :         aEvent.State  = css::frame::DispatchResultState::SUCCESS;
     318           0 :         xListener->dispatchFinished(aEvent);
     319           0 :     }
     320           0 : }
     321             : 
     322             : //________________________________
     323             : /**
     324             :     @short  dispatch a service
     325             :     @descr  We use the given name only to create and if possible to initialize
     326             :             it as an uno service. It can be usefully for creating (caching?)
     327             :             of e.g. one instance services.
     328             : 
     329             :     @param  sService
     330             :                 the uno implementation or service name of the job, which should be instanciated
     331             : 
     332             :     @param  lArgs
     333             :                 optional arguments for this request
     334             :                 Currently not used!
     335             : 
     336             :     @param  xListener
     337             :                 an interested listener for possible results of this operation
     338             : */
     339           0 : void JobDispatch::impl_dispatchService( /*IN*/ const ::rtl::OUString&                                            sService  ,
     340             :                                         /*IN*/ const css::uno::Sequence< css::beans::PropertyValue >&            lArgs     ,
     341             :                                         /*IN*/ const css::uno::Reference< css::frame::XDispatchResultListener >& xListener )
     342             : {
     343             :     /* SAFE { */
     344           0 :     ReadGuard aReadLock(m_aLock);
     345             : 
     346           0 :     JobData aCfg(comphelper::getComponentContext(m_xSMGR));
     347           0 :     aCfg.setService(sService);
     348           0 :     aCfg.setEnvironment(JobData::E_DISPATCH);
     349             : 
     350             :     /*Attention!
     351             :         Jobs implements interfaces and dies by ref count!
     352             :         And freeing of such uno object is done by uno itself.
     353             :         So we have to use dynamic memory everytimes.
     354             :      */
     355           0 :     Job* pJob = new Job(m_xSMGR, m_xFrame);
     356           0 :     css::uno::Reference< css::uno::XInterface > xJob(static_cast< ::cppu::OWeakObject* >(pJob), css::uno::UNO_QUERY);
     357           0 :     pJob->setJobData(aCfg);
     358             : 
     359           0 :     aReadLock.unlock();
     360             :     /* } SAFE */
     361             : 
     362           0 :     css::uno::Reference< css::frame::XDispatchResultListener > xThis( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
     363             : 
     364             :     // Special mode for listener.
     365             :     // We dont notify it directly here. We delegate that
     366             :     // to the job implementation. But we must set ourself there too.
     367             :     // Because this job must fake the source address of the event.
     368             :     // Otherwise the listener may ignore it.
     369           0 :     if (xListener.is())
     370           0 :         pJob->setDispatchResultFake(xListener, xThis);
     371           0 :     pJob->execute(Converter::convert_seqPropVal2seqNamedVal(lArgs));
     372           0 : }
     373             : 
     374             : //________________________________
     375             : /**
     376             :     @short  dispatch an alias
     377             :     @descr  We use this alias to locate a job inside the configuration
     378             :             and execute it. Further we inform the given listener about the results.
     379             : 
     380             :     @param  sAlias
     381             :                 the alias name of the configured job
     382             : 
     383             :     @param  lArgs
     384             :                 optional arguments for this request
     385             :                 Currently not used!
     386             : 
     387             :     @param  xListener
     388             :                 an interested listener for possible results of this operation
     389             : */
     390           0 : void JobDispatch::impl_dispatchAlias( /*IN*/ const ::rtl::OUString&                                            sAlias    ,
     391             :                                       /*IN*/ const css::uno::Sequence< css::beans::PropertyValue >&            lArgs     ,
     392             :                                       /*IN*/ const css::uno::Reference< css::frame::XDispatchResultListener >& xListener )
     393             : {
     394             :     /* SAFE { */
     395           0 :     ReadGuard aReadLock(m_aLock);
     396             : 
     397           0 :     JobData aCfg(comphelper::getComponentContext(m_xSMGR));
     398           0 :     aCfg.setAlias(sAlias);
     399           0 :     aCfg.setEnvironment(JobData::E_DISPATCH);
     400             : 
     401             :     /*Attention!
     402             :         Jobs implements interfaces and dies by ref count!
     403             :         And freeing of such uno object is done by uno itself.
     404             :         So we have to use dynamic memory everytimes.
     405             :      */
     406           0 :     Job* pJob = new Job(m_xSMGR, m_xFrame);
     407           0 :     css::uno::Reference< css::uno::XInterface > xJob(static_cast< ::cppu::OWeakObject* >(pJob), css::uno::UNO_QUERY);
     408           0 :     pJob->setJobData(aCfg);
     409             : 
     410           0 :     aReadLock.unlock();
     411             :     /* } SAFE */
     412             : 
     413           0 :     css::uno::Reference< css::frame::XDispatchResultListener > xThis( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
     414             : 
     415             :     // Special mode for listener.
     416             :     // We dont notify it directly here. We delegate that
     417             :     // to the job implementation. But we must set ourself there too.
     418             :     // Because this job must fake the source address of the event.
     419             :     // Otherwise the listener may ignore it.
     420           0 :     if (xListener.is())
     421           0 :         pJob->setDispatchResultFake(xListener, xThis);
     422           0 :     pJob->execute(Converter::convert_seqPropVal2seqNamedVal(lArgs));
     423           0 : }
     424             : 
     425             : //________________________________
     426             : /**
     427             :     @short  implementation of XDispatch::dispatch()
     428             :     @descr  Because the methods dispatch() and dispatchWithNotification() are different in her parameters
     429             :             only, we can forward this request to dispatchWithNotification() by using an empty listener!
     430             : 
     431             :     @param  aURL
     432             :                 describe the job(s), which should be started
     433             : 
     434             :     @param  lArgs
     435             :                 optional arguments for this request
     436             : 
     437             :     @see    dispatchWithNotification()
     438             : */
     439           0 : void SAL_CALL JobDispatch::dispatch( /*IN*/ const css::util::URL&                                  aURL  ,
     440             :                                      /*IN*/ const css::uno::Sequence< css::beans::PropertyValue >& lArgs ) throw(css::uno::RuntimeException)
     441             : {
     442           0 :     dispatchWithNotification(aURL, lArgs, css::uno::Reference< css::frame::XDispatchResultListener >());
     443           0 : }
     444             : 
     445             : //________________________________
     446             : /**
     447             :     @short  not supported
     448             : */
     449           0 : void SAL_CALL JobDispatch::addStatusListener( /*IN*/ const css::uno::Reference< css::frame::XStatusListener >&,
     450             :                                               /*IN*/ const css::util::URL&                                      ) throw(css::uno::RuntimeException)
     451             : {
     452           0 : }
     453             : 
     454             : //________________________________
     455             : /**
     456             :     @short  not supported
     457             : */
     458           0 : void SAL_CALL JobDispatch::removeStatusListener( /*IN*/ const css::uno::Reference< css::frame::XStatusListener >&,
     459             :                                                  /*IN*/ const css::util::URL&                                          ) throw(css::uno::RuntimeException)
     460             : {
     461           0 : }
     462             : 
     463             : } // namespace framework
     464             : 
     465             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10