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