Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
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.
15 : : *
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).
21 : : *
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.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include <oooresourceloader.hxx>
31 : : #include <vcl/svapp.hxx>
32 : : #include <tools/simplerm.hxx>
33 : : #include <tools/rcid.h>
34 : : #include <cppuhelper/implbase1.hxx>
35 : : #include <cppuhelper/weakref.hxx>
36 : :
37 : : #include <boost/shared_ptr.hpp>
38 : : #include <map>
39 : :
40 : : using namespace ::com::sun::star::uno;
41 : : using namespace ::com::sun::star::resource;
42 : : using namespace ::com::sun::star::container;
43 : : using namespace ::com::sun::star::lang;
44 : :
45 : :
46 : : namespace extensions { namespace resource
47 : : {
48 : : /** encapsulates access to a fixed resource type
49 : : */
50 : 5 : class IResourceType
51 : : {
52 : : public:
53 : : /** returns the RESOURCE_TYPE associated with this instance
54 : : */
55 : : virtual RESOURCE_TYPE getResourceType() const = 0;
56 : :
57 : : /** reads a single resource from the given resource manager
58 : : @param _resourceManager
59 : : the resource manager to read from
60 : : @param _resourceId
61 : : the id of the resource to read
62 : : @return
63 : : the required resource
64 : : @precond
65 : : the caler checked via <code>_resourceManager.IsAvailable( getResourceType(), _resourceId )</code>
66 : : that the required resource really exists
67 : : */
68 : : virtual Any getResource( SimpleResMgr& _resourceManager, sal_Int32 _resourceId ) const = 0;
69 : :
70 [ - + ]: 5 : virtual ~IResourceType() { };
71 : : };
72 : :
73 [ - + ]: 10 : class StringResourceAccess : public IResourceType
74 : : {
75 : : public:
76 : : StringResourceAccess();
77 : :
78 : : // IResourceType
79 : : virtual RESOURCE_TYPE getResourceType() const;
80 : : virtual Any getResource( SimpleResMgr& _resourceManager, sal_Int32 _resourceId ) const;
81 : : };
82 : :
83 : 5 : StringResourceAccess::StringResourceAccess()
84 : : {
85 : 5 : }
86 : :
87 : 46 : RESOURCE_TYPE StringResourceAccess::getResourceType() const
88 : : {
89 : 46 : return RSC_STRING;
90 : : }
91 : :
92 : 46 : Any StringResourceAccess::getResource( SimpleResMgr& _resourceManager, sal_Int32 _resourceId ) const
93 : : {
94 : : OSL_PRECOND( _resourceManager.IsAvailable( getResourceType(), _resourceId ), "StringResourceAccess::getResource: precondition not met!" );
95 : 46 : Any aResource;
96 [ + - ][ + - ]: 46 : aResource <<= ::rtl::OUString( _resourceManager.ReadString( _resourceId ) );
97 : 46 : return aResource;
98 : : }
99 : :
100 : : typedef ::cppu::WeakImplHelper1 < XResourceBundle
101 : : > OpenOfficeResourceBundle_Base;
102 : : class OpenOfficeResourceBundle : public OpenOfficeResourceBundle_Base
103 : : {
104 : : private:
105 : : typedef ::boost::shared_ptr< IResourceType > ResourceTypePtr;
106 : : typedef ::std::map< ::rtl::OUString, ResourceTypePtr > ResourceTypes;
107 : :
108 : : ::osl::Mutex m_aMutex;
109 : : Reference< XResourceBundle > m_xParent;
110 : : Locale m_aLocale;
111 : : SimpleResMgr* m_pResourceManager;
112 : : ResourceTypes m_aResourceTypes;
113 : :
114 : : public:
115 : : OpenOfficeResourceBundle(
116 : : const Reference< XComponentContext >& _rxContext,
117 : : const ::rtl::OUString& _rBaseName,
118 : : const Locale& _rLocale
119 : : );
120 : :
121 : : protected:
122 : : ~OpenOfficeResourceBundle();
123 : :
124 : : public:
125 : : // XResourceBundle
126 : : virtual ::com::sun::star::uno::Reference< ::com::sun::star::resource::XResourceBundle > SAL_CALL getParent() throw (::com::sun::star::uno::RuntimeException);
127 : : virtual void SAL_CALL setParent( const ::com::sun::star::uno::Reference< ::com::sun::star::resource::XResourceBundle >& _parent ) throw (::com::sun::star::uno::RuntimeException);
128 : : virtual ::com::sun::star::lang::Locale SAL_CALL getLocale( ) throw (::com::sun::star::uno::RuntimeException);
129 : : virtual ::com::sun::star::uno::Any SAL_CALL getDirectElement( const ::rtl::OUString& key ) throw (::com::sun::star::uno::RuntimeException);
130 : :
131 : : // XNameAccess (base of XResourceBundle)
132 : : 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);
133 : : virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames( ) throw (::com::sun::star::uno::RuntimeException);
134 : : virtual ::sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName ) throw (::com::sun::star::uno::RuntimeException);
135 : :
136 : : // XElementAccess (base of XNameAccess)
137 : : virtual ::com::sun::star::uno::Type SAL_CALL getElementType( ) throw (::com::sun::star::uno::RuntimeException);
138 : : virtual ::sal_Bool SAL_CALL hasElements( ) throw (::com::sun::star::uno::RuntimeException);
139 : :
140 : : private:
141 : : /** retrievs the element with the given key, without asking our parent bundle
142 : : @param _key
143 : : the key of the element to retrieve
144 : : @param _out_Element
145 : : will contained the retrieved element upon successful return. If the method is unsuccessful, the
146 : : value will not be touched.
147 : : @return
148 : : <TRUE/> if and only if the element could be retrieved
149 : : @precond
150 : : our mutex is locked
151 : : */
152 : : bool impl_getDirectElement_nothrow( const ::rtl::OUString& _key, Any& _out_Element ) const;
153 : :
154 : : /** retrieves the resource type and id from a given resource key, which assembles those two
155 : : @param _key
156 : : the resource key as got via a public API call
157 : : @param _out_resourceType
158 : : the resource type, if successful
159 : : @param _out_resourceId
160 : : the resource id, if successful
161 : : @return
162 : : <TRUE/> if and only if the given key specifies a known resource type, and contains a valid
163 : : resource id
164 : : */
165 : : bool impl_getResourceTypeAndId_nothrow( const ::rtl::OUString& _key, ResourceTypePtr& _out_resourceType, sal_Int32& _out_resourceId ) const;
166 : : };
167 : :
168 : 4 : OpenOfficeResourceLoader::OpenOfficeResourceLoader( Reference< XComponentContext > const& _rxContext )
169 [ + - ][ + - ]: 4 : :m_xContext( _rxContext )
170 : : {
171 : 4 : }
172 : :
173 : : //--------------------------------------------------------------------
174 : 5 : Reference< XResourceBundle > SAL_CALL OpenOfficeResourceLoader::loadBundle_Default( const ::rtl::OUString& _baseName ) throw (MissingResourceException, RuntimeException)
175 : : {
176 : 5 : return loadBundle( _baseName, Application::GetSettings().GetUILocale() );
177 : : }
178 : :
179 : : //--------------------------------------------------------------------
180 : 5 : Reference< XResourceBundle > SAL_CALL OpenOfficeResourceLoader::loadBundle( const ::rtl::OUString& _baseName, const Locale& _locale ) throw (MissingResourceException, RuntimeException)
181 : : {
182 [ + - ]: 5 : ::osl::MutexGuard aGuard( m_aMutex );
183 : :
184 : 5 : Reference< XResourceBundle > xBundle;
185 : :
186 : 5 : ResourceBundleDescriptor resourceDescriptor( _baseName, _locale );
187 [ + - ]: 5 : ResourceBundleCache::iterator cachePos = m_aBundleCache.find( resourceDescriptor );
188 [ + + ]: 5 : if ( cachePos != m_aBundleCache.end() )
189 [ + - ][ + - ]: 1 : xBundle = cachePos->second;
190 : :
191 [ + - ]: 5 : if ( !xBundle.is() )
192 : : { // not in the cache, or already died
193 [ + - ][ + - ]: 5 : xBundle = new OpenOfficeResourceBundle( m_xContext, _baseName, _locale );
[ + - ]
194 [ + - ][ + - ]: 5 : m_aBundleCache.insert( ResourceBundleCache::value_type( resourceDescriptor, xBundle ) );
[ + - ]
195 : : }
196 : :
197 [ + - ]: 5 : return xBundle;
198 : : }
199 : :
200 : 5 : OpenOfficeResourceBundle::OpenOfficeResourceBundle( const Reference< XComponentContext >& /*_rxContext*/, const ::rtl::OUString& _rBaseName, const Locale& _rLocale )
201 : : :m_aLocale( _rLocale )
202 [ + - ][ + - ]: 5 : ,m_pResourceManager( NULL )
203 : : {
204 : 5 : ::rtl::OUString sBaseName( _rBaseName );
205 [ + - ][ + - ]: 5 : m_pResourceManager = new SimpleResMgr( rtl::OUStringToOString( sBaseName, RTL_TEXTENCODING_UTF8 ).getStr(), m_aLocale );
[ + - ]
206 : :
207 [ - + ]: 5 : if ( !m_pResourceManager->IsValid() )
208 : : {
209 [ # # ][ # # ]: 0 : delete m_pResourceManager, m_pResourceManager = NULL;
210 [ # # ]: 0 : throw MissingResourceException();
211 : : }
212 : :
213 : : // supported resource types so far: strings
214 [ + - ][ + - ]: 10 : m_aResourceTypes[ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "string" ) ) ] =
215 [ + - ][ + - ]: 15 : ResourceTypePtr( new StringResourceAccess );
[ + - + - ]
216 : 5 : }
217 : :
218 [ + - ]: 5 : OpenOfficeResourceBundle::~OpenOfficeResourceBundle()
219 : : {
220 [ + - ][ + - ]: 5 : delete m_pResourceManager;
221 [ - + ]: 10 : }
222 : :
223 : 0 : Reference< XResourceBundle > SAL_CALL OpenOfficeResourceBundle::getParent() throw (RuntimeException)
224 : : {
225 [ # # ]: 0 : ::osl::MutexGuard aGuard( m_aMutex );
226 [ # # ]: 0 : return m_xParent;
227 : : }
228 : :
229 : 0 : void SAL_CALL OpenOfficeResourceBundle::setParent( const Reference< XResourceBundle >& _parent ) throw (RuntimeException)
230 : : {
231 [ # # ]: 0 : ::osl::MutexGuard aGuard( m_aMutex );
232 [ # # ][ # # ]: 0 : m_xParent = _parent;
233 : 0 : }
234 : :
235 : 0 : Locale SAL_CALL OpenOfficeResourceBundle::getLocale( ) throw (RuntimeException)
236 : : {
237 [ # # ]: 0 : ::osl::MutexGuard aGuard( m_aMutex );
238 [ # # ]: 0 : return m_aLocale;
239 : : }
240 : :
241 : 46 : bool OpenOfficeResourceBundle::impl_getResourceTypeAndId_nothrow( const ::rtl::OUString& _key, ResourceTypePtr& _out_resourceType, sal_Int32& _out_resourceId ) const
242 : : {
243 : 46 : sal_Int32 typeSeparatorPos = _key.indexOf( ':' );
244 [ - + ]: 46 : if ( typeSeparatorPos == -1 )
245 : : // invalid key
246 : 0 : return false;
247 : :
248 : 46 : ::rtl::OUString resourceType = _key.copy( 0, typeSeparatorPos );
249 : :
250 [ + - ]: 46 : ResourceTypes::const_iterator typePos = m_aResourceTypes.find( resourceType );
251 [ - + ]: 46 : if ( typePos == m_aResourceTypes.end() )
252 : : // don't know this resource type
253 : 0 : return false;
254 : :
255 [ + - ]: 46 : _out_resourceType = typePos->second;
256 : 46 : _out_resourceId = _key.copy( typeSeparatorPos + 1 ).toInt32();
257 : 46 : return true;
258 : : }
259 : :
260 : 46 : bool OpenOfficeResourceBundle::impl_getDirectElement_nothrow( const ::rtl::OUString& _key, Any& _out_Element ) const
261 : : {
262 [ + - ]: 46 : ResourceTypePtr resourceType;
263 : 46 : sal_Int32 resourceId( 0 );
264 [ + - ][ - + ]: 46 : if ( !impl_getResourceTypeAndId_nothrow( _key, resourceType, resourceId ) )
265 : 0 : return false;
266 : :
267 [ + - ][ + - ]: 46 : if ( !m_pResourceManager->IsAvailable( resourceType->getResourceType(), resourceId ) )
[ - + ]
268 : : // no such resource with the given type/id
269 : 0 : return false;
270 : :
271 [ + - ]: 46 : _out_Element = resourceType->getResource( *m_pResourceManager, resourceId );
272 [ + - ]: 46 : return _out_Element.hasValue();
273 : : }
274 : :
275 : 0 : Any SAL_CALL OpenOfficeResourceBundle::getDirectElement( const ::rtl::OUString& _key ) throw (RuntimeException)
276 : : {
277 [ # # ]: 0 : ::osl::MutexGuard aGuard( m_aMutex );
278 : :
279 : 0 : Any aElement;
280 [ # # ]: 0 : impl_getDirectElement_nothrow( _key, aElement );
281 [ # # ]: 0 : return aElement;
282 : : }
283 : :
284 : 46 : Any SAL_CALL OpenOfficeResourceBundle::getByName( const ::rtl::OUString& _key ) throw (NoSuchElementException, WrappedTargetException, RuntimeException)
285 : : {
286 [ + - ]: 46 : ::osl::MutexGuard aGuard( m_aMutex );
287 : :
288 : 46 : Any aElement;
289 [ - + ][ + - ]: 46 : if ( !impl_getDirectElement_nothrow( _key, aElement ) )
290 : : {
291 [ # # ]: 0 : if ( m_xParent.is() )
292 [ # # ][ # # ]: 0 : aElement = m_xParent->getByName( _key );
293 : : }
294 : :
295 [ - + ]: 46 : if ( !aElement.hasValue() )
296 [ # # ][ # # ]: 0 : throw NoSuchElementException( ::rtl::OUString(), *this );
297 : :
298 [ + - ]: 46 : return aElement;
299 : : }
300 : :
301 : 0 : Sequence< ::rtl::OUString > SAL_CALL OpenOfficeResourceBundle::getElementNames( ) throw (RuntimeException)
302 : : {
303 [ # # ]: 0 : ::osl::MutexGuard aGuard( m_aMutex );
304 : : OSL_FAIL( "OpenOfficeResourceBundle::getElementNames: not implemented!" );
305 : : // the (Simple)ResManager does not provide an API to enumerate the resources
306 [ # # ][ # # ]: 0 : return Sequence< ::rtl::OUString >( );
307 : : }
308 : :
309 : 0 : ::sal_Bool SAL_CALL OpenOfficeResourceBundle::hasByName( const ::rtl::OUString& _key ) throw (RuntimeException)
310 : : {
311 [ # # ]: 0 : ::osl::MutexGuard aGuard( m_aMutex );
312 : :
313 [ # # ]: 0 : ResourceTypePtr resourceType;
314 : 0 : sal_Int32 resourceId( 0 );
315 [ # # ][ # # ]: 0 : if ( !impl_getResourceTypeAndId_nothrow( _key, resourceType, resourceId ) )
316 : 0 : return sal_False;
317 : :
318 [ # # ][ # # ]: 0 : if ( !m_pResourceManager->IsAvailable( resourceType->getResourceType(), resourceId ) )
[ # # ]
319 : 0 : return sal_False;
320 : :
321 [ # # ][ # # ]: 0 : return sal_True;
322 : : }
323 : :
324 : 0 : Type SAL_CALL OpenOfficeResourceBundle::getElementType( ) throw (RuntimeException)
325 : : {
326 : 0 : return ::cppu::UnoType< Any >::get();
327 : : }
328 : :
329 : 0 : ::sal_Bool SAL_CALL OpenOfficeResourceBundle::hasElements( ) throw (RuntimeException)
330 : : {
331 [ # # ]: 0 : ::osl::MutexGuard aGuard( m_aMutex );
332 : : OSL_FAIL( "OpenOfficeResourceBundle::hasElements: not implemented!" );
333 : : // the (Simple)ResManager does not provide an API to enumerate the resources
334 [ # # ]: 0 : return ::sal_Bool( );
335 : : }
336 : :
337 : : }}
338 : :
339 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|