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