1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_scripting.hxx" 30 #include <cppuhelper/implementationentry.hxx> 31 #include <cppuhelper/factory.hxx> 32 #include <tools/diagnose_ex.h> 33 34 #include <util/scriptingconstants.hxx> 35 #include <util/util.hxx> 36 37 #include <com/sun/star/container/XContentEnumerationAccess.hpp> 38 #include "ProviderCache.hxx" 39 40 using namespace com::sun::star; 41 using namespace com::sun::star::uno; 42 using namespace com::sun::star::script; 43 44 namespace func_provider 45 { 46 47 ProviderCache::ProviderCache( const Reference< XComponentContext >& xContext, const Sequence< Any >& scriptContext ) 48 throw ( RuntimeException ) : m_Sctx( scriptContext ), m_xContext( xContext ) 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 59 ProviderCache::ProviderCache( const Reference< XComponentContext >& xContext, const Sequence< Any >& scriptContext, const Sequence< ::rtl::OUString >& blackList ) 60 throw ( RuntimeException ) : m_sBlackList( blackList ), m_Sctx( scriptContext ), m_xContext( xContext ) 61 62 { 63 // initialise m_hProviderDetailsCache with details of ScriptProviders 64 // will use createContentEnumeration 65 66 m_xMgr = m_xContext->getServiceManager(); 67 ENSURE_OR_THROW( m_xMgr.is(), "ProviderCache::ProviderCache() failed to obtain ServiceManager" ); 68 populateCache(); 69 } 70 71 ProviderCache::~ProviderCache() 72 { 73 } 74 75 Reference< provider::XScriptProvider > 76 ProviderCache::getProvider( const ::rtl::OUString& providerName ) 77 { 78 ::osl::Guard< osl::Mutex > aGuard( m_mutex ); 79 Reference< provider::XScriptProvider > provider; 80 ProviderDetails_hash::iterator h_it = m_hProviderDetailsCache.find( providerName ); 81 if ( h_it != m_hProviderDetailsCache.end() ) 82 { 83 if ( h_it->second.provider.is() ) 84 { 85 provider = h_it->second.provider; 86 } 87 else 88 { 89 // need to create provider and insert into hash 90 provider = createProvider( h_it->second ); 91 } 92 } 93 return provider; 94 } 95 96 Sequence < Reference< provider::XScriptProvider > > 97 ProviderCache::getAllProviders() throw ( RuntimeException ) 98 { 99 Sequence < Reference< provider::XScriptProvider > > providers ( m_hProviderDetailsCache.size() ); 100 // need to create providers that haven't been created already 101 // so check what providers exist and what ones don't 102 103 ::osl::Guard< osl::Mutex > aGuard( m_mutex ); 104 ProviderDetails_hash::iterator h_itEnd = m_hProviderDetailsCache.end(); 105 ProviderDetails_hash::iterator h_it = m_hProviderDetailsCache.begin(); 106 // should assert if size !> 0 107 if ( m_hProviderDetailsCache.size() ) 108 { 109 sal_Int32 providerIndex = 0; 110 sal_Int32 index = 0; 111 for ( index = 0; h_it != h_itEnd; ++h_it, index++ ) 112 { 113 Reference< provider::XScriptProvider > xScriptProvider = h_it->second.provider; 114 if ( xScriptProvider.is() ) 115 { 116 providers[ providerIndex++ ] = xScriptProvider; 117 } 118 else 119 { 120 // create provider 121 try 122 { 123 xScriptProvider = createProvider( h_it->second ); 124 providers[ providerIndex++ ] = xScriptProvider; 125 } 126 catch ( Exception& e ) 127 { 128 ::rtl::OUString temp = OUSTR( "ProviderCache::getAllProviders: failed to create provider, " ); 129 temp.concat( e.Message ); 130 //throw RuntimeException( temp.concat( e.Message ), 131 // Reference< XInterface >() ); 132 } 133 } 134 } 135 136 if ( providerIndex < index ) 137 { 138 providers.realloc( providerIndex ); 139 } 140 141 } 142 else 143 { 144 OSL_TRACE("no available providers, something very wrong!!!"); 145 } 146 return providers; 147 } 148 149 void 150 ProviderCache::populateCache() throw ( RuntimeException ) 151 { 152 // wrong name in services.rdb 153 ::rtl::OUString serviceName; 154 ::osl::Guard< osl::Mutex > aGuard( m_mutex ); 155 try 156 { 157 ::rtl::OUString languageProviderName( RTL_CONSTASCII_USTRINGPARAM( 158 "com.sun.star.script.provider.LanguageScriptProvider" ) ); 159 160 Reference< container::XContentEnumerationAccess > xEnumAccess = Reference< container::XContentEnumerationAccess >( m_xMgr, UNO_QUERY_THROW ); 161 Reference< container::XEnumeration > xEnum = xEnumAccess->createContentEnumeration ( languageProviderName ); 162 163 while ( xEnum->hasMoreElements() ) 164 { 165 166 Reference< lang::XSingleComponentFactory > factory( xEnum->nextElement(), UNO_QUERY_THROW ); 167 Reference< lang::XServiceInfo > xServiceInfo( factory, UNO_QUERY_THROW ); 168 169 Sequence< ::rtl::OUString > serviceNames = xServiceInfo->getSupportedServiceNames(); 170 171 if ( serviceNames.getLength() > 0 ) 172 { 173 ::rtl::OUString searchString( RTL_CONSTASCII_USTRINGPARAM ( 174 "com.sun.star.script.provider.ScriptProviderFor" ) ); 175 176 for ( sal_Int32 index = 0; index < serviceNames.getLength(); index++ ) 177 { 178 if ( serviceNames[ index ].indexOf( searchString ) == 0 && !isInBlackList( serviceNames[ index ] ) ) 179 { 180 serviceName = serviceNames[ index ]; 181 ProviderDetails details; 182 details.factory = factory; 183 m_hProviderDetailsCache[ serviceName ] = details; 184 break; 185 } 186 } 187 } 188 } 189 } 190 catch ( Exception e ) 191 { 192 ::rtl::OUString temp = OUSTR( 193 "ProviderCache::populateCache: couldn't obtain XSingleComponentFactory for " ); 194 temp.concat( serviceName ); 195 throw RuntimeException( temp.concat( e.Message ), Reference< XInterface >() ); 196 } 197 } 198 199 Reference< provider::XScriptProvider > 200 ProviderCache::createProvider( ProviderDetails& details ) throw ( RuntimeException ) 201 { 202 try 203 { 204 details.provider.set( 205 details.factory->createInstanceWithArgumentsAndContext( m_Sctx, m_xContext ), UNO_QUERY_THROW ); 206 } 207 catch ( RuntimeException& e ) 208 { 209 ::rtl::OUString temp = ::rtl::OUString::createFromAscii("ProviderCache::createProvider() Error creating provider from factory!!!"); 210 throw RuntimeException( temp.concat( e.Message ), Reference< XInterface >() ); 211 } 212 213 return details.provider; 214 } 215 } //end namespace 216