PageRenderTime 38ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/libreoffice-3.6.0.2/scripting/source/stringresource/stringresource.cxx

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