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