summaryrefslogtreecommitdiffstats
path: root/ucb/source/core/ucb.cxx
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
commited5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch)
tree7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /ucb/source/core/ucb.cxx
parentInitial commit. (diff)
downloadlibreoffice-upstream.tar.xz
libreoffice-upstream.zip
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'ucb/source/core/ucb.cxx')
-rw-r--r--ucb/source/core/ucb.cxx887
1 files changed, 887 insertions, 0 deletions
diff --git a/ucb/source/core/ucb.cxx b/ucb/source/core/ucb.cxx
new file mode 100644
index 000000000..4e41e8cff
--- /dev/null
+++ b/ucb/source/core/ucb.cxx
@@ -0,0 +1,887 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * 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 .
+ */
+
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+
+#include <sal/config.h>
+
+#include <string_view>
+
+#include <osl/diagnose.h>
+#include <sal/log.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/propertysequence.hxx>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <com/sun/star/ucb/DuplicateProviderException.hpp>
+#include <com/sun/star/ucb/GlobalTransferCommandArgument2.hpp>
+#include <com/sun/star/ucb/UnsupportedCommandException.hpp>
+#include <com/sun/star/ucb/XCommandInfo.hpp>
+#include <com/sun/star/ucb/XContentProviderSupplier.hpp>
+#include <com/sun/star/configuration/theDefaultProvider.hpp>
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/uno/Any.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <cppuhelper/weak.hxx>
+#include <ucbhelper/cancelcommandexecution.hxx>
+#include <tools/diagnose_ex.h>
+#include "identify.hxx"
+#include "ucbcmds.hxx"
+
+#include "ucb.hxx"
+
+using namespace comphelper;
+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;
+
+namespace {
+
+bool fillPlaceholders(OUString const & rInput,
+ uno::Sequence< uno::Any > const & rReplacements,
+ OUString * pOutput)
+{
+ sal_Unicode const * p = rInput.getStr();
+ sal_Unicode const * pEnd = p + rInput.getLength();
+ sal_Unicode const * pCopy = p;
+ 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('&');
+ 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('<');
+ 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('>');
+ p += 3;
+ pCopy = p;
+ }
+ break;
+
+ case '<':
+ sal_Unicode const * q = p;
+ while (q != pEnd && *q != '>')
+ ++q;
+ if (q == pEnd)
+ break;
+ OUString aKey(p, q - p);
+ OUString aValue;
+ bool bFound = false;
+ for (sal_Int32 i = 2; i + 1 < rReplacements.getLength();
+ i += 2)
+ {
+ 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(
+ OUStringBuffer & rBuffer, const OUString & rIn )
+{
+ sal_Int32 nCount = rIn.getLength();
+ for ( sal_Int32 n = 0; n < nCount; ++n )
+ {
+ const sal_Unicode c = rIn[ n ];
+ switch ( c )
+ {
+ case '&':
+ rBuffer.append( "&amp;" );
+ break;
+
+ case '"':
+ rBuffer.append( "&quot;" );
+ break;
+
+ case '\'':
+ rBuffer.append( "&apos;" );
+ break;
+
+ case '<':
+ rBuffer.append( "&lt;" );
+ break;
+
+ case '>':
+ rBuffer.append( "&gt;" );
+ break;
+
+ default:
+ rBuffer.append( c );
+ break;
+ }
+ }
+}
+
+bool createContentProviderData(
+ std::u16string_view rProvider,
+ const uno::Reference< container::XHierarchicalNameAccess >& rxHierNameAccess,
+ ContentProviderData & rInfo)
+{
+ // Obtain service name.
+
+ OUString aValue;
+ try
+ {
+ if ( !( rxHierNameAccess->getByHierarchicalName(
+ OUString::Concat(rProvider) + "/ServiceName" ) >>= aValue ) )
+ {
+ OSL_FAIL( "UniversalContentBroker::getContentProviderData - "
+ "Error getting item value!" );
+ }
+ }
+ catch (const container::NoSuchElementException&)
+ {
+ return false;
+ }
+
+ rInfo.ServiceName = aValue;
+
+ // Obtain URL Template.
+
+ if ( !( rxHierNameAccess->getByHierarchicalName(
+ OUString::Concat(rProvider) + "/URLTemplate" ) >>= aValue ) )
+ {
+ OSL_FAIL( "UniversalContentBroker::getContentProviderData - "
+ "Error getting item value!" );
+ }
+
+ rInfo.URLTemplate = aValue;
+
+ // Obtain Arguments.
+
+ if ( !( rxHierNameAccess->getByHierarchicalName(
+ OUString::Concat(rProvider) + "/Arguments" ) >>= aValue ) )
+ {
+ OSL_FAIL( "UniversalContentBroker::getContentProviderData - "
+ "Error getting item value!" );
+ }
+
+ rInfo.Arguments = aValue;
+ return true;
+}
+
+}
+
+
+// UniversalContentBroker Implementation.
+
+
+UniversalContentBroker::UniversalContentBroker(
+ const Reference< css::uno::XComponentContext >& xContext )
+: m_xContext( xContext ),
+ m_nCommandId( 0 )
+{
+ OSL_ENSURE( m_xContext.is(),
+ "UniversalContentBroker ctor: No service manager" );
+}
+
+
+// virtual
+UniversalContentBroker::~UniversalContentBroker()
+{
+}
+
+
+// XComponent methods.
+
+
+// virtual
+void SAL_CALL UniversalContentBroker::dispose()
+{
+ if ( m_pDisposeEventListeners && m_pDisposeEventListeners->getLength() )
+ {
+ EventObject aEvt;
+ aEvt.Source = 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 )
+{
+ if ( !m_pDisposeEventListeners )
+ m_pDisposeEventListeners.reset( new OInterfaceContainerHelper3<css::lang::XEventListener>( m_aMutex ) );
+
+ m_pDisposeEventListeners->addInterface( Listener );
+}
+
+
+// virtual
+void SAL_CALL UniversalContentBroker::removeEventListener(
+ const Reference< XEventListener >& Listener )
+{
+ if ( m_pDisposeEventListeners )
+ m_pDisposeEventListeners->removeInterface( Listener );
+
+ // Note: Don't want to delete empty container here -> performance.
+}
+
+
+// XServiceInfo methods.
+
+OUString SAL_CALL UniversalContentBroker::getImplementationName()
+{
+ return "com.sun.star.comp.ucb.UniversalContentBroker";
+}
+sal_Bool SAL_CALL UniversalContentBroker::supportsService( const OUString& ServiceName )
+{
+ return cppu::supportsService( this, ServiceName );
+}
+css::uno::Sequence< OUString > SAL_CALL UniversalContentBroker::getSupportedServiceNames()
+{
+ return { "com.sun.star.ucb.UniversalContentBroker" };
+}
+
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
+ucb_UniversalContentBroker_get_implementation(
+ css::uno::XComponentContext* context , css::uno::Sequence<css::uno::Any> const&)
+{
+ return cppu::acquire(new UniversalContentBroker(context));
+}
+
+
+// XInitialization methods.
+
+
+// virtual
+void SAL_CALL UniversalContentBroker::initialize( const css::uno::Sequence< Any >& aArguments )
+{
+ {
+ osl::MutexGuard aGuard(m_aMutex);
+ if (m_aArguments.hasElements())
+ {
+ if (aArguments.hasElements()
+ && !(m_aArguments.getLength() == 2
+ && aArguments.getLength() == 2
+ && m_aArguments[0] == aArguments[0]
+ && m_aArguments[1] == aArguments[1]))
+ {
+ throw IllegalArgumentException(
+ "UCB reinitialized with different arguments",
+ static_cast< cppu::OWeakObject * >(this), 0);
+ }
+ return;
+ }
+ if (!aArguments.hasElements())
+ {
+ m_aArguments = { Any(OUString("Local")), Any(OUString("Office")) };
+ }
+ else
+ {
+ m_aArguments = aArguments;
+ }
+ }
+ configureUcb();
+}
+
+
+// XContentProviderManager methods.
+
+
+// virtual
+Reference< XContentProvider > SAL_CALL
+UniversalContentBroker::registerContentProvider(
+ const Reference< XContentProvider >& Provider,
+ const OUString& Scheme,
+ sal_Bool ReplaceExisting )
+{
+ osl::MutexGuard aGuard(m_aMutex);
+
+ ProviderMap_Impl::iterator aIt;
+ try
+ {
+ aIt = m_aProviders.find(Scheme);
+ }
+ catch (const IllegalArgumentException&)
+ {
+ return nullptr; //@@@
+ }
+
+ Reference< XContentProvider > xPrevious;
+ if (aIt == m_aProviders.end())
+ {
+ ProviderList_Impl aList;
+ aList.push_front( ProviderListEntry_Impl(Provider) );
+ try
+ {
+ m_aProviders.add(Scheme, aList);
+ }
+ catch (const IllegalArgumentException&)
+ {
+ return nullptr; //@@@
+ }
+ }
+ else
+ {
+ if (!ReplaceExisting)
+ throw DuplicateProviderException();
+
+ ProviderList_Impl & rList = aIt->getValue();
+ xPrevious = rList.front().getProvider();
+ rList.push_front( ProviderListEntry_Impl(Provider) );
+ }
+
+ return xPrevious;
+}
+
+
+// virtual
+void SAL_CALL UniversalContentBroker::deregisterContentProvider(
+ const Reference< XContentProvider >& Provider,
+ const OUString& Scheme )
+{
+ osl::MutexGuard aGuard(m_aMutex);
+
+ ProviderMap_Impl::iterator aMapIt;
+ try
+ {
+ aMapIt = m_aProviders.find(Scheme);
+ }
+ catch (const IllegalArgumentException&)
+ {
+ return; //@@@
+ }
+
+ if (aMapIt != m_aProviders.end())
+ {
+ ProviderList_Impl & rList = aMapIt->getValue();
+
+ auto aListIt = std::find_if(rList.begin(), rList.end(),
+ [&Provider](const ProviderListEntry_Impl& rEntry) { return rEntry.getProvider() == Provider; });
+ if (aListIt != rList.end())
+ rList.erase(aListIt);
+
+ if (rList.empty())
+ m_aProviders.erase(aMapIt);
+ }
+}
+
+
+// virtual
+css::uno::Sequence< ContentProviderInfo > SAL_CALL
+ UniversalContentBroker::queryContentProviders()
+{
+ // Return a list with information about active(!) content providers.
+
+ osl::MutexGuard aGuard(m_aMutex);
+
+ css::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 )
+{
+ return queryContentProvider( Identifier, false );
+}
+
+
+// XContentProvider methods.
+
+
+// virtual
+Reference< XContent > SAL_CALL UniversalContentBroker::queryContent(
+ const Reference< XContentIdentifier >& Identifier )
+{
+
+ // 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(), 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 )
+{
+ OUString aURI1( Id1->getContentIdentifier() );
+ OUString aURI2( Id2->getContentIdentifier() );
+
+ Reference< XContentProvider > xProv1
+ = queryContentProvider( aURI1, true );
+ Reference< XContentProvider > xProv2
+ = queryContentProvider( aURI2, 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 )
+{
+
+ // 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, true );
+ if ( xProv.is() )
+ {
+ Reference< XContentIdentifierFactory > xFac( xProv, UNO_QUERY );
+ if ( xFac.is() )
+ xIdentifier = xFac->createContentIdentifier( ContentId );
+ }
+
+ if ( !xIdentifier.is() )
+ xIdentifier = new ContentIdentifier( ContentId );
+
+ return xIdentifier;
+}
+
+
+// XCommandProcessor methods.
+
+
+// virtual
+sal_Int32 SAL_CALL UniversalContentBroker::createCommandIdentifier()
+{
+ 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 )
+{
+ 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 == GETCOMMANDINFO_NAME )
+ {
+
+ // getCommandInfo
+
+
+ aRet <<= getCommandInfo();
+ }
+ else if ( ( aCommand.Handle == GLOBALTRANSFER_HANDLE ) || aCommand.Name == GLOBALTRANSFER_NAME )
+ {
+
+ // globalTransfer
+
+
+ GlobalTransferCommandArgument2 aTransferArg;
+ if ( !( aCommand.Argument >>= aTransferArg ) )
+ {
+ GlobalTransferCommandArgument aArg;
+ if ( !( aCommand.Argument >>= aArg ) )
+ {
+ ucbhelper::cancelCommandExecution(
+ Any( IllegalArgumentException(
+ "Wrong argument type!",
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ // Unreachable
+ }
+
+ // Copy infos into the new structure
+ aTransferArg.Operation = aArg.Operation;
+ aTransferArg.SourceURL = aArg.SourceURL;
+ aTransferArg.TargetURL = aArg.TargetURL;
+ aTransferArg.NewTitle = aArg.NewTitle;
+ aTransferArg.NameClash = aArg.NameClash;
+ }
+
+ globalTransfer( aTransferArg, Environment );
+ }
+ else if ( ( aCommand.Handle == CHECKIN_HANDLE ) || aCommand.Name == CHECKIN_NAME )
+ {
+ ucb::CheckinArgument aCheckinArg;
+ if ( !( aCommand.Argument >>= aCheckinArg ) )
+ {
+ ucbhelper::cancelCommandExecution(
+ Any( IllegalArgumentException(
+ "Wrong argument type!",
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ // Unreachable
+ }
+ aRet = checkIn( aCheckinArg, Environment );
+ }
+ else
+ {
+
+ // Unknown command
+
+
+ ucbhelper::cancelCommandExecution(
+ Any( UnsupportedCommandException(
+ OUString(),
+ static_cast< cppu::OWeakObject * >( this ) ) ),
+ Environment );
+ // Unreachable
+ }
+
+ return aRet;
+}
+
+
+// XCommandProcessor2 methods.
+
+
+// virtual
+void SAL_CALL UniversalContentBroker::releaseCommandIdentifier(sal_Int32 /*aCommandId*/)
+{
+ // @@@ Not implemented ( yet).
+}
+
+
+// virtual
+void SAL_CALL UniversalContentBroker::abort( sal_Int32 )
+{
+ // @@@ Not implemented ( yet).
+}
+
+
+// XChangesListener methods
+
+
+// virtual
+void SAL_CALL UniversalContentBroker::changesOccurred( const util::ChangesEvent& Event )
+{
+ if ( !Event.Changes.hasElements() )
+ return;
+
+ uno::Reference< container::XHierarchicalNameAccess > xHierNameAccess;
+ Event.Base >>= xHierNameAccess;
+
+ OSL_ASSERT( xHierNameAccess.is() );
+
+ ContentProviderDataList aData;
+ for ( const util::ElementChange& rElem : Event.Changes )
+ {
+ 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&)
+{
+ 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,
+ 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 >();
+}
+
+void UniversalContentBroker::configureUcb()
+{
+ OUString aKey1;
+ OUString aKey2;
+ if (m_aArguments.getLength() < 2
+ || !(m_aArguments[0] >>= aKey1) || !(m_aArguments[1] >>= aKey2))
+ {
+ OSL_FAIL("UniversalContentBroker::configureUcb(): Bad arguments");
+ return;
+ }
+
+ ContentProviderDataList aData;
+ if (!getContentProviderData(aKey1, aKey2, aData))
+ {
+ SAL_WARN( "ucb", "No configuration");
+ return;
+ }
+
+ prepareAndRegister(aData);
+}
+
+void UniversalContentBroker::prepareAndRegister(
+ const ContentProviderDataList& rData)
+{
+ for (const auto& rContentProviderData : rData)
+ {
+ OUString aProviderArguments;
+ if (fillPlaceholders(rContentProviderData.Arguments,
+ m_aArguments,
+ &aProviderArguments))
+ {
+ registerAtUcb(this,
+ m_xContext,
+ rContentProviderData.ServiceName,
+ aProviderArguments,
+ rContentProviderData.URLTemplate);
+
+ }
+ else
+ OSL_FAIL("UniversalContentBroker::prepareAndRegister(): Bad argument placeholders");
+ }
+}
+
+
+bool UniversalContentBroker::getContentProviderData(
+ const OUString & rKey1,
+ const OUString & rKey2,
+ ContentProviderDataList & rListToFill )
+{
+ if ( !m_xContext.is() || rKey1.isEmpty() || rKey2.isEmpty() )
+ {
+ OSL_FAIL( "UniversalContentBroker::getContentProviderData - Invalid argument!" );
+ return false;
+ }
+
+ try
+ {
+ uno::Reference< lang::XMultiServiceFactory > xConfigProv =
+ configuration::theDefaultProvider::get( m_xContext );
+
+ OUStringBuffer aFullPath(128);
+ aFullPath.append(
+ "/org.openoffice.ucb.Configuration/ContentProviders"
+ "/['" );
+ makeAndAppendXMLName( aFullPath, rKey1 );
+ aFullPath.append( "']/SecondaryKeys/['" );
+ makeAndAppendXMLName( aFullPath, rKey2 );
+ aFullPath.append( "']/ProviderData" );
+
+ uno::Sequence<uno::Any> aArguments(comphelper::InitAnyPropertySequence(
+ {
+ {"nodepath", uno::Any(aFullPath.makeStringAndClear())}
+ }));
+
+ uno::Reference< uno::XInterface > xInterface(
+ xConfigProv->createInstanceWithArguments(
+ "com.sun.star.configuration.ConfigurationAccess",
+ aArguments ) );
+
+ if ( !m_xNotifier.is() )
+ {
+ m_xNotifier.set( xInterface, uno::UNO_QUERY_THROW );
+
+ m_xNotifier->addChangesListener( this );
+ }
+
+ uno::Reference< container::XNameAccess > xNameAccess(
+ xInterface, uno::UNO_QUERY_THROW );
+
+ const uno::Sequence< OUString > aElems = xNameAccess->getElementNames();
+
+ if ( aElems.hasElements() )
+ {
+ uno::Reference< container::XHierarchicalNameAccess >
+ xHierNameAccess( xInterface, uno::UNO_QUERY_THROW );
+
+ // Iterate over children.
+ for ( const auto& rElem : aElems )
+ {
+
+ try
+ {
+
+ ContentProviderData aInfo;
+
+ OUStringBuffer aElemBuffer;
+ aElemBuffer.append( "['" );
+ makeAndAppendXMLName( aElemBuffer, rElem );
+ aElemBuffer.append( "']" );
+
+ OSL_VERIFY(
+ createContentProviderData(
+ aElemBuffer.makeStringAndClear(), xHierNameAccess,
+ aInfo));
+
+ rListToFill.push_back( aInfo );
+ }
+ catch (const container::NoSuchElementException&)
+ {
+ // getByHierarchicalName
+ OSL_FAIL( "UniversalContentBroker::getContentProviderData - "
+ "caught NoSuchElementException!" );
+ }
+ }
+ }
+ }
+ catch (const uno::RuntimeException&)
+ {
+ TOOLS_WARN_EXCEPTION( "ucb", "" );
+ return false;
+ }
+ catch (const uno::Exception&)
+ {
+ // createInstance, createInstanceWithArguments
+
+ TOOLS_WARN_EXCEPTION( "ucb", "" );
+ return false;
+ }
+
+ return true;
+}
+
+
+// ProviderListEntry_Impl implementation.
+
+
+Reference< XContentProvider > const & 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;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */