1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_scripting.hxx" 26 #include <cppuhelper/implementationentry.hxx> 27 #include <cppuhelper/factory.hxx> 28 #include <tools/diagnose_ex.h> 29 30 #include <util/scriptingconstants.hxx> 31 #include <util/util.hxx> 32 33 #include <com/sun/star/container/XContentEnumerationAccess.hpp> 34 #include "ProviderCache.hxx" 35 36 using namespace com::sun::star; 37 using namespace com::sun::star::uno; 38 using namespace com::sun::star::script; 39 40 namespace func_provider 41 { 42 43 ProviderCache::ProviderCache( const Reference< XComponentContext >& xContext, const Sequence< Any >& scriptContext ) 44 throw ( RuntimeException ) : m_Sctx( scriptContext ), m_xContext( xContext ) 45 { 46 // initialise m_hProviderDetailsCache with details of ScriptProviders 47 // will use createContentEnumeration 48 49 m_xMgr = m_xContext->getServiceManager(); 50 ENSURE_OR_THROW( m_xMgr.is(), "ProviderCache::ProviderCache() failed to obtain ServiceManager" ); 51 populateCache(); 52 } 53 54 55 ProviderCache::ProviderCache( const Reference< XComponentContext >& xContext, const Sequence< Any >& scriptContext, const Sequence< ::rtl::OUString >& blackList ) 56 throw ( RuntimeException ) : m_sBlackList( blackList ), m_Sctx( scriptContext ), m_xContext( xContext ) 57 58 { 59 // initialise m_hProviderDetailsCache with details of ScriptProviders 60 // will use createContentEnumeration 61 62 m_xMgr = m_xContext->getServiceManager(); 63 ENSURE_OR_THROW( m_xMgr.is(), "ProviderCache::ProviderCache() failed to obtain ServiceManager" ); 64 populateCache(); 65 } 66 67 ProviderCache::~ProviderCache() 68 { 69 } 70 71 Reference< provider::XScriptProvider > 72 ProviderCache::getProvider( const ::rtl::OUString& providerName ) 73 { 74 ::osl::Guard< osl::Mutex > aGuard( m_mutex ); 75 Reference< provider::XScriptProvider > provider; 76 ProviderDetails_hash::iterator h_it = m_hProviderDetailsCache.find( providerName ); 77 if ( h_it != m_hProviderDetailsCache.end() ) 78 { 79 if ( h_it->second.provider.is() ) 80 { 81 provider = h_it->second.provider; 82 } 83 else 84 { 85 // need to create provider and insert into hash 86 provider = createProvider( h_it->second ); 87 } 88 } 89 return provider; 90 } 91 92 Sequence < Reference< provider::XScriptProvider > > 93 ProviderCache::getAllProviders() throw ( RuntimeException ) 94 { 95 Sequence < Reference< provider::XScriptProvider > > providers ( m_hProviderDetailsCache.size() ); 96 // need to create providers that haven't been created already 97 // so check what providers exist and what ones don't 98 99 ::osl::Guard< osl::Mutex > aGuard( m_mutex ); 100 ProviderDetails_hash::iterator h_itEnd = m_hProviderDetailsCache.end(); 101 ProviderDetails_hash::iterator h_it = m_hProviderDetailsCache.begin(); 102 // should assert if size !> 0 103 if ( m_hProviderDetailsCache.size() ) 104 { 105 sal_Int32 providerIndex = 0; 106 sal_Int32 index = 0; 107 for ( index = 0; h_it != h_itEnd; ++h_it, index++ ) 108 { 109 Reference< provider::XScriptProvider > xScriptProvider = h_it->second.provider; 110 if ( xScriptProvider.is() ) 111 { 112 providers[ providerIndex++ ] = xScriptProvider; 113 } 114 else 115 { 116 // create provider 117 try 118 { 119 xScriptProvider = createProvider( h_it->second ); 120 providers[ providerIndex++ ] = xScriptProvider; 121 } 122 catch ( Exception& e ) 123 { 124 ::rtl::OUString temp = OUSTR( "ProviderCache::getAllProviders: failed to create provider, " ); 125 temp.concat( e.Message ); 126 //throw RuntimeException( temp.concat( e.Message ), 127 // Reference< XInterface >() ); 128 } 129 } 130 } 131 132 if ( providerIndex < index ) 133 { 134 providers.realloc( providerIndex ); 135 } 136 137 } 138 else 139 { 140 OSL_TRACE("no available providers, something very wrong!!!"); 141 } 142 return providers; 143 } 144 145 void 146 ProviderCache::populateCache() throw ( RuntimeException ) 147 { 148 // wrong name in services.rdb 149 ::rtl::OUString serviceName; 150 ::osl::Guard< osl::Mutex > aGuard( m_mutex ); 151 try 152 { 153 ::rtl::OUString languageProviderName( RTL_CONSTASCII_USTRINGPARAM( 154 "com.sun.star.script.provider.LanguageScriptProvider" ) ); 155 156 Reference< container::XContentEnumerationAccess > xEnumAccess = Reference< container::XContentEnumerationAccess >( m_xMgr, UNO_QUERY_THROW ); 157 Reference< container::XEnumeration > xEnum = xEnumAccess->createContentEnumeration ( languageProviderName ); 158 159 while ( xEnum->hasMoreElements() ) 160 { 161 162 Reference< lang::XSingleComponentFactory > factory( xEnum->nextElement(), UNO_QUERY_THROW ); 163 Reference< lang::XServiceInfo > xServiceInfo( factory, UNO_QUERY_THROW ); 164 165 Sequence< ::rtl::OUString > serviceNames = xServiceInfo->getSupportedServiceNames(); 166 167 if ( serviceNames.getLength() > 0 ) 168 { 169 ::rtl::OUString searchString( RTL_CONSTASCII_USTRINGPARAM ( 170 "com.sun.star.script.provider.ScriptProviderFor" ) ); 171 172 for ( sal_Int32 index = 0; index < serviceNames.getLength(); index++ ) 173 { 174 if ( serviceNames[ index ].indexOf( searchString ) == 0 && !isInBlackList( serviceNames[ index ] ) ) 175 { 176 serviceName = serviceNames[ index ]; 177 ProviderDetails details; 178 details.factory = factory; 179 m_hProviderDetailsCache[ serviceName ] = details; 180 break; 181 } 182 } 183 } 184 } 185 } 186 catch ( Exception e ) 187 { 188 ::rtl::OUString temp = OUSTR( 189 "ProviderCache::populateCache: couldn't obtain XSingleComponentFactory for " ); 190 temp.concat( serviceName ); 191 throw RuntimeException( temp.concat( e.Message ), Reference< XInterface >() ); 192 } 193 } 194 195 Reference< provider::XScriptProvider > 196 ProviderCache::createProvider( ProviderDetails& details ) throw ( RuntimeException ) 197 { 198 try 199 { 200 details.provider.set( 201 details.factory->createInstanceWithArgumentsAndContext( m_Sctx, m_xContext ), UNO_QUERY_THROW ); 202 } 203 catch ( RuntimeException& e ) 204 { 205 ::rtl::OUString temp = ::rtl::OUString::createFromAscii("ProviderCache::createProvider() Error creating provider from factory!!!"); 206 throw RuntimeException( temp.concat( e.Message ), Reference< XInterface >() ); 207 } 208 209 return details.provider; 210 } 211 } //end namespace 212