1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ucb.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_ucb.hxx"
34 /**************************************************************************
36 **************************************************************************
38 *************************************************************************/
39 #include <osl/diagnose.h>
40 #include <cppuhelper/interfacecontainer.hxx>
41 #include <com/sun/star/lang/IllegalArgumentException.hpp>
42 #include <com/sun/star/ucb/GlobalTransferCommandArgument.hpp>
43 #include <com/sun/star/ucb/XCommandInfo.hpp>
44 #include <com/sun/star/ucb/XContentProvider.hpp>
45 #include <com/sun/star/ucb/XContentProviderSupplier.hpp>
46 #include <ucbhelper/configureucb.hxx>
47 #include <ucbhelper/cancelcommandexecution.hxx>
48 #include "identify.hxx"
49 #include "ucbcmds.hxx"
53 // Definitions for ProviderMap_Impl (Solaris wouldn't find explicit template
54 // instantiations for these in another compilation unit...):
55 #ifndef _UCB_REGEXPMAP_TPT_
56 #include <regexpmap.tpt>
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
;
66 //=========================================================================
68 // UniversalContentBroker Implementation.
70 //=========================================================================
72 UniversalContentBroker::UniversalContentBroker(
73 const Reference
< com::sun::star::lang::XMultiServiceFactory
>& rXSMgr
)
75 m_pDisposeEventListeners( NULL
),
76 m_nInitCount( 0 ), //@@@ see initialize() method
79 OSL_ENSURE( m_xSMgr
.is(),
80 "UniversalContentBroker ctor: No service manager" );
83 //=========================================================================
85 UniversalContentBroker::~UniversalContentBroker()
87 delete m_pDisposeEventListeners
;
90 //=========================================================================
92 // XInterface methods.
94 //=========================================================================
96 XINTERFACE_IMPL_8( UniversalContentBroker
,
101 XContentProviderManager
,
103 XContentIdentifierFactory
,
106 //=========================================================================
108 // XTypeProvider methods.
110 //=========================================================================
112 XTYPEPROVIDER_IMPL_8( UniversalContentBroker
,
117 XContentProviderManager
,
119 XContentIdentifierFactory
,
122 //=========================================================================
124 // XComponent methods.
126 //=========================================================================
129 void SAL_CALL
UniversalContentBroker::dispose()
130 throw( com::sun::star::uno::RuntimeException
)
132 if ( m_pDisposeEventListeners
&& m_pDisposeEventListeners
->getLength() )
135 aEvt
.Source
= SAL_STATIC_CAST( XComponent
*, this );
136 m_pDisposeEventListeners
->disposeAndClear( aEvt
);
140 //=========================================================================
142 void SAL_CALL
UniversalContentBroker::addEventListener(
143 const Reference
< XEventListener
>& Listener
)
144 throw( com::sun::star::uno::RuntimeException
)
146 if ( !m_pDisposeEventListeners
)
147 m_pDisposeEventListeners
= new OInterfaceContainerHelper( m_aMutex
);
149 m_pDisposeEventListeners
->addInterface( Listener
);
152 //=========================================================================
154 void SAL_CALL
UniversalContentBroker::removeEventListener(
155 const Reference
< XEventListener
>& Listener
)
156 throw( com::sun::star::uno::RuntimeException
)
158 if ( m_pDisposeEventListeners
)
159 m_pDisposeEventListeners
->removeInterface( Listener
);
161 // Note: Don't want to delete empty container here -> performance.
164 //=========================================================================
166 // XServiceInfo methods.
168 //=========================================================================
170 XSERVICEINFO_IMPL_1( UniversalContentBroker
,
171 OUString::createFromAscii(
172 "com.sun.star.comp.ucb.UniversalContentBroker" ),
173 OUString::createFromAscii(
174 UCB_SERVICE_NAME
) );
176 //=========================================================================
178 // Service factory implementation.
180 //=========================================================================
182 ONE_INSTANCE_SERVICE_FACTORY_IMPL( UniversalContentBroker
);
184 //=========================================================================
186 // XInitialization methods.
188 //=========================================================================
191 void SAL_CALL
UniversalContentBroker::initialize(
192 const com::sun::star::uno::Sequence
< Any
>& aArguments
)
193 throw( com::sun::star::uno::Exception
,
194 com::sun::star::uno::RuntimeException
)
196 //@@@ At the moment, there's a problem when one (non-one-instance) factory
197 // 'wraps' another (one-instance) factory, causing this method to be
198 // called several times:
199 oslInterlockedCount nCount
= osl_incrementInterlockedCount(&m_nInitCount
);
201 ::ucbhelper::configureUcb(this, m_xSMgr
, aArguments
, 0);
203 osl_decrementInterlockedCount(&m_nInitCount
);
204 // make the possibility of overflow less likely...
207 //=========================================================================
209 // XContentProviderManager methods.
211 //=========================================================================
214 Reference
< XContentProvider
> SAL_CALL
215 UniversalContentBroker::registerContentProvider(
216 const Reference
< XContentProvider
>& Provider
,
217 const OUString
& Scheme
,
218 sal_Bool ReplaceExisting
)
219 throw( DuplicateProviderException
, com::sun::star::uno::RuntimeException
)
221 osl::MutexGuard
aGuard(m_aMutex
);
223 ProviderMap_Impl::iterator aIt
;
226 aIt
= m_aProviders
.find(Scheme
);
228 catch (IllegalArgumentException
const &)
233 Reference
< XContentProvider
> xPrevious
;
234 if (aIt
== m_aProviders
.end())
236 ProviderList_Impl aList
;
237 aList
.push_front(Provider
);
240 m_aProviders
.add(Scheme
, aList
, false);
242 catch (IllegalArgumentException
const &)
249 if (!ReplaceExisting
)
250 throw DuplicateProviderException();
252 ProviderList_Impl
& rList
= aIt
->getValue();
253 xPrevious
= rList
.front().getProvider();
254 rList
.push_front(Provider
);
260 //=========================================================================
262 void SAL_CALL
UniversalContentBroker::deregisterContentProvider(
263 const Reference
< XContentProvider
>& Provider
,
264 const OUString
& Scheme
)
265 throw( com::sun::star::uno::RuntimeException
)
267 osl::MutexGuard
aGuard(m_aMutex
);
269 ProviderMap_Impl::iterator aMapIt
;
272 aMapIt
= m_aProviders
.find(Scheme
);
274 catch (IllegalArgumentException
const &)
279 if (aMapIt
!= m_aProviders
.end())
281 ProviderList_Impl
& rList
= aMapIt
->getValue();
283 ProviderList_Impl::iterator
aListEnd(rList
.end());
284 for (ProviderList_Impl::iterator
aListIt(rList
.begin());
285 aListIt
!= aListEnd
; ++aListIt
)
287 if ((*aListIt
).getProvider() == Provider
)
289 rList
.erase(aListIt
);
295 m_aProviders
.erase(aMapIt
);
299 //=========================================================================
301 com::sun::star::uno::Sequence
< ContentProviderInfo
> SAL_CALL
302 UniversalContentBroker::queryContentProviders()
303 throw( com::sun::star::uno::RuntimeException
)
305 // Return a list with information about active(!) content providers.
307 osl::MutexGuard
aGuard(m_aMutex
);
309 com::sun::star::uno::Sequence
< ContentProviderInfo
> aSeq(
310 m_aProviders
.size() );
311 ContentProviderInfo
* pInfo
= aSeq
.getArray();
313 ProviderMap_Impl::const_iterator end
= m_aProviders
.end();
314 for (ProviderMap_Impl::const_iterator
it(m_aProviders
.begin()); it
!= end
;
317 // Note: Active provider is always the first list element.
318 pInfo
->ContentProvider
= it
->getValue().front().getProvider();
319 pInfo
->Scheme
= it
->getRegexp();
326 //=========================================================================
328 Reference
< XContentProvider
> SAL_CALL
329 UniversalContentBroker::queryContentProvider( const OUString
&
331 throw( com::sun::star::uno::RuntimeException
)
333 return queryContentProvider( Identifier
, sal_False
);
336 //=========================================================================
338 // XContentProvider methods.
340 //=========================================================================
343 Reference
< XContent
> SAL_CALL
UniversalContentBroker::queryContent(
344 const Reference
< XContentIdentifier
>& Identifier
)
345 throw( IllegalIdentifierException
, com::sun::star::uno::RuntimeException
)
347 //////////////////////////////////////////////////////////////////////
348 // Let the content provider for the scheme given with the content
349 // identifier create the XContent instance.
350 //////////////////////////////////////////////////////////////////////
352 if ( !Identifier
.is() )
353 return Reference
< XContent
>();
355 Reference
< XContentProvider
> xProv
=
356 queryContentProvider( Identifier
->getContentIdentifier(), sal_True
);
358 return xProv
->queryContent( Identifier
);
360 return Reference
< XContent
>();
363 //=========================================================================
365 sal_Int32 SAL_CALL
UniversalContentBroker::compareContentIds(
366 const Reference
< XContentIdentifier
>& Id1
,
367 const Reference
< XContentIdentifier
>& Id2
)
368 throw( com::sun::star::uno::RuntimeException
)
370 OUString
aURI1( Id1
->getContentIdentifier() );
371 OUString
aURI2( Id2
->getContentIdentifier() );
373 Reference
< XContentProvider
> xProv1
374 = queryContentProvider( aURI1
, sal_True
);
375 Reference
< XContentProvider
> xProv2
376 = queryContentProvider( aURI2
, sal_True
);
378 // When both identifiers belong to the same provider, let that provider
379 // compare them; otherwise, simply compare the URI strings (which must
381 if ( xProv1
.is() && ( xProv1
== xProv2
) )
382 return xProv1
->compareContentIds( Id1
, Id2
);
384 return aURI1
.compareTo( aURI2
);
387 //=========================================================================
389 // XContentIdentifierFactory methods.
391 //=========================================================================
394 Reference
< XContentIdentifier
> SAL_CALL
395 UniversalContentBroker::createContentIdentifier(
396 const OUString
& ContentId
)
397 throw( com::sun::star::uno::RuntimeException
)
399 //////////////////////////////////////////////////////////////////////
400 // Let the content provider for the scheme given with content
401 // identifier create the XContentIdentifier instance, if he supports
402 // the XContentIdentifierFactory interface. Otherwise create standard
403 // implementation object for XContentIdentifier.
404 //////////////////////////////////////////////////////////////////////
406 Reference
< XContentIdentifier
> xIdentifier
;
408 Reference
< XContentProvider
> xProv
409 = queryContentProvider( ContentId
, sal_True
);
412 Reference
< XContentIdentifierFactory
> xFac( xProv
, UNO_QUERY
);
414 xIdentifier
= xFac
->createContentIdentifier( ContentId
);
417 if ( !xIdentifier
.is() )
418 xIdentifier
= new ContentIdentifier( m_xSMgr
, ContentId
);
423 //=========================================================================
425 // XCommandProcessor methods.
427 //=========================================================================
430 sal_Int32 SAL_CALL
UniversalContentBroker::createCommandIdentifier()
431 throw( RuntimeException
)
433 osl::MutexGuard
aGuard( m_aMutex
);
435 // Just increase counter on every call to generate an identifier.
436 return ++m_nCommandId
;
439 //=========================================================================
441 Any SAL_CALL
UniversalContentBroker::execute(
442 const Command
& aCommand
,
444 const Reference
< XCommandEnvironment
>& Environment
)
445 throw( Exception
, CommandAbortedException
, RuntimeException
)
449 //////////////////////////////////////////////////////////////////////
450 // Note: Don't forget to adapt ucb_commands::CommandProcessorInfo
451 // ctor in ucbcmds.cxx when adding new commands!
452 //////////////////////////////////////////////////////////////////////
454 if ( ( aCommand
.Handle
== GETCOMMANDINFO_HANDLE
) ||
455 aCommand
.Name
.equalsAsciiL(
456 RTL_CONSTASCII_STRINGPARAM( GETCOMMANDINFO_NAME
) ) )
458 //////////////////////////////////////////////////////////////////
460 //////////////////////////////////////////////////////////////////
462 aRet
<<= getCommandInfo();
464 else if ( ( aCommand
.Handle
== GLOBALTRANSFER_HANDLE
) ||
465 aCommand
.Name
.equalsAsciiL(
466 RTL_CONSTASCII_STRINGPARAM(GLOBALTRANSFER_NAME
) ) )
468 //////////////////////////////////////////////////////////////////
470 //////////////////////////////////////////////////////////////////
472 GlobalTransferCommandArgument aTransferArg
;
473 if ( !( aCommand
.Argument
>>= aTransferArg
) )
475 ucbhelper::cancelCommandExecution(
476 makeAny( IllegalArgumentException(
477 rtl::OUString::createFromAscii(
478 "Wrong argument type!" ),
479 static_cast< cppu::OWeakObject
* >( this ),
485 globalTransfer( aTransferArg
, Environment
);
489 //////////////////////////////////////////////////////////////////
491 //////////////////////////////////////////////////////////////////
493 ucbhelper::cancelCommandExecution(
494 makeAny( UnsupportedCommandException(
496 static_cast< cppu::OWeakObject
* >( this ) ) ),
504 //=========================================================================
506 void SAL_CALL
UniversalContentBroker::abort( sal_Int32
)
507 throw( RuntimeException
)
509 // @@@ Not implemeted ( yet).
512 //=========================================================================
514 // Non-interface methods
516 //=========================================================================
518 Reference
< XContentProvider
> UniversalContentBroker::queryContentProvider(
519 const OUString
& Identifier
,
522 osl::MutexGuard
aGuard( m_aMutex
);
524 ProviderList_Impl
const * pList
= m_aProviders
.map( Identifier
);
525 return pList
? bResolved
? pList
->front().getResolvedProvider()
526 : pList
->front().getProvider()
527 : Reference
< XContentProvider
>();
530 //=========================================================================
532 // ProviderListEntry_Impl implementation.
534 //=========================================================================
536 Reference
< XContentProvider
> ProviderListEntry_Impl::resolveProvider() const
538 if ( !m_xResolvedProvider
.is() )
540 Reference
< XContentProviderSupplier
> xSupplier(
541 m_xProvider
, UNO_QUERY
);
542 if ( xSupplier
.is() )
543 m_xResolvedProvider
= xSupplier
->getContentProvider();
545 if ( !m_xResolvedProvider
.is() )
546 m_xResolvedProvider
= m_xProvider
;
549 return m_xResolvedProvider
;