merge the formfield patch from ooo-build
[ooovba.git] / extensions / source / resource / oooresourceloader.cxx
blobdafd3dcd4176b35b53789545b42e6437d2bf574d
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: oooresourceloader.cxx,v $
10 * $Revision: 1.5 $
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>
50 #include <map>
52 //........................................................................
53 namespace res
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 //====================================================================
75 //= helper
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 )
84 return true;
85 if ( _lhs.second.Language < _rhs.second.Language )
86 return true;
87 if ( _lhs.second.Country < _rhs.second.Country )
88 return true;
89 if ( _lhs.second.Variant < _rhs.second.Variant )
90 return true;
91 return false;
95 //====================================================================
96 //= OpenOfficeResourceLoader
97 //====================================================================
98 typedef ::cppu::WeakImplHelper1 < XResourceBundleLoader
99 > OpenOfficeResourceLoader_Base;
100 class OpenOfficeResourceLoader : public OpenOfficeResourceLoader_Base
102 private:
103 typedef ::std::map< ResourceBundleDescriptor, WeakReference< XResourceBundle >, ResourceBundleDescriptorLess >
104 ResourceBundleCache;
106 private:
107 Reference< XComponentContext > m_xContext;
108 ::osl::Mutex m_aMutex;
109 ResourceBundleCache m_aBundleCache;
111 protected:
112 OpenOfficeResourceLoader( const Reference< XComponentContext >& _rxContext );
114 public:
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);
124 private:
125 OpenOfficeResourceLoader(); // never implemented
126 OpenOfficeResourceLoader( const OpenOfficeResourceLoader& ); // never implemented
127 OpenOfficeResourceLoader& operator=( const OpenOfficeResourceLoader& ); // never implemented
130 //====================================================================
131 //= IResourceType
132 //====================================================================
133 /** encapsulates access to a fixed resource type
135 class IResourceType
137 public:
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
145 @param _resourceId
146 the id of the resource to read
147 @return
148 the required resource
149 @precond
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
163 public:
164 StringResourceAccess();
166 // IResourceType
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
179 return RSC_STRING;
182 //--------------------------------------------------------------------
183 Any StringResourceAccess::getResource( SimpleResMgr& _resourceManager, sal_Int32 _resourceId ) const
185 OSL_PRECOND( _resourceManager.IsAvailable( getResourceType(), _resourceId ), "StringResourceAccess::getResource: precondition not met!" );
186 Any aResource;
187 aResource <<= ::rtl::OUString( _resourceManager.ReadString( _resourceId ) );
188 return aResource;
191 //====================================================================
192 //= OpenOfficeResourceBundle
193 //====================================================================
194 typedef ::cppu::WeakImplHelper1 < XResourceBundle
195 > OpenOfficeResourceBundle_Base;
196 class OpenOfficeResourceBundle : public OpenOfficeResourceBundle_Base
198 private:
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;
204 Locale m_aLocale;
205 SimpleResMgr* m_pResourceManager;
206 ResourceTypes m_aResourceTypes;
208 public:
209 OpenOfficeResourceBundle(
210 const Reference< XComponentContext >& _rxContext,
211 const ::rtl::OUString& _rBaseName,
212 const Locale& _rLocale
215 protected:
216 ~OpenOfficeResourceBundle();
218 public:
219 // XResourceBundle
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);
234 private:
235 /** retrievs the element with the given key, without asking our parent bundle
236 @param _key
237 the key of the element to retrieve
238 @param _out_Element
239 will contained the retrieved element upon successful return. If the method is unsuccessful, the
240 value will not be touched.
241 @return
242 <TRUE/> if and only if the element could be retrieved
243 @precond
244 our mutex is locked
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
249 @param _key
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
255 @return
256 <TRUE/> if and only if the given key specifies a known resource type, and contains a valid
257 resource id
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();
276 return aServices;
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;
315 if ( !xBundle.is() )
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 ) );
321 return xBundle;
324 //--------------------------------------------------------------------
325 ComponentInfo getComponentInfo_OpenOfficeResourceLoader()
327 ComponentInfo aInfo;
328 aInfo.aSupportedServices = OpenOfficeResourceLoader::getSupportedServiceNames_static();
329 aInfo.sImplementationName = OpenOfficeResourceLoader::getImplementationName_static();
330 aInfo.sSingletonName = OpenOfficeResourceLoader::getSingletonName_static();
331 aInfo.pFactory = &OpenOfficeResourceLoader::Create;
332 return aInfo;
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 );
367 return m_xParent;
370 //--------------------------------------------------------------------
371 void SAL_CALL OpenOfficeResourceBundle::setParent( const Reference< XResourceBundle >& _parent ) throw (RuntimeException)
373 ::osl::MutexGuard aGuard( m_aMutex );
374 m_xParent = _parent;
377 //--------------------------------------------------------------------
378 Locale SAL_CALL OpenOfficeResourceBundle::getLocale( ) throw (RuntimeException)
380 ::osl::MutexGuard aGuard( m_aMutex );
381 return m_aLocale;
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 )
389 // invalid key
390 return false;
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
397 return false;
399 _out_resourceType = typePos->second;
400 _out_resourceId = _key.copy( typeSeparatorPos + 1 ).toInt32();
401 return true;
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 ) )
410 return false;
412 if ( !m_pResourceManager->IsAvailable( resourceType->getResourceType(), resourceId ) )
413 // no such resource with the given type/id
414 return false;
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 );
425 Any aElement;
426 impl_getDirectElement_nothrow( _key, aElement );
427 return aElement;
430 //--------------------------------------------------------------------
431 Any SAL_CALL OpenOfficeResourceBundle::getByName( const ::rtl::OUString& _key ) throw (NoSuchElementException, WrappedTargetException, RuntimeException)
433 ::osl::MutexGuard aGuard( m_aMutex );
435 Any aElement;
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 );
445 return aElement;
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 ) )
465 return sal_False;
467 if ( !m_pResourceManager->IsAvailable( resourceType->getResourceType(), resourceId ) )
468 return sal_False;
470 return sal_True;
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 //........................................................................
489 } // namespace res
490 //........................................................................
492 #endif // EXTENSIONS_SOURCE_RESOURCE_OOORESOURCELOADER_CXX