1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: oooresourceloader.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_extensions.hxx"
34 #ifndef EXTENSIONS_SOURCE_RESOURCE_OOORESOURCELOADER_CXX
35 #define EXTENSIONS_SOURCE_RESOURCE_OOORESOURCELOADER_CXX
36 #include "res_services.hxx"
38 /** === begin UNO includes === **/
39 #include <com/sun/star/resource/XResourceBundleLoader.hpp>
40 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
41 #include <com/sun/star/uno/XComponentContext.hpp>
42 /** === end UNO includes === **/
43 #include <vcl/svapp.hxx>
44 #include <tools/simplerm.hxx>
45 #include <tools/rcid.h>
46 #include <cppuhelper/implbase1.hxx>
47 #include <cppuhelper/weakref.hxx>
49 #include <boost/shared_ptr.hpp>
52 //........................................................................
55 //........................................................................
57 /** === begin UNO using === **/
58 using ::com::sun::star::uno::Reference
;
59 using ::com::sun::star::resource::XResourceBundleLoader
;
60 using ::com::sun::star::resource::XResourceBundle
;
61 using ::com::sun::star::resource::MissingResourceException
;
62 using ::com::sun::star::uno::XComponentContext
;
63 using ::com::sun::star::uno::Sequence
;
64 using ::com::sun::star::uno::XInterface
;
65 using ::com::sun::star::uno::RuntimeException
;
66 using ::com::sun::star::lang::Locale
;
67 using ::com::sun::star::uno::Any
;
68 using ::com::sun::star::container::NoSuchElementException
;
69 using ::com::sun::star::lang::WrappedTargetException
;
70 using ::com::sun::star::uno::Type
;
71 using ::com::sun::star::uno::WeakReference
;
72 /** === end UNO using === **/
74 //====================================================================
76 //====================================================================
77 typedef ::std::pair
< ::rtl::OUString
, Locale
> ResourceBundleDescriptor
;
79 struct ResourceBundleDescriptorLess
: public ::std::binary_function
< ResourceBundleDescriptor
, ResourceBundleDescriptor
, bool >
81 bool operator()( const ResourceBundleDescriptor
& _lhs
, const ResourceBundleDescriptor
& _rhs
) const
83 if ( _lhs
.first
< _rhs
.first
)
85 if ( _lhs
.second
.Language
< _rhs
.second
.Language
)
87 if ( _lhs
.second
.Country
< _rhs
.second
.Country
)
89 if ( _lhs
.second
.Variant
< _rhs
.second
.Variant
)
95 //====================================================================
96 //= OpenOfficeResourceLoader
97 //====================================================================
98 typedef ::cppu::WeakImplHelper1
< XResourceBundleLoader
99 > OpenOfficeResourceLoader_Base
;
100 class OpenOfficeResourceLoader
: public OpenOfficeResourceLoader_Base
103 typedef ::std::map
< ResourceBundleDescriptor
, WeakReference
< XResourceBundle
>, ResourceBundleDescriptorLess
>
107 Reference
< XComponentContext
> m_xContext
;
108 ::osl::Mutex m_aMutex
;
109 ResourceBundleCache m_aBundleCache
;
112 OpenOfficeResourceLoader( const Reference
< XComponentContext
>& _rxContext
);
115 static Sequence
< ::rtl::OUString
> getSupportedServiceNames_static();
116 static ::rtl::OUString
getImplementationName_static();
117 static ::rtl::OUString
getSingletonName_static();
118 static Reference
< XInterface
> Create( const Reference
< XComponentContext
>& _rxContext
);
120 // XResourceBundleLoader
121 virtual Reference
< XResourceBundle
> SAL_CALL
loadBundle_Default( const ::rtl::OUString
& aBaseName
) throw (MissingResourceException
, RuntimeException
);
122 virtual Reference
< XResourceBundle
> SAL_CALL
loadBundle( const ::rtl::OUString
& abaseName
, const Locale
& aLocale
) throw (MissingResourceException
, RuntimeException
);
125 OpenOfficeResourceLoader(); // never implemented
126 OpenOfficeResourceLoader( const OpenOfficeResourceLoader
& ); // never implemented
127 OpenOfficeResourceLoader
& operator=( const OpenOfficeResourceLoader
& ); // never implemented
130 //====================================================================
132 //====================================================================
133 /** encapsulates access to a fixed resource type
138 /** returns the RESOURCE_TYPE associated with this instance
140 virtual RESOURCE_TYPE
getResourceType() const = 0;
142 /** reads a single resource from the given resource manager
143 @param _resourceManager
144 the resource manager to read from
146 the id of the resource to read
148 the required resource
150 the caler checked via <code>_resourceManager.IsAvailable( getResourceType(), _resourceId )</code>
151 that the required resource really exists
153 virtual Any
getResource( SimpleResMgr
& _resourceManager
, sal_Int32 _resourceId
) const = 0;
155 virtual ~IResourceType() { };
158 //====================================================================
159 //= StringResourceAccess
160 //====================================================================
161 class StringResourceAccess
: public IResourceType
164 StringResourceAccess();
167 virtual RESOURCE_TYPE
getResourceType() const;
168 virtual Any
getResource( SimpleResMgr
& _resourceManager
, sal_Int32 _resourceId
) const;
171 //--------------------------------------------------------------------
172 StringResourceAccess::StringResourceAccess()
176 //--------------------------------------------------------------------
177 RESOURCE_TYPE
StringResourceAccess::getResourceType() const
182 //--------------------------------------------------------------------
183 Any
StringResourceAccess::getResource( SimpleResMgr
& _resourceManager
, sal_Int32 _resourceId
) const
185 OSL_PRECOND( _resourceManager
.IsAvailable( getResourceType(), _resourceId
), "StringResourceAccess::getResource: precondition not met!" );
187 aResource
<<= ::rtl::OUString( _resourceManager
.ReadString( _resourceId
) );
191 //====================================================================
192 //= OpenOfficeResourceBundle
193 //====================================================================
194 typedef ::cppu::WeakImplHelper1
< XResourceBundle
195 > OpenOfficeResourceBundle_Base
;
196 class OpenOfficeResourceBundle
: public OpenOfficeResourceBundle_Base
199 typedef ::boost::shared_ptr
< IResourceType
> ResourceTypePtr
;
200 typedef ::std::map
< ::rtl::OUString
, ResourceTypePtr
> ResourceTypes
;
202 ::osl::Mutex m_aMutex
;
203 Reference
< XResourceBundle
> m_xParent
;
205 SimpleResMgr
* m_pResourceManager
;
206 ResourceTypes m_aResourceTypes
;
209 OpenOfficeResourceBundle(
210 const Reference
< XComponentContext
>& _rxContext
,
211 const ::rtl::OUString
& _rBaseName
,
212 const Locale
& _rLocale
216 ~OpenOfficeResourceBundle();
220 virtual ::com::sun::star::uno::Reference
< ::com::sun::star::resource::XResourceBundle
> SAL_CALL
getParent() throw (::com::sun::star::uno::RuntimeException
);
221 virtual void SAL_CALL
setParent( const ::com::sun::star::uno::Reference
< ::com::sun::star::resource::XResourceBundle
>& _parent
) throw (::com::sun::star::uno::RuntimeException
);
222 virtual ::com::sun::star::lang::Locale SAL_CALL
getLocale( ) throw (::com::sun::star::uno::RuntimeException
);
223 virtual ::com::sun::star::uno::Any SAL_CALL
getDirectElement( const ::rtl::OUString
& key
) throw (::com::sun::star::uno::RuntimeException
);
225 // XNameAccess (base of XResourceBundle)
226 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
);
227 virtual ::com::sun::star::uno::Sequence
< ::rtl::OUString
> SAL_CALL
getElementNames( ) throw (::com::sun::star::uno::RuntimeException
);
228 virtual ::sal_Bool SAL_CALL
hasByName( const ::rtl::OUString
& aName
) throw (::com::sun::star::uno::RuntimeException
);
230 // XElementAccess (base of XNameAccess)
231 virtual ::com::sun::star::uno::Type SAL_CALL
getElementType( ) throw (::com::sun::star::uno::RuntimeException
);
232 virtual ::sal_Bool SAL_CALL
hasElements( ) throw (::com::sun::star::uno::RuntimeException
);
235 /** retrievs the element with the given key, without asking our parent bundle
237 the key of the element to retrieve
239 will contained the retrieved element upon successful return. If the method is unsuccessful, the
240 value will not be touched.
242 <TRUE/> if and only if the element could be retrieved
246 bool impl_getDirectElement_nothrow( const ::rtl::OUString
& _key
, Any
& _out_Element
) const;
248 /** retrieves the resource type and id from a given resource key, which assembles those two
250 the resource key as got via a public API call
251 @param _out_resourceType
252 the resource type, if successful
253 @param _out_resourceId
254 the resource id, if successful
256 <TRUE/> if and only if the given key specifies a known resource type, and contains a valid
259 bool impl_getResourceTypeAndId_nothrow( const ::rtl::OUString
& _key
, ResourceTypePtr
& _out_resourceType
, sal_Int32
& _out_resourceId
) const;
262 //====================================================================
263 //= OpenOfficeResourceLoader
264 //====================================================================
265 //--------------------------------------------------------------------
266 OpenOfficeResourceLoader::OpenOfficeResourceLoader( const Reference
< XComponentContext
>& _rxContext
)
267 :m_xContext( _rxContext
)
271 //--------------------------------------------------------------------
272 Sequence
< ::rtl::OUString
> OpenOfficeResourceLoader::getSupportedServiceNames_static()
274 Sequence
< ::rtl::OUString
> aServices( 1 );
275 aServices
[ 0 ] = getSingletonName_static();
279 //--------------------------------------------------------------------
280 ::rtl::OUString
OpenOfficeResourceLoader::getImplementationName_static()
282 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.resource.OpenOfficeResourceLoader" ) );
285 //--------------------------------------------------------------------
286 ::rtl::OUString
OpenOfficeResourceLoader::getSingletonName_static()
288 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.resource.OfficeResourceLoader" ) );
291 //--------------------------------------------------------------------
292 Reference
< XInterface
> OpenOfficeResourceLoader::Create( const Reference
< XComponentContext
>& _rxContext
)
294 return *( new OpenOfficeResourceLoader( _rxContext
) );
297 //--------------------------------------------------------------------
298 Reference
< XResourceBundle
> SAL_CALL
OpenOfficeResourceLoader::loadBundle_Default( const ::rtl::OUString
& _baseName
) throw (MissingResourceException
, RuntimeException
)
300 return loadBundle( _baseName
, Application::GetSettings().GetUILocale() );
303 //--------------------------------------------------------------------
304 Reference
< XResourceBundle
> SAL_CALL
OpenOfficeResourceLoader::loadBundle( const ::rtl::OUString
& _baseName
, const Locale
& _locale
) throw (MissingResourceException
, RuntimeException
)
306 ::osl::MutexGuard
aGuard( m_aMutex
);
308 Reference
< XResourceBundle
> xBundle
;
310 ResourceBundleDescriptor
resourceDescriptor( _baseName
, _locale
);
311 ResourceBundleCache::iterator cachePos
= m_aBundleCache
.find( resourceDescriptor
);
312 if ( cachePos
!= m_aBundleCache
.end() )
313 xBundle
= cachePos
->second
;
316 { // not in the cache, or already died
317 xBundle
= new OpenOfficeResourceBundle( m_xContext
, _baseName
, _locale
);
318 m_aBundleCache
.insert( ResourceBundleCache::value_type( resourceDescriptor
, xBundle
) );
324 //--------------------------------------------------------------------
325 ComponentInfo
getComponentInfo_OpenOfficeResourceLoader()
328 aInfo
.aSupportedServices
= OpenOfficeResourceLoader::getSupportedServiceNames_static();
329 aInfo
.sImplementationName
= OpenOfficeResourceLoader::getImplementationName_static();
330 aInfo
.sSingletonName
= OpenOfficeResourceLoader::getSingletonName_static();
331 aInfo
.pFactory
= &OpenOfficeResourceLoader::Create
;
335 //====================================================================
336 //= OpenOfficeResourceBundle
337 //====================================================================
338 //--------------------------------------------------------------------
339 OpenOfficeResourceBundle::OpenOfficeResourceBundle( const Reference
< XComponentContext
>& /*_rxContext*/, const ::rtl::OUString
& _rBaseName
, const Locale
& _rLocale
)
340 :m_aLocale( _rLocale
)
341 ,m_pResourceManager( NULL
)
343 ::rtl::OUString
sBaseName( _rBaseName
);
344 m_pResourceManager
= new SimpleResMgr( sBaseName
, m_aLocale
);
346 if ( !m_pResourceManager
->IsValid() )
348 delete m_pResourceManager
, m_pResourceManager
= NULL
;
349 throw MissingResourceException();
352 // supported resource types so far: strings
353 m_aResourceTypes
[ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "string" ) ) ] =
354 ResourceTypePtr( new StringResourceAccess
);
357 //--------------------------------------------------------------------
358 OpenOfficeResourceBundle::~OpenOfficeResourceBundle()
360 delete m_pResourceManager
;
363 //--------------------------------------------------------------------
364 Reference
< XResourceBundle
> SAL_CALL
OpenOfficeResourceBundle::getParent() throw (RuntimeException
)
366 ::osl::MutexGuard
aGuard( m_aMutex
);
370 //--------------------------------------------------------------------
371 void SAL_CALL
OpenOfficeResourceBundle::setParent( const Reference
< XResourceBundle
>& _parent
) throw (RuntimeException
)
373 ::osl::MutexGuard
aGuard( m_aMutex
);
377 //--------------------------------------------------------------------
378 Locale SAL_CALL
OpenOfficeResourceBundle::getLocale( ) throw (RuntimeException
)
380 ::osl::MutexGuard
aGuard( m_aMutex
);
384 //--------------------------------------------------------------------
385 bool OpenOfficeResourceBundle::impl_getResourceTypeAndId_nothrow( const ::rtl::OUString
& _key
, ResourceTypePtr
& _out_resourceType
, sal_Int32
& _out_resourceId
) const
387 sal_Int32 typeSeparatorPos
= _key
.indexOf( ':' );
388 if ( typeSeparatorPos
== -1 )
392 ::rtl::OUString resourceType
= _key
.copy( 0, typeSeparatorPos
);
394 ResourceTypes::const_iterator typePos
= m_aResourceTypes
.find( resourceType
);
395 if ( typePos
== m_aResourceTypes
.end() )
396 // don't know this resource type
399 _out_resourceType
= typePos
->second
;
400 _out_resourceId
= _key
.copy( typeSeparatorPos
+ 1 ).toInt32();
404 //--------------------------------------------------------------------
405 bool OpenOfficeResourceBundle::impl_getDirectElement_nothrow( const ::rtl::OUString
& _key
, Any
& _out_Element
) const
407 ResourceTypePtr resourceType
;
408 sal_Int32
resourceId( 0 );
409 if ( !impl_getResourceTypeAndId_nothrow( _key
, resourceType
, resourceId
) )
412 if ( !m_pResourceManager
->IsAvailable( resourceType
->getResourceType(), resourceId
) )
413 // no such resource with the given type/id
416 _out_Element
= resourceType
->getResource( *m_pResourceManager
, resourceId
);
417 return _out_Element
.hasValue();
420 //--------------------------------------------------------------------
421 Any SAL_CALL
OpenOfficeResourceBundle::getDirectElement( const ::rtl::OUString
& _key
) throw (RuntimeException
)
423 ::osl::MutexGuard
aGuard( m_aMutex
);
426 impl_getDirectElement_nothrow( _key
, aElement
);
430 //--------------------------------------------------------------------
431 Any SAL_CALL
OpenOfficeResourceBundle::getByName( const ::rtl::OUString
& _key
) throw (NoSuchElementException
, WrappedTargetException
, RuntimeException
)
433 ::osl::MutexGuard
aGuard( m_aMutex
);
436 if ( !impl_getDirectElement_nothrow( _key
, aElement
) )
438 if ( m_xParent
.is() )
439 aElement
= m_xParent
->getByName( _key
);
442 if ( !aElement
.hasValue() )
443 throw NoSuchElementException( ::rtl::OUString(), *this );
448 //--------------------------------------------------------------------
449 Sequence
< ::rtl::OUString
> SAL_CALL
OpenOfficeResourceBundle::getElementNames( ) throw (RuntimeException
)
451 ::osl::MutexGuard
aGuard( m_aMutex
);
452 OSL_ENSURE( false, "OpenOfficeResourceBundle::getElementNames: not implemented!" );
453 // the (Simple)ResManager does not provide an API to enumerate the resources
454 return Sequence
< ::rtl::OUString
>( );
457 //--------------------------------------------------------------------
458 ::sal_Bool SAL_CALL
OpenOfficeResourceBundle::hasByName( const ::rtl::OUString
& _key
) throw (RuntimeException
)
460 ::osl::MutexGuard
aGuard( m_aMutex
);
462 ResourceTypePtr resourceType
;
463 sal_Int32
resourceId( 0 );
464 if ( !impl_getResourceTypeAndId_nothrow( _key
, resourceType
, resourceId
) )
467 if ( !m_pResourceManager
->IsAvailable( resourceType
->getResourceType(), resourceId
) )
473 //--------------------------------------------------------------------
474 Type SAL_CALL
OpenOfficeResourceBundle::getElementType( ) throw (RuntimeException
)
476 return ::cppu::UnoType
< Any
>::get();
479 //--------------------------------------------------------------------
480 ::sal_Bool SAL_CALL
OpenOfficeResourceBundle::hasElements( ) throw (RuntimeException
)
482 ::osl::MutexGuard
aGuard( m_aMutex
);
483 OSL_ENSURE( false, "OpenOfficeResourceBundle::hasElements: not implemented!" );
484 // the (Simple)ResManager does not provide an API to enumerate the resources
485 return ::sal_Bool( );
488 //........................................................................
490 //........................................................................
492 #endif // EXTENSIONS_SOURCE_RESOURCE_OOORESOURCELOADER_CXX