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