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*573d1ca0SAriel Constenla-Haile     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