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