merged tag ooo/OOO330_m14
[LibreOffice.git] / extensions / source / resource / oooresourceloader.cxx
blob6a9d6f338c068c1ce7cd0a2b77c66b104c48903c
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
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.
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).
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.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_extensions.hxx"
31 #ifndef EXTENSIONS_SOURCE_RESOURCE_OOORESOURCELOADER_CXX
32 #define EXTENSIONS_SOURCE_RESOURCE_OOORESOURCELOADER_CXX
33 #include "res_services.hxx"
35 /** === begin UNO includes === **/
36 #include <com/sun/star/resource/XResourceBundleLoader.hpp>
37 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
38 #include <com/sun/star/uno/XComponentContext.hpp>
39 /** === end UNO includes === **/
40 #include <vcl/svapp.hxx>
41 #include <tools/simplerm.hxx>
42 #include <tools/rcid.h>
43 #include <cppuhelper/implbase1.hxx>
44 #include <cppuhelper/weakref.hxx>
46 #include <boost/shared_ptr.hpp>
47 #include <map>
49 //........................................................................
50 namespace res
52 //........................................................................
54 /** === begin UNO using === **/
55 using ::com::sun::star::uno::Reference;
56 using ::com::sun::star::resource::XResourceBundleLoader;
57 using ::com::sun::star::resource::XResourceBundle;
58 using ::com::sun::star::resource::MissingResourceException;
59 using ::com::sun::star::uno::XComponentContext;
60 using ::com::sun::star::uno::Sequence;
61 using ::com::sun::star::uno::XInterface;
62 using ::com::sun::star::uno::RuntimeException;
63 using ::com::sun::star::lang::Locale;
64 using ::com::sun::star::uno::Any;
65 using ::com::sun::star::container::NoSuchElementException;
66 using ::com::sun::star::lang::WrappedTargetException;
67 using ::com::sun::star::uno::Type;
68 using ::com::sun::star::uno::WeakReference;
69 /** === end UNO using === **/
71 //====================================================================
72 //= helper
73 //====================================================================
74 typedef ::std::pair< ::rtl::OUString, Locale > ResourceBundleDescriptor;
76 struct ResourceBundleDescriptorLess : public ::std::binary_function< ResourceBundleDescriptor, ResourceBundleDescriptor, bool >
78 bool operator()( const ResourceBundleDescriptor& _lhs, const ResourceBundleDescriptor& _rhs ) const
80 if ( _lhs.first < _rhs.first )
81 return true;
82 if ( _lhs.second.Language < _rhs.second.Language )
83 return true;
84 if ( _lhs.second.Country < _rhs.second.Country )
85 return true;
86 if ( _lhs.second.Variant < _rhs.second.Variant )
87 return true;
88 return false;
92 //====================================================================
93 //= OpenOfficeResourceLoader
94 //====================================================================
95 typedef ::cppu::WeakImplHelper1 < XResourceBundleLoader
96 > OpenOfficeResourceLoader_Base;
97 class OpenOfficeResourceLoader : public OpenOfficeResourceLoader_Base
99 private:
100 typedef ::std::map< ResourceBundleDescriptor, WeakReference< XResourceBundle >, ResourceBundleDescriptorLess >
101 ResourceBundleCache;
103 private:
104 Reference< XComponentContext > m_xContext;
105 ::osl::Mutex m_aMutex;
106 ResourceBundleCache m_aBundleCache;
108 protected:
109 OpenOfficeResourceLoader( const Reference< XComponentContext >& _rxContext );
111 public:
112 static Sequence< ::rtl::OUString > getSupportedServiceNames_static();
113 static ::rtl::OUString getImplementationName_static();
114 static ::rtl::OUString getSingletonName_static();
115 static Reference< XInterface > Create( const Reference< XComponentContext >& _rxContext );
117 // XResourceBundleLoader
118 virtual Reference< XResourceBundle > SAL_CALL loadBundle_Default( const ::rtl::OUString& aBaseName ) throw (MissingResourceException, RuntimeException);
119 virtual Reference< XResourceBundle > SAL_CALL loadBundle( const ::rtl::OUString& abaseName, const Locale& aLocale ) throw (MissingResourceException, RuntimeException);
121 private:
122 OpenOfficeResourceLoader(); // never implemented
123 OpenOfficeResourceLoader( const OpenOfficeResourceLoader& ); // never implemented
124 OpenOfficeResourceLoader& operator=( const OpenOfficeResourceLoader& ); // never implemented
127 //====================================================================
128 //= IResourceType
129 //====================================================================
130 /** encapsulates access to a fixed resource type
132 class IResourceType
134 public:
135 /** returns the RESOURCE_TYPE associated with this instance
137 virtual RESOURCE_TYPE getResourceType() const = 0;
139 /** reads a single resource from the given resource manager
140 @param _resourceManager
141 the resource manager to read from
142 @param _resourceId
143 the id of the resource to read
144 @return
145 the required resource
146 @precond
147 the caler checked via <code>_resourceManager.IsAvailable( getResourceType(), _resourceId )</code>
148 that the required resource really exists
150 virtual Any getResource( SimpleResMgr& _resourceManager, sal_Int32 _resourceId ) const = 0;
152 virtual ~IResourceType() { };
155 //====================================================================
156 //= StringResourceAccess
157 //====================================================================
158 class StringResourceAccess : public IResourceType
160 public:
161 StringResourceAccess();
163 // IResourceType
164 virtual RESOURCE_TYPE getResourceType() const;
165 virtual Any getResource( SimpleResMgr& _resourceManager, sal_Int32 _resourceId ) const;
168 //--------------------------------------------------------------------
169 StringResourceAccess::StringResourceAccess()
173 //--------------------------------------------------------------------
174 RESOURCE_TYPE StringResourceAccess::getResourceType() const
176 return RSC_STRING;
179 //--------------------------------------------------------------------
180 Any StringResourceAccess::getResource( SimpleResMgr& _resourceManager, sal_Int32 _resourceId ) const
182 OSL_PRECOND( _resourceManager.IsAvailable( getResourceType(), _resourceId ), "StringResourceAccess::getResource: precondition not met!" );
183 Any aResource;
184 aResource <<= ::rtl::OUString( _resourceManager.ReadString( _resourceId ) );
185 return aResource;
188 //====================================================================
189 //= OpenOfficeResourceBundle
190 //====================================================================
191 typedef ::cppu::WeakImplHelper1 < XResourceBundle
192 > OpenOfficeResourceBundle_Base;
193 class OpenOfficeResourceBundle : public OpenOfficeResourceBundle_Base
195 private:
196 typedef ::boost::shared_ptr< IResourceType > ResourceTypePtr;
197 typedef ::std::map< ::rtl::OUString, ResourceTypePtr > ResourceTypes;
199 ::osl::Mutex m_aMutex;
200 Reference< XResourceBundle > m_xParent;
201 Locale m_aLocale;
202 SimpleResMgr* m_pResourceManager;
203 ResourceTypes m_aResourceTypes;
205 public:
206 OpenOfficeResourceBundle(
207 const Reference< XComponentContext >& _rxContext,
208 const ::rtl::OUString& _rBaseName,
209 const Locale& _rLocale
212 protected:
213 ~OpenOfficeResourceBundle();
215 public:
216 // XResourceBundle
217 virtual ::com::sun::star::uno::Reference< ::com::sun::star::resource::XResourceBundle > SAL_CALL getParent() throw (::com::sun::star::uno::RuntimeException);
218 virtual void SAL_CALL setParent( const ::com::sun::star::uno::Reference< ::com::sun::star::resource::XResourceBundle >& _parent ) throw (::com::sun::star::uno::RuntimeException);
219 virtual ::com::sun::star::lang::Locale SAL_CALL getLocale( ) throw (::com::sun::star::uno::RuntimeException);
220 virtual ::com::sun::star::uno::Any SAL_CALL getDirectElement( const ::rtl::OUString& key ) throw (::com::sun::star::uno::RuntimeException);
222 // XNameAccess (base of XResourceBundle)
223 virtual ::com::sun::star::uno::Any SAL_CALL getByName( const ::rtl::OUString& aName ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
224 virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames( ) throw (::com::sun::star::uno::RuntimeException);
225 virtual ::sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName ) throw (::com::sun::star::uno::RuntimeException);
227 // XElementAccess (base of XNameAccess)
228 virtual ::com::sun::star::uno::Type SAL_CALL getElementType( ) throw (::com::sun::star::uno::RuntimeException);
229 virtual ::sal_Bool SAL_CALL hasElements( ) throw (::com::sun::star::uno::RuntimeException);
231 private:
232 /** retrievs the element with the given key, without asking our parent bundle
233 @param _key
234 the key of the element to retrieve
235 @param _out_Element
236 will contained the retrieved element upon successful return. If the method is unsuccessful, the
237 value will not be touched.
238 @return
239 <TRUE/> if and only if the element could be retrieved
240 @precond
241 our mutex is locked
243 bool impl_getDirectElement_nothrow( const ::rtl::OUString& _key, Any& _out_Element ) const;
245 /** retrieves the resource type and id from a given resource key, which assembles those two
246 @param _key
247 the resource key as got via a public API call
248 @param _out_resourceType
249 the resource type, if successful
250 @param _out_resourceId
251 the resource id, if successful
252 @return
253 <TRUE/> if and only if the given key specifies a known resource type, and contains a valid
254 resource id
256 bool impl_getResourceTypeAndId_nothrow( const ::rtl::OUString& _key, ResourceTypePtr& _out_resourceType, sal_Int32& _out_resourceId ) const;
259 //====================================================================
260 //= OpenOfficeResourceLoader
261 //====================================================================
262 //--------------------------------------------------------------------
263 OpenOfficeResourceLoader::OpenOfficeResourceLoader( const Reference< XComponentContext >& _rxContext )
264 :m_xContext( _rxContext )
268 //--------------------------------------------------------------------
269 Sequence< ::rtl::OUString > OpenOfficeResourceLoader::getSupportedServiceNames_static()
271 Sequence< ::rtl::OUString > aServices( 1 );
272 aServices[ 0 ] = getSingletonName_static();
273 return aServices;
276 //--------------------------------------------------------------------
277 ::rtl::OUString OpenOfficeResourceLoader::getImplementationName_static()
279 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.resource.OpenOfficeResourceLoader" ) );
282 //--------------------------------------------------------------------
283 ::rtl::OUString OpenOfficeResourceLoader::getSingletonName_static()
285 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.resource.OfficeResourceLoader" ) );
288 //--------------------------------------------------------------------
289 Reference< XInterface > OpenOfficeResourceLoader::Create( const Reference< XComponentContext >& _rxContext )
291 return *( new OpenOfficeResourceLoader( _rxContext ) );
294 //--------------------------------------------------------------------
295 Reference< XResourceBundle > SAL_CALL OpenOfficeResourceLoader::loadBundle_Default( const ::rtl::OUString& _baseName ) throw (MissingResourceException, RuntimeException)
297 return loadBundle( _baseName, Application::GetSettings().GetUILocale() );
300 //--------------------------------------------------------------------
301 Reference< XResourceBundle > SAL_CALL OpenOfficeResourceLoader::loadBundle( const ::rtl::OUString& _baseName, const Locale& _locale ) throw (MissingResourceException, RuntimeException)
303 ::osl::MutexGuard aGuard( m_aMutex );
305 Reference< XResourceBundle > xBundle;
307 ResourceBundleDescriptor resourceDescriptor( _baseName, _locale );
308 ResourceBundleCache::iterator cachePos = m_aBundleCache.find( resourceDescriptor );
309 if ( cachePos != m_aBundleCache.end() )
310 xBundle = cachePos->second;
312 if ( !xBundle.is() )
313 { // not in the cache, or already died
314 xBundle = new OpenOfficeResourceBundle( m_xContext, _baseName, _locale );
315 m_aBundleCache.insert( ResourceBundleCache::value_type( resourceDescriptor, xBundle ) );
318 return xBundle;
321 //--------------------------------------------------------------------
322 ComponentInfo getComponentInfo_OpenOfficeResourceLoader()
324 ComponentInfo aInfo;
325 aInfo.aSupportedServices = OpenOfficeResourceLoader::getSupportedServiceNames_static();
326 aInfo.sImplementationName = OpenOfficeResourceLoader::getImplementationName_static();
327 aInfo.sSingletonName = OpenOfficeResourceLoader::getSingletonName_static();
328 aInfo.pFactory = &OpenOfficeResourceLoader::Create;
329 return aInfo;
332 //====================================================================
333 //= OpenOfficeResourceBundle
334 //====================================================================
335 //--------------------------------------------------------------------
336 OpenOfficeResourceBundle::OpenOfficeResourceBundle( const Reference< XComponentContext >& /*_rxContext*/, const ::rtl::OUString& _rBaseName, const Locale& _rLocale )
337 :m_aLocale( _rLocale )
338 ,m_pResourceManager( NULL )
340 ::rtl::OUString sBaseName( _rBaseName );
341 m_pResourceManager = new SimpleResMgr( sBaseName, m_aLocale );
343 if ( !m_pResourceManager->IsValid() )
345 delete m_pResourceManager, m_pResourceManager = NULL;
346 throw MissingResourceException();
349 // supported resource types so far: strings
350 m_aResourceTypes[ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "string" ) ) ] =
351 ResourceTypePtr( new StringResourceAccess );
354 //--------------------------------------------------------------------
355 OpenOfficeResourceBundle::~OpenOfficeResourceBundle()
357 delete m_pResourceManager;
360 //--------------------------------------------------------------------
361 Reference< XResourceBundle > SAL_CALL OpenOfficeResourceBundle::getParent() throw (RuntimeException)
363 ::osl::MutexGuard aGuard( m_aMutex );
364 return m_xParent;
367 //--------------------------------------------------------------------
368 void SAL_CALL OpenOfficeResourceBundle::setParent( const Reference< XResourceBundle >& _parent ) throw (RuntimeException)
370 ::osl::MutexGuard aGuard( m_aMutex );
371 m_xParent = _parent;
374 //--------------------------------------------------------------------
375 Locale SAL_CALL OpenOfficeResourceBundle::getLocale( ) throw (RuntimeException)
377 ::osl::MutexGuard aGuard( m_aMutex );
378 return m_aLocale;
381 //--------------------------------------------------------------------
382 bool OpenOfficeResourceBundle::impl_getResourceTypeAndId_nothrow( const ::rtl::OUString& _key, ResourceTypePtr& _out_resourceType, sal_Int32& _out_resourceId ) const
384 sal_Int32 typeSeparatorPos = _key.indexOf( ':' );
385 if ( typeSeparatorPos == -1 )
386 // invalid key
387 return false;
389 ::rtl::OUString resourceType = _key.copy( 0, typeSeparatorPos );
391 ResourceTypes::const_iterator typePos = m_aResourceTypes.find( resourceType );
392 if ( typePos == m_aResourceTypes.end() )
393 // don't know this resource type
394 return false;
396 _out_resourceType = typePos->second;
397 _out_resourceId = _key.copy( typeSeparatorPos + 1 ).toInt32();
398 return true;
401 //--------------------------------------------------------------------
402 bool OpenOfficeResourceBundle::impl_getDirectElement_nothrow( const ::rtl::OUString& _key, Any& _out_Element ) const
404 ResourceTypePtr resourceType;
405 sal_Int32 resourceId( 0 );
406 if ( !impl_getResourceTypeAndId_nothrow( _key, resourceType, resourceId ) )
407 return false;
409 if ( !m_pResourceManager->IsAvailable( resourceType->getResourceType(), resourceId ) )
410 // no such resource with the given type/id
411 return false;
413 _out_Element = resourceType->getResource( *m_pResourceManager, resourceId );
414 return _out_Element.hasValue();
417 //--------------------------------------------------------------------
418 Any SAL_CALL OpenOfficeResourceBundle::getDirectElement( const ::rtl::OUString& _key ) throw (RuntimeException)
420 ::osl::MutexGuard aGuard( m_aMutex );
422 Any aElement;
423 impl_getDirectElement_nothrow( _key, aElement );
424 return aElement;
427 //--------------------------------------------------------------------
428 Any SAL_CALL OpenOfficeResourceBundle::getByName( const ::rtl::OUString& _key ) throw (NoSuchElementException, WrappedTargetException, RuntimeException)
430 ::osl::MutexGuard aGuard( m_aMutex );
432 Any aElement;
433 if ( !impl_getDirectElement_nothrow( _key, aElement ) )
435 if ( m_xParent.is() )
436 aElement = m_xParent->getByName( _key );
439 if ( !aElement.hasValue() )
440 throw NoSuchElementException( ::rtl::OUString(), *this );
442 return aElement;
445 //--------------------------------------------------------------------
446 Sequence< ::rtl::OUString > SAL_CALL OpenOfficeResourceBundle::getElementNames( ) throw (RuntimeException)
448 ::osl::MutexGuard aGuard( m_aMutex );
449 OSL_ENSURE( false, "OpenOfficeResourceBundle::getElementNames: not implemented!" );
450 // the (Simple)ResManager does not provide an API to enumerate the resources
451 return Sequence< ::rtl::OUString >( );
454 //--------------------------------------------------------------------
455 ::sal_Bool SAL_CALL OpenOfficeResourceBundle::hasByName( const ::rtl::OUString& _key ) throw (RuntimeException)
457 ::osl::MutexGuard aGuard( m_aMutex );
459 ResourceTypePtr resourceType;
460 sal_Int32 resourceId( 0 );
461 if ( !impl_getResourceTypeAndId_nothrow( _key, resourceType, resourceId ) )
462 return sal_False;
464 if ( !m_pResourceManager->IsAvailable( resourceType->getResourceType(), resourceId ) )
465 return sal_False;
467 return sal_True;
470 //--------------------------------------------------------------------
471 Type SAL_CALL OpenOfficeResourceBundle::getElementType( ) throw (RuntimeException)
473 return ::cppu::UnoType< Any >::get();
476 //--------------------------------------------------------------------
477 ::sal_Bool SAL_CALL OpenOfficeResourceBundle::hasElements( ) throw (RuntimeException)
479 ::osl::MutexGuard aGuard( m_aMutex );
480 OSL_ENSURE( false, "OpenOfficeResourceBundle::hasElements: not implemented!" );
481 // the (Simple)ResManager does not provide an API to enumerate the resources
482 return ::sal_Bool( );
485 //........................................................................
486 } // namespace res
487 //........................................................................
489 #endif // EXTENSIONS_SOURCE_RESOURCE_OOORESOURCELOADER_CXX