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 <tools/diagnose_ex.h> 23 #include <sal/log.hxx> 24 25 #include <com/sun/star/container/XContentEnumerationAccess.hpp> 26 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp> 27 #include "ProviderCache.hxx" 28 29 using namespace com::sun::star; 30 using namespace com::sun::star::uno; 31 using namespace com::sun::star::script; 32 33 namespace func_provider 34 { 35 36 ProviderCache::ProviderCache( const Reference< XComponentContext >& xContext, const Sequence< Any >& scriptContext ) : m_Sctx( scriptContext ), m_xContext( xContext ) 37 { 38 // initialise m_hProviderDetailsCache with details of ScriptProviders 39 // will use createContentEnumeration 40 41 m_xMgr = m_xContext->getServiceManager(); 42 ENSURE_OR_THROW( m_xMgr.is(), "ProviderCache::ProviderCache() failed to obtain ServiceManager" ); 43 populateCache(); 44 } 45 46 47 ProviderCache::ProviderCache( const Reference< XComponentContext >& xContext, const Sequence< Any >& scriptContext, const Sequence< OUString >& blackList ) : m_sBlackList( blackList ), m_Sctx( scriptContext ), m_xContext( xContext ) 48 49 { 50 // initialise m_hProviderDetailsCache with details of ScriptProviders 51 // will use createContentEnumeration 52 53 m_xMgr = m_xContext->getServiceManager(); 54 ENSURE_OR_THROW( m_xMgr.is(), "ProviderCache::ProviderCache() failed to obtain ServiceManager" ); 55 populateCache(); 56 } 57 58 ProviderCache::~ProviderCache() 59 { 60 } 61 62 Reference< provider::XScriptProvider > 63 ProviderCache::getProvider( const OUString& providerName ) 64 { 65 ::osl::Guard< osl::Mutex > aGuard( m_mutex ); 66 Reference< provider::XScriptProvider > provider; 67 ProviderDetails_hash::iterator h_it = m_hProviderDetailsCache.find( providerName ); 68 if ( h_it != m_hProviderDetailsCache.end() ) 69 { 70 if ( h_it->second.provider.is() ) 71 { 72 provider = h_it->second.provider; 73 } 74 else 75 { 76 // need to create provider and insert into hash 77 provider = createProvider( h_it->second ); 78 } 79 } 80 return provider; 81 } 82 83 Sequence < Reference< provider::XScriptProvider > > 84 ProviderCache::getAllProviders() 85 { 86 // need to create providers that haven't been created already 87 // so check what providers exist and what ones don't 88 89 ::osl::Guard< osl::Mutex > aGuard( m_mutex ); 90 Sequence < Reference< provider::XScriptProvider > > providers ( m_hProviderDetailsCache.size() ); 91 // should assert if size !> 0 92 if ( !m_hProviderDetailsCache.empty() ) 93 { 94 sal_Int32 providerIndex = 0; 95 for (auto& rDetail : m_hProviderDetailsCache) 96 { 97 Reference<provider::XScriptProvider> xScriptProvider = rDetail.second.provider; 98 if ( xScriptProvider.is() ) 99 { 100 providers[ providerIndex++ ] = xScriptProvider; 101 } 102 else 103 { 104 // create provider 105 try 106 { 107 xScriptProvider = createProvider(rDetail.second); 108 providers[ providerIndex++ ] = xScriptProvider; 109 } 110 catch ( const Exception& ) 111 { 112 DBG_UNHANDLED_EXCEPTION("scripting"); 113 } 114 } 115 } 116 117 if (providerIndex < providers.getLength()) 118 { 119 providers.realloc( providerIndex ); 120 } 121 122 } 123 else 124 { 125 SAL_WARN("scripting", "no available providers, something very wrong!!!"); 126 } 127 return providers; 128 } 129 130 void 131 ProviderCache::populateCache() 132 { 133 // wrong name in services.rdb 134 OUString serviceName; 135 ::osl::Guard< osl::Mutex > aGuard( m_mutex ); 136 try 137 { 138 OUString const languageProviderName( "com.sun.star.script.provider.LanguageScriptProvider" ); 139 140 Reference< container::XContentEnumerationAccess > xEnumAccess( m_xMgr, UNO_QUERY_THROW ); 141 Reference< container::XEnumeration > xEnum = xEnumAccess->createContentEnumeration ( languageProviderName ); 142 143 while ( xEnum->hasMoreElements() ) 144 { 145 146 Reference< lang::XSingleComponentFactory > factory( xEnum->nextElement(), UNO_QUERY_THROW ); 147 Reference< lang::XServiceInfo > xServiceInfo( factory, UNO_QUERY_THROW ); 148 149 Sequence< OUString > serviceNames = xServiceInfo->getSupportedServiceNames(); 150 151 if ( serviceNames.getLength() > 0 ) 152 { 153 for ( sal_Int32 index = 0; index < serviceNames.getLength(); index++ ) 154 { 155 if ( serviceNames[ index ].startsWith( "com.sun.star.script.provider.ScriptProviderFor" ) 156 && !isInBlackList( serviceNames[ index ] ) ) 157 { 158 serviceName = serviceNames[ index ]; 159 ProviderDetails details; 160 details.factory = factory; 161 m_hProviderDetailsCache[ serviceName ] = details; 162 break; 163 } 164 } 165 } 166 } 167 } 168 catch ( const Exception &e ) 169 { 170 css::uno::Any anyEx = cppu::getCaughtException(); 171 throw css::lang::WrappedTargetRuntimeException( 172 "ProviderCache::populateCache: couldn't obtain XSingleComponentFactory for " + serviceName 173 + " " + e.Message, 174 nullptr, anyEx ); 175 } 176 } 177 178 Reference< provider::XScriptProvider > 179 ProviderCache::createProvider( ProviderDetails& details ) 180 { 181 try 182 { 183 details.provider.set( 184 details.factory->createInstanceWithArgumentsAndContext( m_Sctx, m_xContext ), UNO_QUERY_THROW ); 185 } 186 catch ( const Exception& e ) 187 { 188 css::uno::Any anyEx = cppu::getCaughtException(); 189 throw css::lang::WrappedTargetRuntimeException( 190 "ProviderCache::createProvider() Error creating provider from factory. " + e.Message, 191 nullptr, anyEx ); 192 } 193 194 return details.provider; 195 } 196 } //end namespace 197 198 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 199
