Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include "stringresource.hxx"
21 : #include <com/sun/star/io/TempFile.hpp>
22 : #include <com/sun/star/io/TextInputStream.hpp>
23 : #include <com/sun/star/io/TextOutputStream.hpp>
24 : #include <com/sun/star/io/XActiveDataSink.hpp>
25 : #include <com/sun/star/io/XActiveDataSource.hpp>
26 : #include <com/sun/star/io/XStream.hpp>
27 : #include <com/sun/star/io/XSeekable.hpp>
28 : #include <com/sun/star/embed/ElementModes.hpp>
29 : #include <com/sun/star/lang/XMultiComponentFactory.hpp>
30 : #include <cppuhelper/implementationentry.hxx>
31 : #include <cppuhelper/supportsservice.hxx>
32 : #include <com/sun/star/beans/XPropertySet.hpp>
33 : #include <com/sun/star/container/XNameAccess.hpp>
34 : #include <com/sun/star/ucb/SimpleFileAccess.hpp>
35 :
36 : #include <rtl/tencinfo.h>
37 : #include <rtl/ustrbuf.hxx>
38 : #include <rtl/strbuf.hxx>
39 : #include <tools/urlobj.hxx>
40 : #include <i18nlangtag/languagetag.hxx>
41 :
42 : using namespace ::com::sun::star;
43 : using namespace ::com::sun::star::lang;
44 : using namespace ::com::sun::star::uno;
45 : using namespace ::com::sun::star::ucb;
46 : using namespace ::com::sun::star::util;
47 : using namespace ::com::sun::star::embed;
48 : using namespace ::com::sun::star::container;
49 :
50 :
51 :
52 : namespace stringresource
53 : {
54 :
55 :
56 :
57 : // mutex
58 :
59 :
60 1 : ::osl::Mutex& getMutex()
61 : {
62 : static ::osl::Mutex* s_pMutex = 0;
63 1 : if ( !s_pMutex )
64 : {
65 1 : ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
66 1 : if ( !s_pMutex )
67 : {
68 1 : static ::osl::Mutex s_aMutex;
69 1 : s_pMutex = &s_aMutex;
70 1 : }
71 : }
72 1 : return *s_pMutex;
73 : }
74 :
75 :
76 :
77 : // StringResourceImpl
78 :
79 :
80 : // component operations
81 2 : static Sequence< OUString > getSupportedServiceNames_StringResourceImpl()
82 : {
83 2 : Sequence< OUString > names(1);
84 2 : names[0] = "com.sun.star.resource.StringResource";
85 2 : return names;
86 : }
87 :
88 1 : static OUString getImplementationName_StringResourceImpl()
89 : {
90 1 : return OUString( "com.sun.star.comp.scripting.StringResource" );
91 : }
92 :
93 1 : static Reference< XInterface > SAL_CALL create_StringResourceImpl(
94 : Reference< XComponentContext > const & xContext )
95 : {
96 1 : return static_cast< ::cppu::OWeakObject * >( new StringResourcePersistenceImpl( xContext ) );
97 : }
98 :
99 :
100 :
101 :
102 1 : StringResourceImpl::StringResourceImpl( const Reference< XComponentContext >& rxContext )
103 : : m_xContext( rxContext )
104 : , m_pCurrentLocaleItem( NULL )
105 : , m_pDefaultLocaleItem( NULL )
106 : , m_bDefaultModified( false )
107 1 : , m_aListenerContainer( getMutex() )
108 : , m_bModified( false )
109 : , m_bReadOnly( false )
110 2 : , m_nNextUniqueNumericId( UNIQUE_NUMBER_NEEDS_INITIALISATION )
111 : {
112 1 : }
113 :
114 :
115 :
116 2 : StringResourceImpl::~StringResourceImpl()
117 : {
118 1 : for( LocaleItemVectorIt it = m_aLocaleItemVector.begin(); it != m_aLocaleItemVector.end(); ++it )
119 : {
120 0 : LocaleItem* pLocaleItem = *it;
121 0 : delete pLocaleItem;
122 : }
123 :
124 1 : for( LocaleItemVectorIt it = m_aDeletedLocaleItemVector.begin(); it != m_aDeletedLocaleItemVector.end(); ++it )
125 : {
126 0 : LocaleItem* pLocaleItem = *it;
127 0 : delete pLocaleItem;
128 : }
129 1 : }
130 :
131 :
132 :
133 : // XServiceInfo
134 :
135 0 : OUString StringResourceImpl::getImplementationName( ) throw (RuntimeException, std::exception)
136 : {
137 0 : return getImplementationName_StringResourceImpl();
138 : }
139 :
140 0 : sal_Bool StringResourceImpl::supportsService( const OUString& rServiceName ) throw (RuntimeException, std::exception)
141 : {
142 0 : return cppu::supportsService(this, rServiceName);
143 : }
144 :
145 1 : Sequence< OUString > StringResourceImpl::getSupportedServiceNames( ) throw (RuntimeException, std::exception)
146 : {
147 1 : return getSupportedServiceNames_StringResourceImpl();
148 : }
149 :
150 :
151 :
152 : // XModifyBroadcaster
153 :
154 0 : void StringResourceImpl::addModifyListener( const Reference< XModifyListener >& aListener )
155 : throw (RuntimeException, std::exception)
156 : {
157 0 : if( !aListener.is() )
158 0 : throw RuntimeException();
159 :
160 0 : ::osl::MutexGuard aGuard( getMutex() );
161 0 : m_aListenerContainer.addInterface( Reference<XInterface>( aListener, UNO_QUERY ) );
162 0 : }
163 :
164 0 : void StringResourceImpl::removeModifyListener( const Reference< XModifyListener >& aListener )
165 : throw (RuntimeException, std::exception)
166 : {
167 0 : if( !aListener.is() )
168 0 : throw RuntimeException();
169 :
170 0 : ::osl::MutexGuard aGuard( getMutex() );
171 0 : m_aListenerContainer.removeInterface( Reference<XInterface>( aListener, UNO_QUERY ) );
172 0 : }
173 :
174 :
175 :
176 : // XStringResourceResolver
177 :
178 0 : OUString StringResourceImpl::implResolveString
179 : ( const OUString& ResourceID, LocaleItem* pLocaleItem )
180 : throw (::com::sun::star::resource::MissingResourceException)
181 : {
182 0 : OUString aRetStr;
183 0 : bool bSuccess = false;
184 0 : if( pLocaleItem != NULL && loadLocale( pLocaleItem ) )
185 : {
186 0 : IdToStringMap::iterator it = pLocaleItem->m_aIdToStringMap.find( ResourceID );
187 0 : if( !( it == pLocaleItem->m_aIdToStringMap.end() ) )
188 : {
189 0 : aRetStr = (*it).second;
190 0 : bSuccess = true;
191 : }
192 : }
193 0 : if( !bSuccess )
194 : {
195 0 : OUString errorMsg("StringResourceImpl: No entry for ResourceID: ");
196 0 : errorMsg = errorMsg.concat( ResourceID );
197 0 : throw ::com::sun::star::resource::MissingResourceException( errorMsg );
198 : }
199 0 : return aRetStr;
200 : }
201 :
202 0 : OUString StringResourceImpl::resolveString( const OUString& ResourceID )
203 : throw (::com::sun::star::resource::MissingResourceException, RuntimeException, std::exception)
204 : {
205 0 : ::osl::MutexGuard aGuard( getMutex() );
206 0 : return implResolveString( ResourceID, m_pCurrentLocaleItem );
207 : }
208 :
209 0 : OUString StringResourceImpl::resolveStringForLocale( const OUString& ResourceID, const Locale& locale )
210 : throw ( ::com::sun::star::resource::MissingResourceException, RuntimeException, std::exception)
211 : {
212 0 : ::osl::MutexGuard aGuard( getMutex() );
213 0 : LocaleItem* pLocaleItem = getItemForLocale( locale, false );
214 0 : return implResolveString( ResourceID, pLocaleItem );
215 : }
216 :
217 0 : bool StringResourceImpl::implHasEntryForId( const OUString& ResourceID, LocaleItem* pLocaleItem )
218 : {
219 0 : bool bSuccess = false;
220 0 : if( pLocaleItem != NULL && loadLocale( pLocaleItem ) )
221 : {
222 0 : IdToStringMap::iterator it = pLocaleItem->m_aIdToStringMap.find( ResourceID );
223 0 : if( !( it == pLocaleItem->m_aIdToStringMap.end() ) )
224 0 : bSuccess = true;
225 : }
226 0 : return bSuccess;
227 : }
228 :
229 0 : sal_Bool StringResourceImpl::hasEntryForId( const OUString& ResourceID )
230 : throw (RuntimeException, std::exception)
231 : {
232 0 : ::osl::MutexGuard aGuard( getMutex() );
233 0 : return implHasEntryForId( ResourceID, m_pCurrentLocaleItem );
234 : }
235 :
236 0 : sal_Bool StringResourceImpl::hasEntryForIdAndLocale( const OUString& ResourceID,
237 : const Locale& locale )
238 : throw (RuntimeException, std::exception)
239 : {
240 0 : ::osl::MutexGuard aGuard( getMutex() );
241 0 : LocaleItem* pLocaleItem = getItemForLocale( locale, false );
242 0 : return implHasEntryForId( ResourceID, pLocaleItem );
243 : }
244 :
245 0 : Sequence< OUString > StringResourceImpl::implGetResourceIDs( LocaleItem* pLocaleItem )
246 : {
247 0 : Sequence< OUString > aIDSeq( 0 );
248 0 : if( pLocaleItem && loadLocale( pLocaleItem ) )
249 : {
250 0 : const IdToStringMap& rHashMap = pLocaleItem->m_aIdToStringMap;
251 0 : sal_Int32 nResourceIDCount = rHashMap.size();
252 0 : aIDSeq.realloc( nResourceIDCount );
253 0 : OUString* pStrings = aIDSeq.getArray();
254 :
255 0 : IdToStringMap::const_iterator it;
256 0 : int iTarget = 0;
257 0 : for( it = rHashMap.begin(); it != rHashMap.end(); ++it )
258 : {
259 0 : OUString aStr = (*it).first;
260 0 : pStrings[iTarget] = aStr;
261 0 : iTarget++;
262 0 : }
263 : }
264 0 : return aIDSeq;
265 : }
266 :
267 0 : Sequence< OUString > StringResourceImpl::getResourceIDsForLocale
268 : ( const Locale& locale ) throw (::com::sun::star::uno::RuntimeException, std::exception)
269 : {
270 0 : ::osl::MutexGuard aGuard( getMutex() );
271 0 : LocaleItem* pLocaleItem = getItemForLocale( locale, false );
272 0 : return implGetResourceIDs( pLocaleItem );
273 : }
274 :
275 0 : Sequence< OUString > StringResourceImpl::getResourceIDs( )
276 : throw (RuntimeException, std::exception)
277 : {
278 0 : ::osl::MutexGuard aGuard( getMutex() );
279 0 : return implGetResourceIDs( m_pCurrentLocaleItem );
280 : }
281 :
282 0 : Locale StringResourceImpl::getCurrentLocale()
283 : throw (RuntimeException, std::exception)
284 : {
285 0 : ::osl::MutexGuard aGuard( getMutex() );
286 :
287 0 : Locale aRetLocale;
288 0 : if( m_pCurrentLocaleItem != NULL )
289 0 : aRetLocale = m_pCurrentLocaleItem->m_locale;
290 0 : return aRetLocale;
291 : }
292 :
293 0 : Locale StringResourceImpl::getDefaultLocale( )
294 : throw (RuntimeException, std::exception)
295 : {
296 0 : ::osl::MutexGuard aGuard( getMutex() );
297 :
298 0 : Locale aRetLocale;
299 0 : if( m_pDefaultLocaleItem != NULL )
300 0 : aRetLocale = m_pDefaultLocaleItem->m_locale;
301 0 : return aRetLocale;
302 : }
303 :
304 0 : Sequence< Locale > StringResourceImpl::getLocales( )
305 : throw (RuntimeException, std::exception)
306 : {
307 0 : ::osl::MutexGuard aGuard( getMutex() );
308 :
309 0 : sal_Int32 nSize = m_aLocaleItemVector.size();
310 0 : Sequence< Locale > aLocalSeq( nSize );
311 0 : Locale* pLocales = aLocalSeq.getArray();
312 0 : int iTarget = 0;
313 0 : for( LocaleItemVectorConstIt it = m_aLocaleItemVector.begin(); it != m_aLocaleItemVector.end(); ++it )
314 : {
315 0 : LocaleItem* pLocaleItem = *it;
316 0 : pLocales[iTarget] = pLocaleItem->m_locale;
317 0 : iTarget++;
318 : }
319 0 : return aLocalSeq;
320 : }
321 :
322 :
323 :
324 : // XStringResourceManager
325 :
326 0 : void StringResourceImpl::implCheckReadOnly( const sal_Char* pExceptionMsg )
327 : throw (NoSupportException)
328 : {
329 0 : if( m_bReadOnly )
330 : {
331 0 : OUString errorMsg = OUString::createFromAscii( pExceptionMsg );
332 0 : throw NoSupportException( errorMsg );
333 : }
334 0 : }
335 :
336 0 : sal_Bool StringResourceImpl::isReadOnly()
337 : throw (RuntimeException, std::exception)
338 : {
339 0 : return m_bReadOnly;
340 : }
341 :
342 0 : void StringResourceImpl::implSetCurrentLocale( const Locale& locale,
343 : bool FindClosestMatch, bool bUseDefaultIfNoMatch )
344 : throw (IllegalArgumentException, RuntimeException)
345 : {
346 0 : ::osl::MutexGuard aGuard( getMutex() );
347 :
348 0 : LocaleItem* pLocaleItem = NULL;
349 0 : if( FindClosestMatch )
350 0 : pLocaleItem = getClosestMatchItemForLocale( locale );
351 : else
352 0 : pLocaleItem = getItemForLocale( locale, true );
353 :
354 0 : if( pLocaleItem == NULL && bUseDefaultIfNoMatch )
355 0 : pLocaleItem = m_pDefaultLocaleItem;
356 :
357 0 : if( pLocaleItem != NULL )
358 : {
359 0 : (void)loadLocale( pLocaleItem );
360 0 : m_pCurrentLocaleItem = pLocaleItem;
361 :
362 : // Only notify without modifying
363 0 : implNotifyListeners();
364 0 : }
365 0 : }
366 :
367 0 : void StringResourceImpl::setCurrentLocale( const Locale& locale, sal_Bool FindClosestMatch )
368 : throw (IllegalArgumentException, RuntimeException, std::exception)
369 : {
370 0 : bool bUseDefaultIfNoMatch = false;
371 0 : implSetCurrentLocale( locale, FindClosestMatch, bUseDefaultIfNoMatch );
372 0 : }
373 :
374 0 : void StringResourceImpl::setDefaultLocale( const Locale& locale )
375 : throw (IllegalArgumentException, RuntimeException,NoSupportException, std::exception)
376 : {
377 0 : ::osl::MutexGuard aGuard( getMutex() );
378 0 : implCheckReadOnly( "StringResourceImpl::setDefaultLocale(): Read only" );
379 :
380 0 : LocaleItem* pLocaleItem = getItemForLocale( locale, true );
381 0 : if( pLocaleItem && pLocaleItem != m_pDefaultLocaleItem )
382 : {
383 0 : if( m_pDefaultLocaleItem )
384 : {
385 0 : LocaleItem* pChangedDefaultLocaleItem = new LocaleItem( m_pDefaultLocaleItem->m_locale );
386 0 : m_aChangedDefaultLocaleVector.push_back( pChangedDefaultLocaleItem );
387 : }
388 :
389 0 : m_pDefaultLocaleItem = pLocaleItem;
390 0 : m_bDefaultModified = true;
391 0 : implModified();
392 0 : }
393 0 : }
394 :
395 0 : void StringResourceImpl::implSetString( const OUString& ResourceID,
396 : const OUString& Str, LocaleItem* pLocaleItem )
397 : {
398 0 : if( pLocaleItem != NULL && loadLocale( pLocaleItem ) )
399 : {
400 0 : IdToStringMap& rHashMap = pLocaleItem->m_aIdToStringMap;
401 :
402 0 : IdToStringMap::iterator it = rHashMap.find( ResourceID );
403 0 : bool bNew = ( it == rHashMap.end() );
404 0 : if( bNew )
405 : {
406 0 : IdToIndexMap& rIndexMap = pLocaleItem->m_aIdToIndexMap;
407 0 : rIndexMap[ ResourceID ] = pLocaleItem->m_nNextIndex++;
408 0 : implScanIdForNumber( ResourceID );
409 : }
410 0 : rHashMap[ ResourceID ] = Str;
411 0 : pLocaleItem->m_bModified = true;
412 0 : implModified();
413 : }
414 0 : }
415 :
416 0 : void StringResourceImpl::setString( const OUString& ResourceID, const OUString& Str )
417 : throw (NoSupportException, RuntimeException, std::exception)
418 : {
419 0 : ::osl::MutexGuard aGuard( getMutex() );
420 0 : implCheckReadOnly( "StringResourceImpl::setString(): Read only" );
421 0 : implSetString( ResourceID, Str, m_pCurrentLocaleItem );
422 0 : }
423 :
424 0 : void StringResourceImpl::setStringForLocale
425 : ( const OUString& ResourceID, const OUString& Str, const Locale& locale )
426 : throw (NoSupportException, RuntimeException, std::exception)
427 : {
428 0 : ::osl::MutexGuard aGuard( getMutex() );
429 0 : implCheckReadOnly( "StringResourceImpl::setStringForLocale(): Read only" );
430 0 : LocaleItem* pLocaleItem = getItemForLocale( locale, false );
431 0 : implSetString( ResourceID, Str, pLocaleItem );
432 0 : }
433 :
434 0 : void StringResourceImpl::implRemoveId( const OUString& ResourceID, LocaleItem* pLocaleItem )
435 : throw (::com::sun::star::resource::MissingResourceException)
436 : {
437 0 : if( pLocaleItem != NULL && loadLocale( pLocaleItem ) )
438 : {
439 0 : IdToStringMap& rHashMap = pLocaleItem->m_aIdToStringMap;
440 0 : IdToStringMap::iterator it = rHashMap.find( ResourceID );
441 0 : if( it == rHashMap.end() )
442 : {
443 0 : OUString errorMsg("StringResourceImpl: No entries for ResourceID: ");
444 0 : errorMsg = errorMsg.concat( ResourceID );
445 0 : throw ::com::sun::star::resource::MissingResourceException( errorMsg );
446 : }
447 0 : rHashMap.erase( it );
448 0 : pLocaleItem->m_bModified = true;
449 0 : implModified();
450 : }
451 0 : }
452 :
453 0 : void StringResourceImpl::removeId( const OUString& ResourceID )
454 : throw (::com::sun::star::resource::MissingResourceException, RuntimeException, NoSupportException, std::exception)
455 : {
456 0 : ::osl::MutexGuard aGuard( getMutex() );
457 0 : implCheckReadOnly( "StringResourceImpl::removeId(): Read only" );
458 0 : implRemoveId( ResourceID, m_pCurrentLocaleItem );
459 0 : }
460 :
461 0 : void StringResourceImpl::removeIdForLocale( const OUString& ResourceID, const Locale& locale )
462 : throw (::com::sun::star::resource::MissingResourceException, RuntimeException, NoSupportException, std::exception)
463 : {
464 0 : ::osl::MutexGuard aGuard( getMutex() );
465 0 : implCheckReadOnly( "StringResourceImpl::removeIdForLocale(): Read only" );
466 0 : LocaleItem* pLocaleItem = getItemForLocale( locale, false );
467 0 : implRemoveId( ResourceID, pLocaleItem );
468 0 : }
469 :
470 0 : void StringResourceImpl::newLocale( const Locale& locale )
471 : throw (ElementExistException, IllegalArgumentException, RuntimeException, NoSupportException, std::exception)
472 : {
473 0 : ::osl::MutexGuard aGuard( getMutex() );
474 0 : implCheckReadOnly( "StringResourceImpl::newLocale(): Read only" );
475 :
476 0 : if( getItemForLocale( locale, false ) != NULL )
477 : {
478 0 : OUString errorMsg("StringResourceImpl: locale already exists");
479 0 : throw ElementExistException( errorMsg );
480 : }
481 :
482 : // TODO?: Check if locale is valid? How?
483 : //if (!bValid)
484 : //{
485 : // OUString errorMsg("StringResourceImpl: Invalid locale");
486 : // throw IllegalArgumentException( errorMsg, Reference< XInterface >(), 0 );
487 : //}
488 :
489 0 : LocaleItem* pLocaleItem = new LocaleItem( locale );
490 0 : m_aLocaleItemVector.push_back( pLocaleItem );
491 0 : pLocaleItem->m_bModified = true;
492 :
493 : // Copy strings from default locale
494 0 : LocaleItem* pCopyFromItem = m_pDefaultLocaleItem;
495 0 : if( pCopyFromItem == NULL )
496 0 : pCopyFromItem = m_pCurrentLocaleItem;
497 0 : if( pCopyFromItem != NULL && loadLocale( pCopyFromItem ) )
498 : {
499 0 : const IdToStringMap& rSourceMap = pCopyFromItem->m_aIdToStringMap;
500 0 : IdToStringMap& rTargetMap = pLocaleItem->m_aIdToStringMap;
501 0 : IdToStringMap::const_iterator it;
502 0 : for( it = rSourceMap.begin(); it != rSourceMap.end(); ++it )
503 : {
504 0 : OUString aId = (*it).first;
505 0 : OUString aStr = (*it).second;
506 0 : rTargetMap[ aId ] = aStr;
507 0 : }
508 :
509 0 : const IdToIndexMap& rSourceIndexMap = pCopyFromItem->m_aIdToIndexMap;
510 0 : IdToIndexMap& rTargetIndexMap = pLocaleItem->m_aIdToIndexMap;
511 0 : IdToIndexMap::const_iterator it_index;
512 0 : for( it_index = rSourceIndexMap.begin(); it_index != rSourceIndexMap.end(); ++it_index )
513 : {
514 0 : OUString aId = (*it_index).first;
515 0 : sal_Int32 nIndex = (*it_index).second;
516 0 : rTargetIndexMap[ aId ] = nIndex;
517 0 : }
518 0 : pLocaleItem->m_nNextIndex = pCopyFromItem->m_nNextIndex;
519 : }
520 :
521 0 : if( m_pCurrentLocaleItem == NULL )
522 0 : m_pCurrentLocaleItem = pLocaleItem;
523 :
524 0 : if( m_pDefaultLocaleItem == NULL )
525 : {
526 0 : m_pDefaultLocaleItem = pLocaleItem;
527 0 : m_bDefaultModified = true;
528 : }
529 :
530 0 : implModified();
531 0 : }
532 :
533 0 : void StringResourceImpl::removeLocale( const Locale& locale )
534 : throw (IllegalArgumentException, RuntimeException, NoSupportException, std::exception)
535 : {
536 0 : ::osl::MutexGuard aGuard( getMutex() );
537 0 : implCheckReadOnly( "StringResourceImpl::removeLocale(): Read only" );
538 :
539 0 : LocaleItem* pRemoveItem = getItemForLocale( locale, true );
540 0 : if( pRemoveItem )
541 : {
542 : // Last locale?
543 0 : sal_Int32 nLocaleCount = m_aLocaleItemVector.size();
544 0 : if( nLocaleCount > 1 )
545 : {
546 0 : if( m_pCurrentLocaleItem == pRemoveItem ||
547 0 : m_pDefaultLocaleItem == pRemoveItem )
548 : {
549 0 : LocaleItem* pFallbackItem = NULL;
550 0 : for( LocaleItemVectorIt it = m_aLocaleItemVector.begin(); it != m_aLocaleItemVector.end(); ++it )
551 : {
552 0 : LocaleItem* pLocaleItem = *it;
553 0 : if( pLocaleItem != pRemoveItem )
554 : {
555 0 : pFallbackItem = pLocaleItem;
556 0 : break;
557 : }
558 : }
559 0 : if( m_pCurrentLocaleItem == pRemoveItem )
560 : {
561 0 : bool FindClosestMatch = false;
562 0 : setCurrentLocale( pFallbackItem->m_locale, FindClosestMatch );
563 : }
564 0 : if( m_pDefaultLocaleItem == pRemoveItem )
565 : {
566 0 : setDefaultLocale( pFallbackItem->m_locale );
567 : }
568 : }
569 : }
570 0 : for( LocaleItemVectorIt it = m_aLocaleItemVector.begin(); it != m_aLocaleItemVector.end(); ++it )
571 : {
572 0 : LocaleItem* pLocaleItem = *it;
573 0 : if( pLocaleItem == pRemoveItem )
574 : {
575 : // Remember locale item to delete file while storing
576 0 : m_aDeletedLocaleItemVector.push_back( pLocaleItem );
577 :
578 : // Last locale?
579 0 : if( nLocaleCount == 1 )
580 : {
581 0 : m_nNextUniqueNumericId = 0;
582 0 : if( m_pDefaultLocaleItem )
583 : {
584 0 : LocaleItem* pChangedDefaultLocaleItem = new LocaleItem( m_pDefaultLocaleItem->m_locale );
585 0 : m_aChangedDefaultLocaleVector.push_back( pChangedDefaultLocaleItem );
586 : }
587 0 : m_pCurrentLocaleItem = NULL;
588 0 : m_pDefaultLocaleItem = NULL;
589 : }
590 :
591 0 : m_aLocaleItemVector.erase( it );
592 :
593 0 : implModified();
594 0 : break;
595 : }
596 : }
597 0 : }
598 0 : }
599 :
600 0 : void StringResourceImpl::implScanIdForNumber( const OUString& ResourceID )
601 : {
602 0 : const sal_Unicode* pSrc = ResourceID.getStr();
603 0 : sal_Int32 nLen = ResourceID.getLength();
604 :
605 0 : sal_Int32 nNumber = 0;
606 0 : for( sal_Int32 i = 0 ; i < nLen ; i++ )
607 : {
608 0 : sal_Unicode c = pSrc[i];
609 0 : if( c >= '0' && c <= '9' )
610 : {
611 0 : sal_uInt16 nDigitVal = c - '0';
612 0 : nNumber = 10*nNumber + nDigitVal;
613 : }
614 : else
615 : break;
616 : }
617 :
618 0 : if( m_nNextUniqueNumericId < nNumber + 1 )
619 0 : m_nNextUniqueNumericId = nNumber + 1;
620 0 : }
621 :
622 0 : sal_Int32 StringResourceImpl::getUniqueNumericId( )
623 : throw (RuntimeException, NoSupportException, std::exception)
624 : {
625 0 : if( m_nNextUniqueNumericId == UNIQUE_NUMBER_NEEDS_INITIALISATION )
626 : {
627 0 : implLoadAllLocales();
628 0 : m_nNextUniqueNumericId = 0;
629 : }
630 :
631 0 : if( m_nNextUniqueNumericId < UNIQUE_NUMBER_NEEDS_INITIALISATION )
632 : {
633 0 : OUString errorMsg("getUniqueNumericId: Extended sal_Int32 range");
634 0 : throw NoSupportException( errorMsg );
635 : }
636 0 : return m_nNextUniqueNumericId;
637 : }
638 :
639 :
640 :
641 : // Private helper methods
642 :
643 0 : LocaleItem* StringResourceImpl::getItemForLocale
644 : ( const Locale& locale, bool bException )
645 : throw (::com::sun::star::lang::IllegalArgumentException)
646 : {
647 0 : LocaleItem* pRetItem = NULL;
648 :
649 : // Search for locale
650 0 : for( LocaleItemVectorConstIt it = m_aLocaleItemVector.begin(); it != m_aLocaleItemVector.end(); ++it )
651 : {
652 0 : LocaleItem* pLocaleItem = *it;
653 0 : if( pLocaleItem )
654 : {
655 0 : Locale& cmp_locale = pLocaleItem->m_locale;
656 0 : if( cmp_locale.Language == locale.Language &&
657 0 : cmp_locale.Country == locale.Country &&
658 0 : cmp_locale.Variant == locale.Variant )
659 : {
660 0 : pRetItem = pLocaleItem;
661 0 : break;
662 : }
663 : }
664 : }
665 :
666 0 : if( pRetItem == NULL && bException )
667 : {
668 0 : OUString errorMsg("StringResourceImpl: Invalid locale");
669 0 : throw IllegalArgumentException( errorMsg, Reference< XInterface >(), 0 );
670 : }
671 0 : return pRetItem;
672 : }
673 :
674 : // Returns the LocaleItem for a given locale, if it exists, otherwise NULL.
675 : // This method performs a closest match search, at least the language must match.
676 0 : LocaleItem* StringResourceImpl::getClosestMatchItemForLocale( const Locale& locale )
677 : {
678 0 : LocaleItem* pRetItem = NULL;
679 :
680 0 : ::std::vector< Locale > aLocales( m_aLocaleItemVector.size());
681 0 : size_t i = 0;
682 0 : for( LocaleItemVectorConstIt it = m_aLocaleItemVector.begin(); it != m_aLocaleItemVector.end(); ++it, ++i )
683 : {
684 0 : LocaleItem* pLocaleItem = *it;
685 0 : aLocales[i] = (pLocaleItem ? pLocaleItem->m_locale : Locale());
686 : }
687 0 : ::std::vector< Locale >::const_iterator iFound( LanguageTag::getMatchingFallback( aLocales, locale));
688 0 : if (iFound != aLocales.end())
689 0 : pRetItem = *(m_aLocaleItemVector.begin() + (iFound - aLocales.begin()));
690 :
691 0 : return pRetItem;
692 : }
693 :
694 0 : void StringResourceImpl::implModified()
695 : {
696 0 : m_bModified = true;
697 0 : implNotifyListeners();
698 0 : }
699 :
700 0 : void StringResourceImpl::implNotifyListeners()
701 : {
702 0 : EventObject aEvent;
703 0 : aEvent.Source = static_cast< XInterface* >( static_cast<OWeakObject*>(this) );
704 :
705 0 : ::cppu::OInterfaceIteratorHelper it( m_aListenerContainer );
706 0 : while( it.hasMoreElements() )
707 : {
708 0 : Reference< XInterface > xIface = it.next();
709 0 : Reference< XModifyListener > xListener( xIface, UNO_QUERY );
710 : try
711 : {
712 0 : xListener->modified( aEvent );
713 : }
714 0 : catch(RuntimeException&)
715 : {
716 0 : it.remove();
717 : }
718 0 : }
719 0 : }
720 :
721 :
722 :
723 : // Loading
724 :
725 0 : bool StringResourceImpl::loadLocale( LocaleItem* pLocaleItem )
726 : {
727 : // Base implementation has nothing to load
728 : (void)pLocaleItem;
729 0 : return true;
730 : }
731 :
732 0 : void StringResourceImpl::implLoadAllLocales()
733 : {
734 : // Base implementation has nothing to load
735 0 : }
736 :
737 :
738 0 : Reference< XMultiComponentFactory > StringResourceImpl::getMultiComponentFactory()
739 : {
740 0 : ::osl::MutexGuard aGuard( getMutex() );
741 :
742 0 : if( !m_xMCF.is() )
743 : {
744 0 : Reference< XMultiComponentFactory > xSMgr( m_xContext->getServiceManager(), UNO_QUERY );
745 0 : if( !xSMgr.is() )
746 : {
747 : throw RuntimeException(
748 0 : "StringResourceImpl::getMultiComponentFactory: Couldn't instantiate MultiComponentFactory" );
749 : }
750 0 : m_xMCF = xSMgr;
751 : }
752 0 : return m_xMCF;
753 : }
754 :
755 :
756 :
757 : // StringResourcePersistenceImpl
758 :
759 :
760 1 : StringResourcePersistenceImpl::StringResourcePersistenceImpl( const Reference< XComponentContext >& rxContext )
761 1 : : StringResourcePersistenceImpl_BASE( rxContext )
762 : {
763 1 : }
764 :
765 :
766 :
767 2 : StringResourcePersistenceImpl::~StringResourcePersistenceImpl()
768 : {
769 2 : }
770 :
771 :
772 : // XServiceInfo
773 :
774 :
775 1 : OUString StringResourcePersistenceImpl::getImplementationName( )
776 : throw (RuntimeException, std::exception)
777 : {
778 1 : return OUString( "com.sun.star.comp.scripting.StringResource");
779 : }
780 :
781 :
782 :
783 0 : sal_Bool StringResourcePersistenceImpl::supportsService( const OUString& rServiceName )
784 : throw (RuntimeException, std::exception)
785 : {
786 0 : return cppu::supportsService( this, rServiceName );
787 : }
788 :
789 :
790 :
791 1 : Sequence< OUString > StringResourcePersistenceImpl::getSupportedServiceNames( )
792 : throw (RuntimeException, std::exception)
793 : {
794 1 : return StringResourceImpl::getSupportedServiceNames();
795 : }
796 :
797 :
798 : // XInitialization base functionality for derived classes
799 :
800 :
801 : static const char aNameBaseDefaultStr[] = "strings";
802 :
803 0 : void StringResourcePersistenceImpl::implInitializeCommonParameters
804 : ( const Sequence< Any >& aArguments )
805 : throw (Exception, RuntimeException)
806 : {
807 0 : bool bReadOnlyOk = (aArguments[1] >>= m_bReadOnly);
808 0 : if( !bReadOnlyOk )
809 : {
810 0 : OUString errorMsg("XInitialization::initialize: Expected ReadOnly flag");
811 0 : throw IllegalArgumentException( errorMsg, Reference< XInterface >(), 1 );
812 : }
813 :
814 0 : com::sun::star::lang::Locale aCurrentLocale;
815 0 : bool bLocaleOk = (aArguments[2] >>= aCurrentLocale);
816 0 : if( !bLocaleOk )
817 : {
818 0 : OUString errorMsg("XInitialization::initialize: Expected Locale");
819 0 : throw IllegalArgumentException( errorMsg, Reference< XInterface >(), 2 );
820 : }
821 :
822 0 : bool bNameBaseOk = (aArguments[3] >>= m_aNameBase);
823 0 : if( !bNameBaseOk )
824 : {
825 0 : OUString errorMsg("XInitialization::initialize: Expected NameBase string");
826 0 : throw IllegalArgumentException( errorMsg, Reference< XInterface >(), 3 );
827 : }
828 0 : if( m_aNameBase.isEmpty() )
829 0 : m_aNameBase = aNameBaseDefaultStr;
830 :
831 0 : bool bCommentOk = (aArguments[4] >>= m_aComment);
832 0 : if( !bCommentOk )
833 : {
834 0 : OUString errorMsg("XInitialization::initialize: Expected Comment string");
835 0 : throw IllegalArgumentException( errorMsg, Reference< XInterface >(), 4 );
836 : }
837 :
838 0 : implScanLocales();
839 :
840 0 : bool FindClosestMatch = true;
841 0 : bool bUseDefaultIfNoMatch = true;
842 0 : implSetCurrentLocale( aCurrentLocale, FindClosestMatch, bUseDefaultIfNoMatch );
843 0 : }
844 :
845 :
846 : // Forwarding calls to base class
847 :
848 : // XModifyBroadcaster
849 0 : void StringResourcePersistenceImpl::addModifyListener( const Reference< XModifyListener >& aListener )
850 : throw (RuntimeException, std::exception)
851 : {
852 0 : StringResourceImpl::addModifyListener( aListener );
853 0 : }
854 0 : void StringResourcePersistenceImpl::removeModifyListener( const Reference< XModifyListener >& aListener )
855 : throw (RuntimeException, std::exception)
856 : {
857 0 : StringResourceImpl::removeModifyListener( aListener );
858 0 : }
859 :
860 : // XStringResourceResolver
861 0 : OUString StringResourcePersistenceImpl::resolveString( const OUString& ResourceID )
862 : throw (::com::sun::star::resource::MissingResourceException, RuntimeException, std::exception)
863 : {
864 0 : return StringResourceImpl::resolveString( ResourceID ) ;
865 : }
866 0 : OUString StringResourcePersistenceImpl::resolveStringForLocale( const OUString& ResourceID, const Locale& locale )
867 : throw ( ::com::sun::star::resource::MissingResourceException, RuntimeException, std::exception)
868 : {
869 0 : return StringResourceImpl::resolveStringForLocale( ResourceID, locale );
870 : }
871 0 : sal_Bool StringResourcePersistenceImpl::hasEntryForId( const OUString& ResourceID )
872 : throw (RuntimeException, std::exception)
873 : {
874 0 : return StringResourceImpl::hasEntryForId( ResourceID ) ;
875 : }
876 0 : sal_Bool StringResourcePersistenceImpl::hasEntryForIdAndLocale( const OUString& ResourceID,
877 : const Locale& locale )
878 : throw (RuntimeException, std::exception)
879 : {
880 0 : return StringResourceImpl::hasEntryForIdAndLocale( ResourceID, locale );
881 : }
882 0 : Locale StringResourcePersistenceImpl::getCurrentLocale()
883 : throw (RuntimeException, std::exception)
884 : {
885 0 : return StringResourceImpl::getCurrentLocale();
886 : }
887 0 : Locale StringResourcePersistenceImpl::getDefaultLocale( )
888 : throw (RuntimeException, std::exception)
889 : {
890 0 : return StringResourceImpl::getDefaultLocale();
891 : }
892 0 : Sequence< Locale > StringResourcePersistenceImpl::getLocales( )
893 : throw (RuntimeException, std::exception)
894 : {
895 0 : return StringResourceImpl::getLocales();
896 : }
897 :
898 : // XStringResourceManager
899 0 : sal_Bool StringResourcePersistenceImpl::isReadOnly()
900 : throw (RuntimeException, std::exception)
901 : {
902 0 : return StringResourceImpl::isReadOnly();
903 : }
904 0 : void StringResourcePersistenceImpl::setCurrentLocale( const Locale& locale, sal_Bool FindClosestMatch )
905 : throw (IllegalArgumentException, RuntimeException, std::exception)
906 : {
907 0 : StringResourceImpl::setCurrentLocale( locale, FindClosestMatch );
908 0 : }
909 0 : void StringResourcePersistenceImpl::setDefaultLocale( const Locale& locale )
910 : throw (IllegalArgumentException, RuntimeException,NoSupportException, std::exception)
911 : {
912 0 : StringResourceImpl::setDefaultLocale( locale );
913 0 : }
914 0 : Sequence< OUString > StringResourcePersistenceImpl::getResourceIDs( )
915 : throw (RuntimeException, std::exception)
916 : {
917 0 : return StringResourceImpl::getResourceIDs();
918 : }
919 0 : void StringResourcePersistenceImpl::setString( const OUString& ResourceID, const OUString& Str )
920 : throw (NoSupportException, RuntimeException, std::exception)
921 : {
922 0 : StringResourceImpl::setString( ResourceID, Str );
923 0 : }
924 0 : void StringResourcePersistenceImpl::setStringForLocale
925 : ( const OUString& ResourceID, const OUString& Str, const Locale& locale )
926 : throw (NoSupportException, RuntimeException, std::exception)
927 : {
928 0 : StringResourceImpl::setStringForLocale( ResourceID, Str, locale );
929 0 : }
930 0 : Sequence< OUString > StringResourcePersistenceImpl::getResourceIDsForLocale
931 : ( const Locale& locale ) throw (::com::sun::star::uno::RuntimeException, std::exception)
932 : {
933 0 : return StringResourceImpl::getResourceIDsForLocale( locale );
934 : }
935 0 : void StringResourcePersistenceImpl::removeId( const OUString& ResourceID )
936 : throw (::com::sun::star::resource::MissingResourceException, RuntimeException, NoSupportException, std::exception)
937 : {
938 0 : StringResourceImpl::removeId( ResourceID );
939 0 : }
940 0 : void StringResourcePersistenceImpl::removeIdForLocale( const OUString& ResourceID, const Locale& locale )
941 : throw (::com::sun::star::resource::MissingResourceException, RuntimeException, NoSupportException, std::exception)
942 : {
943 0 : StringResourceImpl::removeIdForLocale( ResourceID, locale );
944 0 : }
945 0 : void StringResourcePersistenceImpl::newLocale( const Locale& locale )
946 : throw (ElementExistException, IllegalArgumentException, RuntimeException, NoSupportException, std::exception)
947 : {
948 0 : StringResourceImpl::newLocale( locale );
949 0 : }
950 0 : void StringResourcePersistenceImpl::removeLocale( const Locale& locale )
951 : throw (IllegalArgumentException, RuntimeException, NoSupportException, std::exception)
952 : {
953 0 : StringResourceImpl::removeLocale( locale );
954 0 : }
955 0 : sal_Int32 StringResourcePersistenceImpl::getUniqueNumericId( )
956 : throw (RuntimeException, NoSupportException, std::exception)
957 : {
958 0 : return StringResourceImpl::getUniqueNumericId();
959 : }
960 :
961 :
962 : // XStringResourcePersistence
963 :
964 0 : void StringResourcePersistenceImpl::store()
965 : throw (NoSupportException, Exception, RuntimeException, std::exception)
966 : {
967 0 : }
968 :
969 0 : sal_Bool StringResourcePersistenceImpl::isModified( )
970 : throw (RuntimeException, std::exception)
971 : {
972 0 : ::osl::MutexGuard aGuard( getMutex() );
973 :
974 0 : return m_bModified;
975 : }
976 :
977 0 : void StringResourcePersistenceImpl::setComment( const OUString& Comment )
978 : throw (::com::sun::star::uno::RuntimeException, std::exception)
979 : {
980 0 : m_aComment = Comment;
981 0 : }
982 :
983 0 : void StringResourcePersistenceImpl::storeToStorage( const Reference< XStorage >& Storage,
984 : const OUString& NameBase, const OUString& Comment )
985 : throw (Exception, RuntimeException, std::exception)
986 : {
987 0 : ::osl::MutexGuard aGuard( getMutex() );
988 :
989 0 : bool bUsedForStore = false;
990 0 : bool bStoreAll = true;
991 0 : implStoreAtStorage( NameBase, Comment, Storage, bUsedForStore, bStoreAll );
992 0 : }
993 :
994 0 : void StringResourcePersistenceImpl::implStoreAtStorage
995 : (
996 : const OUString& aNameBase,
997 : const OUString& aComment,
998 : const Reference< ::com::sun::star::embed::XStorage >& Storage,
999 : bool bUsedForStore,
1000 : bool bStoreAll
1001 : )
1002 : throw (Exception, RuntimeException)
1003 : {
1004 : // Delete files for deleted locales
1005 0 : if( bUsedForStore )
1006 : {
1007 0 : while( m_aDeletedLocaleItemVector.size() > 0 )
1008 : {
1009 0 : LocaleItemVectorIt it = m_aDeletedLocaleItemVector.begin();
1010 0 : LocaleItem* pLocaleItem = *it;
1011 0 : if( pLocaleItem != NULL )
1012 : {
1013 0 : OUString aStreamName = implGetFileNameForLocaleItem( pLocaleItem, m_aNameBase );
1014 0 : aStreamName += ".properties";
1015 :
1016 : try
1017 : {
1018 0 : Storage->removeElement( aStreamName );
1019 : }
1020 0 : catch( Exception& )
1021 : {}
1022 :
1023 0 : m_aDeletedLocaleItemVector.erase( it );
1024 0 : delete pLocaleItem;
1025 : }
1026 : }
1027 : }
1028 :
1029 0 : for( LocaleItemVectorConstIt it = m_aLocaleItemVector.begin(); it != m_aLocaleItemVector.end(); ++it )
1030 : {
1031 0 : LocaleItem* pLocaleItem = *it;
1032 0 : if( pLocaleItem != NULL && (bStoreAll || pLocaleItem->m_bModified) &&
1033 0 : loadLocale( pLocaleItem ) )
1034 : {
1035 0 : OUString aStreamName = implGetFileNameForLocaleItem( pLocaleItem, aNameBase );
1036 0 : aStreamName += ".properties";
1037 :
1038 : Reference< io::XStream > xElementStream =
1039 0 : Storage->openStreamElement( aStreamName, ElementModes::READWRITE );
1040 :
1041 0 : OUString aPropName("MediaType");
1042 0 : OUString aMime("text/plain");
1043 :
1044 0 : uno::Reference< beans::XPropertySet > xProps( xElementStream, uno::UNO_QUERY );
1045 : OSL_ENSURE( xProps.is(), "The StorageStream must implement XPropertySet interface!\n" );
1046 0 : if ( xProps.is() )
1047 : {
1048 0 : xProps->setPropertyValue( aPropName, uno::makeAny( aMime ) );
1049 :
1050 0 : aPropName = "UseCommonStoragePasswordEncryption";
1051 0 : xProps->setPropertyValue( aPropName, uno::makeAny( sal_True ) );
1052 : }
1053 :
1054 0 : Reference< io::XOutputStream > xOutputStream = xElementStream->getOutputStream();
1055 0 : if( xOutputStream.is() )
1056 0 : implWritePropertiesFile( pLocaleItem, xOutputStream, aComment );
1057 0 : xOutputStream->closeOutput();
1058 :
1059 0 : if( bUsedForStore )
1060 0 : pLocaleItem->m_bModified = false;
1061 : }
1062 : }
1063 :
1064 : // Delete files for changed defaults
1065 0 : if( bUsedForStore )
1066 : {
1067 0 : for( LocaleItemVectorIt it = m_aChangedDefaultLocaleVector.begin();
1068 0 : it != m_aChangedDefaultLocaleVector.end(); ++it )
1069 : {
1070 0 : LocaleItem* pLocaleItem = *it;
1071 0 : if( pLocaleItem != NULL )
1072 : {
1073 0 : OUString aStreamName = implGetFileNameForLocaleItem( pLocaleItem, m_aNameBase );
1074 0 : aStreamName += ".default";
1075 :
1076 : try
1077 : {
1078 0 : Storage->removeElement( aStreamName );
1079 : }
1080 0 : catch( Exception& )
1081 : {}
1082 :
1083 0 : delete pLocaleItem;
1084 : }
1085 : }
1086 0 : m_aChangedDefaultLocaleVector.clear();
1087 : }
1088 :
1089 : // Default locale
1090 0 : if( m_pDefaultLocaleItem != NULL && (bStoreAll || m_bDefaultModified) )
1091 : {
1092 0 : OUString aStreamName = implGetFileNameForLocaleItem( m_pDefaultLocaleItem, aNameBase );
1093 0 : aStreamName += ".default";
1094 :
1095 : Reference< io::XStream > xElementStream =
1096 0 : Storage->openStreamElement( aStreamName, ElementModes::READWRITE );
1097 :
1098 : // Only create stream without content
1099 0 : Reference< io::XOutputStream > xOutputStream = xElementStream->getOutputStream();
1100 0 : xOutputStream->closeOutput();
1101 :
1102 0 : if( bUsedForStore )
1103 0 : m_bDefaultModified = false;
1104 : }
1105 0 : }
1106 :
1107 0 : void StringResourcePersistenceImpl::storeToURL( const OUString& URL,
1108 : const OUString& NameBase, const OUString& Comment,
1109 : const Reference< ::com::sun::star::task::XInteractionHandler >& Handler )
1110 : throw (Exception, RuntimeException, std::exception)
1111 : {
1112 0 : ::osl::MutexGuard aGuard( getMutex() );
1113 :
1114 0 : bool bUsedForStore = false;
1115 0 : bool bStoreAll = true;
1116 :
1117 0 : Reference< ucb::XSimpleFileAccess3 > xFileAccess = ucb::SimpleFileAccess::create(m_xContext);
1118 0 : if( xFileAccess.is() && Handler.is() )
1119 0 : xFileAccess->setInteractionHandler( Handler );
1120 :
1121 0 : implStoreAtLocation( URL, NameBase, Comment, xFileAccess, bUsedForStore, bStoreAll );
1122 0 : }
1123 :
1124 0 : void StringResourcePersistenceImpl::implKillRemovedLocaleFiles
1125 : (
1126 : const OUString& Location,
1127 : const OUString& aNameBase,
1128 : const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XSimpleFileAccess3 >& xFileAccess
1129 : )
1130 : throw (Exception, RuntimeException)
1131 : {
1132 : // Delete files for deleted locales
1133 0 : while( m_aDeletedLocaleItemVector.size() > 0 )
1134 : {
1135 0 : LocaleItemVectorIt it = m_aDeletedLocaleItemVector.begin();
1136 0 : LocaleItem* pLocaleItem = *it;
1137 0 : if( pLocaleItem != NULL )
1138 : {
1139 : OUString aCompleteFileName =
1140 0 : implGetPathForLocaleItem( pLocaleItem, aNameBase, Location );
1141 0 : if( xFileAccess->exists( aCompleteFileName ) )
1142 0 : xFileAccess->kill( aCompleteFileName );
1143 :
1144 0 : m_aDeletedLocaleItemVector.erase( it );
1145 0 : delete pLocaleItem;
1146 : }
1147 : }
1148 0 : }
1149 :
1150 0 : void StringResourcePersistenceImpl::implKillChangedDefaultFiles
1151 : (
1152 : const OUString& Location,
1153 : const OUString& aNameBase,
1154 : const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XSimpleFileAccess3 >& xFileAccess
1155 : )
1156 : throw (Exception, RuntimeException)
1157 : {
1158 : // Delete files for changed defaults
1159 0 : for( LocaleItemVectorIt it = m_aChangedDefaultLocaleVector.begin();
1160 0 : it != m_aChangedDefaultLocaleVector.end(); ++it )
1161 : {
1162 0 : LocaleItem* pLocaleItem = *it;
1163 0 : if( pLocaleItem != NULL )
1164 : {
1165 : OUString aCompleteFileName =
1166 0 : implGetPathForLocaleItem( pLocaleItem, aNameBase, Location, true );
1167 0 : if( xFileAccess->exists( aCompleteFileName ) )
1168 0 : xFileAccess->kill( aCompleteFileName );
1169 :
1170 0 : delete pLocaleItem;
1171 : }
1172 : }
1173 0 : m_aChangedDefaultLocaleVector.clear();
1174 0 : }
1175 :
1176 0 : void StringResourcePersistenceImpl::implStoreAtLocation
1177 : (
1178 : const OUString& Location,
1179 : const OUString& aNameBase,
1180 : const OUString& aComment,
1181 : const Reference< ucb::XSimpleFileAccess3 >& xFileAccess,
1182 : bool bUsedForStore,
1183 : bool bStoreAll,
1184 : bool bKillAll
1185 : )
1186 : throw (Exception, RuntimeException)
1187 : {
1188 : // Delete files for deleted locales
1189 0 : if( bUsedForStore || bKillAll )
1190 0 : implKillRemovedLocaleFiles( Location, aNameBase, xFileAccess );
1191 :
1192 0 : for( LocaleItemVectorConstIt it = m_aLocaleItemVector.begin(); it != m_aLocaleItemVector.end(); ++it )
1193 : {
1194 0 : LocaleItem* pLocaleItem = *it;
1195 0 : if( pLocaleItem != NULL && (bStoreAll || bKillAll || pLocaleItem->m_bModified) &&
1196 0 : loadLocale( pLocaleItem ) )
1197 : {
1198 : OUString aCompleteFileName =
1199 0 : implGetPathForLocaleItem( pLocaleItem, aNameBase, Location );
1200 0 : if( xFileAccess->exists( aCompleteFileName ) )
1201 0 : xFileAccess->kill( aCompleteFileName );
1202 :
1203 0 : if( !bKillAll )
1204 : {
1205 : // Create Output stream
1206 0 : Reference< io::XOutputStream > xOutputStream = xFileAccess->openFileWrite( aCompleteFileName );
1207 0 : if( xOutputStream.is() )
1208 : {
1209 0 : implWritePropertiesFile( pLocaleItem, xOutputStream, aComment );
1210 0 : xOutputStream->closeOutput();
1211 : }
1212 0 : if( bUsedForStore )
1213 0 : pLocaleItem->m_bModified = false;
1214 0 : }
1215 : }
1216 : }
1217 :
1218 : // Delete files for changed defaults
1219 0 : if( bUsedForStore || bKillAll )
1220 0 : implKillChangedDefaultFiles( Location, aNameBase, xFileAccess );
1221 :
1222 : // Default locale
1223 0 : if( m_pDefaultLocaleItem != NULL && (bStoreAll || bKillAll || m_bDefaultModified) )
1224 : {
1225 : OUString aCompleteFileName =
1226 0 : implGetPathForLocaleItem( m_pDefaultLocaleItem, aNameBase, Location, true );
1227 0 : if( xFileAccess->exists( aCompleteFileName ) )
1228 0 : xFileAccess->kill( aCompleteFileName );
1229 :
1230 0 : if( !bKillAll )
1231 : {
1232 : // Create Output stream
1233 0 : Reference< io::XOutputStream > xOutputStream = xFileAccess->openFileWrite( aCompleteFileName );
1234 0 : if( xOutputStream.is() )
1235 0 : xOutputStream->closeOutput();
1236 :
1237 0 : if( bUsedForStore )
1238 0 : m_bDefaultModified = false;
1239 0 : }
1240 : }
1241 0 : }
1242 :
1243 :
1244 :
1245 : // BinaryOutput, helper class for exportBinary
1246 :
1247 0 : class BinaryOutput
1248 : {
1249 : Reference< XMultiComponentFactory > m_xMCF;
1250 : Reference< XComponentContext > m_xContext;
1251 : Reference< XInterface > m_xTempFile;
1252 : Reference< io::XOutputStream > m_xOutputStream;
1253 :
1254 : public:
1255 : BinaryOutput( Reference< XMultiComponentFactory > xMCF,
1256 : Reference< XComponentContext > xContext );
1257 :
1258 0 : Reference< io::XOutputStream > getOutputStream() const
1259 0 : { return m_xOutputStream; }
1260 :
1261 : Sequence< ::sal_Int8 > closeAndGetData();
1262 :
1263 : // Template to be used with sal_Int16 and sal_Unicode
1264 : template< class T >
1265 : void write16BitInt( T n );
1266 0 : void writeInt16( sal_Int16 n )
1267 0 : { write16BitInt( n ); }
1268 0 : void writeUnicodeChar( sal_Unicode n )
1269 0 : { write16BitInt( n ); }
1270 : void writeInt32( sal_Int32 n );
1271 : void writeString( const OUString& aStr );
1272 : };
1273 :
1274 0 : BinaryOutput::BinaryOutput( Reference< XMultiComponentFactory > xMCF,
1275 : Reference< XComponentContext > xContext )
1276 : : m_xMCF( xMCF )
1277 0 : , m_xContext( xContext )
1278 : {
1279 0 : m_xTempFile = io::TempFile::create( m_xContext );
1280 0 : m_xOutputStream = Reference< io::XOutputStream >( m_xTempFile, UNO_QUERY_THROW );
1281 0 : }
1282 :
1283 : template< class T >
1284 0 : void BinaryOutput::write16BitInt( T n )
1285 : {
1286 0 : if( !m_xOutputStream.is() )
1287 0 : return;
1288 :
1289 0 : Sequence< sal_Int8 > aSeq( 2 );
1290 0 : sal_Int8* p = aSeq.getArray();
1291 :
1292 0 : sal_Int8 nLow = sal_Int8( n & 0xff );
1293 0 : sal_Int8 nHigh = sal_Int8( n >> 8 );
1294 :
1295 0 : p[0] = nLow;
1296 0 : p[1] = nHigh;
1297 0 : m_xOutputStream->writeBytes( aSeq );
1298 : }
1299 :
1300 0 : void BinaryOutput::writeInt32( sal_Int32 n )
1301 : {
1302 0 : if( !m_xOutputStream.is() )
1303 0 : return;
1304 :
1305 0 : Sequence< sal_Int8 > aSeq( 4 );
1306 0 : sal_Int8* p = aSeq.getArray();
1307 :
1308 0 : for( sal_Int16 i = 0 ; i < 4 ; i++ )
1309 : {
1310 0 : p[i] = sal_Int8( n & 0xff );
1311 0 : n >>= 8;
1312 : }
1313 0 : m_xOutputStream->writeBytes( aSeq );
1314 : }
1315 :
1316 0 : void BinaryOutput::writeString( const OUString& aStr )
1317 : {
1318 0 : sal_Int32 nLen = aStr.getLength();
1319 0 : const sal_Unicode* pStr = aStr.getStr();
1320 :
1321 0 : for( sal_Int32 i = 0 ; i < nLen ; i++ )
1322 0 : writeUnicodeChar( pStr[i] );
1323 :
1324 0 : writeUnicodeChar( 0 );
1325 0 : }
1326 :
1327 0 : Sequence< ::sal_Int8 > BinaryOutput::closeAndGetData()
1328 : {
1329 0 : Sequence< ::sal_Int8 > aRetSeq;
1330 0 : if( !m_xOutputStream.is() )
1331 0 : return aRetSeq;
1332 :
1333 0 : m_xOutputStream->closeOutput();
1334 :
1335 0 : Reference< io::XSeekable> xSeekable( m_xTempFile, UNO_QUERY );
1336 0 : if( !xSeekable.is() )
1337 0 : return aRetSeq;
1338 :
1339 0 : sal_Int32 nSize = (sal_Int32)xSeekable->getPosition();
1340 :
1341 0 : Reference< io::XInputStream> xInputStream( m_xTempFile, UNO_QUERY );
1342 0 : if( !xInputStream.is() )
1343 0 : return aRetSeq;
1344 :
1345 0 : xSeekable->seek( 0 );
1346 0 : sal_Int32 nRead = xInputStream->readBytes( aRetSeq, nSize );
1347 : (void)nRead;
1348 : OSL_ENSURE( nRead == nSize, "BinaryOutput::closeAndGetData: nRead != nSize" );
1349 :
1350 0 : return aRetSeq;
1351 : }
1352 :
1353 :
1354 : // Binary format:
1355 :
1356 : // Header
1357 : // Byte Content
1358 : // 0 + 1 sal_Int16: Version, currently 0, low byte first
1359 : // 2 + 3 sal_Int16: Locale count = n, low byte first
1360 : // 4 + 5 sal_Int16: Default Locale position in Locale list, == n if none
1361 : // 6 - 7 sal_Int32: Start index locale block 0, lowest byte first
1362 : // (n-1) * sal_Int32: Start index locale block 1 to n, lowest byte first
1363 : // 6 + 4*n sal_Int32: "Start index" non existing locale block n+1,
1364 : // marks the first invalid index, kind of EOF
1365 :
1366 : // Locale block
1367 : // All strings are stored as 2-Byte-0 terminated sequence
1368 : // of 16 bit Unicode characters, each with low byte first
1369 : // Empty strings only contain the 2-Byte-0
1370 :
1371 : // Members of com.sun.star.lang.Locale
1372 : // with l1 = Locale.Language.getLength()
1373 : // with l2 = Locale.Country.getLength()
1374 : // with l3 = Locale.Variant.getLength()
1375 : // pos0 = 0 Locale.Language
1376 : // pos1 = 2 * (l1 + 1) Locale.Country
1377 : // pos2 = pos1 + 2 * (l2 + 1) Locale.Variant
1378 : // pos3 = pos2 + 2 * (l3 + 1)
1379 : // pos3 Properties file written by implWritePropertiesFile
1380 :
1381 0 : Sequence< sal_Int8 > StringResourcePersistenceImpl::exportBinary( )
1382 : throw (RuntimeException, std::exception)
1383 : {
1384 0 : Reference< XMultiComponentFactory > xMCF = getMultiComponentFactory();
1385 0 : BinaryOutput aOut( xMCF, m_xContext );
1386 :
1387 0 : sal_Int32 nLocaleCount = m_aLocaleItemVector.size();
1388 0 : Sequence< sal_Int8 >* pLocaleDataSeq = new Sequence< sal_Int8 >[ nLocaleCount ];
1389 :
1390 0 : sal_Int32 iLocale = 0;
1391 0 : sal_Int32 iDefault = 0;
1392 0 : for( LocaleItemVectorConstIt it = m_aLocaleItemVector.begin();
1393 0 : it != m_aLocaleItemVector.end(); ++it,++iLocale )
1394 : {
1395 0 : LocaleItem* pLocaleItem = *it;
1396 0 : if( pLocaleItem != NULL && loadLocale( pLocaleItem ) )
1397 : {
1398 0 : if( m_pDefaultLocaleItem == pLocaleItem )
1399 0 : iDefault = iLocale;
1400 :
1401 0 : BinaryOutput aLocaleOut( m_xMCF, m_xContext );
1402 0 : implWriteLocaleBinary( pLocaleItem, aLocaleOut );
1403 :
1404 0 : pLocaleDataSeq[iLocale] = aLocaleOut.closeAndGetData();
1405 : }
1406 : }
1407 :
1408 : // Write header
1409 0 : sal_Int16 nVersion = 0;
1410 0 : sal_Int16 nLocaleCount16 = (sal_Int16)nLocaleCount;
1411 0 : sal_Int16 iDefault16 = (sal_Int16)iDefault;
1412 0 : aOut.writeInt16( nVersion );
1413 0 : aOut.writeInt16( nLocaleCount16 );
1414 0 : aOut.writeInt16( iDefault16 );
1415 :
1416 : // Write data positions
1417 0 : sal_Int32 nDataPos = 6 + 4 * (nLocaleCount + 1);
1418 0 : for( iLocale = 0; iLocale < nLocaleCount; iLocale++ )
1419 : {
1420 0 : aOut.writeInt32( nDataPos );
1421 :
1422 0 : Sequence< sal_Int8 >& rSeq = pLocaleDataSeq[iLocale];
1423 0 : sal_Int32 nSeqLen = rSeq.getLength();
1424 0 : nDataPos += nSeqLen;
1425 : }
1426 : // Write final position
1427 0 : aOut.writeInt32( nDataPos );
1428 :
1429 : // Write data
1430 0 : Reference< io::XOutputStream > xOutputStream = aOut.getOutputStream();
1431 0 : if( xOutputStream.is() )
1432 : {
1433 0 : for( iLocale = 0; iLocale < nLocaleCount; iLocale++ )
1434 : {
1435 0 : Sequence< sal_Int8 >& rSeq = pLocaleDataSeq[iLocale];
1436 0 : xOutputStream->writeBytes( rSeq );
1437 : }
1438 : }
1439 :
1440 0 : delete[] pLocaleDataSeq;
1441 :
1442 0 : Sequence< sal_Int8 > aRetSeq = aOut.closeAndGetData();
1443 0 : return aRetSeq;
1444 : }
1445 :
1446 0 : void StringResourcePersistenceImpl::implWriteLocaleBinary
1447 : ( LocaleItem* pLocaleItem, BinaryOutput& rOut )
1448 : {
1449 0 : Reference< io::XOutputStream > xOutputStream = rOut.getOutputStream();
1450 0 : if( !xOutputStream.is() )
1451 0 : return;
1452 :
1453 0 : Locale& rLocale = pLocaleItem->m_locale;
1454 0 : rOut.writeString( rLocale.Language );
1455 0 : rOut.writeString( rLocale.Country );
1456 0 : rOut.writeString( rLocale.Variant );
1457 0 : implWritePropertiesFile( pLocaleItem, xOutputStream, m_aComment );
1458 : }
1459 :
1460 :
1461 : // BinaryOutput, helper class for exportBinary
1462 :
1463 0 : class BinaryInput
1464 : {
1465 : Sequence< sal_Int8 > m_aData;
1466 : Reference< XMultiComponentFactory > m_xMCF;
1467 : Reference< XComponentContext > m_xContext;
1468 :
1469 : const sal_Int8* m_pData;
1470 : sal_Int32 m_nCurPos;
1471 : sal_Int32 m_nSize;
1472 :
1473 : public:
1474 : BinaryInput( const Sequence< ::sal_Int8 >& aData, Reference< XMultiComponentFactory > xMCF,
1475 : Reference< XComponentContext > xContext );
1476 :
1477 : Reference< io::XInputStream > getInputStreamForSection( sal_Int32 nSize );
1478 :
1479 : void seek( sal_Int32 nPos );
1480 0 : sal_Int32 getPosition() const
1481 0 : { return m_nCurPos; }
1482 :
1483 : sal_Int16 readInt16();
1484 : sal_Int32 readInt32();
1485 : sal_Unicode readUnicodeChar();
1486 : OUString readString();
1487 : };
1488 :
1489 0 : BinaryInput::BinaryInput( const Sequence< ::sal_Int8 >& aData, Reference< XMultiComponentFactory > xMCF,
1490 : Reference< XComponentContext > xContext )
1491 : : m_aData( aData )
1492 : , m_xMCF( xMCF )
1493 0 : , m_xContext( xContext )
1494 : {
1495 0 : m_pData = m_aData.getConstArray();
1496 0 : m_nCurPos = 0;
1497 0 : m_nSize = m_aData.getLength();
1498 0 : }
1499 :
1500 0 : Reference< io::XInputStream > BinaryInput::getInputStreamForSection( sal_Int32 nSize )
1501 : {
1502 0 : Reference< io::XInputStream > xIn;
1503 0 : if( m_nCurPos + nSize <= m_nSize )
1504 : {
1505 0 : Reference< io::XOutputStream > xTempOut( io::TempFile::create(m_xContext), UNO_QUERY_THROW );
1506 0 : Sequence< sal_Int8 > aSection( m_pData + m_nCurPos, nSize );
1507 0 : xTempOut->writeBytes( aSection );
1508 :
1509 0 : Reference< io::XSeekable> xSeekable( xTempOut, UNO_QUERY );
1510 0 : if( xSeekable.is() )
1511 0 : xSeekable->seek( 0 );
1512 :
1513 0 : xIn = Reference< io::XInputStream>( xTempOut, UNO_QUERY );
1514 : }
1515 : else
1516 : OSL_FAIL( "BinaryInput::getInputStreamForSection(): Read past end" );
1517 :
1518 0 : return xIn;
1519 : }
1520 :
1521 0 : void BinaryInput::seek( sal_Int32 nPos )
1522 : {
1523 0 : if( nPos <= m_nSize )
1524 0 : m_nCurPos = nPos;
1525 : else
1526 : OSL_FAIL( "BinaryInput::seek(): Position past end" );
1527 0 : }
1528 :
1529 :
1530 0 : sal_Int16 BinaryInput::readInt16()
1531 : {
1532 0 : sal_Int16 nRet = 0;
1533 0 : if( m_nCurPos + 2 <= m_nSize )
1534 : {
1535 0 : nRet = nRet + sal_Int16( sal_uInt8( m_pData[m_nCurPos++] ) );
1536 0 : nRet += 256 * sal_Int16( sal_uInt8( m_pData[m_nCurPos++] ) );
1537 : }
1538 : else
1539 : OSL_FAIL( "BinaryInput::readInt16(): Read past end" );
1540 :
1541 0 : return nRet;
1542 : }
1543 :
1544 0 : sal_Int32 BinaryInput::readInt32()
1545 : {
1546 0 : sal_Int32 nRet = 0;
1547 0 : if( m_nCurPos + 4 <= m_nSize )
1548 : {
1549 0 : sal_Int32 nFactor = 1;
1550 0 : for( sal_Int16 i = 0; i < 4; i++ )
1551 : {
1552 0 : nRet += sal_uInt8( m_pData[m_nCurPos++] ) * nFactor;
1553 0 : nFactor *= 256;
1554 : }
1555 : }
1556 : else
1557 : OSL_FAIL( "BinaryInput::readInt32(): Read past end" );
1558 :
1559 0 : return nRet;
1560 : }
1561 :
1562 0 : sal_Unicode BinaryInput::readUnicodeChar()
1563 : {
1564 0 : sal_uInt16 nRet = 0;
1565 0 : if( m_nCurPos + 2 <= m_nSize )
1566 : {
1567 0 : nRet = nRet + sal_uInt8( m_pData[m_nCurPos++] );
1568 0 : nRet += 256 * sal_uInt8( m_pData[m_nCurPos++] );
1569 : }
1570 : else
1571 : OSL_FAIL( "BinaryInput::readUnicodeChar(): Read past end" );
1572 :
1573 0 : sal_Unicode cRet = nRet;
1574 0 : return cRet;
1575 : }
1576 :
1577 0 : OUString BinaryInput::readString()
1578 : {
1579 0 : OUStringBuffer aBuf;
1580 : sal_Unicode c;
1581 0 : do
1582 : {
1583 0 : c = readUnicodeChar();
1584 0 : if( c != 0 )
1585 0 : aBuf.append( c );
1586 : }
1587 : while( c != 0 );
1588 :
1589 0 : OUString aRetStr = aBuf.makeStringAndClear();
1590 0 : return aRetStr;
1591 : }
1592 :
1593 0 : void StringResourcePersistenceImpl::importBinary( const Sequence< ::sal_Int8 >& Data )
1594 : throw (IllegalArgumentException, RuntimeException, std::exception)
1595 : {
1596 : // Init: Remove all locales
1597 0 : sal_Int32 nOldLocaleCount = 0;
1598 0 : do
1599 : {
1600 0 : Sequence< Locale > aLocaleSeq = getLocales();
1601 0 : nOldLocaleCount = aLocaleSeq.getLength();
1602 0 : if( nOldLocaleCount > 0 )
1603 : {
1604 0 : Locale aLocale = aLocaleSeq[0];
1605 0 : removeLocale( aLocale );
1606 0 : }
1607 : }
1608 : while( nOldLocaleCount > 0 );
1609 :
1610 : // Import data
1611 0 : Reference< XMultiComponentFactory > xMCF = getMultiComponentFactory();
1612 0 : BinaryInput aIn( Data, xMCF, m_xContext );
1613 :
1614 0 : sal_Int32 nVersion = aIn.readInt16();
1615 : (void)nVersion;
1616 0 : sal_Int32 nLocaleCount = aIn.readInt16();
1617 0 : sal_Int32 iDefault = aIn.readInt16();
1618 : (void)iDefault;
1619 :
1620 0 : sal_Int32* pPositions = new sal_Int32[nLocaleCount + 1];
1621 0 : for( sal_Int32 i = 0; i < nLocaleCount + 1; i++ )
1622 0 : pPositions[i] = aIn.readInt32();
1623 :
1624 : // Import locales
1625 0 : LocaleItem* pUseAsDefaultItem = NULL;
1626 0 : for( sal_Int32 i = 0; i < nLocaleCount; i++ )
1627 : {
1628 0 : sal_Int32 nPos = pPositions[i];
1629 0 : aIn.seek( nPos );
1630 :
1631 0 : Locale aLocale;
1632 0 : aLocale.Language = aIn.readString();
1633 0 : aLocale.Country = aIn.readString();
1634 0 : aLocale.Variant = aIn.readString();
1635 :
1636 0 : sal_Int32 nAfterStringPos = aIn.getPosition();
1637 0 : sal_Int32 nSize = pPositions[i+1] - nAfterStringPos;
1638 0 : Reference< io::XInputStream > xInput = aIn.getInputStreamForSection( nSize );
1639 0 : if( xInput.is() )
1640 : {
1641 0 : LocaleItem* pLocaleItem = new LocaleItem( aLocale );
1642 0 : if( iDefault == i )
1643 0 : pUseAsDefaultItem = pLocaleItem;
1644 0 : m_aLocaleItemVector.push_back( pLocaleItem );
1645 0 : implReadPropertiesFile( pLocaleItem, xInput );
1646 : }
1647 0 : }
1648 :
1649 0 : if( pUseAsDefaultItem != NULL )
1650 0 : setDefaultLocale( pUseAsDefaultItem->m_locale );
1651 :
1652 0 : delete[] pPositions;
1653 0 : }
1654 :
1655 :
1656 :
1657 : // Private helper methods
1658 :
1659 0 : bool checkNamingSceme( const OUString& aName, const OUString& aNameBase,
1660 : Locale& aLocale )
1661 : {
1662 0 : bool bSuccess = false;
1663 :
1664 0 : sal_Int32 nNameLen = aName.getLength();
1665 0 : sal_Int32 nNameBaseLen = aNameBase.getLength();
1666 :
1667 : // Name has to start with NameBase followed
1668 : // by a '_' and at least one more character
1669 0 : if( aName.startsWith( aNameBase ) && nNameBaseLen < nNameLen-1 &&
1670 0 : aName[nNameBaseLen] == '_' )
1671 : {
1672 0 : bSuccess = true;
1673 :
1674 : /* FIXME-BCP47: this uses '_' underscore character as separator and
1675 : * also appends Variant, which can't be blindly changed as it would
1676 : * violate the naming scheme in use. */
1677 :
1678 0 : sal_Int32 iStart = nNameBaseLen + 1;
1679 0 : sal_Int32 iNext_ = aName.indexOf( '_', iStart );
1680 0 : if( iNext_ != -1 && iNext_ < nNameLen-1 )
1681 : {
1682 0 : aLocale.Language = aName.copy( iStart, iNext_ - iStart );
1683 :
1684 0 : iStart = iNext_ + 1;
1685 0 : iNext_ = aName.indexOf( '_', iStart );
1686 0 : if( iNext_ != -1 && iNext_ < nNameLen-1 )
1687 : {
1688 0 : aLocale.Country = aName.copy( iStart, iNext_ - iStart );
1689 0 : aLocale.Variant = aName.copy( iNext_ + 1 );
1690 : }
1691 : else
1692 0 : aLocale.Country = aName.copy( iStart );
1693 : }
1694 : else
1695 0 : aLocale.Language = aName.copy( iStart );
1696 : }
1697 0 : return bSuccess;
1698 : }
1699 :
1700 0 : void StringResourcePersistenceImpl::implLoadAllLocales()
1701 : {
1702 0 : for( LocaleItemVectorIt it = m_aLocaleItemVector.begin(); it != m_aLocaleItemVector.end(); ++it )
1703 : {
1704 0 : LocaleItem* pLocaleItem = *it;
1705 0 : if( pLocaleItem != NULL )
1706 0 : loadLocale( pLocaleItem );
1707 : }
1708 0 : }
1709 :
1710 : // Scan locale properties files helper
1711 0 : void StringResourcePersistenceImpl::implScanLocaleNames( const Sequence< OUString >& aContentSeq )
1712 : {
1713 0 : Locale aDefaultLocale;
1714 0 : bool bDefaultFound = false;
1715 :
1716 0 : sal_Int32 nCount = aContentSeq.getLength();
1717 0 : const OUString* pFiles = aContentSeq.getConstArray();
1718 0 : for( int i = 0 ; i < nCount ; i++ )
1719 : {
1720 0 : OUString aCompleteName = pFiles[i];
1721 0 : OUString aPureName;
1722 0 : OUString aExtension;
1723 0 : sal_Int32 iDot = aCompleteName.lastIndexOf( '.' );
1724 0 : sal_Int32 iSlash = aCompleteName.lastIndexOf( '/' );
1725 0 : if( iDot != -1 && iDot > iSlash)
1726 : {
1727 0 : sal_Int32 iCopyFrom = (iSlash != -1) ? iSlash + 1 : 0;
1728 0 : aPureName = aCompleteName.copy( iCopyFrom, iDot-iCopyFrom );
1729 0 : aExtension = aCompleteName.copy( iDot + 1 );
1730 : }
1731 :
1732 0 : if ( aExtension == "properties" )
1733 : {
1734 : //OUString aName = aInetObj.getBase();
1735 0 : Locale aLocale;
1736 :
1737 0 : if( checkNamingSceme( aPureName, m_aNameBase, aLocale ) )
1738 : {
1739 0 : LocaleItem* pLocaleItem = new LocaleItem( aLocale, false );
1740 0 : m_aLocaleItemVector.push_back( pLocaleItem );
1741 :
1742 0 : if( m_pCurrentLocaleItem == NULL )
1743 0 : m_pCurrentLocaleItem = pLocaleItem;
1744 :
1745 0 : if( m_pDefaultLocaleItem == NULL )
1746 : {
1747 0 : m_pDefaultLocaleItem = pLocaleItem;
1748 0 : m_bDefaultModified = true;
1749 : }
1750 0 : }
1751 : }
1752 0 : else if( !bDefaultFound && aExtension == "default" )
1753 : {
1754 : //OUString aName = aInetObj.getBase();
1755 0 : Locale aLocale;
1756 :
1757 0 : if( checkNamingSceme( aPureName, m_aNameBase, aDefaultLocale ) )
1758 0 : bDefaultFound = true;
1759 : }
1760 0 : }
1761 0 : if( bDefaultFound )
1762 : {
1763 0 : LocaleItem* pLocaleItem = getItemForLocale( aDefaultLocale, false );
1764 0 : if( pLocaleItem )
1765 : {
1766 0 : m_pDefaultLocaleItem = pLocaleItem;
1767 0 : m_bDefaultModified = false;
1768 : }
1769 0 : }
1770 0 : }
1771 :
1772 : // Scan locale properties files
1773 0 : void StringResourcePersistenceImpl::implScanLocales()
1774 : {
1775 : // Dummy implementation, method not called for this
1776 : // base class, but pure virtual not possible-
1777 0 : }
1778 :
1779 0 : bool StringResourcePersistenceImpl::loadLocale( LocaleItem* pLocaleItem )
1780 : {
1781 0 : bool bSuccess = false;
1782 :
1783 : OSL_ENSURE( pLocaleItem, "StringResourcePersistenceImpl::loadLocale(): pLocaleItem == NULL" );
1784 0 : if( pLocaleItem )
1785 : {
1786 0 : if( pLocaleItem->m_bLoaded )
1787 : {
1788 0 : bSuccess = true;
1789 : }
1790 : else
1791 : {
1792 0 : bSuccess = implLoadLocale( pLocaleItem );
1793 0 : pLocaleItem->m_bLoaded = true; // = bSuccess??? -> leads to more tries
1794 : }
1795 : }
1796 0 : return bSuccess;
1797 : }
1798 :
1799 0 : bool StringResourcePersistenceImpl::implLoadLocale( LocaleItem* )
1800 : {
1801 : // Dummy implementation, method not called for this
1802 : // base class, but pure virtual not possible-
1803 0 : return false;
1804 : }
1805 :
1806 0 : OUString implGetNameScemeForLocaleItem( const LocaleItem* pLocaleItem )
1807 : {
1808 : /* FIXME-BCP47: this uses '_' underscore character as separator and
1809 : * also appends Variant, which can't be blindly changed as it would
1810 : * violate the naming scheme in use. */
1811 :
1812 : static const char aUnder[] = "_";
1813 :
1814 : OSL_ENSURE( pLocaleItem,
1815 : "StringResourcePersistenceImpl::implGetNameScemeForLocaleItem(): pLocaleItem == NULL" );
1816 0 : Locale aLocale = pLocaleItem->m_locale;
1817 :
1818 0 : OUString aRetStr = aUnder;
1819 0 : aRetStr += aLocale.Language;
1820 :
1821 0 : OUString aCountry = aLocale.Country;
1822 0 : if( !aCountry.isEmpty() )
1823 : {
1824 0 : aRetStr += aUnder;
1825 0 : aRetStr += aCountry;
1826 : }
1827 :
1828 0 : OUString aVariant = aLocale.Variant;
1829 0 : if( !aVariant.isEmpty() )
1830 : {
1831 0 : aRetStr += aUnder;
1832 0 : aRetStr += aVariant;
1833 : }
1834 0 : return aRetStr;
1835 : }
1836 :
1837 0 : OUString StringResourcePersistenceImpl::implGetFileNameForLocaleItem
1838 : ( LocaleItem* pLocaleItem, const OUString& aNameBase )
1839 : {
1840 0 : OUString aFileName = aNameBase;
1841 0 : if( aFileName.isEmpty() )
1842 0 : aFileName = aNameBaseDefaultStr;
1843 :
1844 0 : aFileName += implGetNameScemeForLocaleItem( pLocaleItem );
1845 0 : return aFileName;
1846 : }
1847 :
1848 0 : OUString StringResourcePersistenceImpl::implGetPathForLocaleItem
1849 : ( LocaleItem* pLocaleItem, const OUString& aNameBase,
1850 : const OUString& aLocation, bool bDefaultFile )
1851 : {
1852 0 : OUString aFileName = implGetFileNameForLocaleItem( pLocaleItem, aNameBase );
1853 0 : INetURLObject aInetObj( aLocation );
1854 0 : aInetObj.insertName( aFileName, true, INetURLObject::LAST_SEGMENT, true, INetURLObject::ENCODE_ALL );
1855 0 : if( bDefaultFile )
1856 0 : aInetObj.setExtension( OUString( "default" ) );
1857 : else
1858 0 : aInetObj.setExtension( OUString( "properties" ) );
1859 0 : OUString aCompleteFileName = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
1860 0 : return aCompleteFileName;
1861 : }
1862 :
1863 : // White space according to Java property files specification in
1864 : // http://java.sun.com/j2se/1.4.2/docs/api/java/util/Properties.html#load(java.io.InputStream)
1865 0 : inline bool isWhiteSpace( sal_Unicode c )
1866 : {
1867 0 : bool bWhite = ( c == 0x0020 || // space
1868 0 : c == 0x0009 || // tab
1869 0 : c == 0x000a || // line feed, not always handled by TextInputStream
1870 0 : c == 0x000d || // carriage return, not always handled by TextInputStream
1871 0 : c == 0x000C ); // form feed
1872 0 : return bWhite;
1873 : }
1874 :
1875 0 : inline void skipWhites( const sal_Unicode* pBuf, sal_Int32 nLen, sal_Int32& ri )
1876 : {
1877 0 : while( ri < nLen )
1878 : {
1879 0 : if( !isWhiteSpace( pBuf[ri] ) )
1880 0 : break;
1881 0 : ri++;
1882 : }
1883 0 : }
1884 :
1885 0 : inline bool isHexDigit( sal_Unicode c, sal_uInt16& nDigitVal )
1886 : {
1887 0 : bool bRet = true;
1888 0 : if( c >= '0' && c <= '9' )
1889 0 : nDigitVal = c - '0';
1890 0 : else if( c >= 'a' && c <= 'f' )
1891 0 : nDigitVal = c - 'a' + 10;
1892 0 : else if( c >= 'A' && c <= 'F' )
1893 0 : nDigitVal = c - 'A' + 10;
1894 : else
1895 0 : bRet = false;
1896 0 : return bRet;
1897 : }
1898 :
1899 0 : sal_Unicode getEscapeChar( const sal_Unicode* pBuf, sal_Int32 nLen, sal_Int32& ri )
1900 : {
1901 0 : sal_Int32 i = ri;
1902 :
1903 0 : sal_Unicode cRet = 0;
1904 0 : sal_Unicode c = pBuf[i];
1905 0 : switch( c )
1906 : {
1907 : case 't':
1908 0 : cRet = 0x0009;
1909 0 : break;
1910 : case 'n':
1911 0 : cRet = 0x000a;
1912 0 : break;
1913 : case 'f':
1914 0 : cRet = 0x000c;
1915 0 : break;
1916 : case 'r':
1917 0 : cRet = 0x000d;
1918 0 : break;
1919 : case '\\':
1920 0 : cRet = '\\';
1921 0 : break;
1922 : case 'u':
1923 : {
1924 : // Skip multiple u
1925 0 : i++;
1926 0 : while( i < nLen && pBuf[i] == 'u' )
1927 0 : i++;
1928 :
1929 : // Process hex digits
1930 0 : sal_Int32 nDigitCount = 0;
1931 : sal_uInt16 nDigitVal;
1932 0 : while( i < nLen && isHexDigit( pBuf[i], nDigitVal ) )
1933 : {
1934 0 : cRet = 16 * cRet + nDigitVal;
1935 :
1936 0 : nDigitCount++;
1937 0 : if( nDigitCount == 4 )
1938 : {
1939 : // Write back position
1940 0 : ri = i;
1941 0 : break;
1942 : }
1943 0 : i++;
1944 : }
1945 0 : break;
1946 : }
1947 : default:
1948 0 : cRet = c;
1949 : }
1950 :
1951 0 : return cRet;
1952 : }
1953 :
1954 0 : void CheckContinueInNextLine( Reference< io::XTextInputStream2 > xTextInputStream,
1955 : OUString& aLine, bool& bEscapePending, const sal_Unicode*& pBuf,
1956 : sal_Int32& nLen, sal_Int32& i )
1957 : {
1958 0 : if( i == nLen && bEscapePending )
1959 : {
1960 0 : bEscapePending = false;
1961 :
1962 0 : if( !xTextInputStream->isEOF() )
1963 : {
1964 0 : aLine = xTextInputStream->readLine();
1965 0 : nLen = aLine.getLength();
1966 0 : pBuf = aLine.getStr();
1967 0 : i = 0;
1968 :
1969 0 : skipWhites( pBuf, nLen, i );
1970 : }
1971 : }
1972 0 : }
1973 :
1974 0 : bool StringResourcePersistenceImpl::implReadPropertiesFile
1975 : ( LocaleItem* pLocaleItem, const Reference< io::XInputStream >& xInputStream )
1976 : {
1977 0 : if( !xInputStream.is() || pLocaleItem == NULL )
1978 0 : return false;
1979 :
1980 0 : bool bSuccess = false;
1981 0 : Reference< io::XTextInputStream2 > xTextInputStream = io::TextInputStream::create( m_xContext );
1982 :
1983 0 : bSuccess = true;
1984 :
1985 0 : xTextInputStream->setInputStream( xInputStream );
1986 :
1987 : OUString aEncodingStr = OUString::createFromAscii
1988 0 : ( rtl_getMimeCharsetFromTextEncoding( RTL_TEXTENCODING_ISO_8859_1 ) );
1989 0 : xTextInputStream->setEncoding( aEncodingStr );
1990 :
1991 0 : OUString aLine;
1992 0 : while( !xTextInputStream->isEOF() )
1993 : {
1994 0 : aLine = xTextInputStream->readLine();
1995 :
1996 0 : sal_Int32 nLen = aLine.getLength();
1997 0 : if( 0 == nLen )
1998 0 : continue;
1999 0 : const sal_Unicode* pBuf = aLine.getStr();
2000 0 : OUStringBuffer aBuf;
2001 0 : sal_Unicode c = 0;
2002 0 : sal_Int32 i = 0;
2003 :
2004 0 : skipWhites( pBuf, nLen, i );
2005 0 : if( i == nLen )
2006 0 : continue; // line contains only white spaces
2007 :
2008 : // Comment?
2009 0 : c = pBuf[i];
2010 0 : if( c == '#' || c == '!' )
2011 0 : continue;
2012 :
2013 : // Scan key
2014 0 : OUString aResourceID;
2015 0 : bool bEscapePending = false;
2016 0 : bool bStrComplete = false;
2017 0 : while( i < nLen && !bStrComplete )
2018 : {
2019 0 : c = pBuf[i];
2020 0 : if( bEscapePending )
2021 : {
2022 0 : aBuf.append( getEscapeChar( pBuf, nLen, i ) );
2023 0 : bEscapePending = false;
2024 : }
2025 : else
2026 : {
2027 0 : if( c == '\\' )
2028 : {
2029 0 : bEscapePending = true;
2030 : }
2031 : else
2032 : {
2033 0 : if( c == ':' || c == '=' || isWhiteSpace( c ) )
2034 0 : bStrComplete = true;
2035 : else
2036 0 : aBuf.append( c );
2037 : }
2038 : }
2039 0 : i++;
2040 :
2041 0 : CheckContinueInNextLine( xTextInputStream, aLine, bEscapePending, pBuf, nLen, i );
2042 0 : if( i == nLen )
2043 0 : bStrComplete = true;
2044 :
2045 0 : if( bStrComplete )
2046 0 : aResourceID = aBuf.makeStringAndClear();
2047 : }
2048 :
2049 : // Ignore lines with empty keys
2050 0 : if( aResourceID.isEmpty() )
2051 0 : continue;
2052 :
2053 : // Scan value
2054 0 : skipWhites( pBuf, nLen, i );
2055 :
2056 0 : OUString aValueStr;
2057 0 : bEscapePending = false;
2058 0 : bStrComplete = false;
2059 0 : while( i < nLen && !bStrComplete )
2060 : {
2061 0 : c = pBuf[i];
2062 0 : if( c == 0x000a || c == 0x000d ) // line feed/carriage return, not always handled by TextInputStream
2063 : {
2064 0 : i++;
2065 : }
2066 : else
2067 : {
2068 0 : if( bEscapePending )
2069 : {
2070 0 : aBuf.append( getEscapeChar( pBuf, nLen, i ) );
2071 0 : bEscapePending = false;
2072 : }
2073 0 : else if( c == '\\' )
2074 0 : bEscapePending = true;
2075 : else
2076 0 : aBuf.append( c );
2077 0 : i++;
2078 :
2079 0 : CheckContinueInNextLine( xTextInputStream, aLine, bEscapePending, pBuf, nLen, i );
2080 : }
2081 0 : if( i == nLen )
2082 0 : bStrComplete = true;
2083 :
2084 0 : if( bStrComplete )
2085 0 : aValueStr = aBuf.makeStringAndClear();
2086 : }
2087 :
2088 : // Push into table
2089 0 : pLocaleItem->m_aIdToStringMap[ aResourceID ] = aValueStr;
2090 0 : implScanIdForNumber( aResourceID );
2091 0 : IdToIndexMap& rIndexMap = pLocaleItem->m_aIdToIndexMap;
2092 0 : rIndexMap[ aResourceID ] = pLocaleItem->m_nNextIndex++;
2093 0 : }
2094 :
2095 0 : return bSuccess;
2096 : }
2097 :
2098 :
2099 0 : inline sal_Unicode getHexCharForDigit( sal_uInt16 nDigitVal )
2100 : {
2101 0 : sal_Unicode cRet = ( nDigitVal < 10 ) ? ('0' + nDigitVal) : ('a' + (nDigitVal-10));
2102 0 : return cRet;
2103 : }
2104 :
2105 0 : void implWriteCharToBuffer( OUStringBuffer& aBuf, sal_Unicode cu, bool bKey )
2106 : {
2107 0 : if( cu == '\\' )
2108 : {
2109 0 : aBuf.append( '\\' );
2110 0 : aBuf.append( '\\' );
2111 : }
2112 0 : else if( cu == 0x000a )
2113 : {
2114 0 : aBuf.append( '\\' );
2115 0 : aBuf.append( 'n' );
2116 : }
2117 0 : else if( cu == 0x000d )
2118 : {
2119 0 : aBuf.append( '\\' );
2120 0 : aBuf.append( 'r' );
2121 : }
2122 0 : else if( bKey && cu == '=' )
2123 : {
2124 0 : aBuf.append( '\\' );
2125 0 : aBuf.append( '=' );
2126 : }
2127 0 : else if( bKey && cu == ':' )
2128 : {
2129 0 : aBuf.append( '\\' );
2130 0 : aBuf.append( ':' );
2131 : }
2132 : // ISO/IEC 8859-1 range according to:
2133 : // http://en.wikipedia.org/wiki/ISO/IEC_8859-1
2134 0 : else if( (cu >= 0x20 && cu <= 0x7e) )
2135 : //TODO: Check why (cu >= 0xa0 && cu <= 0xFF)
2136 : //is encoded in sample properties files
2137 : //else if( (cu >= 0x20 && cu <= 0x7e) ||
2138 : // (cu >= 0xa0 && cu <= 0xFF) )
2139 : {
2140 0 : aBuf.append( cu );
2141 : }
2142 : else
2143 : {
2144 : // Unicode encoding
2145 0 : aBuf.append( '\\' );
2146 0 : aBuf.append( 'u' );
2147 :
2148 0 : sal_uInt16 nVal = cu;
2149 0 : for( sal_uInt16 i = 0 ; i < 4 ; i++ )
2150 : {
2151 0 : sal_uInt16 nDigit = nVal / 0x1000;
2152 0 : nVal -= nDigit * 0x1000;
2153 0 : nVal *= 0x10;
2154 0 : aBuf.append( getHexCharForDigit( nDigit ) );
2155 : }
2156 : }
2157 0 : }
2158 :
2159 0 : void implWriteStringWithEncoding( const OUString& aStr,
2160 : Reference< io::XTextOutputStream2 > xTextOutputStream, bool bKey )
2161 : {
2162 : static sal_Unicode cLineFeed = 0xa;
2163 :
2164 : (void)aStr;
2165 : (void)xTextOutputStream;
2166 :
2167 0 : OUStringBuffer aBuf;
2168 0 : sal_Int32 nLen = aStr.getLength();
2169 0 : const sal_Unicode* pSrc = aStr.getStr();
2170 0 : for( sal_Int32 i = 0 ; i < nLen ; i++ )
2171 : {
2172 0 : sal_Unicode cu = pSrc[i];
2173 0 : implWriteCharToBuffer( aBuf, cu, bKey );
2174 : // TODO?: split long lines
2175 : }
2176 0 : if( !bKey )
2177 0 : aBuf.append( cLineFeed );
2178 :
2179 0 : OUString aWriteStr = aBuf.makeStringAndClear();
2180 0 : xTextOutputStream->writeString( aWriteStr );
2181 0 : }
2182 :
2183 0 : bool StringResourcePersistenceImpl::implWritePropertiesFile( LocaleItem* pLocaleItem,
2184 : const Reference< io::XOutputStream >& xOutputStream, const OUString& aComment )
2185 : {
2186 : static const char aAssignmentStr[] = "=";
2187 : static const char aLineFeedStr[] = "\n";
2188 :
2189 0 : if( !xOutputStream.is() || pLocaleItem == NULL )
2190 0 : return false;
2191 :
2192 0 : bool bSuccess = false;
2193 0 : Reference< io::XTextOutputStream2 > xTextOutputStream = io::TextOutputStream::create(m_xContext);
2194 :
2195 0 : xTextOutputStream->setOutputStream( xOutputStream );
2196 :
2197 : OUString aEncodingStr = OUString::createFromAscii
2198 0 : ( rtl_getMimeCharsetFromTextEncoding( RTL_TEXTENCODING_ISO_8859_1 ) );
2199 0 : xTextOutputStream->setEncoding( aEncodingStr );
2200 :
2201 0 : xTextOutputStream->writeString( aComment );
2202 0 : xTextOutputStream->writeString( aLineFeedStr );
2203 :
2204 0 : const IdToStringMap& rHashMap = pLocaleItem->m_aIdToStringMap;
2205 0 : if( !rHashMap.empty() )
2206 : {
2207 : // Sort ids according to read order
2208 0 : const IdToIndexMap& rIndexMap = pLocaleItem->m_aIdToIndexMap;
2209 0 : IdToIndexMap::const_iterator it_index;
2210 :
2211 : // Find max/min index
2212 0 : sal_Int32 nMinIndex = -1;
2213 0 : sal_Int32 nMaxIndex = -1;
2214 0 : for( it_index = rIndexMap.begin(); it_index != rIndexMap.end(); ++it_index )
2215 : {
2216 0 : sal_Int32 nIndex = (*it_index).second;
2217 0 : if( nMinIndex > nIndex || nMinIndex == -1 )
2218 0 : nMinIndex = nIndex;
2219 0 : if( nMaxIndex < nIndex )
2220 0 : nMaxIndex = nIndex;
2221 : }
2222 0 : sal_Int32 nTabSize = nMaxIndex - nMinIndex + 1;
2223 :
2224 : // Create sorted array of pointers to the id strings
2225 0 : const OUString** pIdPtrs = new const OUString*[nTabSize];
2226 0 : for(sal_Int32 i = 0 ; i < nTabSize ; i++ )
2227 0 : pIdPtrs[i] = NULL;
2228 0 : for( it_index = rIndexMap.begin(); it_index != rIndexMap.end(); ++it_index )
2229 : {
2230 0 : sal_Int32 nIndex = (*it_index).second;
2231 0 : pIdPtrs[nIndex - nMinIndex] = &((*it_index).first);
2232 : }
2233 :
2234 : // Write lines in correct order
2235 0 : for(sal_Int32 i = 0 ; i < nTabSize ; i++ )
2236 : {
2237 0 : const OUString* pStr = pIdPtrs[i];
2238 0 : if( pStr != NULL )
2239 : {
2240 0 : OUString aResourceID = *pStr;
2241 0 : IdToStringMap::const_iterator it = rHashMap.find( aResourceID );
2242 0 : if( !( it == rHashMap.end() ) )
2243 : {
2244 0 : implWriteStringWithEncoding( aResourceID, xTextOutputStream, true );
2245 0 : xTextOutputStream->writeString( aAssignmentStr );
2246 0 : OUString aValStr = (*it).second;
2247 0 : implWriteStringWithEncoding( aValStr, xTextOutputStream, false );
2248 0 : }
2249 : }
2250 : }
2251 :
2252 0 : delete[] pIdPtrs;
2253 : }
2254 :
2255 0 : bSuccess = true;
2256 :
2257 0 : return bSuccess;
2258 : }
2259 :
2260 :
2261 :
2262 : // StringResourceWithStorageImpl
2263 :
2264 :
2265 : // component operations
2266 0 : static Sequence< OUString > getSupportedServiceNames_StringResourceWithStorageImpl()
2267 : {
2268 0 : Sequence< OUString > names(1);
2269 0 : names[0] = "com.sun.star.resource.StringResourceWithStorage";
2270 0 : return names;
2271 : }
2272 :
2273 1 : static OUString getImplementationName_StringResourceWithStorageImpl()
2274 : {
2275 1 : return OUString( "com.sun.star.comp.scripting.StringResourceWithStorage" );
2276 : }
2277 :
2278 0 : static Reference< XInterface > SAL_CALL create_StringResourceWithStorageImpl(
2279 : Reference< XComponentContext > const & xContext )
2280 : {
2281 0 : return static_cast< ::cppu::OWeakObject * >( new StringResourceWithStorageImpl( xContext ) );
2282 : }
2283 :
2284 :
2285 :
2286 0 : StringResourceWithStorageImpl::StringResourceWithStorageImpl( const Reference< XComponentContext >& rxContext )
2287 : : StringResourceWithStorageImpl_BASE( rxContext )
2288 0 : , m_bStorageChanged( false )
2289 : {
2290 0 : }
2291 :
2292 :
2293 :
2294 0 : StringResourceWithStorageImpl::~StringResourceWithStorageImpl()
2295 : {
2296 0 : }
2297 :
2298 :
2299 : // XServiceInfo
2300 :
2301 :
2302 0 : OUString StringResourceWithStorageImpl::getImplementationName( ) throw (RuntimeException, std::exception)
2303 : {
2304 0 : return getImplementationName_StringResourceWithStorageImpl();
2305 : }
2306 :
2307 0 : sal_Bool StringResourceWithStorageImpl::supportsService( const OUString& rServiceName ) throw (RuntimeException, std::exception)
2308 : {
2309 0 : return cppu::supportsService(this, rServiceName);
2310 : }
2311 :
2312 0 : Sequence< OUString > StringResourceWithStorageImpl::getSupportedServiceNames( ) throw (RuntimeException, std::exception)
2313 : {
2314 0 : return getSupportedServiceNames_StringResourceWithStorageImpl();
2315 : }
2316 :
2317 :
2318 : // XInitialization
2319 :
2320 :
2321 0 : void StringResourceWithStorageImpl::initialize( const Sequence< Any >& aArguments )
2322 : throw (Exception, RuntimeException, std::exception)
2323 : {
2324 0 : ::osl::MutexGuard aGuard( getMutex() );
2325 :
2326 0 : if ( aArguments.getLength() != 5 )
2327 : {
2328 : throw RuntimeException(
2329 0 : "StringResourceWithStorageImpl::initialize: invalid number of arguments!" );
2330 : }
2331 :
2332 0 : bool bOk = (aArguments[0] >>= m_xStorage);
2333 0 : if( bOk && !m_xStorage.is() )
2334 0 : bOk = false;
2335 :
2336 0 : if( !bOk )
2337 : {
2338 0 : OUString errorMsg("StringResourceWithStorageImpl::initialize: invalid storage");
2339 0 : throw IllegalArgumentException( errorMsg, Reference< XInterface >(), 0 );
2340 : }
2341 :
2342 0 : implInitializeCommonParameters( aArguments );
2343 0 : }
2344 :
2345 :
2346 : // Forwarding calls to base class
2347 :
2348 : // XModifyBroadcaster
2349 0 : void StringResourceWithStorageImpl::addModifyListener( const Reference< XModifyListener >& aListener )
2350 : throw (RuntimeException, std::exception)
2351 : {
2352 0 : StringResourceImpl::addModifyListener( aListener );
2353 0 : }
2354 0 : void StringResourceWithStorageImpl::removeModifyListener( const Reference< XModifyListener >& aListener )
2355 : throw (RuntimeException, std::exception)
2356 : {
2357 0 : StringResourceImpl::removeModifyListener( aListener );
2358 0 : }
2359 :
2360 : // XStringResourceResolver
2361 0 : OUString StringResourceWithStorageImpl::resolveString( const OUString& ResourceID )
2362 : throw (::com::sun::star::resource::MissingResourceException, RuntimeException, std::exception)
2363 : {
2364 0 : return StringResourceImpl::resolveString( ResourceID ) ;
2365 : }
2366 0 : OUString StringResourceWithStorageImpl::resolveStringForLocale( const OUString& ResourceID, const Locale& locale )
2367 : throw ( ::com::sun::star::resource::MissingResourceException, RuntimeException, std::exception)
2368 : {
2369 0 : return StringResourceImpl::resolveStringForLocale( ResourceID, locale );
2370 : }
2371 0 : sal_Bool StringResourceWithStorageImpl::hasEntryForId( const OUString& ResourceID )
2372 : throw (RuntimeException, std::exception)
2373 : {
2374 0 : return StringResourceImpl::hasEntryForId( ResourceID ) ;
2375 : }
2376 0 : sal_Bool StringResourceWithStorageImpl::hasEntryForIdAndLocale( const OUString& ResourceID,
2377 : const Locale& locale )
2378 : throw (RuntimeException, std::exception)
2379 : {
2380 0 : return StringResourceImpl::hasEntryForIdAndLocale( ResourceID, locale );
2381 : }
2382 0 : Sequence< OUString > StringResourceWithStorageImpl::getResourceIDs( )
2383 : throw (RuntimeException, std::exception)
2384 : {
2385 0 : return StringResourceImpl::getResourceIDs();
2386 : }
2387 0 : Sequence< OUString > StringResourceWithStorageImpl::getResourceIDsForLocale
2388 : ( const Locale& locale ) throw (::com::sun::star::uno::RuntimeException, std::exception)
2389 : {
2390 0 : return StringResourceImpl::getResourceIDsForLocale( locale );
2391 : }
2392 0 : Locale StringResourceWithStorageImpl::getCurrentLocale()
2393 : throw (RuntimeException, std::exception)
2394 : {
2395 0 : return StringResourceImpl::getCurrentLocale();
2396 : }
2397 0 : Locale StringResourceWithStorageImpl::getDefaultLocale( )
2398 : throw (RuntimeException, std::exception)
2399 : {
2400 0 : return StringResourceImpl::getDefaultLocale();
2401 : }
2402 0 : Sequence< Locale > StringResourceWithStorageImpl::getLocales( )
2403 : throw (RuntimeException, std::exception)
2404 : {
2405 0 : return StringResourceImpl::getLocales();
2406 : }
2407 :
2408 : // XStringResourceManager
2409 0 : sal_Bool StringResourceWithStorageImpl::isReadOnly()
2410 : throw (RuntimeException, std::exception)
2411 : {
2412 0 : return StringResourceImpl::isReadOnly();
2413 : }
2414 0 : void StringResourceWithStorageImpl::setCurrentLocale( const Locale& locale, sal_Bool FindClosestMatch )
2415 : throw (IllegalArgumentException, RuntimeException, std::exception)
2416 : {
2417 0 : StringResourceImpl::setCurrentLocale( locale, FindClosestMatch );
2418 0 : }
2419 0 : void StringResourceWithStorageImpl::setDefaultLocale( const Locale& locale )
2420 : throw (IllegalArgumentException, RuntimeException,NoSupportException, std::exception)
2421 : {
2422 0 : StringResourceImpl::setDefaultLocale( locale );
2423 0 : }
2424 0 : void StringResourceWithStorageImpl::setString( const OUString& ResourceID, const OUString& Str )
2425 : throw (NoSupportException, RuntimeException, std::exception)
2426 : {
2427 0 : StringResourceImpl::setString( ResourceID, Str );
2428 0 : }
2429 0 : void StringResourceWithStorageImpl::setStringForLocale
2430 : ( const OUString& ResourceID, const OUString& Str, const Locale& locale )
2431 : throw (NoSupportException, RuntimeException, std::exception)
2432 : {
2433 0 : StringResourceImpl::setStringForLocale( ResourceID, Str, locale );
2434 0 : }
2435 0 : void StringResourceWithStorageImpl::removeId( const OUString& ResourceID )
2436 : throw (::com::sun::star::resource::MissingResourceException, RuntimeException, NoSupportException, std::exception)
2437 : {
2438 0 : StringResourceImpl::removeId( ResourceID );
2439 0 : }
2440 0 : void StringResourceWithStorageImpl::removeIdForLocale( const OUString& ResourceID, const Locale& locale )
2441 : throw (::com::sun::star::resource::MissingResourceException, RuntimeException, NoSupportException, std::exception)
2442 : {
2443 0 : StringResourceImpl::removeIdForLocale( ResourceID, locale );
2444 0 : }
2445 0 : void StringResourceWithStorageImpl::newLocale( const Locale& locale )
2446 : throw (ElementExistException, IllegalArgumentException, RuntimeException, NoSupportException, std::exception)
2447 : {
2448 0 : StringResourceImpl::newLocale( locale );
2449 0 : }
2450 0 : void StringResourceWithStorageImpl::removeLocale( const Locale& locale )
2451 : throw (IllegalArgumentException, RuntimeException, NoSupportException, std::exception)
2452 : {
2453 0 : StringResourceImpl::removeLocale( locale );
2454 0 : }
2455 0 : sal_Int32 StringResourceWithStorageImpl::getUniqueNumericId( )
2456 : throw (RuntimeException, NoSupportException, std::exception)
2457 : {
2458 0 : return StringResourceImpl::getUniqueNumericId();
2459 : }
2460 :
2461 : // XStringResourcePersistence
2462 0 : void StringResourceWithStorageImpl::store()
2463 : throw (NoSupportException, Exception, RuntimeException, std::exception)
2464 : {
2465 0 : ::osl::MutexGuard aGuard( getMutex() );
2466 0 : implCheckReadOnly( "StringResourceWithStorageImpl::store(): Read only" );
2467 :
2468 0 : bool bUsedForStore = true;
2469 0 : bool bStoreAll = m_bStorageChanged;
2470 0 : m_bStorageChanged = false;
2471 0 : if( !m_bModified && !bStoreAll )
2472 0 : return;
2473 :
2474 0 : implStoreAtStorage( m_aNameBase, m_aComment, m_xStorage, bUsedForStore, bStoreAll );
2475 0 : m_bModified = false;
2476 : }
2477 :
2478 0 : sal_Bool StringResourceWithStorageImpl::isModified( )
2479 : throw (RuntimeException, std::exception)
2480 : {
2481 0 : return StringResourcePersistenceImpl::isModified();
2482 : }
2483 0 : void StringResourceWithStorageImpl::setComment( const OUString& Comment )
2484 : throw (::com::sun::star::uno::RuntimeException, std::exception)
2485 : {
2486 0 : StringResourcePersistenceImpl::setComment( Comment );
2487 0 : }
2488 0 : void StringResourceWithStorageImpl::storeToStorage( const Reference< XStorage >& Storage,
2489 : const OUString& NameBase, const OUString& Comment )
2490 : throw (Exception, RuntimeException, std::exception)
2491 : {
2492 0 : StringResourcePersistenceImpl::storeToStorage( Storage, NameBase, Comment );
2493 0 : }
2494 0 : void StringResourceWithStorageImpl::storeToURL( const OUString& URL,
2495 : const OUString& NameBase, const OUString& Comment,
2496 : const Reference< ::com::sun::star::task::XInteractionHandler >& Handler )
2497 : throw (Exception, RuntimeException, std::exception)
2498 : {
2499 0 : StringResourcePersistenceImpl::storeToURL( URL, NameBase, Comment, Handler );
2500 0 : }
2501 0 : Sequence< ::sal_Int8 > StringResourceWithStorageImpl::exportBinary( )
2502 : throw (RuntimeException, std::exception)
2503 : {
2504 0 : return StringResourcePersistenceImpl::exportBinary();
2505 : }
2506 0 : void StringResourceWithStorageImpl::importBinary( const Sequence< ::sal_Int8 >& Data )
2507 : throw (IllegalArgumentException, RuntimeException, std::exception)
2508 : {
2509 0 : StringResourcePersistenceImpl::importBinary( Data );
2510 0 : }
2511 :
2512 :
2513 : // XStringResourceWithStorage
2514 :
2515 0 : void StringResourceWithStorageImpl::storeAsStorage( const Reference< XStorage >& Storage )
2516 : throw (Exception, RuntimeException, std::exception)
2517 : {
2518 0 : setStorage( Storage );
2519 0 : store();
2520 0 : }
2521 :
2522 0 : void StringResourceWithStorageImpl::setStorage( const Reference< XStorage >& Storage )
2523 : throw (IllegalArgumentException, RuntimeException, std::exception)
2524 : {
2525 0 : ::osl::MutexGuard aGuard( getMutex() );
2526 :
2527 0 : if( !Storage.is() )
2528 : {
2529 0 : OUString errorMsg( "StringResourceWithStorageImpl::setStorage: invalid storage" );
2530 0 : throw IllegalArgumentException( errorMsg, Reference< XInterface >(), 0 );
2531 : }
2532 :
2533 0 : implLoadAllLocales();
2534 :
2535 0 : m_xStorage = Storage;
2536 0 : m_bStorageChanged = true;
2537 0 : }
2538 :
2539 :
2540 :
2541 : // Private helper methods
2542 :
2543 :
2544 : // Scan locale properties files
2545 0 : void StringResourceWithStorageImpl::implScanLocales()
2546 : {
2547 0 : Reference< container::XNameAccess > xNameAccess( m_xStorage, UNO_QUERY );
2548 0 : if( xNameAccess.is() )
2549 : {
2550 0 : Sequence< OUString > aContentSeq = xNameAccess->getElementNames();
2551 0 : implScanLocaleNames( aContentSeq );
2552 : }
2553 :
2554 0 : implLoadAllLocales();
2555 0 : }
2556 :
2557 : // Loading
2558 0 : bool StringResourceWithStorageImpl::implLoadLocale( LocaleItem* pLocaleItem )
2559 : {
2560 0 : bool bSuccess = false;
2561 : try
2562 : {
2563 0 : OUString aStreamName = implGetFileNameForLocaleItem( pLocaleItem, m_aNameBase );
2564 0 : aStreamName += ".properties";
2565 :
2566 : Reference< io::XStream > xElementStream =
2567 0 : m_xStorage->openStreamElement( aStreamName, ElementModes::READ );
2568 :
2569 0 : if( xElementStream.is() )
2570 : {
2571 0 : Reference< io::XInputStream > xInputStream = xElementStream->getInputStream();
2572 0 : if( xInputStream.is() )
2573 : {
2574 0 : bSuccess = StringResourcePersistenceImpl::implReadPropertiesFile( pLocaleItem, xInputStream );
2575 0 : xInputStream->closeInput();
2576 0 : }
2577 0 : }
2578 : }
2579 0 : catch( uno::Exception& )
2580 : {}
2581 :
2582 0 : return bSuccess;
2583 : }
2584 :
2585 :
2586 :
2587 : // StringResourceWithLocationImpl
2588 :
2589 :
2590 : // component operations
2591 0 : static Sequence< OUString > getSupportedServiceNames_StringResourceWithLocationImpl()
2592 : {
2593 0 : Sequence< OUString > names(1);
2594 0 : names[0] = "com.sun.star.resource.StringResourceWithLocation";
2595 0 : return names;
2596 : }
2597 :
2598 1 : static OUString getImplementationName_StringResourceWithLocationImpl()
2599 : {
2600 1 : return OUString( "com.sun.star.comp.scripting.StringResourceWithLocation" );
2601 : }
2602 :
2603 0 : static Reference< XInterface > SAL_CALL create_StringResourceWithLocationImpl(
2604 : Reference< XComponentContext > const & xContext )
2605 : {
2606 0 : return static_cast< ::cppu::OWeakObject * >( new StringResourceWithLocationImpl( xContext ) );
2607 : }
2608 :
2609 :
2610 :
2611 0 : StringResourceWithLocationImpl::StringResourceWithLocationImpl( const Reference< XComponentContext >& rxContext )
2612 : : StringResourceWithLocationImpl_BASE( rxContext )
2613 0 : , m_bLocationChanged( false )
2614 : {
2615 0 : }
2616 :
2617 :
2618 :
2619 0 : StringResourceWithLocationImpl::~StringResourceWithLocationImpl()
2620 : {
2621 0 : }
2622 :
2623 :
2624 : // XServiceInfo
2625 :
2626 :
2627 0 : OUString StringResourceWithLocationImpl::getImplementationName( ) throw (RuntimeException, std::exception)
2628 : {
2629 0 : return getImplementationName_StringResourceWithLocationImpl();
2630 : }
2631 :
2632 0 : sal_Bool StringResourceWithLocationImpl::supportsService( const OUString& rServiceName ) throw (RuntimeException, std::exception)
2633 : {
2634 0 : return cppu::supportsService(this, rServiceName);
2635 : }
2636 :
2637 0 : Sequence< OUString > StringResourceWithLocationImpl::getSupportedServiceNames( ) throw (RuntimeException, std::exception)
2638 : {
2639 0 : return getSupportedServiceNames_StringResourceWithLocationImpl();
2640 : }
2641 :
2642 :
2643 : // XInitialization
2644 :
2645 :
2646 0 : void StringResourceWithLocationImpl::initialize( const Sequence< Any >& aArguments )
2647 : throw (Exception, RuntimeException, std::exception)
2648 : {
2649 0 : ::osl::MutexGuard aGuard( getMutex() );
2650 :
2651 0 : if ( aArguments.getLength() != 6 )
2652 : {
2653 : throw RuntimeException(
2654 0 : "XInitialization::initialize: invalid number of arguments!" );
2655 : }
2656 :
2657 0 : bool bOk = (aArguments[0] >>= m_aLocation);
2658 0 : sal_Int32 nLen = m_aLocation.getLength();
2659 0 : if( bOk && nLen == 0 )
2660 : {
2661 0 : bOk = false;
2662 : }
2663 : else
2664 : {
2665 0 : if( m_aLocation[nLen - 1] != '/' )
2666 0 : m_aLocation += "/";
2667 : }
2668 :
2669 0 : if( !bOk )
2670 : {
2671 0 : OUString errorMsg("XInitialization::initialize: invalid URL");
2672 0 : throw IllegalArgumentException( errorMsg, Reference< XInterface >(), 0 );
2673 : }
2674 :
2675 :
2676 0 : bOk = (aArguments[5] >>= m_xInteractionHandler);
2677 0 : if( !bOk )
2678 : {
2679 0 : OUString errorMsg("StringResourceWithStorageImpl::initialize: invalid type");
2680 0 : throw IllegalArgumentException( errorMsg, Reference< XInterface >(), 5 );
2681 : }
2682 :
2683 0 : implInitializeCommonParameters( aArguments );
2684 0 : }
2685 :
2686 :
2687 : // Forwarding calls to base class
2688 :
2689 : // XModifyBroadcaster
2690 0 : void StringResourceWithLocationImpl::addModifyListener( const Reference< XModifyListener >& aListener )
2691 : throw (RuntimeException, std::exception)
2692 : {
2693 0 : StringResourceImpl::addModifyListener( aListener );
2694 0 : }
2695 0 : void StringResourceWithLocationImpl::removeModifyListener( const Reference< XModifyListener >& aListener )
2696 : throw (RuntimeException, std::exception)
2697 : {
2698 0 : StringResourceImpl::removeModifyListener( aListener );
2699 0 : }
2700 :
2701 : // XStringResourceResolver
2702 0 : OUString StringResourceWithLocationImpl::resolveString( const OUString& ResourceID )
2703 : throw (::com::sun::star::resource::MissingResourceException, RuntimeException, std::exception)
2704 : {
2705 0 : return StringResourceImpl::resolveString( ResourceID ) ;
2706 : }
2707 0 : OUString StringResourceWithLocationImpl::resolveStringForLocale( const OUString& ResourceID, const Locale& locale )
2708 : throw ( ::com::sun::star::resource::MissingResourceException, RuntimeException, std::exception)
2709 : {
2710 0 : return StringResourceImpl::resolveStringForLocale( ResourceID, locale );
2711 : }
2712 0 : sal_Bool StringResourceWithLocationImpl::hasEntryForId( const OUString& ResourceID )
2713 : throw (RuntimeException, std::exception)
2714 : {
2715 0 : return StringResourceImpl::hasEntryForId( ResourceID ) ;
2716 : }
2717 0 : sal_Bool StringResourceWithLocationImpl::hasEntryForIdAndLocale( const OUString& ResourceID,
2718 : const Locale& locale )
2719 : throw (RuntimeException, std::exception)
2720 : {
2721 0 : return StringResourceImpl::hasEntryForIdAndLocale( ResourceID, locale );
2722 : }
2723 0 : Sequence< OUString > StringResourceWithLocationImpl::getResourceIDs( )
2724 : throw (RuntimeException, std::exception)
2725 : {
2726 0 : return StringResourceImpl::getResourceIDs();
2727 : }
2728 0 : Sequence< OUString > StringResourceWithLocationImpl::getResourceIDsForLocale
2729 : ( const Locale& locale ) throw (::com::sun::star::uno::RuntimeException, std::exception)
2730 : {
2731 0 : return StringResourceImpl::getResourceIDsForLocale( locale );
2732 : }
2733 0 : Locale StringResourceWithLocationImpl::getCurrentLocale()
2734 : throw (RuntimeException, std::exception)
2735 : {
2736 0 : return StringResourceImpl::getCurrentLocale();
2737 : }
2738 0 : Locale StringResourceWithLocationImpl::getDefaultLocale( )
2739 : throw (RuntimeException, std::exception)
2740 : {
2741 0 : return StringResourceImpl::getDefaultLocale();
2742 : }
2743 0 : Sequence< Locale > StringResourceWithLocationImpl::getLocales( )
2744 : throw (RuntimeException, std::exception)
2745 : {
2746 0 : return StringResourceImpl::getLocales();
2747 : }
2748 :
2749 : // XStringResourceManager
2750 0 : sal_Bool StringResourceWithLocationImpl::isReadOnly()
2751 : throw (RuntimeException, std::exception)
2752 : {
2753 0 : return StringResourceImpl::isReadOnly();
2754 : }
2755 0 : void StringResourceWithLocationImpl::setCurrentLocale( const Locale& locale, sal_Bool FindClosestMatch )
2756 : throw (IllegalArgumentException, RuntimeException, std::exception)
2757 : {
2758 0 : StringResourceImpl::setCurrentLocale( locale, FindClosestMatch );
2759 0 : }
2760 0 : void StringResourceWithLocationImpl::setDefaultLocale( const Locale& locale )
2761 : throw (IllegalArgumentException, RuntimeException,NoSupportException, std::exception)
2762 : {
2763 0 : StringResourceImpl::setDefaultLocale( locale );
2764 0 : }
2765 0 : void StringResourceWithLocationImpl::setString( const OUString& ResourceID, const OUString& Str )
2766 : throw (NoSupportException, RuntimeException, std::exception)
2767 : {
2768 0 : StringResourceImpl::setString( ResourceID, Str );
2769 0 : }
2770 0 : void StringResourceWithLocationImpl::setStringForLocale
2771 : ( const OUString& ResourceID, const OUString& Str, const Locale& locale )
2772 : throw (NoSupportException, RuntimeException, std::exception)
2773 : {
2774 0 : StringResourceImpl::setStringForLocale( ResourceID, Str, locale );
2775 0 : }
2776 0 : void StringResourceWithLocationImpl::removeId( const OUString& ResourceID )
2777 : throw (::com::sun::star::resource::MissingResourceException, RuntimeException, NoSupportException, std::exception)
2778 : {
2779 0 : StringResourceImpl::removeId( ResourceID );
2780 0 : }
2781 0 : void StringResourceWithLocationImpl::removeIdForLocale( const OUString& ResourceID, const Locale& locale )
2782 : throw (::com::sun::star::resource::MissingResourceException, RuntimeException, NoSupportException, std::exception)
2783 : {
2784 0 : StringResourceImpl::removeIdForLocale( ResourceID, locale );
2785 0 : }
2786 0 : void StringResourceWithLocationImpl::newLocale( const Locale& locale )
2787 : throw (ElementExistException, IllegalArgumentException, RuntimeException, NoSupportException, std::exception)
2788 : {
2789 0 : StringResourceImpl::newLocale( locale );
2790 0 : }
2791 0 : void StringResourceWithLocationImpl::removeLocale( const Locale& locale )
2792 : throw (IllegalArgumentException, RuntimeException, NoSupportException, std::exception)
2793 : {
2794 0 : StringResourceImpl::removeLocale( locale );
2795 0 : }
2796 0 : sal_Int32 StringResourceWithLocationImpl::getUniqueNumericId( )
2797 : throw (RuntimeException, NoSupportException, std::exception)
2798 : {
2799 0 : return StringResourceImpl::getUniqueNumericId();
2800 : }
2801 :
2802 : // XStringResourcePersistence
2803 0 : void StringResourceWithLocationImpl::store()
2804 : throw (NoSupportException, Exception, RuntimeException, std::exception)
2805 : {
2806 0 : ::osl::MutexGuard aGuard( getMutex() );
2807 0 : implCheckReadOnly( "StringResourceWithLocationImpl::store(): Read only" );
2808 :
2809 0 : bool bUsedForStore = true;
2810 0 : bool bStoreAll = m_bLocationChanged;
2811 0 : m_bLocationChanged = false;
2812 0 : if( !m_bModified && !bStoreAll )
2813 0 : return;
2814 :
2815 0 : Reference< ucb::XSimpleFileAccess3 > xFileAccess = getFileAccess();
2816 : implStoreAtLocation( m_aLocation, m_aNameBase, m_aComment,
2817 0 : xFileAccess, bUsedForStore, bStoreAll );
2818 0 : m_bModified = false;
2819 : }
2820 :
2821 0 : sal_Bool StringResourceWithLocationImpl::isModified( )
2822 : throw (RuntimeException, std::exception)
2823 : {
2824 0 : return StringResourcePersistenceImpl::isModified();
2825 : }
2826 0 : void StringResourceWithLocationImpl::setComment( const OUString& Comment )
2827 : throw (::com::sun::star::uno::RuntimeException, std::exception)
2828 : {
2829 0 : StringResourcePersistenceImpl::setComment( Comment );
2830 0 : }
2831 0 : void StringResourceWithLocationImpl::storeToStorage( const Reference< XStorage >& Storage,
2832 : const OUString& NameBase, const OUString& Comment )
2833 : throw (Exception, RuntimeException, std::exception)
2834 : {
2835 0 : StringResourcePersistenceImpl::storeToStorage( Storage, NameBase, Comment );
2836 0 : }
2837 0 : void StringResourceWithLocationImpl::storeToURL( const OUString& URL,
2838 : const OUString& NameBase, const OUString& Comment,
2839 : const Reference< ::com::sun::star::task::XInteractionHandler >& Handler )
2840 : throw (Exception, RuntimeException, std::exception)
2841 : {
2842 0 : StringResourcePersistenceImpl::storeToURL( URL, NameBase, Comment, Handler );
2843 0 : }
2844 0 : Sequence< ::sal_Int8 > StringResourceWithLocationImpl::exportBinary( )
2845 : throw (RuntimeException, std::exception)
2846 : {
2847 0 : return StringResourcePersistenceImpl::exportBinary();
2848 : }
2849 0 : void StringResourceWithLocationImpl::importBinary( const Sequence< ::sal_Int8 >& Data )
2850 : throw (IllegalArgumentException, RuntimeException, std::exception)
2851 : {
2852 0 : StringResourcePersistenceImpl::importBinary( Data );
2853 0 : }
2854 :
2855 :
2856 : // XStringResourceWithLocation
2857 :
2858 : // XStringResourceWithLocation
2859 0 : void StringResourceWithLocationImpl::storeAsURL( const OUString& URL )
2860 : throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException, std::exception)
2861 : {
2862 0 : setURL( URL );
2863 0 : store();
2864 0 : }
2865 :
2866 0 : void StringResourceWithLocationImpl::setURL( const OUString& URL )
2867 : throw (css::lang::IllegalArgumentException,
2868 : css::lang::NoSupportException,
2869 : css::uno::RuntimeException, std::exception)
2870 : {
2871 0 : ::osl::MutexGuard aGuard( getMutex() );
2872 0 : implCheckReadOnly( "StringResourceWithLocationImpl::setURL(): Read only" );
2873 :
2874 0 : sal_Int32 nLen = URL.getLength();
2875 0 : if( nLen == 0 )
2876 : {
2877 0 : OUString errorMsg( "StringResourceWithLocationImpl::setURL: invalid URL" );
2878 0 : throw IllegalArgumentException( errorMsg, Reference< XInterface >(), 0 );
2879 : }
2880 :
2881 0 : implLoadAllLocales();
2882 :
2883 : // Delete files at old location
2884 0 : bool bUsedForStore = false;
2885 0 : bool bStoreAll = false;
2886 0 : bool bKillAll = true;
2887 : implStoreAtLocation( m_aLocation, m_aNameBase, m_aComment,
2888 0 : getFileAccess(), bUsedForStore, bStoreAll, bKillAll );
2889 :
2890 0 : m_aLocation = URL;
2891 0 : m_bLocationChanged = true;
2892 0 : }
2893 :
2894 :
2895 :
2896 : // Private helper methods
2897 :
2898 :
2899 : // Scan locale properties files
2900 0 : void StringResourceWithLocationImpl::implScanLocales()
2901 : {
2902 0 : const Reference< ucb::XSimpleFileAccess3 > xFileAccess = getFileAccess();
2903 0 : if( xFileAccess.is() && xFileAccess->isFolder( m_aLocation ) )
2904 : {
2905 0 : Sequence< OUString > aContentSeq = xFileAccess->getFolderContents( m_aLocation, false );
2906 0 : implScanLocaleNames( aContentSeq );
2907 0 : }
2908 0 : }
2909 :
2910 : // Loading
2911 0 : bool StringResourceWithLocationImpl::implLoadLocale( LocaleItem* pLocaleItem )
2912 : {
2913 0 : bool bSuccess = false;
2914 :
2915 0 : const Reference< ucb::XSimpleFileAccess3 > xFileAccess = getFileAccess();
2916 0 : if( xFileAccess.is() )
2917 : {
2918 : OUString aCompleteFileName =
2919 0 : implGetPathForLocaleItem( pLocaleItem, m_aNameBase, m_aLocation );
2920 :
2921 0 : Reference< io::XInputStream > xInputStream;
2922 : try
2923 : {
2924 0 : xInputStream = xFileAccess->openFileRead( aCompleteFileName );
2925 : }
2926 0 : catch( Exception& )
2927 : {}
2928 0 : if( xInputStream.is() )
2929 : {
2930 0 : bSuccess = StringResourcePersistenceImpl::implReadPropertiesFile( pLocaleItem, xInputStream );
2931 0 : xInputStream->closeInput();
2932 0 : }
2933 : }
2934 :
2935 0 : return bSuccess;
2936 : }
2937 :
2938 0 : const Reference< ucb::XSimpleFileAccess3 > StringResourceWithLocationImpl::getFileAccess()
2939 : {
2940 0 : ::osl::MutexGuard aGuard( getMutex() );
2941 :
2942 0 : if( !m_xSFI.is() )
2943 : {
2944 0 : m_xSFI = ucb::SimpleFileAccess::create(m_xContext);
2945 :
2946 0 : if( m_xSFI.is() && m_xInteractionHandler.is() )
2947 0 : m_xSFI->setInteractionHandler( m_xInteractionHandler );
2948 : }
2949 0 : return m_xSFI;
2950 : }
2951 :
2952 :
2953 :
2954 : // component export operations
2955 :
2956 :
2957 : static const struct ::cppu::ImplementationEntry s_component_entries [] =
2958 : {
2959 : {
2960 : create_StringResourceImpl, getImplementationName_StringResourceImpl,
2961 : getSupportedServiceNames_StringResourceImpl,
2962 : ::cppu::createSingleComponentFactory,
2963 : 0, 0
2964 : },
2965 : {
2966 : create_StringResourceWithLocationImpl, getImplementationName_StringResourceWithLocationImpl,
2967 : getSupportedServiceNames_StringResourceWithLocationImpl,
2968 : ::cppu::createSingleComponentFactory,
2969 : 0, 0
2970 : },
2971 : {
2972 : create_StringResourceWithStorageImpl, getImplementationName_StringResourceWithStorageImpl,
2973 : getSupportedServiceNames_StringResourceWithStorageImpl,
2974 : ::cppu::createSingleComponentFactory,
2975 : 0, 0
2976 : },
2977 : { 0, 0, 0, 0, 0, 0 }
2978 : };
2979 :
2980 :
2981 :
2982 : } // namespace dlgprov
2983 :
2984 :
2985 :
2986 :
2987 : // component exports
2988 :
2989 :
2990 : extern "C"
2991 : {
2992 1 : SAL_DLLPUBLIC_EXPORT void * SAL_CALL stringresource_component_getFactory(
2993 : const sal_Char * pImplName, void * pServiceManager,
2994 : void * pRegistryKey )
2995 : {
2996 : return ::cppu::component_getFactoryHelper(
2997 1 : pImplName, pServiceManager, pRegistryKey, ::stringresource::s_component_entries );
2998 : }
2999 : }
3000 :
3001 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|