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
ProviderCache(const Reference<XComponentContext> & xContext,const Sequence<Any> & scriptContext)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
ProviderCache(const Reference<XComponentContext> & xContext,const Sequence<Any> & scriptContext,const Sequence<::rtl::OUString> & blackList)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
~ProviderCache()67 ProviderCache::~ProviderCache()
68 {
69 }
70
71 Reference< provider::XScriptProvider >
getProvider(const::rtl::OUString & providerName)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 > >
getAllProviders()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
populateCache()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 >
createProvider(ProviderDetails & details)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 ( Exception& 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