PageRenderTime 259ms CodeModel.GetById 108ms RepoModel.GetById 2ms app.codeStats 1ms

/scripting/source/stringresource/stringresource.cxx

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