LCOV - code coverage report
Current view: top level - framework/source/dispatch - dispatchprovider.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 110 180 61.1 %
Date: 2014-11-03 Functions: 11 13 84.6 %
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 <stdio.h>
      21             : #include <dispatch/dispatchprovider.hxx>
      22             : #include <loadenv/loadenv.hxx>
      23             : #include <dispatch/loaddispatcher.hxx>
      24             : #include <dispatch/closedispatcher.hxx>
      25             : #include <dispatch/menudispatcher.hxx>
      26             : #include <dispatch/startmoduledispatcher.hxx>
      27             : 
      28             : #include <pattern/window.hxx>
      29             : #include <threadhelp/transactionguard.hxx>
      30             : #include <dispatchcommands.h>
      31             : #include <protocols.h>
      32             : #include <services.h>
      33             : #include <targets.h>
      34             : #include <general.h>
      35             : 
      36             : #include <com/sun/star/frame/FrameSearchFlag.hpp>
      37             : #include <com/sun/star/uno/Exception.hpp>
      38             : #include <com/sun/star/ucb/XContentProviderManager.hpp>
      39             : #include <com/sun/star/document/XTypeDetection.hpp>
      40             : #include <com/sun/star/lang/XInitialization.hpp>
      41             : 
      42             : #include <osl/diagnose.h>
      43             : #include <rtl/string.h>
      44             : #include <rtl/ustring.hxx>
      45             : #include <vcl/svapp.hxx>
      46             : #include <rtl/ustrbuf.hxx>
      47             : 
      48             : namespace framework{
      49             : 
      50             : /**
      51             :     @short      standard ctor/dtor
      52             :     @descr      These initialize a new instance of this class with needed information for work.
      53             :                 We hold a weakreference to our owner frame which start dispatches at us.
      54             :                 We can't use a normal reference because he hold a reference of us too ...
      55             :                 nobody can die so ...!
      56             : 
      57             :     @seealso    using at owner
      58             : 
      59             :     @param      rxContext
      60             :                     reference to servicemanager to create new services.
      61             :     @param      xFrame
      62             :                     reference to our owner frame.
      63             : */
      64        5883 : DispatchProvider::DispatchProvider( const css::uno::Reference< css::uno::XComponentContext >& rxContext  ,
      65             :                                     const css::uno::Reference< css::frame::XFrame >&              xFrame    )
      66             :         : m_xContext    ( rxContext                     )
      67        5883 :         , m_xFrame      ( xFrame                        )
      68             : {
      69        5883 : }
      70             : 
      71             : /**
      72             :     @short      protected(!) dtor for deinitializing
      73             :     @descr      We made it protected to prevent using of us as base class instead as a member.
      74             :  */
      75       11746 : DispatchProvider::~DispatchProvider()
      76             : {
      77       11746 : }
      78             : 
      79             : /**
      80             :     @interface  XDispatchProvider
      81             :     @short      search a dispatcher for given URL
      82             :     @descr      If no interceptor is set on owner, we search for right frame and dispatch URL to it.
      83             :                 If no frame was found, we do nothing.
      84             :                 But we don't do it directly here. We detect the type of our owner frame and calls
      85             :                 specialized queryDispatch() helper dependen from that. Because a Desktop handle some
      86             :                 requests in another way then a normal frame.
      87             : 
      88             :     @param      aURL
      89             :                     URL to dispatch.
      90             :     @param      sTargetFrameName
      91             :                     name of searched frame.
      92             :     @param      nSearchFlags
      93             :                     flags for searching.
      94             :     @return     A reference to a dispatch object for this URL (if someone was found!).
      95             : 
      96             :     @threadsafe yes
      97             : */
      98      290150 : css::uno::Reference< css::frame::XDispatch > SAL_CALL DispatchProvider::queryDispatch( const css::util::URL&  aURL             ,
      99             :                                                                                        const OUString& sTargetFrameName ,
     100             :                                                                                              sal_Int32        nSearchFlags     ) throw( css::uno::RuntimeException, std::exception )
     101             : {
     102      290150 :     css::uno::Reference< css::frame::XDispatch > xDispatcher;
     103             : 
     104      580300 :     css::uno::Reference< css::frame::XFrame > xOwner(m_xFrame);
     105             : 
     106      580300 :     css::uno::Reference< css::frame::XDesktop > xDesktopCheck( xOwner, css::uno::UNO_QUERY );
     107             : 
     108      290150 :     if (xDesktopCheck.is())
     109         206 :         xDispatcher = implts_queryDesktopDispatch(xOwner, aURL, sTargetFrameName, nSearchFlags);
     110             :     else
     111      289944 :         xDispatcher = implts_queryFrameDispatch(xOwner, aURL, sTargetFrameName, nSearchFlags);
     112             : 
     113      580300 :     return xDispatcher;
     114             : }
     115             : 
     116             : /**
     117             :     @interface  XDispatchProvider
     118             :     @short      do the same like queryDispatch() ... but handle multiple dispatches at the same time
     119             :     @descr      It's an optimism. User give us a list of queries ... and we return a list of dispatcher.
     120             :                 If one of given queries couldn't be solved to a real existing dispatcher ...
     121             :                 we return a list with empty references in it! Order of both lists will be retained!
     122             : 
     123             :     @seealso    method queryDispatch()
     124             : 
     125             :     @param      lDescriptions
     126             :                     a list of all dispatch parameters for multiple requests
     127             :     @return     A reference a list of dispatch objects for these URLs - may with some <NULL/> values inside.
     128             : 
     129             :     @threadsafe yes
     130             : */
     131           0 : css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > SAL_CALL DispatchProvider::queryDispatches( const css::uno::Sequence< css::frame::DispatchDescriptor >& lDescriptions ) throw( css::uno::RuntimeException, std::exception )
     132             : {
     133             :     // Create return list - which must have same size then the given descriptor
     134             :     // It's not allowed to pack it!
     135           0 :     sal_Int32                                                          nCount     = lDescriptions.getLength();
     136           0 :     css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > lDispatcher( nCount );
     137             : 
     138             :     // Step over all descriptors and try to get any dispatcher for it.
     139           0 :     for( sal_Int32 i=0; i<nCount; ++i )
     140             :     {
     141           0 :         lDispatcher[i] = queryDispatch( lDescriptions[i].FeatureURL  ,
     142           0 :                                         lDescriptions[i].FrameName   ,
     143           0 :                                         lDescriptions[i].SearchFlags );
     144             :     }
     145             : 
     146           0 :     return lDispatcher;
     147             : }
     148             : 
     149           0 : bool lcl_isStartModuleDispatch (const css::util::URL& aURL)
     150             : {
     151           0 :     return aURL.Complete == CMD_UNO_SHOWSTARTMODULE;
     152             : }
     153             : 
     154             : /**
     155             :     @short      helper for queryDispatch()
     156             :     @descr      Every member of the frame tree (frame, desktop) must handle such request
     157             :                 in another way. So we implement different specialized metods for every one.
     158             : 
     159             :     @threadsafe yes
     160             :  */
     161         206 : css::uno::Reference< css::frame::XDispatch > DispatchProvider::implts_queryDesktopDispatch( const css::uno::Reference< css::frame::XFrame > xDesktop         ,
     162             :                                                                                             const css::util::URL&                           aURL             ,
     163             :                                                                                             const OUString&                          sTargetFrameName ,
     164             :                                                                                                   sal_Int32                                 nSearchFlags     )
     165             : {
     166         206 :     css::uno::Reference< css::frame::XDispatch > xDispatcher;
     167             : 
     168             :     // ignore wrong requests which are not supported
     169         412 :     if (
     170        1236 :         (sTargetFrameName==SPECIALTARGET_MENUBAR  )   ||    // valid for frame dispatches - not for desktop
     171        1442 :         (sTargetFrameName==SPECIALTARGET_PARENT   )   ||    // we have no parent by definition
     172         618 :         (sTargetFrameName==SPECIALTARGET_BEAMER   )         // beamer frames are allowed as child of tasks only -
     173             :                                                             // and they exist more than ones. We have no idea which our sub tasks is the right one
     174             :        )
     175             :     {
     176           0 :         return NULL;
     177             :     }
     178             : 
     179             :     // I) handle special cases which not right for using findFrame() first
     180             : 
     181             :     // I.I) "_blank"
     182             :     //  It's not the right place to create a new task here - because we are queried for a dispatch object
     183             :     //  only, which can handle such request. Such dispatcher should create the required task on demand.
     184             :     //  Normally the functionality for "_blank" is provided by findFrame() - but that would create it directly
     185             :     //  here. Thats why we must "intercept" here.
     186             : 
     187         206 :     if (sTargetFrameName==SPECIALTARGET_BLANK)
     188             :     {
     189           0 :         if (implts_isLoadableContent(aURL))
     190           0 :             xDispatcher = implts_getOrCreateDispatchHelper( E_BLANKDISPATCHER, xDesktop );
     191             :     }
     192             : 
     193             :     // I.II) "_default"
     194             :     //  This is a combination of search an empty task for recycling - or create a new one.
     195             : 
     196         206 :     else if (sTargetFrameName==SPECIALTARGET_DEFAULT)
     197             :     {
     198           0 :         if (implts_isLoadableContent(aURL))
     199           0 :             xDispatcher = implts_getOrCreateDispatchHelper( E_DEFAULTDISPATCHER, xDesktop );
     200             : 
     201           0 :         if (lcl_isStartModuleDispatch(aURL))
     202           0 :             xDispatcher = implts_getOrCreateDispatchHelper( E_STARTMODULEDISPATCHER, xDesktop );
     203             :     }
     204             : 
     205             :     // I.III) "_self", "", "_top"
     206             :     //  The desktop can't load any document - but he can handle some special protocols like "uno", "slot" ...
     207             :     //  Why is "top" here handled too? Because the desktop is the topest frame. Normally it's superflous
     208             :     //  to use this target - but we can handle it in the same manner then "_self".
     209             : 
     210         412 :     else if (
     211         832 :              (sTargetFrameName==SPECIALTARGET_SELF)  ||
     212         828 :              (sTargetFrameName==SPECIALTARGET_TOP )  ||
     213           0 :              (sTargetFrameName.isEmpty())
     214             :             )
     215             :     {
     216         206 :         xDispatcher = implts_searchProtocolHandler(aURL);
     217             :     }
     218             : 
     219             :     // I.IV) no further special targets exist
     220             :     //  Now we have to search for the right target frame by calling findFrame() - but should provide our code
     221             :     //  against creation of a new task if no frame could be found.
     222             :     //  I said it b efore - it's allowed for dispatch() only.
     223             : 
     224             :     else
     225             :     {
     226           0 :         sal_Int32 nRightFlags  = nSearchFlags;
     227           0 :                   nRightFlags &= ~css::frame::FrameSearchFlag::CREATE;
     228             : 
     229             :         // try to find any existing target and ask him for his dispatcher
     230           0 :         css::uno::Reference< css::frame::XFrame > xFoundFrame = xDesktop->findFrame(sTargetFrameName, nRightFlags);
     231           0 :         if (xFoundFrame.is())
     232             :         {
     233           0 :             css::uno::Reference< css::frame::XDispatchProvider > xProvider( xFoundFrame, css::uno::UNO_QUERY );
     234           0 :             xDispatcher = xProvider->queryDispatch(aURL,SPECIALTARGET_SELF,0);
     235             :         }
     236             :         // if it couldn't be found - but creation was allowed
     237             :         // use special dispatcher for creatio or froward it to the browser
     238           0 :         else if (nSearchFlags & css::frame::FrameSearchFlag::CREATE)
     239           0 :             xDispatcher = implts_getOrCreateDispatchHelper( E_CREATEDISPATCHER, xDesktop, sTargetFrameName, nSearchFlags );
     240             :     }
     241             : 
     242         206 :     return xDispatcher;
     243             : }
     244             : 
     245      289944 : css::uno::Reference< css::frame::XDispatch > DispatchProvider::implts_queryFrameDispatch( const css::uno::Reference< css::frame::XFrame > xFrame           ,
     246             :                                                                                           const css::util::URL&                           aURL             ,
     247             :                                                                                           const OUString&                          sTargetFrameName ,
     248             :                                                                                                 sal_Int32                                 nSearchFlags     )
     249             : {
     250      289944 :     css::uno::Reference< css::frame::XDispatch > xDispatcher;
     251             : 
     252             :     // 0) Some URLs are dispatched in a generic way (e.g. by the menu) using the default target "".
     253             :     //    But they are specified to use her own fix target. Detect such URLs here and use the correct target.
     254             : 
     255      579888 :     OUString sTargetName = sTargetFrameName;
     256             : 
     257             :     // I) handle special cases which not right for using findFrame() first
     258             : 
     259             :     // I.I) "_blank", "_default"
     260             :     //  It's not the right place to create a new task here. Only the desktop can do that.
     261             :     //  Normally the functionality for "_blank" is provided by findFrame() - but that would create it directly
     262             :     //  here. Thats why we must "intercept" here.
     263             : 
     264      579888 :     if (
     265     1449720 :         (sTargetName==SPECIALTARGET_BLANK  ) ||
     266      869832 :         (sTargetName==SPECIALTARGET_DEFAULT)
     267             :        )
     268             :     {
     269           0 :         css::uno::Reference< css::frame::XDispatchProvider > xParent( xFrame->getCreator(), css::uno::UNO_QUERY );
     270           0 :         if (xParent.is())
     271           0 :             xDispatcher = xParent->queryDispatch(aURL, sTargetName, 0); // it's a special target - ignore search flags
     272             :     }
     273             : 
     274             :     // I.II) "_menubar"
     275             :     //  Special mode on frame or task to receive the local menu. Not supported by findFrame()
     276             : 
     277      289944 :     else if (sTargetName==SPECIALTARGET_MENUBAR)
     278             :     {
     279           2 :         xDispatcher = implts_getOrCreateDispatchHelper( E_MENUDISPATCHER, xFrame );
     280             :     }
     281             : 
     282             :     // I.IV) "_beamer"
     283             :     //  Special sub frame of a top frame only. Search or create it. ... OK it's currently a little bit HACKI.
     284             :     //  Only the sfx (means the controller) can create it it.
     285             : 
     286      289942 :     else if (sTargetName==SPECIALTARGET_BEAMER)
     287             :     {
     288           4 :         css::uno::Reference< css::frame::XDispatchProvider > xBeamer( xFrame->findFrame( SPECIALTARGET_BEAMER, css::frame::FrameSearchFlag::CHILDREN | css::frame::FrameSearchFlag::SELF ), css::uno::UNO_QUERY );
     289           4 :         if (xBeamer.is())
     290             :         {
     291           2 :             xDispatcher = xBeamer->queryDispatch(aURL, SPECIALTARGET_SELF, 0);
     292             :         }
     293             :         else
     294             :         {
     295           2 :             css::uno::Reference< css::frame::XDispatchProvider > xController( xFrame->getController(), css::uno::UNO_QUERY );
     296           2 :             if (xController.is())
     297             :                 // force using of special target - but use original search flags
     298             :                 // May the caller used the CREATE flag or not!
     299           2 :                 xDispatcher = xController->queryDispatch(aURL, SPECIALTARGET_BEAMER, nSearchFlags);
     300           4 :         }
     301             :     }
     302             : 
     303             :     // I.V) "_parent"
     304             :     //  Our parent frame (if it exist) should handle this URL.
     305             : 
     306      289938 :     else if (sTargetName==SPECIALTARGET_PARENT)
     307             :     {
     308           8 :         css::uno::Reference< css::frame::XDispatchProvider > xParent( xFrame->getCreator(), css::uno::UNO_QUERY );
     309           8 :         if (xParent.is())
     310             :             // SELF => we must address the parent directly... and not his parent or any other parent!
     311           8 :             xDispatcher = xParent->queryDispatch(aURL, SPECIALTARGET_SELF, 0);
     312             :     }
     313             : 
     314             :     // I.VI) "_top"
     315             :     //  This request must be forwarded to any parent frame, till we reach a top frame.
     316             :     //  If no parent exist, we can handle itself.
     317             : 
     318      289930 :     else if (sTargetName==SPECIALTARGET_TOP)
     319             :     {
     320           0 :         if (xFrame->isTop())
     321             :         {
     322             :             // If we are this top frame itself (means our owner frame)
     323             :             // we should call ourself recursiv with a better target "_self".
     324             :             // So we can share the same code! (see reaction for "_self" inside this method too.)
     325           0 :             xDispatcher = this->queryDispatch(aURL,SPECIALTARGET_SELF,0);
     326             :         }
     327             :         else
     328             :         {
     329           0 :             css::uno::Reference< css::frame::XDispatchProvider > xParent( xFrame->getCreator(), css::uno::UNO_QUERY );
     330             :             // Normally if isTop() returned sal_False ... the parent frame MUST(!) exist ...
     331             :             // But it seems to be better to check that here to prevent us against an access violation.
     332           0 :             if (xParent.is())
     333           0 :                 xDispatcher = xParent->queryDispatch(aURL, SPECIALTARGET_TOP, 0);
     334             :         }
     335             :     }
     336             : 
     337             :     // I.VII) "_self", ""
     338             :     //  Our owner frame should handle this URL. But we can't do it for all of them.
     339             :     //  So we ask the internal setted controller first. If he disagree we try to find a registered
     340             :     //  protocol handler. If this failed too - we check for a loadable content and in case of true
     341             :     //  we load it into the frame by returning specilized dispatch object.
     342             : 
     343      579860 :     else if (
     344     1159696 :              (sTargetName==SPECIALTARGET_SELF)  ||
     345      289906 :              (sTargetName.isEmpty())
     346             :             )
     347             :     {
     348             :         // There exist a hard coded interception for special URLs.
     349      289930 :         if ( aURL.Complete == ".uno:CloseDoc" || aURL.Complete == ".uno:CloseWin" )
     350             :         {
     351           4 :             css::uno::Reference< css::frame::XDispatchProvider > xParent( xFrame->getCreator(), css::uno::UNO_QUERY );
     352             :             // In case the frame is not a top one, is not based on system window and has a parent,
     353             :             // the parent frame should to be queried for the correct dispatcher.
     354             :             // See i93473
     355           8 :             if (
     356          16 :                 !WindowHelper::isTopWindow(xFrame->getContainerWindow()) &&
     357          16 :                 !VCLUnoHelper::GetWindow(xFrame->getContainerWindow())->IsSystemWindow() &&
     358           0 :                 xParent.is()
     359             :                )
     360           0 :                 xDispatcher = xParent->queryDispatch(aURL, SPECIALTARGET_SELF, 0);
     361             :             else
     362           4 :                 xDispatcher = implts_getOrCreateDispatchHelper( E_CLOSEDISPATCHER, xFrame );
     363             :         }
     364      289926 :         else if ( aURL.Complete == ".uno:CloseFrame" )
     365           0 :             xDispatcher = implts_getOrCreateDispatchHelper( E_CLOSEDISPATCHER, xFrame );
     366             : 
     367      289930 :         if ( ! xDispatcher.is())
     368             :         {
     369             :             // Ask our controller for his agreement for these dispatched URL ...
     370             :             // because some URLs are internal and can be handled faster by SFX - which most is the current controller!
     371             :             // But in case of e.g. the bibliography not all queries will be handled successfully here.
     372      289926 :             css::uno::Reference< css::frame::XDispatchProvider > xController( xFrame->getController(), css::uno::UNO_QUERY );
     373      289926 :             if (xController.is())
     374      289900 :                 xDispatcher = xController->queryDispatch(aURL, SPECIALTARGET_SELF, 0);
     375             :         }
     376             : 
     377             :         // If controller has no fun to dispatch these URL - we must search another right dispatcher.
     378             :         // Search for any registered protocol handler first.
     379      289930 :         if (!xDispatcher.is())
     380       51487 :             xDispatcher = implts_searchProtocolHandler(aURL);
     381             : 
     382             :         // Not for controller - not for protocol handler
     383             :         // It should be a loadable content - may be a file. Check it ...
     384             :         // This check is necessary to found out, that
     385             :         // support for some protocols isn't installed by user. May be
     386             :         // "ftp" isn't available. So we suppress creation of our self dispatcher.
     387             :         // The result will be clear. He can't handle it - but he would try it.
     388      289930 :         if (
     389      332496 :             ( ! xDispatcher.is()             )  &&
     390       42566 :             ( implts_isLoadableContent(aURL) )
     391             :            )
     392             :         {
     393           2 :             xDispatcher = implts_getOrCreateDispatchHelper( E_SELFDISPATCHER, xFrame );
     394             :         }
     395             :     }
     396             : 
     397             :     // I.VI) no further special handlings exist
     398             :     //  Now we have to search for the right target frame by calling findFrame() - but should provide our code
     399             :     //  against creation of a new task if no frame could be found.
     400             :     //  I said it before - it's allowed for dispatch() only.
     401             : 
     402             :     else
     403             :     {
     404           0 :         sal_Int32 nRightFlags  = nSearchFlags;
     405           0 :                   nRightFlags &= ~css::frame::FrameSearchFlag::CREATE;
     406             : 
     407             :         // try to find any existing target and ask him for his dispatcher
     408           0 :         css::uno::Reference< css::frame::XFrame > xFoundFrame = xFrame->findFrame(sTargetName, nRightFlags);
     409           0 :         if (xFoundFrame.is())
     410             :         {
     411             :             // Attention: Found target is our own owner frame!
     412             :             // Don't ask him for his dispatcher. We know it already - it's our self dispatch helper.
     413             :             // Otherwhise we can start a never ending recursiv call. Why?
     414             :             // Somewere called our owner frame - he called some interceptor objects - and may by this dispatch provider
     415             :             // is called. If wa use queryDispatch() on our owner frame again - we start this call stack again ... and again.
     416           0 :             if (xFoundFrame==xFrame)
     417           0 :                 xDispatcher = implts_getOrCreateDispatchHelper( E_SELFDISPATCHER, xFrame );
     418             :             else
     419             :             {
     420           0 :                 css::uno::Reference< css::frame::XDispatchProvider > xProvider( xFoundFrame, css::uno::UNO_QUERY );
     421           0 :                 xDispatcher = xProvider->queryDispatch(aURL,SPECIALTARGET_SELF,0);
     422             :             }
     423             :         }
     424             :         else
     425             :         // if it couldn't be found - but creation was allowed
     426             :         // forward request to the desktop.
     427             :         // Note: The given target name must be used to set the name on new created task!
     428             :         //       Don't forward request by changing it to a special one e.g _blank.
     429             :         //       Use the CREATE flag only to prevent call against further searches.
     430             :         //       We already know it - the target must be created new.
     431           0 :         if (nSearchFlags & css::frame::FrameSearchFlag::CREATE)
     432             :         {
     433           0 :             css::uno::Reference< css::frame::XDispatchProvider > xParent( xFrame->getCreator(), css::uno::UNO_QUERY );
     434           0 :             if (xParent.is())
     435           0 :                 xDispatcher = xParent->queryDispatch(aURL, sTargetName, css::frame::FrameSearchFlag::CREATE);
     436           0 :         }
     437             :     }
     438             : 
     439      579888 :     return xDispatcher;
     440             : }
     441             : 
     442             : /**
     443             :     @short      search for a registered protocol handler and ask him for a dispatch object
     444             :     @descr      Wes earch a suitable handler inside our cfg package org.openoffice.Office.ProtocolHandler.
     445             :                 If we found anyone, we create and initialize it. Initialize means: we set our owner frame on it
     446             :                 as context information. He can use it or leave it. Of course - we are aware of handler implementations,
     447             :                 which doesn't support initialization. It's an optional feature.
     448             : 
     449             :     @param      aURL
     450             :                     the dispatch URL for which may a handler is registered
     451             : 
     452             :     @return     A dispatch object if a handler was found and agree with the given URL or <NULL/> otherwise.
     453             : 
     454             :     @threadsafe yes
     455             : */
     456       51693 : css::uno::Reference< css::frame::XDispatch > DispatchProvider::implts_searchProtocolHandler( const css::util::URL& aURL )
     457             : {
     458       51693 :     css::uno::Reference< css::frame::XDispatch > xDispatcher;
     459      103386 :     ProtocolHandler                              aHandler;
     460             : 
     461             :     // This member is threadsafe by himself and lives if we live - we don't need any mutex here.
     462       51693 :     if (m_aProtocolHandlerCache.search(aURL,&aHandler))
     463             :     {
     464       51691 :         css::uno::Reference< css::frame::XDispatchProvider > xHandler;
     465             :         {
     466       51691 :             SolarMutexGuard g;
     467             : 
     468             :             // create it
     469             :             try
     470             :             {
     471      103382 :                 xHandler = css::uno::Reference< css::frame::XDispatchProvider >(
     472       51691 :                     css::uno::Reference<css::lang::XMultiServiceFactory>(m_xContext->getServiceManager(), css::uno::UNO_QUERY_THROW)
     473      103382 :                     ->createInstance(aHandler.m_sUNOName),
     474       51691 :                     css::uno::UNO_QUERY);
     475             :             }
     476           0 :             catch(const css::uno::Exception&) {}
     477             : 
     478             :             // look if initialization is necessary
     479      103382 :             css::uno::Reference< css::lang::XInitialization > xInit( xHandler, css::uno::UNO_QUERY );
     480       51691 :             if (xInit.is())
     481             :             {
     482       13465 :                 css::uno::Reference< css::frame::XFrame > xOwner( m_xFrame.get(), css::uno::UNO_QUERY );
     483             :                 SAL_WARN_IF(!xOwner.is(), "fwk", "DispatchProvider::implts_searchProtocolHandler(): Couldn't get reference to my owner frame. So I can't set may needed context information for this protocol handler.");
     484       13465 :                 if (xOwner.is())
     485             :                 {
     486             :                     try
     487             :                     {
     488             :                         // but do it only, if all context information are OK
     489       13465 :                         css::uno::Sequence< css::uno::Any > lContext(1);
     490       13465 :                         lContext[0] <<= xOwner;
     491       13465 :                         xInit->initialize(lContext);
     492             :                     }
     493           0 :                     catch(const css::uno::Exception&) {}
     494       13465 :                 }
     495       51691 :             }
     496             :         }
     497             : 
     498             :         // ask for his (sub)dispatcher for the given URL
     499       51691 :         if (xHandler.is())
     500       13465 :             xDispatcher = xHandler->queryDispatch(aURL,SPECIALTARGET_SELF,0);
     501             :     }
     502             : 
     503      103386 :     return xDispatcher;
     504             : }
     505             : 
     506             : /**
     507             :     @short      get or create new dispatch helper
     508             :     @descr      Sometimes we need some helper implementations to support dispatching of special URLs or commands.
     509             :                 But it's not a good idea to hold these services for the whole life time of this provider instance.
     510             :                 We should create it on demand ...
     511             :                 Thats why we implement this method. It return an already existing helper or create a new one otherwise.
     512             : 
     513             :     @attention  The parameter sTarget and nSearchFlags are defaulted to "" and 0!
     514             :                 Please use it only, if you can be sure, that the really given by the outside calli!
     515             :                 Mostly it depends from the parameter eHelper is they are required or not.
     516             : 
     517             :     @param      eHelper
     518             :                     specify the requested dispatch helper
     519             :     @param      xOwner
     520             :                     the target of possible dispatch() call on created dispatch helper
     521             :     @param      sTarget
     522             :                     the target parameter of the original queryDispatch() request
     523             :     @param      nSearchFlags
     524             :                     the flags parameter of the original queryDispatch() request
     525             :     @return     A reference to a dispatch helper.
     526             : 
     527             :     @threadsafe yes
     528             : */
     529           8 : css::uno::Reference< css::frame::XDispatch > DispatchProvider::implts_getOrCreateDispatchHelper( EDispatchHelper                                  eHelper     ,
     530             :                                                                                                  const css::uno::Reference< css::frame::XFrame >& xOwner      ,
     531             :                                                                                                  const OUString&                           sTarget     ,
     532             :                                                                                                        sal_Int32                                  nSearchFlags)
     533             : {
     534           8 :     css::uno::Reference< css::frame::XDispatch > xDispatchHelper;
     535             : 
     536           8 :     switch (eHelper)
     537             :     {
     538             :         case E_MENUDISPATCHER :
     539             :                 {
     540             :                     // Attention: Such menue dispatcher must be a singleton for this frame - means our owner frame.
     541             :                     // Otherwhise he can make some trouble.
     542           2 :                     SolarMutexGuard g;
     543           2 :                     if ( ! m_xMenuDispatcher.is() )
     544             :                     {
     545           2 :                         MenuDispatcher* pDispatcher = new MenuDispatcher( m_xContext, xOwner );
     546           2 :                         m_xMenuDispatcher = css::uno::Reference< css::frame::XDispatch >( static_cast< ::cppu::OWeakObject* >(pDispatcher), css::uno::UNO_QUERY );
     547             :                     }
     548           2 :                     xDispatchHelper = m_xMenuDispatcher;
     549             :                 }
     550           2 :                 break;
     551             : 
     552             :         case E_CREATEDISPATCHER :
     553             :                 {
     554           0 :                     LoadDispatcher* pDispatcher = new LoadDispatcher(m_xContext, xOwner, sTarget, nSearchFlags);
     555           0 :                     xDispatchHelper = css::uno::Reference< css::frame::XDispatch >( static_cast< ::cppu::OWeakObject* >(pDispatcher), css::uno::UNO_QUERY );
     556             :                 }
     557           0 :                 break;
     558             : 
     559             :         case E_BLANKDISPATCHER :
     560             :                 {
     561           0 :                     css::uno::Reference< css::frame::XFrame > xDesktop( xOwner, css::uno::UNO_QUERY );
     562           0 :                     if (xDesktop.is())
     563             :                     {
     564           0 :                         LoadDispatcher* pDispatcher = new LoadDispatcher(m_xContext, xOwner, SPECIALTARGET_BLANK, 0);
     565           0 :                         xDispatchHelper = css::uno::Reference< css::frame::XDispatch >( static_cast< ::cppu::OWeakObject* >(pDispatcher), css::uno::UNO_QUERY );
     566           0 :                     }
     567             :                 }
     568           0 :                 break;
     569             : 
     570             :         case E_DEFAULTDISPATCHER :
     571             :                 {
     572           0 :                     css::uno::Reference< css::frame::XFrame > xDesktop( xOwner, css::uno::UNO_QUERY );
     573           0 :                     if (xDesktop.is())
     574             :                     {
     575           0 :                         LoadDispatcher* pDispatcher = new LoadDispatcher(m_xContext, xOwner, SPECIALTARGET_DEFAULT, 0);
     576           0 :                         xDispatchHelper = css::uno::Reference< css::frame::XDispatch >( static_cast< ::cppu::OWeakObject* >(pDispatcher), css::uno::UNO_QUERY );
     577           0 :                     }
     578             :                 }
     579           0 :                 break;
     580             : 
     581             :         case E_SELFDISPATCHER :
     582             :                 {
     583           2 :                     LoadDispatcher* pDispatcher = new LoadDispatcher(m_xContext, xOwner, SPECIALTARGET_SELF, 0);
     584           2 :                     xDispatchHelper = css::uno::Reference< css::frame::XDispatch >( static_cast< ::cppu::OWeakObject* >(pDispatcher), css::uno::UNO_QUERY );
     585             :                 }
     586           2 :                 break;
     587             : 
     588             :         case E_CLOSEDISPATCHER :
     589             :                 {
     590           4 :                     CloseDispatcher* pDispatcher = new CloseDispatcher( m_xContext, xOwner, sTarget );
     591           4 :                     xDispatchHelper = css::uno::Reference< css::frame::XDispatch >( static_cast< ::cppu::OWeakObject* >(pDispatcher), css::uno::UNO_QUERY );
     592             :                 }
     593           4 :                 break;
     594             : 
     595             :         case E_STARTMODULEDISPATCHER :
     596             :                 {
     597           0 :                     StartModuleDispatcher* pDispatcher = new StartModuleDispatcher( m_xContext, xOwner );
     598           0 :                     xDispatchHelper = css::uno::Reference< css::frame::XDispatch >( static_cast< ::cppu::OWeakObject* >(pDispatcher), css::uno::UNO_QUERY );
     599             :                 }
     600           0 :                 break;
     601             :     }
     602             : 
     603           8 :     return xDispatchHelper;
     604             : }
     605             : 
     606             : /**
     607             :     @short      check URL for support by our used loader or handler
     608             :     @descr      If we must return our own dispatch helper implementations (self, blank, create dispatcher!)
     609             :                 we should be sure, that URL describe any loadable content. Otherwise slot/uno URLs
     610             :                 will be detected ... but there exist nothing for ral loading into a target frame!
     611             : 
     612             :     @param      aURL
     613             :                     URL which should be "detected"
     614             :     @return     <TRUE/> if somewhere could handle that - <FALSE/> otherwise.
     615             : 
     616             :     @threadsafe yes
     617             : */
     618       42566 : bool DispatchProvider::implts_isLoadableContent( const css::util::URL& aURL )
     619             : {
     620       42566 :     LoadEnv::EContentType eType = LoadEnv::classifyContent(aURL.Complete, css::uno::Sequence< css::beans::PropertyValue >());
     621       42566 :     return ( eType == LoadEnv::E_CAN_BE_LOADED );
     622             : }
     623             : 
     624         951 : } // namespace framework
     625             : 
     626             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10