1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 // MARKER(update_precomp.py): autogen include statement, do not remove
30 #include "precompiled_extensions.hxx"
32 #ifndef EXTENSIONS_SOURCE_RESOURCE_OOORESOURCELOADER_CXX
33 #define EXTENSIONS_SOURCE_RESOURCE_OOORESOURCELOADER_CXX
34 #include "res_services.hxx"
36 /** === begin UNO includes === **/
37 #include <com/sun/star/resource/XResourceBundleLoader.hpp>
38 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
39 #include <com/sun/star/uno/XComponentContext.hpp>
40 /** === end UNO includes === **/
41 #include <vcl/svapp.hxx>
42 #include <tools/simplerm.hxx>
43 #include <tools/rcid.h>
44 #include <cppuhelper/implbase1.hxx>
45 #include <cppuhelper/weakref.hxx>
47 #include <boost/shared_ptr.hpp>
50 //........................................................................
53 //........................................................................
55 /** === begin UNO using === **/
56 using ::com::sun::star::uno::Reference
;
57 using ::com::sun::star::resource::XResourceBundleLoader
;
58 using ::com::sun::star::resource::XResourceBundle
;
59 using ::com::sun::star::resource::MissingResourceException
;
60 using ::com::sun::star::uno::XComponentContext
;
61 using ::com::sun::star::uno::Sequence
;
62 using ::com::sun::star::uno::XInterface
;
63 using ::com::sun::star::uno::RuntimeException
;
64 using ::com::sun::star::lang::Locale
;
65 using ::com::sun::star::uno::Any
;
66 using ::com::sun::star::container::NoSuchElementException
;
67 using ::com::sun::star::lang::WrappedTargetException
;
68 using ::com::sun::star::uno::Type
;
69 using ::com::sun::star::uno::WeakReference
;
70 /** === end UNO using === **/
72 //====================================================================
74 //====================================================================
75 typedef ::std::pair
< ::rtl::OUString
, Locale
> ResourceBundleDescriptor
;
77 struct ResourceBundleDescriptorLess
: public ::std::binary_function
< ResourceBundleDescriptor
, ResourceBundleDescriptor
, bool >
79 bool operator()( const ResourceBundleDescriptor
& _lhs
, const ResourceBundleDescriptor
& _rhs
) const
81 if ( _lhs
.first
< _rhs
.first
)
83 if ( _lhs
.second
.Language
< _rhs
.second
.Language
)
85 if ( _lhs
.second
.Country
< _rhs
.second
.Country
)
87 if ( _lhs
.second
.Variant
< _rhs
.second
.Variant
)
93 //====================================================================
94 //= OpenOfficeResourceLoader
95 //====================================================================
96 typedef ::cppu::WeakImplHelper1
< XResourceBundleLoader
97 > OpenOfficeResourceLoader_Base
;
98 class OpenOfficeResourceLoader
: public OpenOfficeResourceLoader_Base
101 typedef ::std::map
< ResourceBundleDescriptor
, WeakReference
< XResourceBundle
>, ResourceBundleDescriptorLess
>
105 Reference
< XComponentContext
> m_xContext
;
106 ::osl::Mutex m_aMutex
;
107 ResourceBundleCache m_aBundleCache
;
110 OpenOfficeResourceLoader( const Reference
< XComponentContext
>& _rxContext
);
113 static Sequence
< ::rtl::OUString
> getSupportedServiceNames_static();
114 static ::rtl::OUString
getImplementationName_static();
115 static ::rtl::OUString
getSingletonName_static();
116 static Reference
< XInterface
> Create( const Reference
< XComponentContext
>& _rxContext
);
118 // XResourceBundleLoader
119 virtual Reference
< XResourceBundle
> SAL_CALL
loadBundle_Default( const ::rtl::OUString
& aBaseName
) throw (MissingResourceException
, RuntimeException
);
120 virtual Reference
< XResourceBundle
> SAL_CALL
loadBundle( const ::rtl::OUString
& abaseName
, const Locale
& aLocale
) throw (MissingResourceException
, RuntimeException
);
123 OpenOfficeResourceLoader(); // never implemented
124 OpenOfficeResourceLoader( const OpenOfficeResourceLoader
& ); // never implemented
125 OpenOfficeResourceLoader
& operator=( const OpenOfficeResourceLoader
& ); // never implemented
128 //====================================================================
130 //====================================================================
131 /** encapsulates access to a fixed resource type
136 /** returns the RESOURCE_TYPE associated with this instance
138 virtual RESOURCE_TYPE
getResourceType() const = 0;
140 /** reads a single resource from the given resource manager
141 @param _resourceManager
142 the resource manager to read from
144 the id of the resource to read
146 the required resource
148 the caler checked via <code>_resourceManager.IsAvailable( getResourceType(), _resourceId )</code>
149 that the required resource really exists
151 virtual Any
getResource( SimpleResMgr
& _resourceManager
, sal_Int32 _resourceId
) const = 0;
153 virtual ~IResourceType() { };
156 //====================================================================
157 //= StringResourceAccess
158 //====================================================================
159 class StringResourceAccess
: public IResourceType
162 StringResourceAccess();
165 virtual RESOURCE_TYPE
getResourceType() const;
166 virtual Any
getResource( SimpleResMgr
& _resourceManager
, sal_Int32 _resourceId
) const;
169 //--------------------------------------------------------------------
170 StringResourceAccess::StringResourceAccess()
174 //--------------------------------------------------------------------
175 RESOURCE_TYPE
StringResourceAccess::getResourceType() const
180 //--------------------------------------------------------------------
181 Any
StringResourceAccess::getResource( SimpleResMgr
& _resourceManager
, sal_Int32 _resourceId
) const
183 OSL_PRECOND( _resourceManager
.IsAvailable( getResourceType(), _resourceId
), "StringResourceAccess::getResource: precondition not met!" );
185 aResource
<<= ::rtl::OUString( _resourceManager
.ReadString( _resourceId
) );
189 //====================================================================
190 //= OpenOfficeResourceBundle
191 //====================================================================
192 typedef ::cppu::WeakImplHelper1
< XResourceBundle
193 > OpenOfficeResourceBundle_Base
;
194 class OpenOfficeResourceBundle
: public OpenOfficeResourceBundle_Base
197 typedef ::boost::shared_ptr
< IResourceType
> ResourceTypePtr
;
198 typedef ::std::map
< ::rtl::OUString
, ResourceTypePtr
> ResourceTypes
;
200 ::osl::Mutex m_aMutex
;
201 Reference
< XResourceBundle
> m_xParent
;
203 SimpleResMgr
* m_pResourceManager
;
204 ResourceTypes m_aResourceTypes
;
207 OpenOfficeResourceBundle(
208 const Reference
< XComponentContext
>& _rxContext
,
209 const ::rtl::OUString
& _rBaseName
,
210 const Locale
& _rLocale
214 ~OpenOfficeResourceBundle();
218 virtual ::com::sun::star::uno::Reference
< ::com::sun::star::resource::XResourceBundle
> SAL_CALL
getParent() throw (::com::sun::star::uno::RuntimeException
);
219 virtual void SAL_CALL
setParent( const ::com::sun::star::uno::Reference
< ::com::sun::star::resource::XResourceBundle
>& _parent
) throw (::com::sun::star::uno::RuntimeException
);
220 virtual ::com::sun::star::lang::Locale SAL_CALL
getLocale( ) throw (::com::sun::star::uno::RuntimeException
);
221 virtual ::com::sun::star::uno::Any SAL_CALL
getDirectElement( const ::rtl::OUString
& key
) throw (::com::sun::star::uno::RuntimeException
);
223 // XNameAccess (base of XResourceBundle)
224 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
);
225 virtual ::com::sun::star::uno::Sequence
< ::rtl::OUString
> SAL_CALL
getElementNames( ) throw (::com::sun::star::uno::RuntimeException
);
226 virtual ::sal_Bool SAL_CALL
hasByName( const ::rtl::OUString
& aName
) throw (::com::sun::star::uno::RuntimeException
);
228 // XElementAccess (base of XNameAccess)
229 virtual ::com::sun::star::uno::Type SAL_CALL
getElementType( ) throw (::com::sun::star::uno::RuntimeException
);
230 virtual ::sal_Bool SAL_CALL
hasElements( ) throw (::com::sun::star::uno::RuntimeException
);
233 /** retrievs the element with the given key, without asking our parent bundle
235 the key of the element to retrieve
237 will contained the retrieved element upon successful return. If the method is unsuccessful, the
238 value will not be touched.
240 <TRUE/> if and only if the element could be retrieved
244 bool impl_getDirectElement_nothrow( const ::rtl::OUString
& _key
, Any
& _out_Element
) const;
246 /** retrieves the resource type and id from a given resource key, which assembles those two
248 the resource key as got via a public API call
249 @param _out_resourceType
250 the resource type, if successful
251 @param _out_resourceId
252 the resource id, if successful
254 <TRUE/> if and only if the given key specifies a known resource type, and contains a valid
257 bool impl_getResourceTypeAndId_nothrow( const ::rtl::OUString
& _key
, ResourceTypePtr
& _out_resourceType
, sal_Int32
& _out_resourceId
) const;
260 //====================================================================
261 //= OpenOfficeResourceLoader
262 //====================================================================
263 //--------------------------------------------------------------------
264 OpenOfficeResourceLoader::OpenOfficeResourceLoader( const Reference
< XComponentContext
>& _rxContext
)
265 :m_xContext( _rxContext
)
269 //--------------------------------------------------------------------
270 Sequence
< ::rtl::OUString
> OpenOfficeResourceLoader::getSupportedServiceNames_static()
272 Sequence
< ::rtl::OUString
> aServices( 1 );
273 aServices
[ 0 ] = getSingletonName_static();
277 //--------------------------------------------------------------------
278 ::rtl::OUString
OpenOfficeResourceLoader::getImplementationName_static()
280 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.resource.OpenOfficeResourceLoader" ) );
283 //--------------------------------------------------------------------
284 ::rtl::OUString
OpenOfficeResourceLoader::getSingletonName_static()
286 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.resource.OfficeResourceLoader" ) );
289 //--------------------------------------------------------------------
290 Reference
< XInterface
> OpenOfficeResourceLoader::Create( const Reference
< XComponentContext
>& _rxContext
)
292 return *( new OpenOfficeResourceLoader( _rxContext
) );
295 //--------------------------------------------------------------------
296 Reference
< XResourceBundle
> SAL_CALL
OpenOfficeResourceLoader::loadBundle_Default( const ::rtl::OUString
& _baseName
) throw (MissingResourceException
, RuntimeException
)
298 return loadBundle( _baseName
, Application::GetSettings().GetUILocale() );
301 //--------------------------------------------------------------------
302 Reference
< XResourceBundle
> SAL_CALL
OpenOfficeResourceLoader::loadBundle( const ::rtl::OUString
& _baseName
, const Locale
& _locale
) throw (MissingResourceException
, RuntimeException
)
304 ::osl::MutexGuard
aGuard( m_aMutex
);
306 Reference
< XResourceBundle
> xBundle
;
308 ResourceBundleDescriptor
resourceDescriptor( _baseName
, _locale
);
309 ResourceBundleCache::iterator cachePos
= m_aBundleCache
.find( resourceDescriptor
);
310 if ( cachePos
!= m_aBundleCache
.end() )
311 xBundle
= cachePos
->second
;
314 { // not in the cache, or already died
315 xBundle
= new OpenOfficeResourceBundle( m_xContext
, _baseName
, _locale
);
316 m_aBundleCache
.insert( ResourceBundleCache::value_type( resourceDescriptor
, xBundle
) );
322 //--------------------------------------------------------------------
323 ComponentInfo
getComponentInfo_OpenOfficeResourceLoader()
326 aInfo
.aSupportedServices
= OpenOfficeResourceLoader::getSupportedServiceNames_static();
327 aInfo
.sImplementationName
= OpenOfficeResourceLoader::getImplementationName_static();
328 aInfo
.sSingletonName
= OpenOfficeResourceLoader::getSingletonName_static();
329 aInfo
.pFactory
= &OpenOfficeResourceLoader::Create
;
333 //====================================================================
334 //= OpenOfficeResourceBundle
335 //====================================================================
336 //--------------------------------------------------------------------
337 OpenOfficeResourceBundle::OpenOfficeResourceBundle( const Reference
< XComponentContext
>& /*_rxContext*/, const ::rtl::OUString
& _rBaseName
, const Locale
& _rLocale
)
338 :m_aLocale( _rLocale
)
339 ,m_pResourceManager( NULL
)
341 ::rtl::OUString
sBaseName( _rBaseName
);
342 m_pResourceManager
= new SimpleResMgr( sBaseName
, m_aLocale
);
344 if ( !m_pResourceManager
->IsValid() )
346 delete m_pResourceManager
, m_pResourceManager
= NULL
;
347 throw MissingResourceException();
350 // supported resource types so far: strings
351 m_aResourceTypes
[ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "string" ) ) ] =
352 ResourceTypePtr( new StringResourceAccess
);
355 //--------------------------------------------------------------------
356 OpenOfficeResourceBundle::~OpenOfficeResourceBundle()
358 delete m_pResourceManager
;
361 //--------------------------------------------------------------------
362 Reference
< XResourceBundle
> SAL_CALL
OpenOfficeResourceBundle::getParent() throw (RuntimeException
)
364 ::osl::MutexGuard
aGuard( m_aMutex
);
368 //--------------------------------------------------------------------
369 void SAL_CALL
OpenOfficeResourceBundle::setParent( const Reference
< XResourceBundle
>& _parent
) throw (RuntimeException
)
371 ::osl::MutexGuard
aGuard( m_aMutex
);
375 //--------------------------------------------------------------------
376 Locale SAL_CALL
OpenOfficeResourceBundle::getLocale( ) throw (RuntimeException
)
378 ::osl::MutexGuard
aGuard( m_aMutex
);
382 //--------------------------------------------------------------------
383 bool OpenOfficeResourceBundle::impl_getResourceTypeAndId_nothrow( const ::rtl::OUString
& _key
, ResourceTypePtr
& _out_resourceType
, sal_Int32
& _out_resourceId
) const
385 sal_Int32 typeSeparatorPos
= _key
.indexOf( ':' );
386 if ( typeSeparatorPos
== -1 )
390 ::rtl::OUString resourceType
= _key
.copy( 0, typeSeparatorPos
);
392 ResourceTypes::const_iterator typePos
= m_aResourceTypes
.find( resourceType
);
393 if ( typePos
== m_aResourceTypes
.end() )
394 // don't know this resource type
397 _out_resourceType
= typePos
->second
;
398 _out_resourceId
= _key
.copy( typeSeparatorPos
+ 1 ).toInt32();
402 //--------------------------------------------------------------------
403 bool OpenOfficeResourceBundle::impl_getDirectElement_nothrow( const ::rtl::OUString
& _key
, Any
& _out_Element
) const
405 ResourceTypePtr resourceType
;
406 sal_Int32
resourceId( 0 );
407 if ( !impl_getResourceTypeAndId_nothrow( _key
, resourceType
, resourceId
) )
410 if ( !m_pResourceManager
->IsAvailable( resourceType
->getResourceType(), resourceId
) )
411 // no such resource with the given type/id
414 _out_Element
= resourceType
->getResource( *m_pResourceManager
, resourceId
);
415 return _out_Element
.hasValue();
418 //--------------------------------------------------------------------
419 Any SAL_CALL
OpenOfficeResourceBundle::getDirectElement( const ::rtl::OUString
& _key
) throw (RuntimeException
)
421 ::osl::MutexGuard
aGuard( m_aMutex
);
424 impl_getDirectElement_nothrow( _key
, aElement
);
428 //--------------------------------------------------------------------
429 Any SAL_CALL
OpenOfficeResourceBundle::getByName( const ::rtl::OUString
& _key
) throw (NoSuchElementException
, WrappedTargetException
, RuntimeException
)
431 ::osl::MutexGuard
aGuard( m_aMutex
);
434 if ( !impl_getDirectElement_nothrow( _key
, aElement
) )
436 if ( m_xParent
.is() )
437 aElement
= m_xParent
->getByName( _key
);
440 if ( !aElement
.hasValue() )
441 throw NoSuchElementException( ::rtl::OUString(), *this );
446 //--------------------------------------------------------------------
447 Sequence
< ::rtl::OUString
> SAL_CALL
OpenOfficeResourceBundle::getElementNames( ) throw (RuntimeException
)
449 ::osl::MutexGuard
aGuard( m_aMutex
);
450 OSL_ENSURE( false, "OpenOfficeResourceBundle::getElementNames: not implemented!" );
451 // the (Simple)ResManager does not provide an API to enumerate the resources
452 return Sequence
< ::rtl::OUString
>( );
455 //--------------------------------------------------------------------
456 ::sal_Bool SAL_CALL
OpenOfficeResourceBundle::hasByName( const ::rtl::OUString
& _key
) throw (RuntimeException
)
458 ::osl::MutexGuard
aGuard( m_aMutex
);
460 ResourceTypePtr resourceType
;
461 sal_Int32
resourceId( 0 );
462 if ( !impl_getResourceTypeAndId_nothrow( _key
, resourceType
, resourceId
) )
465 if ( !m_pResourceManager
->IsAvailable( resourceType
->getResourceType(), resourceId
) )
471 //--------------------------------------------------------------------
472 Type SAL_CALL
OpenOfficeResourceBundle::getElementType( ) throw (RuntimeException
)
474 return ::cppu::UnoType
< Any
>::get();
477 //--------------------------------------------------------------------
478 ::sal_Bool SAL_CALL
OpenOfficeResourceBundle::hasElements( ) throw (RuntimeException
)
480 ::osl::MutexGuard
aGuard( m_aMutex
);
481 OSL_ENSURE( false, "OpenOfficeResourceBundle::hasElements: not implemented!" );
482 // the (Simple)ResManager does not provide an API to enumerate the resources
483 return ::sal_Bool( );
486 //........................................................................
488 //........................................................................
490 #endif // EXTENSIONS_SOURCE_RESOURCE_OOORESOURCELOADER_CXX
492 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */