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_unotools.hxx"
26
27 #include <unotools/atom.hxx>
28
29 using namespace utl;
30 using namespace ::com::sun::star::uno;
31 using namespace ::com::sun::star::util;
32 #define NMSP_UTIL ::com::sun::star::util
33
AtomProvider()34 AtomProvider::AtomProvider()
35 {
36 m_nAtoms = 1;
37 }
38
~AtomProvider()39 AtomProvider::~AtomProvider()
40 {
41 }
42
getAtom(const::rtl::OUString & rString,sal_Bool bCreate)43 int AtomProvider::getAtom( const ::rtl::OUString& rString, sal_Bool bCreate )
44 {
45 ::std::hash_map< ::rtl::OUString, int, ::rtl::OUStringHash >::iterator it = m_aAtomMap.find( rString );
46 if( it != m_aAtomMap.end() )
47 return it->second;
48 if( ! bCreate )
49 return INVALID_ATOM;
50 m_aAtomMap[ rString ] = m_nAtoms;
51 m_aStringMap[ m_nAtoms ] = rString;
52 m_nAtoms++;
53 return m_nAtoms-1;
54 }
55
getAll(::std::list<::utl::AtomDescription> & atoms)56 void AtomProvider::getAll( ::std::list< ::utl::AtomDescription >& atoms )
57 {
58 atoms.clear();
59 ::std::hash_map< ::rtl::OUString, int, ::rtl::OUStringHash >::const_iterator it = m_aAtomMap.begin();
60
61 ::utl::AtomDescription aDesc;
62 while( it != m_aAtomMap.end() )
63 {
64 aDesc.atom = it->second;
65 aDesc.description = it->first;
66 atoms.push_back( aDesc );
67 ++it;
68 }
69 }
70
getRecent(int atom,::std::list<::utl::AtomDescription> & atoms)71 void AtomProvider::getRecent( int atom, ::std::list< ::utl::AtomDescription >& atoms )
72 {
73 atoms.clear();
74
75 ::std::hash_map< ::rtl::OUString, int, ::rtl::OUStringHash >::const_iterator it = m_aAtomMap.begin();
76
77 ::utl::AtomDescription aDesc;
78 while( it != m_aAtomMap.end() )
79 {
80 if( it->second > atom )
81 {
82 aDesc.atom = it->second;
83 aDesc.description = it->first;
84 atoms.push_back( aDesc );
85 }
86 ++it;
87 }
88 }
89
getString(int nAtom) const90 const ::rtl::OUString& AtomProvider::getString( int nAtom ) const
91 {
92 static ::rtl::OUString aEmpty;
93 ::std::hash_map< int, ::rtl::OUString, ::std::hash< int > >::const_iterator it = m_aStringMap.find( nAtom );
94
95 return it == m_aStringMap.end() ? aEmpty : it->second;
96 }
97
overrideAtom(int atom,const::rtl::OUString & description)98 void AtomProvider::overrideAtom( int atom, const ::rtl::OUString& description )
99 {
100 m_aAtomMap[ description ] = atom;
101 m_aStringMap[ atom ] = description;
102 if( m_nAtoms <= atom )
103 m_nAtoms=atom+1;
104 }
105
hasAtom(int atom) const106 sal_Bool AtomProvider::hasAtom( int atom ) const
107 {
108 return m_aStringMap.find( atom ) != m_aStringMap.end() ? sal_True : sal_False;
109 }
110
111 // -----------------------------------------------------------------------
112
MultiAtomProvider()113 MultiAtomProvider::MultiAtomProvider()
114 {
115 }
116
~MultiAtomProvider()117 MultiAtomProvider::~MultiAtomProvider()
118 {
119 for( ::std::hash_map< int, AtomProvider*, ::std::hash< int > >::iterator it = m_aAtomLists.begin(); it != m_aAtomLists.end(); ++it )
120 delete it->second;
121 }
122
123
insertAtomClass(int atomClass)124 sal_Bool MultiAtomProvider::insertAtomClass( int atomClass )
125 {
126 ::std::hash_map< int, AtomProvider*, ::std::hash< int > >::iterator it =
127 m_aAtomLists.find( atomClass );
128 if( it != m_aAtomLists.end() )
129 return sal_False;
130 m_aAtomLists[ atomClass ] = new AtomProvider();
131 return sal_True;
132 }
133
getAtom(int atomClass,const::rtl::OUString & rString,sal_Bool bCreate)134 int MultiAtomProvider::getAtom( int atomClass, const ::rtl::OUString& rString, sal_Bool bCreate )
135 {
136 ::std::hash_map< int, AtomProvider*, ::std::hash< int > >::iterator it =
137 m_aAtomLists.find( atomClass );
138 if( it != m_aAtomLists.end() )
139 return it->second->getAtom( rString, bCreate );
140
141 if( bCreate )
142 {
143 AtomProvider* pNewClass;
144 m_aAtomLists[ atomClass ] = pNewClass = new AtomProvider();
145 return pNewClass->getAtom( rString, bCreate );
146 }
147 return INVALID_ATOM;
148 }
149
getLastAtom(int atomClass) const150 int MultiAtomProvider::getLastAtom( int atomClass ) const
151 {
152 ::std::hash_map< int, AtomProvider*, ::std::hash< int > >::const_iterator it =
153 m_aAtomLists.find( atomClass );
154
155 return it != m_aAtomLists.end() ? it->second->getLastAtom() : INVALID_ATOM;
156 }
157
getRecent(int atomClass,int atom,::std::list<::utl::AtomDescription> & atoms)158 void MultiAtomProvider::getRecent( int atomClass, int atom, ::std::list< ::utl::AtomDescription >& atoms )
159 {
160 ::std::hash_map< int, AtomProvider*, ::std::hash< int > >::const_iterator it =
161 m_aAtomLists.find( atomClass );
162 if( it != m_aAtomLists.end() )
163 it->second->getRecent( atom, atoms );
164 else
165 atoms.clear();
166 }
167
getString(int atomClass,int atom) const168 const ::rtl::OUString& MultiAtomProvider::getString( int atomClass, int atom ) const
169 {
170 ::std::hash_map< int, AtomProvider*, ::std::hash< int > >::const_iterator it =
171 m_aAtomLists.find( atomClass );
172 if( it != m_aAtomLists.end() )
173 return it->second->getString( atom );
174
175 static ::rtl::OUString aEmpty;
176 return aEmpty;
177 }
178
hasAtom(int atomClass,int atom) const179 sal_Bool MultiAtomProvider::hasAtom( int atomClass, int atom ) const
180 {
181 ::std::hash_map< int, AtomProvider*, ::std::hash< int > >::const_iterator it = m_aAtomLists.find( atomClass );
182 return it != m_aAtomLists.end() ? it->second->hasAtom( atom ) : sal_False;
183 }
184
getClass(int atomClass,::std::list<::utl::AtomDescription> & atoms) const185 void MultiAtomProvider::getClass( int atomClass, ::std::list< ::utl::AtomDescription >& atoms) const
186 {
187 ::std::hash_map< int, AtomProvider*, ::std::hash< int > >::const_iterator it = m_aAtomLists.find( atomClass );
188
189 if( it != m_aAtomLists.end() )
190 it->second->getAll( atoms );
191 else
192 atoms.clear();
193 }
194
overrideAtom(int atomClass,int atom,const::rtl::OUString & description)195 void MultiAtomProvider::overrideAtom( int atomClass, int atom, const ::rtl::OUString& description )
196 {
197 ::std::hash_map< int, AtomProvider*, ::std::hash< int > >::const_iterator it = m_aAtomLists.find( atomClass );
198 if( it == m_aAtomLists.end() )
199 m_aAtomLists[ atomClass ] = new AtomProvider();
200 m_aAtomLists[ atomClass ]->overrideAtom( atom, description );
201 }
202
203 // -----------------------------------------------------------------------
204
AtomServer()205 AtomServer::AtomServer()
206 {
207 }
208
~AtomServer()209 AtomServer::~AtomServer()
210 {
211 }
212
getAtom(sal_Int32 atomClass,const::rtl::OUString & description,sal_Bool create)213 sal_Int32 AtomServer::getAtom( sal_Int32 atomClass, const ::rtl::OUString& description, sal_Bool create ) throw()
214 {
215 ::osl::Guard< ::osl::Mutex > guard( m_aMutex );
216
217 return m_aProvider.getAtom( atomClass, description, create );
218 }
219
getClasses(const Sequence<sal_Int32> & atomClasses)220 Sequence< Sequence< NMSP_UTIL::AtomDescription > > AtomServer::getClasses( const Sequence< sal_Int32 >& atomClasses ) throw()
221 {
222 ::osl::Guard< ::osl::Mutex > guard( m_aMutex );
223
224 Sequence< Sequence< NMSP_UTIL::AtomDescription > > aRet( atomClasses.getLength() );
225 for( int i = 0; i < atomClasses.getLength(); i++ )
226 {
227 aRet.getArray()[i] = getClass( atomClasses.getConstArray()[i] );
228 }
229 return aRet;
230 }
231
getClass(sal_Int32 atomClass)232 Sequence< NMSP_UTIL::AtomDescription > AtomServer::getClass( sal_Int32 atomClass ) throw()
233 {
234 ::osl::Guard< ::osl::Mutex > guard( m_aMutex );
235
236 ::std::list< ::utl::AtomDescription > atoms;
237 m_aProvider.getClass( atomClass, atoms );
238
239 Sequence< NMSP_UTIL::AtomDescription > aRet( atoms.size() );
240 for( int i = aRet.getLength()-1; i >= 0; i-- )
241 {
242 aRet.getArray()[i].atom = atoms.back().atom;
243 aRet.getArray()[i].description = atoms.back().description;
244 atoms.pop_back();
245 }
246
247 return aRet;
248 }
249
getRecentAtoms(sal_Int32 atomClass,sal_Int32 atom)250 Sequence< NMSP_UTIL::AtomDescription > AtomServer::getRecentAtoms( sal_Int32 atomClass, sal_Int32 atom ) throw()
251 {
252 ::osl::Guard< ::osl::Mutex > guard( m_aMutex );
253
254 ::std::list< ::utl::AtomDescription > atoms;
255 m_aProvider.getRecent( atomClass, atom, atoms );
256
257 Sequence< NMSP_UTIL::AtomDescription > aRet( atoms.size() );
258 for( int i = aRet.getLength()-1; i >= 0; i-- )
259 {
260 aRet.getArray()[i].atom = atoms.back().atom;
261 aRet.getArray()[i].description = atoms.back().description;
262 atoms.pop_back();
263 }
264
265 return aRet;
266 }
267
getAtomDescriptions(const Sequence<AtomClassRequest> & atoms)268 Sequence< ::rtl::OUString > AtomServer::getAtomDescriptions( const Sequence< AtomClassRequest >& atoms ) throw()
269 {
270 ::osl::Guard< ::osl::Mutex > guard( m_aMutex );
271
272 int nStrings = 0, i;
273 for( i = 0; i < atoms.getLength(); i++ )
274 nStrings += atoms.getConstArray()[ i ].atoms.getLength();
275 Sequence< ::rtl::OUString > aRet( nStrings );
276 for( i = 0, nStrings = 0; i < atoms.getLength(); i++ )
277 {
278 const AtomClassRequest& rRequest = atoms.getConstArray()[i];
279 for( int n = 0; n < rRequest.atoms.getLength(); n++ )
280 aRet.getArray()[ nStrings++ ] = m_aProvider.getString( rRequest.atomClass, rRequest.atoms.getConstArray()[ n ] );
281 }
282 return aRet;
283 }
284
285 // -----------------------------------------------------------------------
286
AtomClient(const Reference<XAtomServer> & xServer)287 AtomClient::AtomClient( const Reference< XAtomServer >& xServer ) :
288 m_xServer( xServer )
289 {
290 }
291
~AtomClient()292 AtomClient::~AtomClient()
293 {
294 }
295
getAtom(int atomClass,const::rtl::OUString & description,sal_Bool bCreate)296 int AtomClient::getAtom( int atomClass, const ::rtl::OUString& description, sal_Bool bCreate )
297 {
298 int nAtom = m_aProvider.getAtom( atomClass, description, sal_False );
299 if( nAtom == INVALID_ATOM && bCreate )
300 {
301 try
302 {
303 nAtom = m_xServer->getAtom( atomClass, description, bCreate );
304 }
305 catch( RuntimeException& )
306 {
307 return INVALID_ATOM;
308 }
309 if( nAtom != INVALID_ATOM )
310 m_aProvider.overrideAtom( atomClass, nAtom, description );
311 }
312 return nAtom;
313 }
314
getString(int atomClass,int atom)315 const ::rtl::OUString& AtomClient::getString( int atomClass, int atom )
316 {
317 static ::rtl::OUString aEmpty;
318
319 if( ! m_aProvider.hasAtom( atomClass, atom ) )
320 {
321 Sequence< NMSP_UTIL::AtomDescription > aSeq;
322 try
323 {
324 aSeq = m_xServer->getRecentAtoms( atomClass, m_aProvider.getLastAtom( atomClass ) );
325 }
326 catch( RuntimeException& )
327 {
328 return aEmpty;
329 }
330 const NMSP_UTIL::AtomDescription* pDescriptions = aSeq.getConstArray();
331 for( int i = 0; i < aSeq.getLength(); i++ )
332 m_aProvider.overrideAtom( atomClass,
333 pDescriptions[i].atom,
334 pDescriptions[i].description
335 );
336
337 if( ! m_aProvider.hasAtom( atomClass, atom ) )
338 {
339 // holes may occur by the above procedure!
340 Sequence< AtomClassRequest > aReq( 1 );
341 aReq.getArray()[0].atomClass = atomClass;
342 aReq.getArray()[0].atoms.realloc( 1 );
343 aReq.getArray()[0].atoms.getArray()[0] = atom;
344 Sequence< ::rtl::OUString > aRet;
345 try
346 {
347 aRet = m_xServer->getAtomDescriptions( aReq );
348 }
349 catch( RuntimeException& )
350 {
351 return aEmpty;
352 }
353 if( aRet.getLength() == 1 )
354 m_aProvider.overrideAtom( atomClass, atom, aRet.getConstArray()[0] );
355 }
356 }
357 return m_aProvider.getString( atomClass, atom );
358 }
359
updateAtomClasses(const Sequence<sal_Int32> & atomClasses)360 void AtomClient::updateAtomClasses( const Sequence< sal_Int32 >& atomClasses )
361 {
362 Sequence< Sequence< NMSP_UTIL::AtomDescription > > aUpdate;
363 try
364 {
365 aUpdate = m_xServer->getClasses( atomClasses );
366 }
367 catch( RuntimeException& )
368 {
369 return;
370 }
371 for( int i = 0; i < atomClasses.getLength(); i++ )
372 {
373 int nClass = atomClasses.getConstArray()[i];
374 const Sequence< NMSP_UTIL::AtomDescription >& rClass = aUpdate.getConstArray()[i];
375 const NMSP_UTIL::AtomDescription* pDesc = rClass.getConstArray();
376 for( int n = 0; n < rClass.getLength(); n++, pDesc++ )
377 m_aProvider.overrideAtom( nClass, pDesc->atom, pDesc->description );
378 }
379 }
380