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