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