1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_connectivity.hxx"
30 #include "resource/sharedresources.hxx"
31 
32 #include <comphelper/processfactory.hxx>
33 #include <comphelper/officeresourcebundle.hxx>
34 
35 /** === begin UNO includes === **/
36 #include <com/sun/star/beans/XPropertySet.hpp>
37 #include <com/sun/star/uno/XComponentContext.hpp>
38 /** === end UNO includes === **/
39 
40 #include <tools/diagnose_ex.h>
41 #include <osl/diagnose.h>
42 
43 //........................................................................
44 namespace connectivity
45 {
46 //........................................................................
47 
48 	/** === begin UNO using === **/
49     using ::com::sun::star::uno::Reference;
50     using ::com::sun::star::beans::XPropertySet;
51     using ::com::sun::star::uno::UNO_QUERY_THROW;
52     using ::com::sun::star::uno::XComponentContext;
53     using ::com::sun::star::uno::Exception;
54 	/** === end UNO using === **/
55 
56 	//====================================================================
57 	//= SharedResources_Impl
58 	//====================================================================
59     class SharedResources_Impl
60     {
61     private:
62         static  SharedResources_Impl*   s_pInstance;
63         static  oslInterlockedCount     s_nClients;
64 
65     private:
66         ::std::auto_ptr< ::comphelper::OfficeResourceBundle >
67                                         m_pResourceBundle;
68 
69     public:
70         static void     registerClient();
71         static void     revokeClient();
72 
73         static SharedResources_Impl&
74                         getInstance();
75 
76         ::rtl::OUString getResourceString( ResourceId _nId );
77 
78     private:
79         SharedResources_Impl();
80 
81         static ::osl::Mutex& getMutex()
82         {
83             static ::osl::Mutex s_aMutex;
84             return s_aMutex;
85         }
86     };
87 
88 	//--------------------------------------------------------------------
89     SharedResources_Impl*   SharedResources_Impl::s_pInstance( NULL );
90     oslInterlockedCount     SharedResources_Impl::s_nClients( 0 );
91 
92 	//--------------------------------------------------------------------
93     SharedResources_Impl::SharedResources_Impl()
94     {
95         try
96         {
97             Reference< XPropertySet > xFactoryProps(
98                 ::comphelper::getProcessServiceFactory(), UNO_QUERY_THROW );
99             Reference< XComponentContext > xContext(
100                 xFactoryProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ) ) ),
101                 UNO_QUERY_THROW
102             );
103             m_pResourceBundle.reset( new ::comphelper::OfficeResourceBundle( xContext, "cnr" ) );
104         }
105         catch( const Exception& )
106         {
107             DBG_UNHANDLED_EXCEPTION();
108         }
109     }
110 
111     //--------------------------------------------------------------------
112     ::rtl::OUString SharedResources_Impl::getResourceString( ResourceId _nId )
113     {
114         if ( m_pResourceBundle.get() == NULL )
115             // this should never happen, but we gracefully ignore it. It has been reported
116             // in the constructor in non-product builds.
117             return ::rtl::OUString();
118 
119         return m_pResourceBundle->loadString( _nId );
120     }
121 
122 	//--------------------------------------------------------------------
123     void SharedResources_Impl::registerClient()
124     {
125         osl_incrementInterlockedCount( &s_nClients );
126     }
127 
128 	//--------------------------------------------------------------------
129     void SharedResources_Impl::revokeClient()
130     {
131         ::osl::MutexGuard aGuard( getMutex() );
132         if ( 0 == osl_decrementInterlockedCount( &s_nClients ) )
133         {
134             delete s_pInstance;
135             s_pInstance = NULL;
136         }
137     }
138 
139 	//--------------------------------------------------------------------
140     SharedResources_Impl& SharedResources_Impl::getInstance()
141     {
142         ::osl::MutexGuard aGuard( getMutex() );
143         OSL_ENSURE( s_nClients > 0, "SharedResources_Impl::getInstance: no active clients!" );
144 
145         if ( !s_pInstance )
146             s_pInstance = new SharedResources_Impl;
147 
148         return *s_pInstance;
149     }
150 
151     //====================================================================
152 	//= helpers
153 	//====================================================================
154     namespace
155     {
156         size_t lcl_substitute( ::rtl::OUString& _inout_rString,
157             const sal_Char* _pAsciiPattern, const ::rtl::OUString& _rReplace )
158         {
159             size_t nOccurences = 0;
160 
161             ::rtl::OUString sPattern( ::rtl::OUString::createFromAscii( _pAsciiPattern ) );
162             sal_Int32 nIndex = 0;
163             while ( ( nIndex = _inout_rString.indexOf( sPattern ) ) > -1 )
164             {
165                 ++nOccurences;
166                 _inout_rString = _inout_rString.replaceAt( nIndex, sPattern.getLength(), _rReplace );
167             }
168 
169             return nOccurences;
170         }
171     }
172 
173     //====================================================================
174 	//= SharedResources
175 	//====================================================================
176 	//--------------------------------------------------------------------
177     SharedResources::SharedResources()
178     {
179         SharedResources_Impl::registerClient();
180     }
181 
182 	//--------------------------------------------------------------------
183     SharedResources::~SharedResources()
184     {
185         SharedResources_Impl::revokeClient();
186     }
187 
188 	//--------------------------------------------------------------------
189     ::rtl::OUString SharedResources::getResourceString( ResourceId _nResId ) const
190     {
191         return SharedResources_Impl::getInstance().getResourceString( _nResId );
192     }
193 
194 	//--------------------------------------------------------------------
195     ::rtl::OUString SharedResources::getResourceStringWithSubstitution( ResourceId _nResId,
196                 const sal_Char* _pAsciiPatternToReplace, const ::rtl::OUString& _rStringToSubstitute ) const
197     {
198         ::rtl::OUString sString( SharedResources_Impl::getInstance().getResourceString( _nResId ) );
199         OSL_VERIFY( lcl_substitute( sString, _pAsciiPatternToReplace, _rStringToSubstitute ) );
200         return sString;
201     }
202 
203 	//--------------------------------------------------------------------
204     ::rtl::OUString SharedResources::getResourceStringWithSubstitution( ResourceId _nResId,
205                 const sal_Char* _pAsciiPatternToReplace1, const ::rtl::OUString& _rStringToSubstitute1,
206                 const sal_Char* _pAsciiPatternToReplace2, const ::rtl::OUString& _rStringToSubstitute2 ) const
207     {
208         ::rtl::OUString sString( SharedResources_Impl::getInstance().getResourceString( _nResId ) );
209         OSL_VERIFY( lcl_substitute( sString, _pAsciiPatternToReplace1, _rStringToSubstitute1 ) );
210         OSL_VERIFY( lcl_substitute( sString, _pAsciiPatternToReplace2, _rStringToSubstitute2 ) );
211         return sString;
212     }
213 
214 	//--------------------------------------------------------------------
215     ::rtl::OUString SharedResources::getResourceStringWithSubstitution( ResourceId _nResId,
216                 const sal_Char* _pAsciiPatternToReplace1, const ::rtl::OUString& _rStringToSubstitute1,
217                 const sal_Char* _pAsciiPatternToReplace2, const ::rtl::OUString& _rStringToSubstitute2,
218                 const sal_Char* _pAsciiPatternToReplace3, const ::rtl::OUString& _rStringToSubstitute3 ) const
219     {
220         ::rtl::OUString sString( SharedResources_Impl::getInstance().getResourceString( _nResId ) );
221         OSL_VERIFY( lcl_substitute( sString, _pAsciiPatternToReplace1, _rStringToSubstitute1 ) );
222         OSL_VERIFY( lcl_substitute( sString, _pAsciiPatternToReplace2, _rStringToSubstitute2 ) );
223         OSL_VERIFY( lcl_substitute( sString, _pAsciiPatternToReplace3, _rStringToSubstitute3 ) );
224         return sString;
225     }
226     //--------------------------------------------------------------------
227     ::rtl::OUString SharedResources::getResourceStringWithSubstitution( ResourceId _nResId,
228                     const ::std::list< ::std::pair<const sal_Char* , ::rtl::OUString > > _aStringToSubstitutes) const
229     {
230         ::rtl::OUString sString( SharedResources_Impl::getInstance().getResourceString( _nResId ) );
231         ::std::list< ::std::pair<const sal_Char* , ::rtl::OUString > >::const_iterator aIter = _aStringToSubstitutes.begin();
232         ::std::list< ::std::pair<const sal_Char* , ::rtl::OUString > >::const_iterator aEnd  = _aStringToSubstitutes.end();
233         for(;aIter != aEnd; ++aIter)
234             OSL_VERIFY( lcl_substitute( sString, aIter->first, aIter->second ) );
235 
236         return sString;
237     }
238 
239 //........................................................................
240 } // namespace connectivity
241 //........................................................................
242 
243