Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : /**************************************************************************
31 : : TODO
32 : : **************************************************************************
33 : :
34 : : *************************************************************************/
35 : : #include <osl/diagnose.h>
36 : : #include <cppuhelper/interfacecontainer.hxx>
37 : : #include <com/sun/star/lang/IllegalArgumentException.hpp>
38 : : #include <com/sun/star/ucb/GlobalTransferCommandArgument.hpp>
39 : : #include <com/sun/star/ucb/XCommandInfo.hpp>
40 : : #include <com/sun/star/ucb/XContentProvider.hpp>
41 : : #include <com/sun/star/ucb/XContentProviderSupplier.hpp>
42 : : #include <com/sun/star/ucb/XParameterizedContentProvider.hpp>
43 : : #include <com/sun/star/ucb/XContentProviderFactory.hpp>
44 : : #include <com/sun/star/beans/PropertyValue.hpp>
45 : : #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
46 : : #include <com/sun/star/container/XNameAccess.hpp>
47 : : #include <com/sun/star/uno/Any.hxx>
48 : : #include <ucbhelper/cancelcommandexecution.hxx>
49 : : #include "identify.hxx"
50 : : #include "ucbcmds.hxx"
51 : :
52 : : #include "ucb.hxx"
53 : :
54 : : // Definitions for ProviderMap_Impl (Solaris wouldn't find explicit template
55 : : // instantiations for these in another compilation unit...):
56 : : #ifndef _UCB_REGEXPMAP_TPT_
57 : : #include <regexpmap.tpt>
58 : : #endif
59 : :
60 : : using namespace cppu;
61 : : using namespace com::sun::star::uno;
62 : : using namespace com::sun::star::lang;
63 : : using namespace com::sun::star::ucb;
64 : : using namespace ucb_impl;
65 : : using namespace com::sun::star;
66 : : using namespace ucbhelper;
67 : :
68 : : using ::rtl::OUString;
69 : : using ::rtl::OUStringBuffer;
70 : :
71 : : #define CONFIG_CONTENTPROVIDERS_KEY \
72 : : "/org.openoffice.ucb.Configuration/ContentProviders"
73 : :
74 : :
75 : : namespace {
76 : :
77 : 3711 : bool fillPlaceholders(OUString const & rInput,
78 : : uno::Sequence< uno::Any > const & rReplacements,
79 : : OUString * pOutput)
80 : : {
81 : 3711 : sal_Unicode const * p = rInput.getStr();
82 : 3711 : sal_Unicode const * pEnd = p + rInput.getLength();
83 : 3711 : sal_Unicode const * pCopy = p;
84 : 3711 : OUStringBuffer aBuffer;
85 [ - + ]: 3711 : while (p != pEnd)
86 [ # # # ]: 0 : switch (*p++)
87 : : {
88 : : case '&':
89 [ # # ][ # # ]: 0 : if (pEnd - p >= 4
[ # # ][ # # ]
[ # # ]
90 : 0 : && p[0] == 'a' && p[1] == 'm' && p[2] == 'p'
91 : 0 : && p[3] == ';')
92 : : {
93 [ # # ]: 0 : aBuffer.append(pCopy, p - 1 - pCopy);
94 [ # # ]: 0 : aBuffer.append(sal_Unicode('&'));
95 : 0 : p += 4;
96 : 0 : pCopy = p;
97 : : }
98 [ # # ][ # # ]: 0 : else if (pEnd - p >= 3
[ # # ][ # # ]
99 : 0 : && p[0] == 'l' && p[1] == 't' && p[2] == ';')
100 : : {
101 [ # # ]: 0 : aBuffer.append(pCopy, p - 1 - pCopy);
102 [ # # ]: 0 : aBuffer.append(sal_Unicode('<'));
103 : 0 : p += 3;
104 : 0 : pCopy = p;
105 : : }
106 [ # # ][ # # ]: 0 : else if (pEnd - p >= 3
[ # # ][ # # ]
107 : 0 : && p[0] == 'g' && p[1] == 't' && p[2] == ';')
108 : : {
109 [ # # ]: 0 : aBuffer.append(pCopy, p - 1 - pCopy);
110 [ # # ]: 0 : aBuffer.append(sal_Unicode('>'));
111 : 0 : p += 3;
112 : 0 : pCopy = p;
113 : : }
114 : : break;
115 : :
116 : : case '<':
117 : 0 : sal_Unicode const * q = p;
118 [ # # ][ # # ]: 0 : while (q != pEnd && *q != '>')
[ # # ]
119 : 0 : ++q;
120 [ # # ]: 0 : if (q == pEnd)
121 : : break;
122 : 0 : OUString aKey(p, q - p);
123 : 0 : OUString aValue;
124 : 0 : bool bFound = false;
125 [ # # ]: 0 : for (sal_Int32 i = 2; i + 1 < rReplacements.getLength();
126 : : i += 2)
127 : : {
128 : 0 : OUString aReplaceKey;
129 [ # # ][ # # : 0 : if ((rReplacements[i] >>= aReplaceKey)
# # # # ]
130 : 0 : && aReplaceKey == aKey
131 : 0 : && (rReplacements[i + 1] >>= aValue))
132 : : {
133 : 0 : bFound = true;
134 : : break;
135 : : }
136 [ # # ]: 0 : }
137 [ # # ]: 0 : if (!bFound)
138 : 0 : return false;
139 [ # # ]: 0 : aBuffer.append(pCopy, p - 1 - pCopy);
140 [ # # ]: 0 : aBuffer.append(aValue);
141 : 0 : p = q + 1;
142 : 0 : pCopy = p;
143 [ # # ][ # # ]: 0 : break;
144 : : }
145 [ + - ]: 3711 : aBuffer.append(pCopy, pEnd - pCopy);
146 [ + - ]: 3711 : *pOutput = aBuffer.makeStringAndClear();
147 : 3711 : return true;
148 : : }
149 : :
150 : 4207 : void makeAndAppendXMLName(
151 : : OUStringBuffer & rBuffer, const OUString & rIn )
152 : : {
153 : 4207 : sal_Int32 nCount = rIn.getLength();
154 [ + + ]: 41957 : for ( sal_Int32 n = 0; n < nCount; ++n )
155 : : {
156 : 37750 : const sal_Unicode c = rIn.getStr()[ n ];
157 [ - - - - : 37750 : switch ( c )
- + ]
158 : : {
159 : : case '&':
160 : 0 : rBuffer.appendAscii( "&" );
161 : 0 : break;
162 : :
163 : : case '"':
164 : 0 : rBuffer.appendAscii( """ );
165 : 0 : break;
166 : :
167 : : case '\'':
168 : 0 : rBuffer.appendAscii( "'" );
169 : 0 : break;
170 : :
171 : : case '<':
172 : 0 : rBuffer.appendAscii( "<" );
173 : 0 : break;
174 : :
175 : : case '>':
176 : 0 : rBuffer.appendAscii( ">" );
177 : 0 : break;
178 : :
179 : : default:
180 : 37750 : rBuffer.append( c );
181 : 37750 : break;
182 : : }
183 : : }
184 : 4207 : }
185 : :
186 : 3711 : bool createContentProviderData(
187 : : const OUString & rProvider,
188 : : const uno::Reference< container::XHierarchicalNameAccess >& rxHierNameAccess,
189 : : ContentProviderData & rInfo)
190 : : {
191 : : // Obtain service name.
192 [ + - ]: 3711 : OUStringBuffer aKeyBuffer (rProvider);
193 [ + - ]: 3711 : aKeyBuffer.appendAscii( "/ServiceName" );
194 : :
195 : 3711 : OUString aValue;
196 : : try
197 : : {
198 [ + - ]: 3711 : if ( !( rxHierNameAccess->getByHierarchicalName(
199 [ + - ][ + - ]: 3711 : aKeyBuffer.makeStringAndClear() ) >>= aValue ) )
[ # # ]
200 : : {
201 : : OSL_FAIL( "UniversalContentBroker::getContentProviderData - "
202 : : "Error getting item value!" );
203 : : }
204 : : }
205 [ # # ]: 0 : catch (const container::NoSuchElementException&)
206 : : {
207 : 0 : return false;
208 : : }
209 : :
210 : 3711 : rInfo.ServiceName = aValue;
211 : :
212 : : // Obtain URL Template.
213 [ + - ]: 3711 : aKeyBuffer.append(rProvider);
214 [ + - ]: 3711 : aKeyBuffer.appendAscii( "/URLTemplate" );
215 : :
216 [ + - ]: 3711 : if ( !( rxHierNameAccess->getByHierarchicalName(
217 [ + - ][ + - ]: 3711 : aKeyBuffer.makeStringAndClear() ) >>= aValue ) )
218 : : {
219 : : OSL_FAIL( "UniversalContentBroker::getContentProviderData - "
220 : : "Error getting item value!" );
221 : : }
222 : :
223 : 3711 : rInfo.URLTemplate = aValue;
224 : :
225 : : // Obtain Arguments.
226 [ + - ]: 3711 : aKeyBuffer.append(rProvider);
227 [ + - ]: 3711 : aKeyBuffer.appendAscii( "/Arguments" );
228 : :
229 [ + - ]: 3711 : if ( !( rxHierNameAccess->getByHierarchicalName(
230 [ + - ][ + - ]: 3711 : aKeyBuffer.makeStringAndClear() ) >>= aValue ) )
231 : : {
232 : : OSL_FAIL( "UniversalContentBroker::getContentProviderData - "
233 : : "Error getting item value!" );
234 : : }
235 : :
236 : 3711 : rInfo.Arguments = aValue;
237 : 3711 : return true;
238 : : }
239 : :
240 : : }
241 : :
242 : : //=========================================================================
243 : : //
244 : : // UniversalContentBroker Implementation.
245 : : //
246 : : //=========================================================================
247 : :
248 : 250 : UniversalContentBroker::UniversalContentBroker(
249 : : const Reference< com::sun::star::lang::XMultiServiceFactory >& rXSMgr )
250 : : : m_xSMgr( rXSMgr ),
251 : : m_pDisposeEventListeners( NULL ),
252 : : m_nInitCount( 0 ), //@@@ see initialize() method
253 [ + - ][ + - ]: 250 : m_nCommandId( 0 )
[ + - ]
254 : : {
255 : : OSL_ENSURE( m_xSMgr.is(),
256 : : "UniversalContentBroker ctor: No service manager" );
257 : 250 : }
258 : :
259 : : //=========================================================================
260 : : // virtual
261 [ + - ][ + - ]: 250 : UniversalContentBroker::~UniversalContentBroker()
[ + - ]
262 : : {
263 [ + + ][ + - ]: 250 : delete m_pDisposeEventListeners;
264 [ - + ]: 500 : }
265 : :
266 : : //=========================================================================
267 : : //
268 : : // XInterface methods.
269 : : //
270 : : //=========================================================================
271 : :
272 [ + - ][ + + ]: 622577 : XINTERFACE_IMPL_8( UniversalContentBroker,
[ + - ]
273 : : XTypeProvider,
274 : : XComponent,
275 : : XServiceInfo,
276 : : XInitialization,
277 : : XContentProviderManager,
278 : : XContentProvider,
279 : : XContentIdentifierFactory,
280 : : XCommandProcessor );
281 : :
282 : : //=========================================================================
283 : : //
284 : : // XTypeProvider methods.
285 : : //
286 : : //=========================================================================
287 : :
288 [ # # ][ # # ]: 0 : XTYPEPROVIDER_IMPL_8( UniversalContentBroker,
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
289 : : XTypeProvider,
290 : : XComponent,
291 : : XServiceInfo,
292 : : XInitialization,
293 : : XContentProviderManager,
294 : : XContentProvider,
295 : : XContentIdentifierFactory,
296 : : XCommandProcessor );
297 : :
298 : : //=========================================================================
299 : : //
300 : : // XComponent methods.
301 : : //
302 : : //=========================================================================
303 : :
304 : : // virtual
305 : 1314 : void SAL_CALL UniversalContentBroker::dispose()
306 : : throw( com::sun::star::uno::RuntimeException )
307 : : {
308 [ + + ][ + + ]: 1314 : if ( m_pDisposeEventListeners && m_pDisposeEventListeners->getLength() )
[ + + ]
309 : : {
310 [ + - ]: 2 : EventObject aEvt;
311 [ + - ]: 2 : aEvt.Source = (static_cast< XComponent* >(this));
312 [ + - ][ + - ]: 2 : m_pDisposeEventListeners->disposeAndClear( aEvt );
313 : : }
314 : :
315 [ + + ]: 1314 : if ( m_xNotifier.is() )
316 [ + - ]: 1312 : m_xNotifier->removeChangesListener( this );
317 : 1314 : }
318 : :
319 : : //=========================================================================
320 : : // virtual
321 : 4 : void SAL_CALL UniversalContentBroker::addEventListener(
322 : : const Reference< XEventListener >& Listener )
323 : : throw( com::sun::star::uno::RuntimeException )
324 : : {
325 [ + + ]: 4 : if ( !m_pDisposeEventListeners )
326 [ + - ]: 2 : m_pDisposeEventListeners = new OInterfaceContainerHelper( m_aMutex );
327 : :
328 : 4 : m_pDisposeEventListeners->addInterface( Listener );
329 : 4 : }
330 : :
331 : : //=========================================================================
332 : : // virtual
333 : 2 : void SAL_CALL UniversalContentBroker::removeEventListener(
334 : : const Reference< XEventListener >& Listener )
335 : : throw( com::sun::star::uno::RuntimeException )
336 : : {
337 [ + - ]: 2 : if ( m_pDisposeEventListeners )
338 : 2 : m_pDisposeEventListeners->removeInterface( Listener );
339 : :
340 : : // Note: Don't want to delete empty container here -> performance.
341 : 2 : }
342 : :
343 : : //=========================================================================
344 : : //
345 : : // XServiceInfo methods.
346 : : //
347 : : //=========================================================================
348 : :
349 [ + - ][ + - ]: 1505 : XSERVICEINFO_IMPL_1( UniversalContentBroker,
[ + - ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
350 : : OUString( "com.sun.star.comp.ucb.UniversalContentBroker" ),
351 : 250 : OUString( UCB_SERVICE_NAME ) );
352 : :
353 : : //=========================================================================
354 : : //
355 : : // Service factory implementation.
356 : : //
357 : : //=========================================================================
358 : :
359 [ + - ][ + - ]: 250 : ONE_INSTANCE_SERVICE_FACTORY_IMPL( UniversalContentBroker );
360 : :
361 : : //=========================================================================
362 : : //
363 : : // XInitialization methods.
364 : : //
365 : : //=========================================================================
366 : :
367 : : // virtual
368 : 252 : void SAL_CALL UniversalContentBroker::initialize(
369 : : const com::sun::star::uno::Sequence< Any >& aArguments )
370 : : throw( com::sun::star::uno::Exception,
371 : : com::sun::star::uno::RuntimeException )
372 : : {
373 : : //@@@ At the moment, there's a problem when one (non-one-instance) factory
374 : : // 'wraps' another (one-instance) factory, causing this method to be
375 : : // called several times:
376 : 252 : m_aArguments = aArguments;
377 : :
378 : 252 : oslInterlockedCount nCount = osl_incrementInterlockedCount(&m_nInitCount);
379 [ + + ]: 252 : if (nCount == 1)
380 : 250 : configureUcb();
381 : : else
382 : 2 : osl_decrementInterlockedCount(&m_nInitCount);
383 : : // make the possibility of overflow less likely...
384 : 252 : }
385 : :
386 : : //=========================================================================
387 : : //
388 : : // XContentProviderManager methods.
389 : : //
390 : : //=========================================================================
391 : :
392 : : // virtual
393 : : Reference< XContentProvider > SAL_CALL
394 : 4623 : UniversalContentBroker::registerContentProvider(
395 : : const Reference< XContentProvider >& Provider,
396 : : const OUString& Scheme,
397 : : sal_Bool ReplaceExisting )
398 : : throw( DuplicateProviderException, com::sun::star::uno::RuntimeException )
399 : : {
400 [ + - ]: 4623 : osl::MutexGuard aGuard(m_aMutex);
401 : :
402 [ + - ]: 4623 : ProviderMap_Impl::iterator aIt;
403 : : try
404 : : {
405 [ + - ][ + - ]: 4623 : aIt = m_aProviders.find(Scheme);
[ + - ]
406 : : }
407 [ # # # # ]: 0 : catch (const IllegalArgumentException&)
408 : : {
409 [ # # ]: 0 : return 0; //@@@
410 : : }
411 : :
412 : 4623 : Reference< XContentProvider > xPrevious;
413 [ + - ][ + - ]: 4623 : if (aIt == m_aProviders.end())
[ + + ][ + - ]
414 : : {
415 [ + - ]: 3715 : ProviderList_Impl aList;
416 [ + - ][ + - ]: 3715 : aList.push_front(Provider);
[ + - ]
417 : : try
418 : : {
419 [ + - ][ + - ]: 7430 : m_aProviders.add(Scheme, aList, false);
420 : : }
421 [ # # # # ]: 0 : catch (const IllegalArgumentException&)
422 : : {
423 [ # # ]: 0 : return 0; //@@@
424 : 3715 : }
425 : : }
426 : : else
427 : : {
428 [ + + ]: 908 : if (!ReplaceExisting)
429 [ + - ]: 2 : throw DuplicateProviderException();
430 : :
431 [ + - ]: 906 : ProviderList_Impl & rList = aIt->getValue();
432 [ + - ][ + - ]: 906 : xPrevious = rList.front().getProvider();
[ + - ]
433 [ + - ][ + - ]: 906 : rList.push_front(Provider);
[ + - ]
434 : : }
435 : :
436 [ + - ][ + - ]: 4623 : return xPrevious;
437 : : }
438 : :
439 : : //=========================================================================
440 : : // virtual
441 : 4 : void SAL_CALL UniversalContentBroker::deregisterContentProvider(
442 : : const Reference< XContentProvider >& Provider,
443 : : const OUString& Scheme )
444 : : throw( com::sun::star::uno::RuntimeException )
445 : : {
446 [ + - ]: 4 : osl::MutexGuard aGuard(m_aMutex);
447 : :
448 [ + - ]: 4 : ProviderMap_Impl::iterator aMapIt;
449 : : try
450 : : {
451 [ + - ][ + - ]: 4 : aMapIt = m_aProviders.find(Scheme);
[ + - # # ]
452 : : }
453 [ # # ]: 0 : catch (const IllegalArgumentException&)
454 : : {
455 : 4 : return; //@@@
456 : : }
457 : :
458 [ + - ][ + - ]: 4 : if (aMapIt != m_aProviders.end())
[ + - ][ + - ]
459 : : {
460 [ + - ]: 4 : ProviderList_Impl & rList = aMapIt->getValue();
461 : :
462 : 4 : ProviderList_Impl::iterator aListEnd(rList.end());
463 [ + - ]: 4 : for (ProviderList_Impl::iterator aListIt(rList.begin());
464 : : aListIt != aListEnd; ++aListIt)
465 : : {
466 [ + - ][ + - ]: 4 : if ((*aListIt).getProvider() == Provider)
[ + - ]
467 : : {
468 [ + - ]: 4 : rList.erase(aListIt);
469 : 4 : break;
470 : : }
471 : : }
472 : :
473 [ + + ]: 4 : if (rList.empty())
474 [ + - ]: 4 : m_aProviders.erase(aMapIt);
475 [ + - ][ - + ]: 4 : }
[ + - ][ + - ]
476 : : }
477 : :
478 : : //=========================================================================
479 : : // virtual
480 : : com::sun::star::uno::Sequence< ContentProviderInfo > SAL_CALL
481 : 6 : UniversalContentBroker::queryContentProviders()
482 : : throw( com::sun::star::uno::RuntimeException )
483 : : {
484 : : // Return a list with information about active(!) content providers.
485 : :
486 [ + - ]: 6 : osl::MutexGuard aGuard(m_aMutex);
487 : :
488 : : com::sun::star::uno::Sequence< ContentProviderInfo > aSeq(
489 [ + - ]: 6 : m_aProviders.size() );
490 [ + - ]: 6 : ContentProviderInfo* pInfo = aSeq.getArray();
491 : :
492 [ + - ][ + - ]: 6 : ProviderMap_Impl::const_iterator end = m_aProviders.end();
[ + - ]
493 [ + - ][ + - ]: 100 : for (ProviderMap_Impl::const_iterator it(m_aProviders.begin()); it != end;
[ + - ][ + - ]
[ + - ][ + + ]
494 : : ++it)
495 : : {
496 : : // Note: Active provider is always the first list element.
497 [ + - ][ + - ]: 94 : pInfo->ContentProvider = it->getValue().front().getProvider();
[ + - ][ + - ]
498 [ + - ]: 94 : pInfo->Scheme = it->getRegexp();
499 : 94 : ++pInfo;
500 : 6 : }
501 : :
502 [ + - ]: 6 : return aSeq;
503 : : }
504 : :
505 : : //=========================================================================
506 : : // virtual
507 : : Reference< XContentProvider > SAL_CALL
508 : 31055 : UniversalContentBroker::queryContentProvider( const OUString&
509 : : Identifier )
510 : : throw( com::sun::star::uno::RuntimeException )
511 : : {
512 : 31055 : return queryContentProvider( Identifier, sal_False );
513 : : }
514 : :
515 : : //=========================================================================
516 : : //
517 : : // XContentProvider methods.
518 : : //
519 : : //=========================================================================
520 : :
521 : : // virtual
522 : 121524 : Reference< XContent > SAL_CALL UniversalContentBroker::queryContent(
523 : : const Reference< XContentIdentifier >& Identifier )
524 : : throw( IllegalIdentifierException, com::sun::star::uno::RuntimeException )
525 : : {
526 : : //////////////////////////////////////////////////////////////////////
527 : : // Let the content provider for the scheme given with the content
528 : : // identifier create the XContent instance.
529 : : //////////////////////////////////////////////////////////////////////
530 : :
531 [ - + ]: 121524 : if ( !Identifier.is() )
532 : 0 : return Reference< XContent >();
533 : :
534 : : Reference< XContentProvider > xProv =
535 [ + - ][ + - ]: 121524 : queryContentProvider( Identifier->getContentIdentifier(), sal_True );
[ + - ]
536 [ + + ]: 121524 : if ( xProv.is() )
537 [ + - ][ + + ]: 116017 : return xProv->queryContent( Identifier );
538 : :
539 : 121524 : return Reference< XContent >();
540 : : }
541 : :
542 : : //=========================================================================
543 : : // virtual
544 : 2230 : sal_Int32 SAL_CALL UniversalContentBroker::compareContentIds(
545 : : const Reference< XContentIdentifier >& Id1,
546 : : const Reference< XContentIdentifier >& Id2 )
547 : : throw( com::sun::star::uno::RuntimeException )
548 : : {
549 [ + - ][ + - ]: 2230 : OUString aURI1( Id1->getContentIdentifier() );
550 [ + - ][ + - ]: 2230 : OUString aURI2( Id2->getContentIdentifier() );
551 : :
552 : : Reference< XContentProvider > xProv1
553 [ + - ]: 2230 : = queryContentProvider( aURI1, sal_True );
554 : : Reference< XContentProvider > xProv2
555 [ + - ]: 2230 : = queryContentProvider( aURI2, sal_True );
556 : :
557 : : // When both identifiers belong to the same provider, let that provider
558 : : // compare them; otherwise, simply compare the URI strings (which must
559 : : // be different):
560 [ + - ][ + - ]: 2230 : if ( xProv1.is() && ( xProv1 == xProv2 ) )
[ + + ][ + + ]
561 [ + - ][ + - ]: 2228 : return xProv1->compareContentIds( Id1, Id2 );
562 : : else
563 : 2230 : return aURI1.compareTo( aURI2 );
564 : : }
565 : :
566 : : //=========================================================================
567 : : //
568 : : // XContentIdentifierFactory methods.
569 : : //
570 : : //=========================================================================
571 : :
572 : : // virtual
573 : : Reference< XContentIdentifier > SAL_CALL
574 : 126012 : UniversalContentBroker::createContentIdentifier(
575 : : const OUString& ContentId )
576 : : throw( com::sun::star::uno::RuntimeException )
577 : : {
578 : : //////////////////////////////////////////////////////////////////////
579 : : // Let the content provider for the scheme given with content
580 : : // identifier create the XContentIdentifier instance, if he supports
581 : : // the XContentIdentifierFactory interface. Otherwise create standard
582 : : // implementation object for XContentIdentifier.
583 : : //////////////////////////////////////////////////////////////////////
584 : :
585 : 126012 : Reference< XContentIdentifier > xIdentifier;
586 : :
587 : : Reference< XContentProvider > xProv
588 [ + - ]: 126012 : = queryContentProvider( ContentId, sal_True );
589 [ + + ]: 126012 : if ( xProv.is() )
590 : : {
591 [ + - ]: 120499 : Reference< XContentIdentifierFactory > xFac( xProv, UNO_QUERY );
592 [ + + ]: 120499 : if ( xFac.is() )
593 [ + - ][ + - ]: 120499 : xIdentifier = xFac->createContentIdentifier( ContentId );
[ + - ]
594 : : }
595 : :
596 [ + + ]: 126012 : if ( !xIdentifier.is() )
597 [ + - ][ + - ]: 31960 : xIdentifier = new ContentIdentifier( m_xSMgr, ContentId );
[ + - ]
598 : :
599 : 126012 : return xIdentifier;
600 : : }
601 : :
602 : : //=========================================================================
603 : : //
604 : : // XCommandProcessor methods.
605 : : //
606 : : //=========================================================================
607 : :
608 : : // virtual
609 : 0 : sal_Int32 SAL_CALL UniversalContentBroker::createCommandIdentifier()
610 : : throw( RuntimeException )
611 : : {
612 [ # # ]: 0 : osl::MutexGuard aGuard( m_aMutex );
613 : :
614 : : // Just increase counter on every call to generate an identifier.
615 [ # # ]: 0 : return ++m_nCommandId;
616 : : }
617 : :
618 : : //=========================================================================
619 : : // virtual
620 : 1244 : Any SAL_CALL UniversalContentBroker::execute(
621 : : const Command& aCommand,
622 : : sal_Int32,
623 : : const Reference< XCommandEnvironment >& Environment )
624 : : throw( Exception, CommandAbortedException, RuntimeException )
625 : : {
626 : 1244 : Any aRet;
627 : :
628 : : //////////////////////////////////////////////////////////////////////
629 : : // Note: Don't forget to adapt ucb_commands::CommandProcessorInfo
630 : : // ctor in ucbcmds.cxx when adding new commands!
631 : : //////////////////////////////////////////////////////////////////////
632 : :
633 [ - + ][ - + ]: 1244 : if ( ( aCommand.Handle == GETCOMMANDINFO_HANDLE ) || aCommand.Name == GETCOMMANDINFO_NAME )
[ + - ]
634 : : {
635 : : //////////////////////////////////////////////////////////////////
636 : : // getCommandInfo
637 : : //////////////////////////////////////////////////////////////////
638 : :
639 [ # # ][ # # ]: 0 : aRet <<= getCommandInfo();
640 : : }
641 [ + - ][ + - ]: 1244 : else if ( ( aCommand.Handle == GLOBALTRANSFER_HANDLE ) || aCommand.Name == GLOBALTRANSFER_NAME )
[ + - ]
642 : : {
643 : : //////////////////////////////////////////////////////////////////
644 : : // globalTransfer
645 : : //////////////////////////////////////////////////////////////////
646 : :
647 : 1244 : GlobalTransferCommandArgument aTransferArg;
648 [ - + ][ + - ]: 1244 : if ( !( aCommand.Argument >>= aTransferArg ) )
649 : : {
650 : : ucbhelper::cancelCommandExecution(
651 : : makeAny( IllegalArgumentException(
652 : : OUString( "Wrong argument type!" ),
653 : : static_cast< cppu::OWeakObject * >( this ),
654 : : -1 ) ),
655 [ # # ][ # # ]: 0 : Environment );
[ # # ][ # # ]
[ # # ]
656 : : // Unreachable
657 : : }
658 : :
659 [ + + ]: 1244 : globalTransfer( aTransferArg, Environment );
660 : : }
661 : : else
662 : : {
663 : : //////////////////////////////////////////////////////////////////
664 : : // Unknown command
665 : : //////////////////////////////////////////////////////////////////
666 : :
667 : : ucbhelper::cancelCommandExecution(
668 : : makeAny( UnsupportedCommandException(
669 : : OUString(),
670 : : static_cast< cppu::OWeakObject * >( this ) ) ),
671 [ # # ][ # # ]: 0 : Environment );
[ # # ][ # # ]
[ # # ]
672 : : // Unreachable
673 : : }
674 : :
675 : 1244 : return aRet;
676 : : }
677 : :
678 : : //=========================================================================
679 : : // virtual
680 : 0 : void SAL_CALL UniversalContentBroker::abort( sal_Int32 )
681 : : throw( RuntimeException )
682 : : {
683 : : // @@@ Not implemeted ( yet).
684 : 0 : }
685 : :
686 : : //=========================================================================
687 : : //
688 : : // XChangesListener methods
689 : : //
690 : : //=========================================================================
691 : : // virtual
692 : 0 : void SAL_CALL UniversalContentBroker::changesOccurred( const util::ChangesEvent& Event )
693 : : throw( uno::RuntimeException )
694 : : {
695 : 0 : sal_Int32 nCount = Event.Changes.getLength();
696 [ # # ]: 0 : if ( nCount )
697 : : {
698 : 0 : uno::Reference< container::XHierarchicalNameAccess > xHierNameAccess;
699 [ # # ]: 0 : Event.Base >>= xHierNameAccess;
700 : :
701 : : OSL_ASSERT( xHierNameAccess.is() );
702 : :
703 : : const util::ElementChange* pElementChanges
704 : 0 : = Event.Changes.getConstArray();
705 : :
706 [ # # ]: 0 : ContentProviderDataList aData;
707 [ # # ]: 0 : for ( sal_Int32 n = 0; n < nCount; ++n )
708 : : {
709 : 0 : const util::ElementChange& rElem = pElementChanges[ n ];
710 : 0 : OUString aKey;
711 : 0 : rElem.Accessor >>= aKey;
712 : :
713 : 0 : ContentProviderData aInfo;
714 : :
715 : : // Removal of UCPs from the configuration leads to changesOccurred
716 : : // notifications, too, but it is hard to tell for a given
717 : : // ElementChange whether it is an addition or a removal, so as a
718 : : // heuristic consider as removals those that cause a
719 : : // NoSuchElementException in createContentProviderData.
720 : : //
721 : : // For now, removal of UCPs from the configuration is simply ignored
722 : : // (and not reflected in the UCB's data structures):
723 [ # # ][ # # ]: 0 : if (createContentProviderData(aKey, xHierNameAccess, aInfo))
724 : : {
725 [ # # ]: 0 : aData.push_back(aInfo);
726 : : }
727 : 0 : }
728 : :
729 [ # # ]: 0 : prepareAndRegister(aData);
730 : : }
731 : 0 : }
732 : :
733 : : //=========================================================================
734 : : //
735 : : // XEventListener methods
736 : : //
737 : : //=========================================================================
738 : : // virtual
739 : 0 : void SAL_CALL UniversalContentBroker::disposing(const lang::EventObject&)
740 : : throw( uno::RuntimeException )
741 : : {
742 [ # # ]: 0 : if ( m_xNotifier.is() )
743 : : {
744 [ # # ]: 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
745 : :
746 [ # # ]: 0 : if ( m_xNotifier.is() )
747 [ # # ]: 0 : m_xNotifier.clear();
748 : : }
749 : 0 : }
750 : :
751 : : //=========================================================================
752 : : //
753 : : // Non-interface methods
754 : : //
755 : : //=========================================================================
756 : :
757 : 283051 : Reference< XContentProvider > UniversalContentBroker::queryContentProvider(
758 : : const OUString& Identifier,
759 : : sal_Bool bResolved )
760 : : {
761 [ + - ]: 283051 : osl::MutexGuard aGuard( m_aMutex );
762 : :
763 [ + - ]: 283051 : ProviderList_Impl const * pList = m_aProviders.map( Identifier );
764 [ + - ]: 240974 : return pList ? bResolved ? pList->front().getResolvedProvider()
765 [ + - ]: 25554 : : pList->front().getProvider()
766 [ + + ][ + + ]: 549579 : : Reference< XContentProvider >();
[ + - ][ + - ]
[ + - ]
767 : : }
768 : :
769 : 250 : bool UniversalContentBroker::configureUcb()
770 : : throw (uno::RuntimeException)
771 : : {
772 : 250 : OUString aKey1;
773 : 250 : OUString aKey2;
774 [ - + ][ + - : 750 : if (m_aArguments.getLength() < 2
+ - - + ]
775 [ + - ][ + - ]: 500 : || !(m_aArguments[0] >>= aKey1) || !(m_aArguments[1] >>= aKey2))
776 : : {
777 : : OSL_FAIL("UniversalContentBroker::configureUcb(): Bad arguments");
778 : 0 : return false;
779 : : }
780 : :
781 [ + - ]: 250 : ContentProviderDataList aData;
782 [ + - ][ + + ]: 250 : if (!getContentProviderData(aKey1, aKey2, aData))
783 : : {
784 : : OSL_TRACE("UniversalContentBroker::configureUcb(): No configuration");
785 : 2 : return false;
786 : : }
787 : :
788 [ + - ]: 248 : prepareAndRegister(aData);
789 : :
790 : 250 : return true;
791 : : }
792 : :
793 : 248 : void UniversalContentBroker::prepareAndRegister(
794 : : const ContentProviderDataList& rData)
795 : : {
796 : 248 : ContentProviderDataList::const_iterator aEnd(rData.end());
797 [ + - ][ + + ]: 3959 : for (ContentProviderDataList::const_iterator aIt(rData.begin());
798 : : aIt != aEnd; ++aIt)
799 : : {
800 : 3711 : OUString aProviderArguments;
801 [ + - ][ + - ]: 3711 : if (fillPlaceholders(aIt->Arguments,
802 : : m_aArguments,
803 : 7422 : &aProviderArguments))
804 : : {
805 : : registerAtUcb(this,
806 : : m_xSMgr,
807 : 3711 : aIt->ServiceName,
808 : : aProviderArguments,
809 : 3711 : aIt->URLTemplate,
810 [ + - ][ + - ]: 3711 : 0);
811 : :
812 : : }
813 : : else
814 : : OSL_FAIL("UniversalContentBroker::prepareAndRegister(): Bad argument placeholders");
815 : 3711 : }
816 : 248 : }
817 : :
818 : : //=========================================================================
819 : 250 : bool UniversalContentBroker::getContentProviderData(
820 : : const OUString & rKey1,
821 : : const OUString & rKey2,
822 : : ContentProviderDataList & rListToFill )
823 : : {
824 [ + - ][ + - ]: 250 : if ( !m_xSMgr.is() || rKey1.isEmpty() || rKey2.isEmpty() )
[ - + ][ - + ]
825 : : {
826 : : OSL_FAIL( "UniversalContentBroker::getContentProviderData - Invalid argument!" );
827 : 0 : return false;
828 : : }
829 : :
830 : : try
831 : : {
832 : : uno::Reference< lang::XMultiServiceFactory > xConfigProv(
833 [ + - ]: 250 : m_xSMgr->createInstance(
834 : : OUString(
835 : 250 : "com.sun.star.configuration.ConfigurationProvider" ) ),
836 [ + - ][ + + ]: 250 : uno::UNO_QUERY_THROW );
837 : :
838 : 248 : OUStringBuffer aFullPath;
839 [ + - ]: 248 : aFullPath.appendAscii( CONFIG_CONTENTPROVIDERS_KEY "/['" );
840 [ + - ]: 248 : makeAndAppendXMLName( aFullPath, rKey1 );
841 [ + - ]: 248 : aFullPath.appendAscii( "']/SecondaryKeys/['" );
842 [ + - ]: 248 : makeAndAppendXMLName( aFullPath, rKey2 );
843 [ + - ]: 248 : aFullPath.appendAscii( "']/ProviderData" );
844 : :
845 [ + - ]: 248 : uno::Sequence< uno::Any > aArguments( 1 );
846 : 248 : beans::PropertyValue aProperty;
847 : : aProperty.Name
848 : 248 : = OUString( "nodepath" );
849 [ + - ][ + - ]: 248 : aProperty.Value <<= aFullPath.makeStringAndClear();
850 [ + - ][ + - ]: 248 : aArguments[ 0 ] <<= aProperty;
851 : :
852 : : uno::Reference< uno::XInterface > xInterface(
853 [ + - ]: 248 : xConfigProv->createInstanceWithArguments(
854 : : OUString( "com.sun.star.configuration.ConfigurationAccess" ),
855 [ + - ]: 248 : aArguments ) );
856 : :
857 [ + - ]: 248 : if ( !m_xNotifier.is() )
858 : : {
859 : : m_xNotifier = uno::Reference< util::XChangesNotifier >(
860 [ + - ][ + - ]: 248 : xInterface, uno::UNO_QUERY_THROW );
861 : :
862 [ + - ][ + - ]: 248 : m_xNotifier->addChangesListener( this );
[ + - ]
863 : : }
864 : :
865 : : uno::Reference< container::XNameAccess > xNameAccess(
866 [ + - ]: 248 : xInterface, uno::UNO_QUERY_THROW );
867 : :
868 [ + - ][ + - ]: 248 : uno::Sequence< OUString > aElems = xNameAccess->getElementNames();
869 : 248 : const OUString* pElems = aElems.getConstArray();
870 : 248 : sal_Int32 nCount = aElems.getLength();
871 : :
872 [ + - ]: 248 : if ( nCount > 0 )
873 : : {
874 : : uno::Reference< container::XHierarchicalNameAccess >
875 [ + - ]: 248 : xHierNameAccess( xInterface, uno::UNO_QUERY_THROW );
876 : :
877 : : // Iterate over children.
878 [ + + ]: 3959 : for ( sal_Int32 n = 0; n < nCount; ++n )
879 : : {
880 : :
881 : : try
882 : : {
883 : :
884 : 3711 : ContentProviderData aInfo;
885 : :
886 : 3711 : OUStringBuffer aElemBuffer;
887 [ + - ]: 3711 : aElemBuffer.appendAscii( "['" );
888 [ + - ]: 3711 : makeAndAppendXMLName( aElemBuffer, pElems[ n ] );
889 [ + - ]: 3711 : aElemBuffer.appendAscii( "']" );
890 : :
891 [ + - ][ + - ]: 3711 : OSL_VERIFY(
892 : : createContentProviderData(
893 : : aElemBuffer.makeStringAndClear(), xHierNameAccess,
894 : : aInfo));
895 : :
896 [ # # ][ + - ]: 3711 : rListToFill.push_back( aInfo );
897 : : }
898 [ # # ]: 0 : catch (const container::NoSuchElementException&)
899 : : {
900 : : // getByHierarchicalName
901 : : OSL_FAIL( "UniversalContentBroker::getContentProviderData - "
902 : : "caught NoSuchElementException!" );
903 : : }
904 : 248 : }
905 [ + - ][ + - ]: 250 : }
[ - + - ]
906 : : }
907 : 2 : catch (const uno::RuntimeException&)
908 : : {
909 : : OSL_TRACE( "UniversalContentBroker::getContentProviderData - caught RuntimeException!" );
910 : 2 : return false;
911 : : }
912 : 0 : catch (const uno::Exception&)
913 : : {
914 : : // createInstance, createInstanceWithArguments
915 : :
916 : : OSL_TRACE( "UniversalContentBroker::getContentProviderData - caught Exception!" );
917 : 0 : return false;
918 : : }
919 : :
920 : 250 : return true;
921 : : }
922 : :
923 : : //=========================================================================
924 : : //
925 : : // ProviderListEntry_Impl implementation.
926 : : //
927 : : //=========================================================================
928 : :
929 : 1134 : Reference< XContentProvider > ProviderListEntry_Impl::resolveProvider() const
930 : : {
931 [ + - ]: 1134 : if ( !m_xResolvedProvider.is() )
932 : : {
933 : : Reference< XContentProviderSupplier > xSupplier(
934 [ + - ]: 1134 : m_xProvider, UNO_QUERY );
935 [ + + ]: 1134 : if ( xSupplier.is() )
936 [ + - ][ + - ]: 540 : m_xResolvedProvider = xSupplier->getContentProvider();
[ + - ]
937 : :
938 [ + + ]: 1134 : if ( !m_xResolvedProvider.is() )
939 [ + - ]: 1134 : m_xResolvedProvider = m_xProvider;
940 : : }
941 : :
942 : 1134 : return m_xResolvedProvider;
943 : : }
944 : :
945 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|