PageRenderTime 59ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/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

Large files files are truncated, but you can click here to view the full file

  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++

Large files files are truncated, but you can click here to view the full file