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