update dev300-m58
[ooovba.git] / ucb / source / core / ucb.cxx
blobd1d93596abb77943ebcd44f3293e495437f383bc
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ucb.cxx,v $
10 * $Revision: 1.12 $
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 /**************************************************************************
35 TODO
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"
51 #include "ucb.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>
57 #endif
59 using namespace rtl;
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;
66 //=========================================================================
68 // UniversalContentBroker Implementation.
70 //=========================================================================
72 UniversalContentBroker::UniversalContentBroker(
73 const Reference< com::sun::star::lang::XMultiServiceFactory >& rXSMgr )
74 : m_xSMgr( rXSMgr ),
75 m_pDisposeEventListeners( NULL ),
76 m_nInitCount( 0 ), //@@@ see initialize() method
77 m_nCommandId( 0 )
79 OSL_ENSURE( m_xSMgr.is(),
80 "UniversalContentBroker ctor: No service manager" );
83 //=========================================================================
84 // virtual
85 UniversalContentBroker::~UniversalContentBroker()
87 delete m_pDisposeEventListeners;
90 //=========================================================================
92 // XInterface methods.
94 //=========================================================================
96 XINTERFACE_IMPL_8( UniversalContentBroker,
97 XTypeProvider,
98 XComponent,
99 XServiceInfo,
100 XInitialization,
101 XContentProviderManager,
102 XContentProvider,
103 XContentIdentifierFactory,
104 XCommandProcessor );
106 //=========================================================================
108 // XTypeProvider methods.
110 //=========================================================================
112 XTYPEPROVIDER_IMPL_8( UniversalContentBroker,
113 XTypeProvider,
114 XComponent,
115 XServiceInfo,
116 XInitialization,
117 XContentProviderManager,
118 XContentProvider,
119 XContentIdentifierFactory,
120 XCommandProcessor );
122 //=========================================================================
124 // XComponent methods.
126 //=========================================================================
128 // virtual
129 void SAL_CALL UniversalContentBroker::dispose()
130 throw( com::sun::star::uno::RuntimeException )
132 if ( m_pDisposeEventListeners && m_pDisposeEventListeners->getLength() )
134 EventObject aEvt;
135 aEvt.Source = SAL_STATIC_CAST( XComponent*, this );
136 m_pDisposeEventListeners->disposeAndClear( aEvt );
140 //=========================================================================
141 // virtual
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 //=========================================================================
153 // virtual
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 //=========================================================================
190 // virtual
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);
200 if (nCount == 1)
201 ::ucbhelper::configureUcb(this, m_xSMgr, aArguments, 0);
202 else
203 osl_decrementInterlockedCount(&m_nInitCount);
204 // make the possibility of overflow less likely...
207 //=========================================================================
209 // XContentProviderManager methods.
211 //=========================================================================
213 // virtual
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 &)
230 return 0; //@@@
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 &)
244 return 0; //@@@
247 else
249 if (!ReplaceExisting)
250 throw DuplicateProviderException();
252 ProviderList_Impl & rList = aIt->getValue();
253 xPrevious = rList.front().getProvider();
254 rList.push_front(Provider);
257 return xPrevious;
260 //=========================================================================
261 // virtual
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 &)
276 return; //@@@
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);
290 break;
294 if (rList.empty())
295 m_aProviders.erase(aMapIt);
299 //=========================================================================
300 // virtual
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;
315 ++it)
317 // Note: Active provider is always the first list element.
318 pInfo->ContentProvider = it->getValue().front().getProvider();
319 pInfo->Scheme = it->getRegexp();
320 ++pInfo;
323 return aSeq;
326 //=========================================================================
327 // virtual
328 Reference< XContentProvider > SAL_CALL
329 UniversalContentBroker::queryContentProvider( const OUString&
330 Identifier )
331 throw( com::sun::star::uno::RuntimeException )
333 return queryContentProvider( Identifier, sal_False );
336 //=========================================================================
338 // XContentProvider methods.
340 //=========================================================================
342 // virtual
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 );
357 if ( xProv.is() )
358 return xProv->queryContent( Identifier );
360 return Reference< XContent >();
363 //=========================================================================
364 // virtual
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
380 // be different):
381 if ( xProv1.is() && ( xProv1 == xProv2 ) )
382 return xProv1->compareContentIds( Id1, Id2 );
383 else
384 return aURI1.compareTo( aURI2 );
387 //=========================================================================
389 // XContentIdentifierFactory methods.
391 //=========================================================================
393 // virtual
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 );
410 if ( xProv.is() )
412 Reference< XContentIdentifierFactory > xFac( xProv, UNO_QUERY );
413 if ( xFac.is() )
414 xIdentifier = xFac->createContentIdentifier( ContentId );
417 if ( !xIdentifier.is() )
418 xIdentifier = new ContentIdentifier( m_xSMgr, ContentId );
420 return xIdentifier;
423 //=========================================================================
425 // XCommandProcessor methods.
427 //=========================================================================
429 // virtual
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 //=========================================================================
440 // virtual
441 Any SAL_CALL UniversalContentBroker::execute(
442 const Command& aCommand,
443 sal_Int32,
444 const Reference< XCommandEnvironment >& Environment )
445 throw( Exception, CommandAbortedException, RuntimeException )
447 Any aRet;
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 //////////////////////////////////////////////////////////////////
459 // getCommandInfo
460 //////////////////////////////////////////////////////////////////
462 aRet <<= getCommandInfo();
464 else if ( ( aCommand.Handle == GLOBALTRANSFER_HANDLE ) ||
465 aCommand.Name.equalsAsciiL(
466 RTL_CONSTASCII_STRINGPARAM(GLOBALTRANSFER_NAME ) ) )
468 //////////////////////////////////////////////////////////////////
469 // globalTransfer
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 ),
480 -1 ) ),
481 Environment );
482 // Unreachable
485 globalTransfer( aTransferArg, Environment );
487 else
489 //////////////////////////////////////////////////////////////////
490 // Unknown command
491 //////////////////////////////////////////////////////////////////
493 ucbhelper::cancelCommandExecution(
494 makeAny( UnsupportedCommandException(
495 rtl::OUString(),
496 static_cast< cppu::OWeakObject * >( this ) ) ),
497 Environment );
498 // Unreachable
501 return aRet;
504 //=========================================================================
505 // virtual
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,
520 sal_Bool bResolved )
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;