1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <oooresourceloader.hxx>
22 #include <vcl/svapp.hxx>
23 #include <tools/simplerm.hxx>
24 #include <tools/rcid.h>
25 #include <cppuhelper/implbase1.hxx>
26 #include <cppuhelper/weakref.hxx>
28 #include <boost/shared_ptr.hpp>
31 using namespace ::com::sun::star::uno
;
32 using namespace ::com::sun::star::resource
;
33 using namespace ::com::sun::star::container
;
34 using namespace ::com::sun::star::lang
;
37 namespace extensions
{ namespace resource
39 /** encapsulates access to a fixed resource type
44 /** returns the RESOURCE_TYPE associated with this instance
46 virtual RESOURCE_TYPE
getResourceType() const = 0;
48 /** reads a single resource from the given resource manager
49 @param _resourceManager
50 the resource manager to read from
52 the id of the resource to read
56 the caler checked via <code>_resourceManager.IsAvailable( getResourceType(), _resourceId )</code>
57 that the required resource really exists
59 virtual Any
getResource( SimpleResMgr
& _resourceManager
, sal_Int32 _resourceId
) const = 0;
61 virtual ~IResourceType() { };
64 class StringResourceAccess
: public IResourceType
67 StringResourceAccess();
70 virtual RESOURCE_TYPE
getResourceType() const;
71 virtual Any
getResource( SimpleResMgr
& _resourceManager
, sal_Int32 _resourceId
) const;
74 StringResourceAccess::StringResourceAccess()
78 RESOURCE_TYPE
StringResourceAccess::getResourceType() const
83 Any
StringResourceAccess::getResource( SimpleResMgr
& _resourceManager
, sal_Int32 _resourceId
) const
85 OSL_PRECOND( _resourceManager
.IsAvailable( getResourceType(), _resourceId
), "StringResourceAccess::getResource: precondition not met!" );
87 aResource
<<= OUString( _resourceManager
.ReadString( _resourceId
) );
91 typedef ::cppu::WeakImplHelper1
< XResourceBundle
92 > OpenOfficeResourceBundle_Base
;
93 class OpenOfficeResourceBundle
: public OpenOfficeResourceBundle_Base
96 typedef ::boost::shared_ptr
< IResourceType
> ResourceTypePtr
;
97 typedef ::std::map
< OUString
, ResourceTypePtr
> ResourceTypes
;
99 ::osl::Mutex m_aMutex
;
100 Reference
< XResourceBundle
> m_xParent
;
102 SimpleResMgr
* m_pResourceManager
;
103 ResourceTypes m_aResourceTypes
;
106 OpenOfficeResourceBundle(
107 const Reference
< XComponentContext
>& _rxContext
,
108 const OUString
& _rBaseName
,
109 const Locale
& _rLocale
113 ~OpenOfficeResourceBundle();
117 virtual ::com::sun::star::uno::Reference
< ::com::sun::star::resource::XResourceBundle
> SAL_CALL
getParent() throw (::com::sun::star::uno::RuntimeException
);
118 virtual void SAL_CALL
setParent( const ::com::sun::star::uno::Reference
< ::com::sun::star::resource::XResourceBundle
>& _parent
) throw (::com::sun::star::uno::RuntimeException
);
119 virtual ::com::sun::star::lang::Locale SAL_CALL
getLocale( ) throw (::com::sun::star::uno::RuntimeException
);
120 virtual ::com::sun::star::uno::Any SAL_CALL
getDirectElement( const OUString
& key
) throw (::com::sun::star::uno::RuntimeException
);
122 // XNameAccess (base of XResourceBundle)
123 virtual ::com::sun::star::uno::Any SAL_CALL
getByName( const OUString
& aName
) throw (::com::sun::star::container::NoSuchElementException
, ::com::sun::star::lang::WrappedTargetException
, ::com::sun::star::uno::RuntimeException
);
124 virtual ::com::sun::star::uno::Sequence
< OUString
> SAL_CALL
getElementNames( ) throw (::com::sun::star::uno::RuntimeException
);
125 virtual ::sal_Bool SAL_CALL
hasByName( const OUString
& aName
) throw (::com::sun::star::uno::RuntimeException
);
127 // XElementAccess (base of XNameAccess)
128 virtual ::com::sun::star::uno::Type SAL_CALL
getElementType( ) throw (::com::sun::star::uno::RuntimeException
);
129 virtual ::sal_Bool SAL_CALL
hasElements( ) throw (::com::sun::star::uno::RuntimeException
);
132 /** retrievs the element with the given key, without asking our parent bundle
134 the key of the element to retrieve
136 will contained the retrieved element upon successful return. If the method is unsuccessful, the
137 value will not be touched.
139 <TRUE/> if and only if the element could be retrieved
143 bool impl_getDirectElement_nothrow( const OUString
& _key
, Any
& _out_Element
) const;
145 /** retrieves the resource type and id from a given resource key, which assembles those two
147 the resource key as got via a public API call
148 @param _out_resourceType
149 the resource type, if successful
150 @param _out_resourceId
151 the resource id, if successful
153 <TRUE/> if and only if the given key specifies a known resource type, and contains a valid
156 bool impl_getResourceTypeAndId_nothrow( const OUString
& _key
, ResourceTypePtr
& _out_resourceType
, sal_Int32
& _out_resourceId
) const;
159 OpenOfficeResourceLoader::OpenOfficeResourceLoader( Reference
< XComponentContext
> const& _rxContext
)
160 :m_xContext( _rxContext
)
164 //--------------------------------------------------------------------
165 Reference
< XResourceBundle
> SAL_CALL
OpenOfficeResourceLoader::loadBundle_Default( const OUString
& _baseName
) throw (MissingResourceException
, RuntimeException
)
167 return loadBundle( _baseName
, Application::GetSettings().GetUILanguageTag().getLocale() );
170 //--------------------------------------------------------------------
171 Reference
< XResourceBundle
> SAL_CALL
OpenOfficeResourceLoader::loadBundle( const OUString
& _baseName
, const Locale
& _locale
) throw (MissingResourceException
, RuntimeException
)
173 ::osl::MutexGuard
aGuard( m_aMutex
);
175 Reference
< XResourceBundle
> xBundle
;
177 ResourceBundleDescriptor
resourceDescriptor( _baseName
, _locale
);
178 ResourceBundleCache::iterator cachePos
= m_aBundleCache
.find( resourceDescriptor
);
179 if ( cachePos
!= m_aBundleCache
.end() )
180 xBundle
= cachePos
->second
;
183 { // not in the cache, or already died
184 xBundle
= new OpenOfficeResourceBundle( m_xContext
, _baseName
, _locale
);
185 m_aBundleCache
.insert( ResourceBundleCache::value_type( resourceDescriptor
, xBundle
) );
191 OpenOfficeResourceBundle::OpenOfficeResourceBundle( const Reference
< XComponentContext
>& /*_rxContext*/, const OUString
& _rBaseName
, const Locale
& _rLocale
)
192 :m_aLocale( _rLocale
)
193 ,m_pResourceManager( NULL
)
195 OUString
sBaseName( _rBaseName
);
196 m_pResourceManager
= new SimpleResMgr( OUStringToOString( sBaseName
, RTL_TEXTENCODING_UTF8
).getStr(),
197 LanguageTag( m_aLocale
) );
199 if ( !m_pResourceManager
->IsValid() )
201 delete m_pResourceManager
, m_pResourceManager
= NULL
;
202 throw MissingResourceException();
205 // supported resource types so far: strings
206 m_aResourceTypes
[ OUString( "string" ) ] =
207 ResourceTypePtr( new StringResourceAccess
);
210 OpenOfficeResourceBundle::~OpenOfficeResourceBundle()
212 delete m_pResourceManager
;
215 Reference
< XResourceBundle
> SAL_CALL
OpenOfficeResourceBundle::getParent() throw (RuntimeException
)
217 ::osl::MutexGuard
aGuard( m_aMutex
);
221 void SAL_CALL
OpenOfficeResourceBundle::setParent( const Reference
< XResourceBundle
>& _parent
) throw (RuntimeException
)
223 ::osl::MutexGuard
aGuard( m_aMutex
);
227 Locale SAL_CALL
OpenOfficeResourceBundle::getLocale( ) throw (RuntimeException
)
229 ::osl::MutexGuard
aGuard( m_aMutex
);
233 bool OpenOfficeResourceBundle::impl_getResourceTypeAndId_nothrow( const OUString
& _key
, ResourceTypePtr
& _out_resourceType
, sal_Int32
& _out_resourceId
) const
235 sal_Int32 typeSeparatorPos
= _key
.indexOf( ':' );
236 if ( typeSeparatorPos
== -1 )
240 OUString resourceType
= _key
.copy( 0, typeSeparatorPos
);
242 ResourceTypes::const_iterator typePos
= m_aResourceTypes
.find( resourceType
);
243 if ( typePos
== m_aResourceTypes
.end() )
244 // don't know this resource type
247 _out_resourceType
= typePos
->second
;
248 _out_resourceId
= _key
.copy( typeSeparatorPos
+ 1 ).toInt32();
252 bool OpenOfficeResourceBundle::impl_getDirectElement_nothrow( const OUString
& _key
, Any
& _out_Element
) const
254 ResourceTypePtr resourceType
;
255 sal_Int32
resourceId( 0 );
256 if ( !impl_getResourceTypeAndId_nothrow( _key
, resourceType
, resourceId
) )
259 if ( !m_pResourceManager
->IsAvailable( resourceType
->getResourceType(), resourceId
) )
260 // no such resource with the given type/id
263 _out_Element
= resourceType
->getResource( *m_pResourceManager
, resourceId
);
264 return _out_Element
.hasValue();
267 Any SAL_CALL
OpenOfficeResourceBundle::getDirectElement( const OUString
& _key
) throw (RuntimeException
)
269 ::osl::MutexGuard
aGuard( m_aMutex
);
272 impl_getDirectElement_nothrow( _key
, aElement
);
276 Any SAL_CALL
OpenOfficeResourceBundle::getByName( const OUString
& _key
) throw (NoSuchElementException
, WrappedTargetException
, RuntimeException
)
278 ::osl::MutexGuard
aGuard( m_aMutex
);
281 if ( !impl_getDirectElement_nothrow( _key
, aElement
) )
283 if ( m_xParent
.is() )
284 aElement
= m_xParent
->getByName( _key
);
287 if ( !aElement
.hasValue() )
288 throw NoSuchElementException( OUString(), *this );
293 Sequence
< OUString
> SAL_CALL
OpenOfficeResourceBundle::getElementNames( ) throw (RuntimeException
)
295 ::osl::MutexGuard
aGuard( m_aMutex
);
296 OSL_FAIL( "OpenOfficeResourceBundle::getElementNames: not implemented!" );
297 // the (Simple)ResManager does not provide an API to enumerate the resources
298 return Sequence
< OUString
>( );
301 ::sal_Bool SAL_CALL
OpenOfficeResourceBundle::hasByName( const OUString
& _key
) throw (RuntimeException
)
303 ::osl::MutexGuard
aGuard( m_aMutex
);
305 ResourceTypePtr resourceType
;
306 sal_Int32
resourceId( 0 );
307 if ( !impl_getResourceTypeAndId_nothrow( _key
, resourceType
, resourceId
) )
310 if ( !m_pResourceManager
->IsAvailable( resourceType
->getResourceType(), resourceId
) )
316 Type SAL_CALL
OpenOfficeResourceBundle::getElementType( ) throw (RuntimeException
)
318 return ::cppu::UnoType
< Any
>::get();
321 ::sal_Bool SAL_CALL
OpenOfficeResourceBundle::hasElements( ) throw (RuntimeException
)
323 ::osl::MutexGuard
aGuard( m_aMutex
);
324 OSL_FAIL( "OpenOfficeResourceBundle::hasElements: not implemented!" );
325 // the (Simple)ResManager does not provide an API to enumerate the resources
326 return ::sal_Bool( );
331 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */