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