LCOV - code coverage report
Current view: top level - scripting/source/provider - ActiveMSPList.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 61 128 47.7 %
Date: 2015-06-13 12:38:46 Functions: 8 12 66.7 %
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 <cppuhelper/implementationentry.hxx>
      21             : #include <cppuhelper/factory.hxx>
      22             : #include <cppuhelper/implbase1.hxx>
      23             : #include <cppuhelper/exc_hlp.hxx>
      24             : #include <util/scriptingconstants.hxx>
      25             : #include <util/MiscUtils.hxx>
      26             : 
      27             : #include <com/sun/star/beans/XPropertySet.hpp>
      28             : #include <com/sun/star/util/XMacroExpander.hpp>
      29             : #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
      30             : 
      31             : #include <com/sun/star/script/browse/BrowseNodeTypes.hpp>
      32             : 
      33             : #include "MasterScriptProvider.hxx"
      34             : #include "ActiveMSPList.hxx"
      35             : 
      36             : #include <tools/diagnose_ex.h>
      37             : 
      38             : using namespace com::sun::star;
      39             : using namespace com::sun::star::uno;
      40             : using namespace com::sun::star::script;
      41             : using namespace ::sf_misc;
      42             : 
      43             : namespace func_provider
      44             : {
      45             : 
      46           4 : ActiveMSPList::ActiveMSPList(  const Reference< XComponentContext > & xContext ) : m_xContext( xContext )
      47             : {
      48           4 :     userDirString = "user";
      49           4 :     shareDirString = "share";
      50           4 :     bundledDirString = "bundled";
      51           4 : }
      52             : 
      53           8 : ActiveMSPList::~ActiveMSPList()
      54             : {
      55           8 : }
      56             : 
      57             : Reference< provider::XScriptProvider >
      58          31 : ActiveMSPList::createNewMSP( const uno::Any& context )
      59             : {
      60          31 :     OUString serviceName("com.sun.star.script.provider.MasterScriptProvider");
      61          62 :     Sequence< Any > args( &context, 1 );
      62             : 
      63             :     Reference< provider::XScriptProvider > msp(
      64          62 :         m_xContext->getServiceManager()->createInstanceWithArgumentsAndContext(
      65          31 :             serviceName, args, m_xContext ), UNO_QUERY );
      66          62 :     return msp;
      67             : }
      68             : 
      69             : class NonDocMSPCreator
      70             : {
      71             : public:
      72           0 :     NonDocMSPCreator(ActiveMSPList *pList)
      73             :     {
      74           0 :         pList->createNonDocMSPs();
      75           0 :     }
      76             : };
      77             : 
      78             : namespace
      79             : {
      80             :     //thread-safe double-locked class to ensure createNonDocMSPs is called once
      81             :     class theNonDocMSPCreator : public rtl::StaticWithArg<NonDocMSPCreator, ActiveMSPList*, theNonDocMSPCreator> {};
      82             : 
      83           0 :     void ensureNonDocMSPs(ActiveMSPList *pList)
      84             :     {
      85           0 :         theNonDocMSPCreator::get(pList);
      86           0 :     }
      87             : }
      88             : 
      89             : Reference< provider::XScriptProvider >
      90         109 : ActiveMSPList::getMSPFromAnyContext( const Any& aContext )
      91             : {
      92         109 :     Reference< provider::XScriptProvider > msp;
      93         218 :     OUString sContext;
      94         109 :     if ( aContext >>= sContext )
      95             :     {
      96           0 :         msp = getMSPFromStringContext( sContext );
      97           0 :         return msp;
      98             :     }
      99             : 
     100         218 :     Reference< frame::XModel > xModel( aContext, UNO_QUERY );
     101             : 
     102         218 :     Reference< document::XScriptInvocationContext > xScriptContext( aContext, UNO_QUERY );
     103         109 :     if ( xScriptContext.is() )
     104             :     {
     105             :         try
     106             :         {
     107             :             // the component supports executing scripts embedded in a - possibly foreign document.
     108             :             // Check whether this other document its the component itself.
     109         109 :             if ( !xModel.is() || ( xModel != xScriptContext->getScriptContainer() ) )
     110             :             {
     111           0 :                 msp = getMSPFromInvocationContext( xScriptContext );
     112           0 :                 return msp;
     113             :             }
     114             :         }
     115           0 :         catch( const lang::IllegalArgumentException& )
     116             :         {
     117           0 :             xModel.set( Reference< frame::XModel >() );
     118             :         }
     119             :     }
     120             : 
     121         109 :     if ( xModel.is() )
     122             :     {
     123         109 :         sContext = MiscUtils::xModelToTdocUrl( xModel, m_xContext );
     124         109 :         msp = getMSPFromStringContext( sContext );
     125         109 :         return msp;
     126             :     }
     127             : 
     128           0 :     ensureNonDocMSPs(this);
     129         109 :     return m_hMsps[ shareDirString ];
     130             : }
     131             : 
     132             : Reference< provider::XScriptProvider >
     133           0 :     ActiveMSPList::getMSPFromInvocationContext( const Reference< document::XScriptInvocationContext >& xContext )
     134             : {
     135           0 :     Reference< provider::XScriptProvider > msp;
     136             : 
     137           0 :     Reference< document::XEmbeddedScripts > xScripts;
     138           0 :     if ( xContext.is() )
     139           0 :         xScripts.set( xContext->getScriptContainer() );
     140           0 :     if ( !xScripts.is() )
     141             :     {
     142           0 :         OUStringBuffer buf;
     143           0 :         buf.appendAscii( "Failed to create MasterScriptProvider for ScriptInvocationContext: " );
     144           0 :         buf.appendAscii( "Component supporting XEmbeddScripts interface not found." );
     145           0 :         throw lang::IllegalArgumentException( buf.makeStringAndClear(), NULL, 1 );
     146             :     }
     147             : 
     148           0 :     ::osl::MutexGuard guard( m_mutex );
     149             : 
     150           0 :     Reference< XInterface > xNormalized( xContext, UNO_QUERY );
     151           0 :     ScriptComponent_map::const_iterator pos = m_mScriptComponents.find( xNormalized );
     152           0 :     if ( pos == m_mScriptComponents.end() )
     153             :     {
     154             :         // TODO
     155           0 :         msp = createNewMSP( uno::makeAny( xContext ) );
     156           0 :         addActiveMSP( xNormalized, msp );
     157             :     }
     158             :     else
     159             :     {
     160           0 :         msp = pos->second;
     161             :     }
     162             : 
     163           0 :     return msp;
     164             : }
     165             : 
     166             : Reference< provider::XScriptProvider >
     167         109 :     ActiveMSPList::getMSPFromStringContext( const OUString& context )
     168             : {
     169         109 :     Reference< provider::XScriptProvider > msp;
     170             :     try
     171             :     {
     172         109 :         if ( context.startsWith( "vnd.sun.star.tdoc" ) )
     173             :         {
     174         109 :             Reference< frame::XModel > xModel( MiscUtils::tDocUrlToModel( context ) );
     175             : 
     176         218 :             Reference< document::XEmbeddedScripts > xScripts( xModel, UNO_QUERY );
     177         218 :             Reference< document::XScriptInvocationContext > xScriptsContext( xModel, UNO_QUERY );
     178         109 :             if ( !xScripts.is() && !xScriptsContext.is() )
     179             :             {
     180           0 :                 OUStringBuffer buf;
     181           0 :                 buf.appendAscii( "Failed to create MasterScriptProvider for '" );
     182           0 :                 buf.append     ( context );
     183           0 :                 buf.appendAscii( "': Either XEmbeddScripts or XScriptInvocationContext need to be supported by the document." );
     184           0 :                 throw lang::IllegalArgumentException( buf.makeStringAndClear(), NULL, 1 );
     185             :             }
     186             : 
     187         218 :             ::osl::MutexGuard guard( m_mutex );
     188         218 :             Reference< XInterface > xNormalized( xModel, UNO_QUERY );
     189         109 :             ScriptComponent_map::const_iterator pos = m_mScriptComponents.find( xNormalized );
     190         109 :             if ( pos == m_mScriptComponents.end() )
     191             :             {
     192          31 :                 msp = createNewMSP( context );
     193          31 :                 addActiveMSP( xNormalized, msp );
     194             :             }
     195             :             else
     196             :             {
     197          78 :                 msp = pos->second;
     198         109 :             }
     199             :         }
     200             :         else
     201             :         {
     202           0 :             ::osl::MutexGuard guard( m_mutex );
     203           0 :             Msp_hash::iterator h_itEnd =  m_hMsps.end();
     204           0 :             Msp_hash::const_iterator itr = m_hMsps.find( context );
     205           0 :             if ( itr ==  h_itEnd )
     206             :             {
     207           0 :                 msp = createNewMSP( context );
     208           0 :                 m_hMsps[ context ] = msp;
     209             :             }
     210             :             else
     211             :             {
     212           0 :                 msp = m_hMsps[ context ];
     213           0 :             }
     214             :         }
     215             :     }
     216           0 :     catch( const lang::IllegalArgumentException& )
     217             :     {
     218             :         // allowed to leave
     219             :     }
     220           0 :     catch( const RuntimeException& )
     221             :     {
     222             :         // allowed to leave
     223             :     }
     224           0 :     catch( const Exception& )
     225             :     {
     226           0 :         OUStringBuffer aMessage;
     227           0 :         aMessage.appendAscii( "Failed to create MasterScriptProvider for context '" );
     228           0 :         aMessage.append     ( context );
     229           0 :         aMessage.appendAscii( "'." );
     230             :         throw lang::WrappedTargetRuntimeException(
     231           0 :             aMessage.makeStringAndClear(), *this, ::cppu::getCaughtException() );
     232             :     }
     233         109 :     return msp;
     234             : }
     235             : 
     236             : void
     237          31 : ActiveMSPList::addActiveMSP( const Reference< uno::XInterface >& xComponent,
     238             :                const Reference< provider::XScriptProvider >& msp )
     239             : {
     240          31 :     ::osl::MutexGuard guard( m_mutex );
     241          62 :     Reference< XInterface > xNormalized( xComponent, UNO_QUERY );
     242          31 :     ScriptComponent_map::const_iterator pos = m_mScriptComponents.find( xNormalized );
     243          31 :     if ( pos == m_mScriptComponents.end() )
     244             :     {
     245          31 :         m_mScriptComponents[ xNormalized ] = msp;
     246             : 
     247             :         // add self as listener for component disposal
     248             :         // should probably throw from this method!!, reexamine
     249             :         try
     250             :         {
     251             :             Reference< lang::XComponent > xBroadcaster =
     252          31 :                 Reference< lang::XComponent >( xComponent, UNO_QUERY_THROW );
     253          31 :             xBroadcaster->addEventListener( this );
     254             :         }
     255           0 :         catch ( const Exception& )
     256             :         {
     257             :             DBG_UNHANDLED_EXCEPTION();
     258             :         }
     259          31 :     }
     260          31 : }
     261             : 
     262             : 
     263             : void SAL_CALL
     264          31 : ActiveMSPList::disposing( const ::com::sun::star::lang::EventObject& Source )
     265             : throw ( ::com::sun::star::uno::RuntimeException, std::exception )
     266             : 
     267             : {
     268             :     try
     269             :     {
     270          31 :         Reference< XInterface > xNormalized( Source.Source, UNO_QUERY );
     271          31 :         if ( xNormalized.is() )
     272             :         {
     273          31 :             ::osl::MutexGuard guard( m_mutex );
     274          31 :             ScriptComponent_map::iterator pos = m_mScriptComponents.find( xNormalized );
     275          31 :             if ( pos != m_mScriptComponents.end() )
     276          31 :                 m_mScriptComponents.erase( pos );
     277          31 :         }
     278             :     }
     279           0 :     catch ( const Exception& )
     280             :     {
     281             :         // if we get an exception here, there is not much we can do about
     282             :         // it can't throw as it will screw up the model that is calling dispose
     283             :         DBG_UNHANDLED_EXCEPTION();
     284             :     }
     285          31 : }
     286             : 
     287             : void
     288           0 : ActiveMSPList::createNonDocMSPs()
     289             : {
     290             :     // do creation of user and share MSPs here
     291           0 :     OUString serviceName("com.sun.star.script.provider.MasterScriptProvider");
     292           0 :     Sequence< Any > args(1);
     293             : 
     294           0 :     args[ 0 ] <<= userDirString;
     295           0 :     Reference< provider::XScriptProvider > userMsp( m_xContext->getServiceManager()->createInstanceWithArgumentsAndContext( serviceName, args, m_xContext ), UNO_QUERY );
     296             :     // should check if provider reference is valid
     297           0 :     m_hMsps[ userDirString ] = userMsp;
     298             : 
     299           0 :     args[ 0 ] <<= shareDirString;
     300           0 :     Reference< provider::XScriptProvider > shareMsp( m_xContext->getServiceManager()->createInstanceWithArgumentsAndContext( serviceName, args, m_xContext ), UNO_QUERY );
     301             :     // should check if provider reference is valid
     302           0 :     m_hMsps[ shareDirString ] = shareMsp;
     303             : 
     304           0 :     args[ 0 ] <<= bundledDirString;
     305           0 :     Reference< provider::XScriptProvider > bundledMsp( m_xContext->getServiceManager()->createInstanceWithArgumentsAndContext( serviceName, args, m_xContext ), UNO_QUERY );
     306             :     // should check if provider reference is valid
     307           0 :     m_hMsps[ bundledDirString ] = bundledMsp;
     308           0 : }
     309             : 
     310             : } // namespace func_provider
     311             : 
     312             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11