| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_ucb.hxx" |
| |
| /************************************************************************** |
| TODO |
| ************************************************************************** |
| |
| *************************************************************************/ |
| #include <osl/diagnose.h> |
| #include <cppuhelper/interfacecontainer.hxx> |
| #include <com/sun/star/lang/IllegalArgumentException.hpp> |
| #include <com/sun/star/ucb/GlobalTransferCommandArgument.hpp> |
| #include <com/sun/star/ucb/XCommandInfo.hpp> |
| #include <com/sun/star/ucb/XContentProvider.hpp> |
| #include <com/sun/star/ucb/XContentProviderSupplier.hpp> |
| #include <com/sun/star/ucb/XParameterizedContentProvider.hpp> |
| #include <com/sun/star/ucb/XContentProviderFactory.hpp> |
| #include <com/sun/star/beans/PropertyValue.hpp> |
| #include <com/sun/star/container/XHierarchicalNameAccess.hpp> |
| #include <com/sun/star/container/XNameAccess.hpp> |
| #include <com/sun/star/uno/Any.hxx> |
| #include <ucbhelper/cancelcommandexecution.hxx> |
| #include "identify.hxx" |
| #include "ucbcmds.hxx" |
| |
| #include "ucb.hxx" |
| |
| // Definitions for ProviderMap_Impl (Solaris wouldn't find explicit template |
| // instantiations for these in another compilation unit...): |
| #ifndef _UCB_REGEXPMAP_TPT_ |
| #include <regexpmap.tpt> |
| #endif |
| |
| using namespace rtl; |
| using namespace cppu; |
| using namespace com::sun::star::uno; |
| using namespace com::sun::star::lang; |
| using namespace com::sun::star::ucb; |
| using namespace ucb_impl; |
| using namespace com::sun::star; |
| using namespace ucbhelper; |
| |
| |
| #define CONFIG_CONTENTPROVIDERS_KEY \ |
| "/org.openoffice.ucb.Configuration/ContentProviders" |
| |
| |
| namespace { |
| |
| bool fillPlaceholders(rtl::OUString const & rInput, |
| uno::Sequence< uno::Any > const & rReplacements, |
| rtl::OUString * pOutput) |
| { |
| sal_Unicode const * p = rInput.getStr(); |
| sal_Unicode const * pEnd = p + rInput.getLength(); |
| sal_Unicode const * pCopy = p; |
| rtl::OUStringBuffer aBuffer; |
| while (p != pEnd) |
| switch (*p++) |
| { |
| case '&': |
| if (pEnd - p >= 4 |
| && p[0] == 'a' && p[1] == 'm' && p[2] == 'p' |
| && p[3] == ';') |
| { |
| aBuffer.append(pCopy, p - 1 - pCopy); |
| aBuffer.append(sal_Unicode('&')); |
| p += 4; |
| pCopy = p; |
| } |
| else if (pEnd - p >= 3 |
| && p[0] == 'l' && p[1] == 't' && p[2] == ';') |
| { |
| aBuffer.append(pCopy, p - 1 - pCopy); |
| aBuffer.append(sal_Unicode('<')); |
| p += 3; |
| pCopy = p; |
| } |
| else if (pEnd - p >= 3 |
| && p[0] == 'g' && p[1] == 't' && p[2] == ';') |
| { |
| aBuffer.append(pCopy, p - 1 - pCopy); |
| aBuffer.append(sal_Unicode('>')); |
| p += 3; |
| pCopy = p; |
| } |
| break; |
| |
| case '<': |
| sal_Unicode const * q = p; |
| while (q != pEnd && *q != '>') |
| ++q; |
| if (q == pEnd) |
| break; |
| rtl::OUString aKey(p, q - p); |
| rtl::OUString aValue; |
| bool bFound = false; |
| for (sal_Int32 i = 2; i + 1 < rReplacements.getLength(); |
| i += 2) |
| { |
| rtl::OUString aReplaceKey; |
| if ((rReplacements[i] >>= aReplaceKey) |
| && aReplaceKey == aKey |
| && (rReplacements[i + 1] >>= aValue)) |
| { |
| bFound = true; |
| break; |
| } |
| } |
| if (!bFound) |
| return false; |
| aBuffer.append(pCopy, p - 1 - pCopy); |
| aBuffer.append(aValue); |
| p = q + 1; |
| pCopy = p; |
| break; |
| } |
| aBuffer.append(pCopy, pEnd - pCopy); |
| *pOutput = aBuffer.makeStringAndClear(); |
| return true; |
| } |
| |
| void makeAndAppendXMLName( |
| rtl::OUStringBuffer & rBuffer, const rtl::OUString & rIn ) |
| { |
| sal_Int32 nCount = rIn.getLength(); |
| for ( sal_Int32 n = 0; n < nCount; ++n ) |
| { |
| const sal_Unicode c = rIn.getStr()[ n ]; |
| switch ( c ) |
| { |
| case '&': |
| rBuffer.appendAscii( "&" ); |
| break; |
| |
| case '"': |
| rBuffer.appendAscii( """ ); |
| break; |
| |
| case '\'': |
| rBuffer.appendAscii( "'" ); |
| break; |
| |
| case '<': |
| rBuffer.appendAscii( "<" ); |
| break; |
| |
| case '>': |
| rBuffer.appendAscii( ">" ); |
| break; |
| |
| default: |
| rBuffer.append( c ); |
| break; |
| } |
| } |
| } |
| |
| bool createContentProviderData( |
| const rtl::OUString & rProvider, |
| const uno::Reference< container::XHierarchicalNameAccess >& rxHierNameAccess, |
| ContentProviderData & rInfo) |
| { |
| // Obtain service name. |
| rtl::OUStringBuffer aKeyBuffer (rProvider); |
| aKeyBuffer.appendAscii( "/ServiceName" ); |
| |
| rtl::OUString aValue; |
| try |
| { |
| if ( !( rxHierNameAccess->getByHierarchicalName( |
| aKeyBuffer.makeStringAndClear() ) >>= aValue ) ) |
| { |
| OSL_ENSURE( false, |
| "UniversalContentBroker::getContentProviderData - " |
| "Error getting item value!" ); |
| } |
| } |
| catch (container::NoSuchElementException &) |
| { |
| return false; |
| } |
| |
| rInfo.ServiceName = aValue; |
| |
| // Obtain URL Template. |
| aKeyBuffer.append(rProvider); |
| aKeyBuffer.appendAscii( "/URLTemplate" ); |
| |
| if ( !( rxHierNameAccess->getByHierarchicalName( |
| aKeyBuffer.makeStringAndClear() ) >>= aValue ) ) |
| { |
| OSL_ENSURE( false, |
| "UniversalContentBroker::getContentProviderData - " |
| "Error getting item value!" ); |
| } |
| |
| rInfo.URLTemplate = aValue; |
| |
| // Obtain Arguments. |
| aKeyBuffer.append(rProvider); |
| aKeyBuffer.appendAscii( "/Arguments" ); |
| |
| if ( !( rxHierNameAccess->getByHierarchicalName( |
| aKeyBuffer.makeStringAndClear() ) >>= aValue ) ) |
| { |
| OSL_ENSURE( false, |
| "UniversalContentBroker::getContentProviderData - " |
| "Error getting item value!" ); |
| } |
| |
| rInfo.Arguments = aValue; |
| return true; |
| } |
| |
| } |
| |
| //========================================================================= |
| // |
| // UniversalContentBroker Implementation. |
| // |
| //========================================================================= |
| |
| UniversalContentBroker::UniversalContentBroker( |
| const Reference< com::sun::star::lang::XMultiServiceFactory >& rXSMgr ) |
| : m_xSMgr( rXSMgr ), |
| m_pDisposeEventListeners( NULL ), |
| m_nInitCount( 0 ), //@@@ see initialize() method |
| m_nCommandId( 0 ) |
| { |
| OSL_ENSURE( m_xSMgr.is(), |
| "UniversalContentBroker ctor: No service manager" ); |
| } |
| |
| //========================================================================= |
| // virtual |
| UniversalContentBroker::~UniversalContentBroker() |
| { |
| delete m_pDisposeEventListeners; |
| } |
| |
| //========================================================================= |
| // |
| // XInterface methods. |
| // |
| //========================================================================= |
| |
| XINTERFACE_IMPL_8( UniversalContentBroker, |
| XTypeProvider, |
| XComponent, |
| XServiceInfo, |
| XInitialization, |
| XContentProviderManager, |
| XContentProvider, |
| XContentIdentifierFactory, |
| XCommandProcessor ); |
| |
| //========================================================================= |
| // |
| // XTypeProvider methods. |
| // |
| //========================================================================= |
| |
| XTYPEPROVIDER_IMPL_8( UniversalContentBroker, |
| XTypeProvider, |
| XComponent, |
| XServiceInfo, |
| XInitialization, |
| XContentProviderManager, |
| XContentProvider, |
| XContentIdentifierFactory, |
| XCommandProcessor ); |
| |
| //========================================================================= |
| // |
| // XComponent methods. |
| // |
| //========================================================================= |
| |
| // virtual |
| void SAL_CALL UniversalContentBroker::dispose() |
| throw( com::sun::star::uno::RuntimeException ) |
| { |
| if ( m_pDisposeEventListeners && m_pDisposeEventListeners->getLength() ) |
| { |
| EventObject aEvt; |
| aEvt.Source = SAL_STATIC_CAST( XComponent*, this ); |
| m_pDisposeEventListeners->disposeAndClear( aEvt ); |
| } |
| |
| if ( m_xNotifier.is() ) |
| m_xNotifier->removeChangesListener( this ); |
| } |
| |
| //========================================================================= |
| // virtual |
| void SAL_CALL UniversalContentBroker::addEventListener( |
| const Reference< XEventListener >& Listener ) |
| throw( com::sun::star::uno::RuntimeException ) |
| { |
| if ( !m_pDisposeEventListeners ) |
| m_pDisposeEventListeners = new OInterfaceContainerHelper( m_aMutex ); |
| |
| m_pDisposeEventListeners->addInterface( Listener ); |
| } |
| |
| //========================================================================= |
| // virtual |
| void SAL_CALL UniversalContentBroker::removeEventListener( |
| const Reference< XEventListener >& Listener ) |
| throw( com::sun::star::uno::RuntimeException ) |
| { |
| if ( m_pDisposeEventListeners ) |
| m_pDisposeEventListeners->removeInterface( Listener ); |
| |
| // Note: Don't want to delete empty container here -> performance. |
| } |
| |
| //========================================================================= |
| // |
| // XServiceInfo methods. |
| // |
| //========================================================================= |
| |
| XSERVICEINFO_IMPL_1( UniversalContentBroker, |
| OUString::createFromAscii( |
| "com.sun.star.comp.ucb.UniversalContentBroker" ), |
| OUString::createFromAscii( |
| UCB_SERVICE_NAME ) ); |
| |
| //========================================================================= |
| // |
| // Service factory implementation. |
| // |
| //========================================================================= |
| |
| ONE_INSTANCE_SERVICE_FACTORY_IMPL( UniversalContentBroker ); |
| |
| //========================================================================= |
| // |
| // XInitialization methods. |
| // |
| //========================================================================= |
| |
| // virtual |
| void SAL_CALL UniversalContentBroker::initialize( |
| const com::sun::star::uno::Sequence< Any >& aArguments ) |
| throw( com::sun::star::uno::Exception, |
| com::sun::star::uno::RuntimeException ) |
| { |
| //@@@ At the moment, there's a problem when one (non-one-instance) factory |
| // 'wraps' another (one-instance) factory, causing this method to be |
| // called several times: |
| m_aArguments = aArguments; |
| |
| oslInterlockedCount nCount = osl_incrementInterlockedCount(&m_nInitCount); |
| if (nCount == 1) |
| configureUcb(); |
| else |
| osl_decrementInterlockedCount(&m_nInitCount); |
| // make the possibility of overflow less likely... |
| } |
| |
| //========================================================================= |
| // |
| // XContentProviderManager methods. |
| // |
| //========================================================================= |
| |
| // virtual |
| Reference< XContentProvider > SAL_CALL |
| UniversalContentBroker::registerContentProvider( |
| const Reference< XContentProvider >& Provider, |
| const OUString& Scheme, |
| sal_Bool ReplaceExisting ) |
| throw( DuplicateProviderException, com::sun::star::uno::RuntimeException ) |
| { |
| osl::MutexGuard aGuard(m_aMutex); |
| |
| ProviderMap_Impl::iterator aIt; |
| try |
| { |
| aIt = m_aProviders.find(Scheme); |
| } |
| catch (IllegalArgumentException const &) |
| { |
| return 0; //@@@ |
| } |
| |
| Reference< XContentProvider > xPrevious; |
| if (aIt == m_aProviders.end()) |
| { |
| ProviderList_Impl aList; |
| aList.push_front(Provider); |
| try |
| { |
| m_aProviders.add(Scheme, aList, false); |
| } |
| catch (IllegalArgumentException const &) |
| { |
| return 0; //@@@ |
| } |
| } |
| else |
| { |
| if (!ReplaceExisting) |
| throw DuplicateProviderException(); |
| |
| ProviderList_Impl & rList = aIt->getValue(); |
| xPrevious = rList.front().getProvider(); |
| rList.push_front(Provider); |
| } |
| |
| return xPrevious; |
| } |
| |
| //========================================================================= |
| // virtual |
| void SAL_CALL UniversalContentBroker::deregisterContentProvider( |
| const Reference< XContentProvider >& Provider, |
| const OUString& Scheme ) |
| throw( com::sun::star::uno::RuntimeException ) |
| { |
| osl::MutexGuard aGuard(m_aMutex); |
| |
| ProviderMap_Impl::iterator aMapIt; |
| try |
| { |
| aMapIt = m_aProviders.find(Scheme); |
| } |
| catch (IllegalArgumentException const &) |
| { |
| return; //@@@ |
| } |
| |
| if (aMapIt != m_aProviders.end()) |
| { |
| ProviderList_Impl & rList = aMapIt->getValue(); |
| |
| ProviderList_Impl::iterator aListEnd(rList.end()); |
| for (ProviderList_Impl::iterator aListIt(rList.begin()); |
| aListIt != aListEnd; ++aListIt) |
| { |
| if ((*aListIt).getProvider() == Provider) |
| { |
| rList.erase(aListIt); |
| break; |
| } |
| } |
| |
| if (rList.empty()) |
| m_aProviders.erase(aMapIt); |
| } |
| } |
| |
| //========================================================================= |
| // virtual |
| com::sun::star::uno::Sequence< ContentProviderInfo > SAL_CALL |
| UniversalContentBroker::queryContentProviders() |
| throw( com::sun::star::uno::RuntimeException ) |
| { |
| // Return a list with information about active(!) content providers. |
| |
| osl::MutexGuard aGuard(m_aMutex); |
| |
| com::sun::star::uno::Sequence< ContentProviderInfo > aSeq( |
| m_aProviders.size() ); |
| ContentProviderInfo* pInfo = aSeq.getArray(); |
| |
| ProviderMap_Impl::const_iterator end = m_aProviders.end(); |
| for (ProviderMap_Impl::const_iterator it(m_aProviders.begin()); it != end; |
| ++it) |
| { |
| // Note: Active provider is always the first list element. |
| pInfo->ContentProvider = it->getValue().front().getProvider(); |
| pInfo->Scheme = it->getRegexp(); |
| ++pInfo; |
| } |
| |
| return aSeq; |
| } |
| |
| //========================================================================= |
| // virtual |
| Reference< XContentProvider > SAL_CALL |
| UniversalContentBroker::queryContentProvider( const OUString& |
| Identifier ) |
| throw( com::sun::star::uno::RuntimeException ) |
| { |
| return queryContentProvider( Identifier, sal_False ); |
| } |
| |
| //========================================================================= |
| // |
| // XContentProvider methods. |
| // |
| //========================================================================= |
| |
| // virtual |
| Reference< XContent > SAL_CALL UniversalContentBroker::queryContent( |
| const Reference< XContentIdentifier >& Identifier ) |
| throw( IllegalIdentifierException, com::sun::star::uno::RuntimeException ) |
| { |
| ////////////////////////////////////////////////////////////////////// |
| // Let the content provider for the scheme given with the content |
| // identifier create the XContent instance. |
| ////////////////////////////////////////////////////////////////////// |
| |
| if ( !Identifier.is() ) |
| return Reference< XContent >(); |
| |
| Reference< XContentProvider > xProv = |
| queryContentProvider( Identifier->getContentIdentifier(), sal_True ); |
| if ( xProv.is() ) |
| return xProv->queryContent( Identifier ); |
| |
| return Reference< XContent >(); |
| } |
| |
| //========================================================================= |
| // virtual |
| sal_Int32 SAL_CALL UniversalContentBroker::compareContentIds( |
| const Reference< XContentIdentifier >& Id1, |
| const Reference< XContentIdentifier >& Id2 ) |
| throw( com::sun::star::uno::RuntimeException ) |
| { |
| OUString aURI1( Id1->getContentIdentifier() ); |
| OUString aURI2( Id2->getContentIdentifier() ); |
| |
| Reference< XContentProvider > xProv1 |
| = queryContentProvider( aURI1, sal_True ); |
| Reference< XContentProvider > xProv2 |
| = queryContentProvider( aURI2, sal_True ); |
| |
| // When both identifiers belong to the same provider, let that provider |
| // compare them; otherwise, simply compare the URI strings (which must |
| // be different): |
| if ( xProv1.is() && ( xProv1 == xProv2 ) ) |
| return xProv1->compareContentIds( Id1, Id2 ); |
| else |
| return aURI1.compareTo( aURI2 ); |
| } |
| |
| //========================================================================= |
| // |
| // XContentIdentifierFactory methods. |
| // |
| //========================================================================= |
| |
| // virtual |
| Reference< XContentIdentifier > SAL_CALL |
| UniversalContentBroker::createContentIdentifier( |
| const OUString& ContentId ) |
| throw( com::sun::star::uno::RuntimeException ) |
| { |
| ////////////////////////////////////////////////////////////////////// |
| // Let the content provider for the scheme given with content |
| // identifier create the XContentIdentifier instance, if he supports |
| // the XContentIdentifierFactory interface. Otherwise create standard |
| // implementation object for XContentIdentifier. |
| ////////////////////////////////////////////////////////////////////// |
| |
| Reference< XContentIdentifier > xIdentifier; |
| |
| Reference< XContentProvider > xProv |
| = queryContentProvider( ContentId, sal_True ); |
| if ( xProv.is() ) |
| { |
| Reference< XContentIdentifierFactory > xFac( xProv, UNO_QUERY ); |
| if ( xFac.is() ) |
| xIdentifier = xFac->createContentIdentifier( ContentId ); |
| } |
| |
| if ( !xIdentifier.is() ) |
| xIdentifier = new ContentIdentifier( m_xSMgr, ContentId ); |
| |
| return xIdentifier; |
| } |
| |
| //========================================================================= |
| // |
| // XCommandProcessor methods. |
| // |
| //========================================================================= |
| |
| // virtual |
| sal_Int32 SAL_CALL UniversalContentBroker::createCommandIdentifier() |
| throw( RuntimeException ) |
| { |
| osl::MutexGuard aGuard( m_aMutex ); |
| |
| // Just increase counter on every call to generate an identifier. |
| return ++m_nCommandId; |
| } |
| |
| //========================================================================= |
| // virtual |
| Any SAL_CALL UniversalContentBroker::execute( |
| const Command& aCommand, |
| sal_Int32, |
| const Reference< XCommandEnvironment >& Environment ) |
| throw( Exception, CommandAbortedException, RuntimeException ) |
| { |
| Any aRet; |
| |
| ////////////////////////////////////////////////////////////////////// |
| // Note: Don't forget to adapt ucb_commands::CommandProcessorInfo |
| // ctor in ucbcmds.cxx when adding new commands! |
| ////////////////////////////////////////////////////////////////////// |
| |
| if ( ( aCommand.Handle == GETCOMMANDINFO_HANDLE ) || |
| aCommand.Name.equalsAsciiL( |
| RTL_CONSTASCII_STRINGPARAM( GETCOMMANDINFO_NAME ) ) ) |
| { |
| ////////////////////////////////////////////////////////////////// |
| // getCommandInfo |
| ////////////////////////////////////////////////////////////////// |
| |
| aRet <<= getCommandInfo(); |
| } |
| else if ( ( aCommand.Handle == GLOBALTRANSFER_HANDLE ) || |
| aCommand.Name.equalsAsciiL( |
| RTL_CONSTASCII_STRINGPARAM(GLOBALTRANSFER_NAME ) ) ) |
| { |
| ////////////////////////////////////////////////////////////////// |
| // globalTransfer |
| ////////////////////////////////////////////////////////////////// |
| |
| GlobalTransferCommandArgument aTransferArg; |
| if ( !( aCommand.Argument >>= aTransferArg ) ) |
| { |
| ucbhelper::cancelCommandExecution( |
| makeAny( IllegalArgumentException( |
| rtl::OUString::createFromAscii( |
| "Wrong argument type!" ), |
| static_cast< cppu::OWeakObject * >( this ), |
| -1 ) ), |
| Environment ); |
| // Unreachable |
| } |
| |
| globalTransfer( aTransferArg, Environment ); |
| } |
| else |
| { |
| ////////////////////////////////////////////////////////////////// |
| // Unknown command |
| ////////////////////////////////////////////////////////////////// |
| |
| ucbhelper::cancelCommandExecution( |
| makeAny( UnsupportedCommandException( |
| rtl::OUString(), |
| static_cast< cppu::OWeakObject * >( this ) ) ), |
| Environment ); |
| // Unreachable |
| } |
| |
| return aRet; |
| } |
| |
| //========================================================================= |
| // virtual |
| void SAL_CALL UniversalContentBroker::abort( sal_Int32 ) |
| throw( RuntimeException ) |
| { |
| // @@@ Not implemeted ( yet). |
| } |
| |
| //========================================================================= |
| // |
| // XChangesListener methods |
| // |
| //========================================================================= |
| // virtual |
| void SAL_CALL UniversalContentBroker::changesOccurred( const util::ChangesEvent& Event ) |
| throw( uno::RuntimeException ) |
| { |
| sal_Int32 nCount = Event.Changes.getLength(); |
| if ( nCount ) |
| { |
| uno::Reference< container::XHierarchicalNameAccess > xHierNameAccess; |
| Event.Base >>= xHierNameAccess; |
| |
| OSL_ASSERT( xHierNameAccess.is() ); |
| |
| const util::ElementChange* pElementChanges |
| = Event.Changes.getConstArray(); |
| |
| ContentProviderDataList aData; |
| for ( sal_Int32 n = 0; n < nCount; ++n ) |
| { |
| const util::ElementChange& rElem = pElementChanges[ n ]; |
| rtl::OUString aKey; |
| rElem.Accessor >>= aKey; |
| |
| ContentProviderData aInfo; |
| |
| // Removal of UCPs from the configuration leads to changesOccurred |
| // notifications, too, but it is hard to tell for a given |
| // ElementChange whether it is an addition or a removal, so as a |
| // heuristic consider as removals those that cause a |
| // NoSuchElementException in createContentProviderData. |
| // |
| // For now, removal of UCPs from the configuration is simply ignored |
| // (and not reflected in the UCB's data structures): |
| if (createContentProviderData(aKey, xHierNameAccess, aInfo)) |
| { |
| aData.push_back(aInfo); |
| } |
| } |
| |
| prepareAndRegister(aData); |
| } |
| } |
| |
| //========================================================================= |
| // |
| // XEventListener methods |
| // |
| //========================================================================= |
| // virtual |
| void SAL_CALL UniversalContentBroker::disposing(const lang::EventObject&) |
| throw( uno::RuntimeException ) |
| { |
| if ( m_xNotifier.is() ) |
| { |
| osl::Guard< osl::Mutex > aGuard( m_aMutex ); |
| |
| if ( m_xNotifier.is() ) |
| m_xNotifier.clear(); |
| } |
| } |
| |
| //========================================================================= |
| // |
| // Non-interface methods |
| // |
| //========================================================================= |
| |
| Reference< XContentProvider > UniversalContentBroker::queryContentProvider( |
| const OUString& Identifier, |
| sal_Bool bResolved ) |
| { |
| osl::MutexGuard aGuard( m_aMutex ); |
| |
| ProviderList_Impl const * pList = m_aProviders.map( Identifier ); |
| return pList ? bResolved ? pList->front().getResolvedProvider() |
| : pList->front().getProvider() |
| : Reference< XContentProvider >(); |
| } |
| |
| bool UniversalContentBroker::configureUcb() |
| throw (uno::RuntimeException) |
| { |
| rtl::OUString aKey1; |
| rtl::OUString aKey2; |
| if (m_aArguments.getLength() < 2 |
| || !(m_aArguments[0] >>= aKey1) || !(m_aArguments[1] >>= aKey2)) |
| { |
| OSL_ENSURE(false, "UniversalContentBroker::configureUcb(): Bad arguments"); |
| return false; |
| } |
| |
| ContentProviderDataList aData; |
| if (!getContentProviderData(aKey1, aKey2, aData)) |
| { |
| OSL_ENSURE(false, "UniversalContentBroker::configureUcb(): No configuration"); |
| return false; |
| } |
| |
| prepareAndRegister(aData); |
| |
| return true; |
| } |
| |
| void UniversalContentBroker::prepareAndRegister( |
| const ContentProviderDataList& rData) |
| { |
| ContentProviderDataList::const_iterator aEnd(rData.end()); |
| for (ContentProviderDataList::const_iterator aIt(rData.begin()); |
| aIt != aEnd; ++aIt) |
| { |
| rtl::OUString aProviderArguments; |
| if (fillPlaceholders(aIt->Arguments, |
| m_aArguments, |
| &aProviderArguments)) |
| { |
| registerAtUcb(this, |
| m_xSMgr, |
| aIt->ServiceName, |
| aProviderArguments, |
| aIt->URLTemplate, |
| 0); |
| |
| } |
| else |
| OSL_ENSURE(false, |
| "UniversalContentBroker::prepareAndRegister(): Bad argument placeholders"); |
| } |
| } |
| |
| //========================================================================= |
| bool UniversalContentBroker::getContentProviderData( |
| const rtl::OUString & rKey1, |
| const rtl::OUString & rKey2, |
| ContentProviderDataList & rListToFill ) |
| { |
| if ( !m_xSMgr.is() || !rKey1.getLength() || !rKey2.getLength() ) |
| { |
| OSL_ENSURE( false, |
| "UniversalContentBroker::getContentProviderData - Invalid argument!" ); |
| return false; |
| } |
| |
| try |
| { |
| uno::Reference< lang::XMultiServiceFactory > xConfigProv( |
| m_xSMgr->createInstance( |
| rtl::OUString::createFromAscii( |
| "com.sun.star.configuration.ConfigurationProvider" ) ), |
| uno::UNO_QUERY_THROW ); |
| |
| rtl::OUStringBuffer aFullPath; |
| aFullPath.appendAscii( CONFIG_CONTENTPROVIDERS_KEY "/['" ); |
| makeAndAppendXMLName( aFullPath, rKey1 ); |
| aFullPath.appendAscii( "']/SecondaryKeys/['" ); |
| makeAndAppendXMLName( aFullPath, rKey2 ); |
| aFullPath.appendAscii( "']/ProviderData" ); |
| |
| uno::Sequence< uno::Any > aArguments( 1 ); |
| beans::PropertyValue aProperty; |
| aProperty.Name |
| = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" ) ); |
| aProperty.Value <<= aFullPath.makeStringAndClear(); |
| aArguments[ 0 ] <<= aProperty; |
| |
| uno::Reference< uno::XInterface > xInterface( |
| xConfigProv->createInstanceWithArguments( |
| rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( |
| "com.sun.star.configuration.ConfigurationAccess" ) ), |
| aArguments ) ); |
| |
| if ( !m_xNotifier.is() ) |
| { |
| m_xNotifier = uno::Reference< util::XChangesNotifier >( |
| xInterface, uno::UNO_QUERY_THROW ); |
| |
| m_xNotifier->addChangesListener( this ); |
| } |
| |
| uno::Reference< container::XNameAccess > xNameAccess( |
| xInterface, uno::UNO_QUERY_THROW ); |
| |
| uno::Sequence< rtl::OUString > aElems = xNameAccess->getElementNames(); |
| const rtl::OUString* pElems = aElems.getConstArray(); |
| sal_Int32 nCount = aElems.getLength(); |
| |
| if ( nCount > 0 ) |
| { |
| uno::Reference< container::XHierarchicalNameAccess > |
| xHierNameAccess( xInterface, uno::UNO_QUERY_THROW ); |
| |
| // Iterate over children. |
| for ( sal_Int32 n = 0; n < nCount; ++n ) |
| { |
| |
| try |
| { |
| |
| ContentProviderData aInfo; |
| |
| rtl::OUStringBuffer aElemBuffer; |
| aElemBuffer.appendAscii( "['" ); |
| makeAndAppendXMLName( aElemBuffer, pElems[ n ] ); |
| aElemBuffer.appendAscii( "']" ); |
| |
| OSL_VERIFY( |
| createContentProviderData( |
| aElemBuffer.makeStringAndClear(), xHierNameAccess, |
| aInfo)); |
| |
| rListToFill.push_back( aInfo ); |
| } |
| catch ( container::NoSuchElementException& ) |
| { |
| // getByHierarchicalName |
| OSL_ENSURE( false, |
| "UniversalContentBroker::getContentProviderData - " |
| "caught NoSuchElementException!" ); |
| } |
| } |
| } |
| } |
| catch ( uno::RuntimeException& ) |
| { |
| OSL_ENSURE( false, |
| "UniversalContentBroker::getContentProviderData - caught RuntimeException!" ); |
| return false; |
| } |
| catch ( uno::Exception& ) |
| { |
| // createInstance, createInstanceWithArguments |
| |
| OSL_ENSURE( false, |
| "UniversalContentBroker::getContentProviderData - caught Exception!" ); |
| return false; |
| } |
| |
| return true; |
| } |
| |
| //========================================================================= |
| // |
| // ProviderListEntry_Impl implementation. |
| // |
| //========================================================================= |
| |
| Reference< XContentProvider > ProviderListEntry_Impl::resolveProvider() const |
| { |
| if ( !m_xResolvedProvider.is() ) |
| { |
| Reference< XContentProviderSupplier > xSupplier( |
| m_xProvider, UNO_QUERY ); |
| if ( xSupplier.is() ) |
| m_xResolvedProvider = xSupplier->getContentProvider(); |
| |
| if ( !m_xResolvedProvider.is() ) |
| m_xResolvedProvider = m_xProvider; |
| } |
| |
| return m_xResolvedProvider; |
| } |