summaryrefslogtreecommitdiffstats
path: root/ucb/source/ucp/ext/ucpext_provider.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'ucb/source/ucp/ext/ucpext_provider.cxx')
-rw-r--r--ucb/source/ucp/ext/ucpext_provider.cxx171
1 files changed, 171 insertions, 0 deletions
diff --git a/ucb/source/ucp/ext/ucpext_provider.cxx b/ucb/source/ucp/ext/ucpext_provider.cxx
new file mode 100644
index 000000000..765ea7856
--- /dev/null
+++ b/ucb/source/ucp/ext/ucpext_provider.cxx
@@ -0,0 +1,171 @@
+/* -*- 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 .
+ */
+
+#include "ucpext_provider.hxx"
+#include "ucpext_content.hxx"
+
+#include <com/sun/star/ucb/IllegalIdentifierException.hpp>
+#include <cppuhelper/weak.hxx>
+#include <ucbhelper/contentidentifier.hxx>
+#include <osl/mutex.hxx>
+#include <rtl/ustrbuf.hxx>
+
+
+namespace ucb::ucp::ext
+{
+
+
+ using ::com::sun::star::uno::Reference;
+ using ::com::sun::star::uno::XInterface;
+ using ::com::sun::star::uno::Sequence;
+ using ::com::sun::star::ucb::XContentIdentifier;
+ using ::com::sun::star::ucb::IllegalIdentifierException;
+ using ::com::sun::star::ucb::XContent;
+ using ::com::sun::star::uno::XComponentContext;
+
+
+ //= ContentProvider
+
+
+ ContentProvider::ContentProvider( const Reference< XComponentContext >& rxContext )
+ :ContentProvider_Base( rxContext )
+ {
+ }
+
+
+ ContentProvider::~ContentProvider()
+ {
+ }
+
+
+ OUString SAL_CALL ContentProvider::getImplementationName()
+ {
+ return "org.openoffice.comp.ucp.ext.ContentProvider";
+ }
+
+
+ Sequence< OUString > SAL_CALL ContentProvider::getSupportedServiceNames( )
+ {
+ return { "com.sun.star.ucb.ContentProvider", "com.sun.star.ucb.ExtensionContentProvider" };
+ }
+
+
+ OUString ContentProvider::getRootURL()
+ {
+ return "vnd.sun.star.extension://";
+ }
+
+
+ OUString ContentProvider::getArtificialNodeContentType()
+ {
+ return "application/vnd.sun.star.extension-content";
+ }
+
+
+ namespace
+ {
+ void lcl_ensureAndTransfer( std::u16string_view& io_rIdentifierFragment, OUStringBuffer& o_rNormalization, const sal_Unicode i_nLeadingChar )
+ {
+ if ( ( io_rIdentifierFragment.empty() ) || ( io_rIdentifierFragment[0] != i_nLeadingChar ) )
+ throw IllegalIdentifierException();
+ io_rIdentifierFragment = io_rIdentifierFragment.substr( 1 );
+ o_rNormalization.append( i_nLeadingChar );
+ }
+ }
+
+
+ Reference< XContent > SAL_CALL ContentProvider::queryContent( const Reference< XContentIdentifier >& i_rIdentifier )
+ {
+ // Check URL scheme...
+ static const OUStringLiteral sScheme( u"vnd.sun.star.extension" );
+ if ( !i_rIdentifier->getContentProviderScheme().equalsIgnoreAsciiCase( sScheme ) )
+ throw IllegalIdentifierException();
+
+ // normalize the identifier
+ const OUString sIdentifier( i_rIdentifier->getContentIdentifier() );
+
+ // the scheme needs to be lower-case
+ OUStringBuffer aComposer;
+ aComposer.append( sIdentifier.copy( 0, sScheme.getLength() ).toAsciiLowerCase() );
+
+ // one : is required after the scheme
+ std::u16string_view sRemaining( sIdentifier.subView( sScheme.getLength() ) );
+ lcl_ensureAndTransfer( sRemaining, aComposer, ':' );
+
+ // and at least one /
+ lcl_ensureAndTransfer( sRemaining, aComposer, '/' );
+
+ // the normalized form requires one additional /, but we also accept identifiers which don't have it
+ if ( sRemaining.empty() )
+ {
+ // the root content is a special case, it requires /
+ aComposer.append( "//" );
+ }
+ else
+ {
+ if ( sRemaining[0] != '/' )
+ {
+ aComposer.append( '/' );
+ aComposer.append( sRemaining );
+ }
+ else
+ {
+ lcl_ensureAndTransfer( sRemaining, aComposer, '/' );
+ // by now, we moved "vnd.sun.star.extension://" from the URL to aComposer
+ if ( sRemaining.empty() )
+ {
+ // again, it's the root content, but one / is missing
+ aComposer.append( '/' );
+ }
+ else
+ {
+ aComposer.append( sRemaining );
+ }
+ }
+ }
+ const Reference< XContentIdentifier > xNormalizedIdentifier( new ::ucbhelper::ContentIdentifier( aComposer.makeStringAndClear() ) );
+
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ // check if a content with given id already exists...
+ Reference< XContent > xContent( queryExistingContent( xNormalizedIdentifier ) );
+ if ( xContent.is() )
+ return xContent;
+
+ // create a new content
+ xContent = new Content( m_xContext, this, xNormalizedIdentifier );
+ if ( !xContent->getIdentifier().is() )
+ throw IllegalIdentifierException();
+
+ registerNewContent( xContent );
+ return xContent;
+ }
+
+
+} // namespace ucb::ucp::ext
+
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
+ucb_ext_ContentProvider_get_implementation(
+ css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&)
+{
+ return cppu::acquire(new ucb::ucp::ext::ContentProvider(context));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */