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>
49 //........................................................................
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 //====================================================================
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
)
82 if ( _lhs
.second
.Language
< _rhs
.second
.Language
)
84 if ( _lhs
.second
.Country
< _rhs
.second
.Country
)
86 if ( _lhs
.second
.Variant
< _rhs
.second
.Variant
)
92 //====================================================================
93 //= OpenOfficeResourceLoader
94 //====================================================================
95 typedef ::cppu::WeakImplHelper1
< XResourceBundleLoader
96 > OpenOfficeResourceLoader_Base
;
97 class OpenOfficeResourceLoader
: public OpenOfficeResourceLoader_Base
100 typedef ::std::map
< ResourceBundleDescriptor
, WeakReference
< XResourceBundle
>, ResourceBundleDescriptorLess
>
104 Reference
< XComponentContext
> m_xContext
;
105 ::osl::Mutex m_aMutex
;
106 ResourceBundleCache m_aBundleCache
;
109 OpenOfficeResourceLoader( const Reference
< XComponentContext
>& _rxContext
);
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
);
122 OpenOfficeResourceLoader(); // never implemented
123 OpenOfficeResourceLoader( const OpenOfficeResourceLoader
& ); // never implemented
124 OpenOfficeResourceLoader
& operator=( const OpenOfficeResourceLoader
& ); // never implemented
127 //====================================================================
129 //====================================================================
130 /** encapsulates access to a fixed resource type
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
143 the id of the resource to read
145 the required resource
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
161 StringResourceAccess();
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
179 //--------------------------------------------------------------------
180 Any
StringResourceAccess::getResource( SimpleResMgr
& _resourceManager
, sal_Int32 _resourceId
) const
182 OSL_PRECOND( _resourceManager
.IsAvailable( getResourceType(), _resourceId
), "StringResourceAccess::getResource: precondition not met!" );
184 aResource
<<= ::rtl::OUString( _resourceManager
.ReadString( _resourceId
) );
188 //====================================================================
189 //= OpenOfficeResourceBundle
190 //====================================================================
191 typedef ::cppu::WeakImplHelper1
< XResourceBundle
192 > OpenOfficeResourceBundle_Base
;
193 class OpenOfficeResourceBundle
: public OpenOfficeResourceBundle_Base
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
;
202 SimpleResMgr
* m_pResourceManager
;
203 ResourceTypes m_aResourceTypes
;
206 OpenOfficeResourceBundle(
207 const Reference
< XComponentContext
>& _rxContext
,
208 const ::rtl::OUString
& _rBaseName
,
209 const Locale
& _rLocale
213 ~OpenOfficeResourceBundle();
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
);
232 /** retrievs the element with the given key, without asking our parent bundle
234 the key of the element to retrieve
236 will contained the retrieved element upon successful return. If the method is unsuccessful, the
237 value will not be touched.
239 <TRUE/> if and only if the element could be retrieved
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
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
253 <TRUE/> if and only if the given key specifies a known resource type, and contains a valid
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();
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
;
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
) );
321 //--------------------------------------------------------------------
322 ComponentInfo
getComponentInfo_OpenOfficeResourceLoader()
325 aInfo
.aSupportedServices
= OpenOfficeResourceLoader::getSupportedServiceNames_static();
326 aInfo
.sImplementationName
= OpenOfficeResourceLoader::getImplementationName_static();
327 aInfo
.sSingletonName
= OpenOfficeResourceLoader::getSingletonName_static();
328 aInfo
.pFactory
= &OpenOfficeResourceLoader::Create
;
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
);
367 //--------------------------------------------------------------------
368 void SAL_CALL
OpenOfficeResourceBundle::setParent( const Reference
< XResourceBundle
>& _parent
) throw (RuntimeException
)
370 ::osl::MutexGuard
aGuard( m_aMutex
);
374 //--------------------------------------------------------------------
375 Locale SAL_CALL
OpenOfficeResourceBundle::getLocale( ) throw (RuntimeException
)
377 ::osl::MutexGuard
aGuard( m_aMutex
);
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 )
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
396 _out_resourceType
= typePos
->second
;
397 _out_resourceId
= _key
.copy( typeSeparatorPos
+ 1 ).toInt32();
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
) )
409 if ( !m_pResourceManager
->IsAvailable( resourceType
->getResourceType(), resourceId
) )
410 // no such resource with the given type/id
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
);
423 impl_getDirectElement_nothrow( _key
, aElement
);
427 //--------------------------------------------------------------------
428 Any SAL_CALL
OpenOfficeResourceBundle::getByName( const ::rtl::OUString
& _key
) throw (NoSuchElementException
, WrappedTargetException
, RuntimeException
)
430 ::osl::MutexGuard
aGuard( m_aMutex
);
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 );
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
) )
464 if ( !m_pResourceManager
->IsAvailable( resourceType
->getResourceType(), resourceId
) )
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 //........................................................................
487 //........................................................................
489 #endif // EXTENSIONS_SOURCE_RESOURCE_OOORESOURCELOADER_CXX