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 <vcl/settings.hxx>
24 #include <tools/simplerm.hxx>
25 #include <tools/rcid.h>
26 #include <cppuhelper/implbase1.hxx>
27 #include <cppuhelper/weakref.hxx>
29 #include <boost/shared_ptr.hpp>
32 using namespace ::com::sun::star::uno
;
33 using namespace ::com::sun::star::resource
;
34 using namespace ::com::sun::star::container
;
35 using namespace ::com::sun::star::lang
;
38 namespace extensions
{ namespace resource
40 /** encapsulates access to a fixed resource type
45 /** returns the RESOURCE_TYPE associated with this instance
47 virtual RESOURCE_TYPE
getResourceType() const = 0;
49 /** reads a single resource from the given resource manager
50 @param _resourceManager
51 the resource manager to read from
53 the id of the resource to read
57 the caler checked via <code>_resourceManager.IsAvailable( getResourceType(), _resourceId )</code>
58 that the required resource really exists
60 virtual Any
getResource( SimpleResMgr
& _resourceManager
, sal_Int32 _resourceId
) const = 0;
62 virtual ~IResourceType() { };
65 class StringResourceAccess
: public IResourceType
68 StringResourceAccess();
71 virtual RESOURCE_TYPE
getResourceType() const SAL_OVERRIDE
;
72 virtual Any
getResource( SimpleResMgr
& _resourceManager
, sal_Int32 _resourceId
) const SAL_OVERRIDE
;
75 StringResourceAccess::StringResourceAccess()
79 RESOURCE_TYPE
StringResourceAccess::getResourceType() const
84 Any
StringResourceAccess::getResource( SimpleResMgr
& _resourceManager
, sal_Int32 _resourceId
) const
86 OSL_PRECOND( _resourceManager
.IsAvailable( getResourceType(), _resourceId
), "StringResourceAccess::getResource: precondition not met!" );
88 aResource
<<= OUString( _resourceManager
.ReadString( _resourceId
) );
92 typedef ::cppu::WeakImplHelper1
< XResourceBundle
93 > OpenOfficeResourceBundle_Base
;
94 class OpenOfficeResourceBundle
: public OpenOfficeResourceBundle_Base
97 typedef ::boost::shared_ptr
< IResourceType
> ResourceTypePtr
;
98 typedef ::std::map
< OUString
, ResourceTypePtr
> ResourceTypes
;
100 ::osl::Mutex m_aMutex
;
101 Reference
< XResourceBundle
> m_xParent
;
103 SimpleResMgr
* m_pResourceManager
;
104 ResourceTypes m_aResourceTypes
;
107 OpenOfficeResourceBundle(
108 const Reference
< XComponentContext
>& _rxContext
,
109 const OUString
& _rBaseName
,
110 const Locale
& _rLocale
114 virtual ~OpenOfficeResourceBundle();
118 virtual ::com::sun::star::uno::Reference
< ::com::sun::star::resource::XResourceBundle
> SAL_CALL
getParent() throw (::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
119 virtual void SAL_CALL
setParent( const ::com::sun::star::uno::Reference
< ::com::sun::star::resource::XResourceBundle
>& _parent
) throw (::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
120 virtual ::com::sun::star::lang::Locale SAL_CALL
getLocale( ) throw (::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
121 virtual ::com::sun::star::uno::Any SAL_CALL
getDirectElement( const OUString
& key
) throw (::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
123 // XNameAccess (base of XResourceBundle)
124 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
, std::exception
) SAL_OVERRIDE
;
125 virtual ::com::sun::star::uno::Sequence
< OUString
> SAL_CALL
getElementNames( ) throw (::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
126 virtual sal_Bool SAL_CALL
hasByName( const OUString
& aName
) throw (::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
128 // XElementAccess (base of XNameAccess)
129 virtual ::com::sun::star::uno::Type SAL_CALL
getElementType( ) throw (::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
130 virtual sal_Bool SAL_CALL
hasElements( ) throw (::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
133 /** retrievs the element with the given key, without asking our parent bundle
135 the key of the element to retrieve
137 will contained the retrieved element upon successful return. If the method is unsuccessful, the
138 value will not be touched.
140 <TRUE/> if and only if the element could be retrieved
144 bool impl_getDirectElement_nothrow( const OUString
& _key
, Any
& _out_Element
) const;
146 /** retrieves the resource type and id from a given resource key, which assembles those two
148 the resource key as got via a public API call
149 @param _out_resourceType
150 the resource type, if successful
151 @param _out_resourceId
152 the resource id, if successful
154 <TRUE/> if and only if the given key specifies a known resource type, and contains a valid
157 bool impl_getResourceTypeAndId_nothrow( const OUString
& _key
, ResourceTypePtr
& _out_resourceType
, sal_Int32
& _out_resourceId
) const;
160 OpenOfficeResourceLoader::OpenOfficeResourceLoader( Reference
< XComponentContext
> const& _rxContext
)
161 :m_xContext( _rxContext
)
166 Reference
< XResourceBundle
> SAL_CALL
OpenOfficeResourceLoader::loadBundle_Default( const OUString
& _baseName
) throw (MissingResourceException
, RuntimeException
, std::exception
)
168 return loadBundle( _baseName
, Application::GetSettings().GetUILanguageTag().getLocale() );
172 Reference
< XResourceBundle
> SAL_CALL
OpenOfficeResourceLoader::loadBundle( const OUString
& _baseName
, const Locale
& _locale
) throw (MissingResourceException
, RuntimeException
, std::exception
)
174 ::osl::MutexGuard
aGuard( m_aMutex
);
176 Reference
< XResourceBundle
> xBundle
;
178 ResourceBundleDescriptor
resourceDescriptor( _baseName
, _locale
);
179 ResourceBundleCache::iterator cachePos
= m_aBundleCache
.find( resourceDescriptor
);
180 if ( cachePos
!= m_aBundleCache
.end() )
181 xBundle
= cachePos
->second
;
184 { // not in the cache, or already died
185 xBundle
= new OpenOfficeResourceBundle( m_xContext
, _baseName
, _locale
);
186 m_aBundleCache
.insert( ResourceBundleCache::value_type( resourceDescriptor
, xBundle
) );
192 OpenOfficeResourceBundle::OpenOfficeResourceBundle( const Reference
< XComponentContext
>& /*_rxContext*/, const OUString
& _rBaseName
, const Locale
& _rLocale
)
193 :m_aLocale( _rLocale
)
194 ,m_pResourceManager( NULL
)
196 OUString
sBaseName( _rBaseName
);
197 m_pResourceManager
= new SimpleResMgr( OUStringToOString( sBaseName
, RTL_TEXTENCODING_UTF8
).getStr(),
198 LanguageTag( m_aLocale
) );
200 if ( !m_pResourceManager
->IsValid() )
202 delete m_pResourceManager
, m_pResourceManager
= NULL
;
203 throw MissingResourceException();
206 // supported resource types so far: strings
207 m_aResourceTypes
[ OUString( "string" ) ] =
208 ResourceTypePtr( new StringResourceAccess
);
211 OpenOfficeResourceBundle::~OpenOfficeResourceBundle()
213 delete m_pResourceManager
;
216 Reference
< XResourceBundle
> SAL_CALL
OpenOfficeResourceBundle::getParent() throw (RuntimeException
, std::exception
)
218 ::osl::MutexGuard
aGuard( m_aMutex
);
222 void SAL_CALL
OpenOfficeResourceBundle::setParent( const Reference
< XResourceBundle
>& _parent
) throw (RuntimeException
, std::exception
)
224 ::osl::MutexGuard
aGuard( m_aMutex
);
228 Locale SAL_CALL
OpenOfficeResourceBundle::getLocale( ) throw (RuntimeException
, std::exception
)
230 ::osl::MutexGuard
aGuard( m_aMutex
);
234 bool OpenOfficeResourceBundle::impl_getResourceTypeAndId_nothrow( const OUString
& _key
, ResourceTypePtr
& _out_resourceType
, sal_Int32
& _out_resourceId
) const
236 sal_Int32 typeSeparatorPos
= _key
.indexOf( ':' );
237 if ( typeSeparatorPos
== -1 )
241 OUString resourceType
= _key
.copy( 0, typeSeparatorPos
);
243 ResourceTypes::const_iterator typePos
= m_aResourceTypes
.find( resourceType
);
244 if ( typePos
== m_aResourceTypes
.end() )
245 // don't know this resource type
248 _out_resourceType
= typePos
->second
;
249 _out_resourceId
= _key
.copy( typeSeparatorPos
+ 1 ).toInt32();
253 bool OpenOfficeResourceBundle::impl_getDirectElement_nothrow( const OUString
& _key
, Any
& _out_Element
) const
255 ResourceTypePtr resourceType
;
256 sal_Int32
resourceId( 0 );
257 if ( !impl_getResourceTypeAndId_nothrow( _key
, resourceType
, resourceId
) )
260 if ( !m_pResourceManager
->IsAvailable( resourceType
->getResourceType(), resourceId
) )
261 // no such resource with the given type/id
264 _out_Element
= resourceType
->getResource( *m_pResourceManager
, resourceId
);
265 return _out_Element
.hasValue();
268 Any SAL_CALL
OpenOfficeResourceBundle::getDirectElement( const OUString
& _key
) throw (RuntimeException
, std::exception
)
270 ::osl::MutexGuard
aGuard( m_aMutex
);
273 impl_getDirectElement_nothrow( _key
, aElement
);
277 Any SAL_CALL
OpenOfficeResourceBundle::getByName( const OUString
& _key
) throw (NoSuchElementException
, WrappedTargetException
, RuntimeException
, std::exception
)
279 ::osl::MutexGuard
aGuard( m_aMutex
);
282 if ( !impl_getDirectElement_nothrow( _key
, aElement
) )
284 if ( m_xParent
.is() )
285 aElement
= m_xParent
->getByName( _key
);
288 if ( !aElement
.hasValue() )
289 throw NoSuchElementException( OUString(), *this );
294 Sequence
< OUString
> SAL_CALL
OpenOfficeResourceBundle::getElementNames( ) throw (RuntimeException
, std::exception
)
296 ::osl::MutexGuard
aGuard( m_aMutex
);
297 OSL_FAIL( "OpenOfficeResourceBundle::getElementNames: not implemented!" );
298 // the (Simple)ResManager does not provide an API to enumerate the resources
299 return Sequence
< OUString
>( );
302 sal_Bool SAL_CALL
OpenOfficeResourceBundle::hasByName( const OUString
& _key
) throw (RuntimeException
, std::exception
)
304 ::osl::MutexGuard
aGuard( m_aMutex
);
306 ResourceTypePtr resourceType
;
307 sal_Int32
resourceId( 0 );
308 if ( !impl_getResourceTypeAndId_nothrow( _key
, resourceType
, resourceId
) )
311 if ( !m_pResourceManager
->IsAvailable( resourceType
->getResourceType(), resourceId
) )
317 Type SAL_CALL
OpenOfficeResourceBundle::getElementType( ) throw (RuntimeException
, std::exception
)
319 return ::cppu::UnoType
< Any
>::get();
322 sal_Bool SAL_CALL
OpenOfficeResourceBundle::hasElements( ) throw (RuntimeException
, std::exception
)
324 ::osl::MutexGuard
aGuard( m_aMutex
);
325 OSL_FAIL( "OpenOfficeResourceBundle::hasElements: not implemented!" );
326 // the (Simple)ResManager does not provide an API to enumerate the resources
332 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */