1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_connectivity.hxx"
26 #include "resource/sharedresources.hxx"
27 
28 #include <comphelper/processfactory.hxx>
29 #include <comphelper/officeresourcebundle.hxx>
30 
31 /** === begin UNO includes === **/
32 #include <com/sun/star/beans/XPropertySet.hpp>
33 #include <com/sun/star/uno/XComponentContext.hpp>
34 /** === end UNO includes === **/
35 
36 #include <tools/diagnose_ex.h>
37 #include <osl/diagnose.h>
38 
39 //........................................................................
40 namespace connectivity
41 {
42 //........................................................................
43 
44 	/** === begin UNO using === **/
45     using ::com::sun::star::uno::Reference;
46     using ::com::sun::star::beans::XPropertySet;
47     using ::com::sun::star::uno::UNO_QUERY_THROW;
48     using ::com::sun::star::uno::XComponentContext;
49     using ::com::sun::star::uno::Exception;
50 	/** === end UNO using === **/
51 
52 	//====================================================================
53 	//= SharedResources_Impl
54 	//====================================================================
55     class SharedResources_Impl
56     {
57     private:
58         static  SharedResources_Impl*   s_pInstance;
59         static  oslInterlockedCount     s_nClients;
60 
61     private:
62         ::std::auto_ptr< ::comphelper::OfficeResourceBundle >
63                                         m_pResourceBundle;
64 
65     public:
66         static void     registerClient();
67         static void     revokeClient();
68 
69         static SharedResources_Impl&
70                         getInstance();
71 
72         ::rtl::OUString getResourceString( ResourceId _nId );
73 
74     private:
75         SharedResources_Impl();
76 
getMutex()77         static ::osl::Mutex& getMutex()
78         {
79             static ::osl::Mutex s_aMutex;
80             return s_aMutex;
81         }
82     };
83 
84 	//--------------------------------------------------------------------
85     SharedResources_Impl*   SharedResources_Impl::s_pInstance( NULL );
86     oslInterlockedCount     SharedResources_Impl::s_nClients( 0 );
87 
88 	//--------------------------------------------------------------------
SharedResources_Impl()89     SharedResources_Impl::SharedResources_Impl()
90     {
91         try
92         {
93             Reference< XPropertySet > xFactoryProps(
94                 ::comphelper::getProcessServiceFactory(), UNO_QUERY_THROW );
95             Reference< XComponentContext > xContext(
96                 xFactoryProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ) ) ),
97                 UNO_QUERY_THROW
98             );
99             m_pResourceBundle.reset( new ::comphelper::OfficeResourceBundle( xContext, "cnr" ) );
100         }
101         catch( const Exception& )
102         {
103             DBG_UNHANDLED_EXCEPTION();
104         }
105     }
106 
107     //--------------------------------------------------------------------
getResourceString(ResourceId _nId)108     ::rtl::OUString SharedResources_Impl::getResourceString( ResourceId _nId )
109     {
110         if ( m_pResourceBundle.get() == NULL )
111             // this should never happen, but we gracefully ignore it. It has been reported
112             // in the constructor in non-product builds.
113             return ::rtl::OUString();
114 
115         return m_pResourceBundle->loadString( _nId );
116     }
117 
118 	//--------------------------------------------------------------------
registerClient()119     void SharedResources_Impl::registerClient()
120     {
121         osl_incrementInterlockedCount( &s_nClients );
122     }
123 
124 	//--------------------------------------------------------------------
revokeClient()125     void SharedResources_Impl::revokeClient()
126     {
127         ::osl::MutexGuard aGuard( getMutex() );
128         if ( 0 == osl_decrementInterlockedCount( &s_nClients ) )
129         {
130             delete s_pInstance;
131             s_pInstance = NULL;
132         }
133     }
134 
135 	//--------------------------------------------------------------------
getInstance()136     SharedResources_Impl& SharedResources_Impl::getInstance()
137     {
138         ::osl::MutexGuard aGuard( getMutex() );
139         OSL_ENSURE( s_nClients > 0, "SharedResources_Impl::getInstance: no active clients!" );
140 
141         if ( !s_pInstance )
142             s_pInstance = new SharedResources_Impl;
143 
144         return *s_pInstance;
145     }
146 
147     //====================================================================
148 	//= helpers
149 	//====================================================================
150     namespace
151     {
lcl_substitute(::rtl::OUString & _inout_rString,const sal_Char * _pAsciiPattern,const::rtl::OUString & _rReplace)152         size_t lcl_substitute( ::rtl::OUString& _inout_rString,
153             const sal_Char* _pAsciiPattern, const ::rtl::OUString& _rReplace )
154         {
155             size_t nOccurences = 0;
156 
157             ::rtl::OUString sPattern( ::rtl::OUString::createFromAscii( _pAsciiPattern ) );
158             sal_Int32 nIndex = 0;
159             while ( ( nIndex = _inout_rString.indexOf( sPattern ) ) > -1 )
160             {
161                 ++nOccurences;
162                 _inout_rString = _inout_rString.replaceAt( nIndex, sPattern.getLength(), _rReplace );
163             }
164 
165             return nOccurences;
166         }
167     }
168 
169     //====================================================================
170 	//= SharedResources
171 	//====================================================================
172 	//--------------------------------------------------------------------
SharedResources()173     SharedResources::SharedResources()
174     {
175         SharedResources_Impl::registerClient();
176     }
177 
178 	//--------------------------------------------------------------------
~SharedResources()179     SharedResources::~SharedResources()
180     {
181         SharedResources_Impl::revokeClient();
182     }
183 
184 	//--------------------------------------------------------------------
getResourceString(ResourceId _nResId) const185     ::rtl::OUString SharedResources::getResourceString( ResourceId _nResId ) const
186     {
187         return SharedResources_Impl::getInstance().getResourceString( _nResId );
188     }
189 
190 	//--------------------------------------------------------------------
getResourceStringWithSubstitution(ResourceId _nResId,const sal_Char * _pAsciiPatternToReplace,const::rtl::OUString & _rStringToSubstitute) const191     ::rtl::OUString SharedResources::getResourceStringWithSubstitution( ResourceId _nResId,
192                 const sal_Char* _pAsciiPatternToReplace, const ::rtl::OUString& _rStringToSubstitute ) const
193     {
194         ::rtl::OUString sString( SharedResources_Impl::getInstance().getResourceString( _nResId ) );
195         OSL_VERIFY( lcl_substitute( sString, _pAsciiPatternToReplace, _rStringToSubstitute ) );
196         return sString;
197     }
198 
199 	//--------------------------------------------------------------------
getResourceStringWithSubstitution(ResourceId _nResId,const sal_Char * _pAsciiPatternToReplace1,const::rtl::OUString & _rStringToSubstitute1,const sal_Char * _pAsciiPatternToReplace2,const::rtl::OUString & _rStringToSubstitute2) const200     ::rtl::OUString SharedResources::getResourceStringWithSubstitution( ResourceId _nResId,
201                 const sal_Char* _pAsciiPatternToReplace1, const ::rtl::OUString& _rStringToSubstitute1,
202                 const sal_Char* _pAsciiPatternToReplace2, const ::rtl::OUString& _rStringToSubstitute2 ) const
203     {
204         ::rtl::OUString sString( SharedResources_Impl::getInstance().getResourceString( _nResId ) );
205         OSL_VERIFY( lcl_substitute( sString, _pAsciiPatternToReplace1, _rStringToSubstitute1 ) );
206         OSL_VERIFY( lcl_substitute( sString, _pAsciiPatternToReplace2, _rStringToSubstitute2 ) );
207         return sString;
208     }
209 
210 	//--------------------------------------------------------------------
getResourceStringWithSubstitution(ResourceId _nResId,const sal_Char * _pAsciiPatternToReplace1,const::rtl::OUString & _rStringToSubstitute1,const sal_Char * _pAsciiPatternToReplace2,const::rtl::OUString & _rStringToSubstitute2,const sal_Char * _pAsciiPatternToReplace3,const::rtl::OUString & _rStringToSubstitute3) const211     ::rtl::OUString SharedResources::getResourceStringWithSubstitution( ResourceId _nResId,
212                 const sal_Char* _pAsciiPatternToReplace1, const ::rtl::OUString& _rStringToSubstitute1,
213                 const sal_Char* _pAsciiPatternToReplace2, const ::rtl::OUString& _rStringToSubstitute2,
214                 const sal_Char* _pAsciiPatternToReplace3, const ::rtl::OUString& _rStringToSubstitute3 ) const
215     {
216         ::rtl::OUString sString( SharedResources_Impl::getInstance().getResourceString( _nResId ) );
217         OSL_VERIFY( lcl_substitute( sString, _pAsciiPatternToReplace1, _rStringToSubstitute1 ) );
218         OSL_VERIFY( lcl_substitute( sString, _pAsciiPatternToReplace2, _rStringToSubstitute2 ) );
219         OSL_VERIFY( lcl_substitute( sString, _pAsciiPatternToReplace3, _rStringToSubstitute3 ) );
220         return sString;
221     }
222     //--------------------------------------------------------------------
getResourceStringWithSubstitution(ResourceId _nResId,const::std::list<::std::pair<const sal_Char *,::rtl::OUString>> _aStringToSubstitutes) const223     ::rtl::OUString SharedResources::getResourceStringWithSubstitution( ResourceId _nResId,
224                     const ::std::list< ::std::pair<const sal_Char* , ::rtl::OUString > > _aStringToSubstitutes) const
225     {
226         ::rtl::OUString sString( SharedResources_Impl::getInstance().getResourceString( _nResId ) );
227         ::std::list< ::std::pair<const sal_Char* , ::rtl::OUString > >::const_iterator aIter = _aStringToSubstitutes.begin();
228         ::std::list< ::std::pair<const sal_Char* , ::rtl::OUString > >::const_iterator aEnd  = _aStringToSubstitutes.end();
229         for(;aIter != aEnd; ++aIter)
230             OSL_VERIFY( lcl_substitute( sString, aIter->first, aIter->second ) );
231 
232         return sString;
233     }
234 
235 //........................................................................
236 } // namespace connectivity
237 //........................................................................
238 
239