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