summaryrefslogtreecommitdiffstats
path: root/ucb/source/ucp/expand/ucpexpand.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'ucb/source/ucp/expand/ucpexpand.cxx')
-rw-r--r--ucb/source/ucp/expand/ucpexpand.cxx235
1 files changed, 235 insertions, 0 deletions
diff --git a/ucb/source/ucp/expand/ucpexpand.cxx b/ucb/source/ucp/expand/ucpexpand.cxx
new file mode 100644
index 000000000..16bf38bbf
--- /dev/null
+++ b/ucb/source/ucp/expand/ucpexpand.cxx
@@ -0,0 +1,235 @@
+/* -*- 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 <rtl/uri.hxx>
+#include <osl/mutex.hxx>
+#include <cppuhelper/compbase.hxx>
+#include <cppuhelper/factory.hxx>
+#include <cppuhelper/implementationentry.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <ucbhelper/content.hxx>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/util/theMacroExpander.hpp>
+#include <com/sun/star/ucb/IllegalIdentifierException.hpp>
+#include <com/sun/star/ucb/XContentProvider.hpp>
+#include <tools/diagnose_ex.h>
+
+#define EXPAND_PROTOCOL "vnd.sun.star.expand"
+
+
+using namespace ::com::sun::star;
+
+namespace
+{
+
+struct MutexHolder
+{
+ mutable ::osl::Mutex m_mutex;
+};
+
+typedef ::cppu::WeakComponentImplHelper<
+ lang::XServiceInfo, ucb::XContentProvider > t_impl_helper;
+
+
+class ExpandContentProviderImpl : protected MutexHolder, public t_impl_helper
+{
+ uno::Reference< uno::XComponentContext > m_xComponentContext;
+ uno::Reference< util::XMacroExpander > m_xMacroExpander;
+ OUString expandUri(
+ uno::Reference< ucb::XContentIdentifier > const & xIdentifier ) const;
+
+protected:
+ void check() const;
+ virtual void SAL_CALL disposing() override;
+
+public:
+ explicit ExpandContentProviderImpl(
+ uno::Reference< uno::XComponentContext > const & xComponentContext )
+ : t_impl_helper( m_mutex ),
+ m_xComponentContext( xComponentContext ),
+ m_xMacroExpander( util::theMacroExpander::get(xComponentContext) )
+ {}
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() override;
+ virtual sal_Bool SAL_CALL supportsService( OUString const & serviceName ) override;
+ virtual uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
+
+ // XContentProvider
+ virtual uno::Reference< ucb::XContent > SAL_CALL queryContent(
+ uno::Reference< ucb::XContentIdentifier > const & xIdentifier ) override;
+ virtual sal_Int32 SAL_CALL compareContentIds(
+ uno::Reference< ucb::XContentIdentifier > const & xId1,
+ uno::Reference< ucb::XContentIdentifier > const & xId2 ) override;
+};
+
+
+void ExpandContentProviderImpl::check() const
+{
+ // xxx todo guard?
+// MutexGuard guard( m_mutex );
+ if (rBHelper.bInDispose || rBHelper.bDisposed)
+ {
+ throw lang::DisposedException(
+ "expand content provider instance has "
+ "already been disposed!",
+ static_cast< OWeakObject * >(
+ const_cast< ExpandContentProviderImpl * >(this) ) );
+ }
+}
+
+void ExpandContentProviderImpl::disposing()
+{
+}
+
+
+uno::Reference< uno::XInterface > create(
+ uno::Reference< uno::XComponentContext > const & xComponentContext )
+{
+ return static_cast< ::cppu::OWeakObject * >(
+ new ExpandContentProviderImpl( xComponentContext ) );
+}
+
+
+OUString implName()
+{
+ return "com.sun.star.comp.ucb.ExpandContentProvider";
+}
+
+
+uno::Sequence< OUString > supportedServices()
+{
+ return uno::Sequence< OUString > {
+ OUString("com.sun.star.ucb.ExpandContentProvider"),
+ OUString("com.sun.star.ucb.ContentProvider")
+ };
+}
+
+// XServiceInfo
+
+OUString ExpandContentProviderImpl::getImplementationName()
+{
+ check();
+ return implName();
+}
+
+
+uno::Sequence< OUString > ExpandContentProviderImpl::getSupportedServiceNames()
+{
+ check();
+ return supportedServices();
+}
+
+sal_Bool ExpandContentProviderImpl::supportsService(OUString const & serviceName )
+{
+ return cppu::supportsService(this, serviceName);
+}
+
+OUString ExpandContentProviderImpl::expandUri(
+ uno::Reference< ucb::XContentIdentifier > const & xIdentifier ) const
+{
+ OUString uri( xIdentifier->getContentIdentifier() );
+ if (!uri.startsWith(EXPAND_PROTOCOL ":"))
+ {
+ throw ucb::IllegalIdentifierException(
+ "expected protocol " EXPAND_PROTOCOL "!",
+ static_cast< OWeakObject * >(
+ const_cast< ExpandContentProviderImpl * >(this) ) );
+ }
+ // cut protocol
+ OUString str( uri.copy( sizeof (EXPAND_PROTOCOL ":") -1 ) );
+ // decode uric class chars
+ str = ::rtl::Uri::decode(
+ str, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 );
+ // expand macro string
+ return m_xMacroExpander->expandMacros( str );
+}
+
+// XContentProvider
+
+uno::Reference< ucb::XContent > ExpandContentProviderImpl::queryContent(
+ uno::Reference< ucb::XContentIdentifier > const & xIdentifier )
+{
+ check();
+ OUString uri( expandUri( xIdentifier ) );
+
+ ::ucbhelper::Content ucb_content;
+ if (::ucbhelper::Content::create(
+ uri, uno::Reference< ucb::XCommandEnvironment >(),
+ m_xComponentContext, ucb_content ))
+ {
+ return ucb_content.get();
+ }
+ else
+ {
+ return uno::Reference< ucb::XContent >();
+ }
+}
+
+
+sal_Int32 ExpandContentProviderImpl::compareContentIds(
+ uno::Reference< ucb::XContentIdentifier > const & xId1,
+ uno::Reference< ucb::XContentIdentifier > const & xId2 )
+{
+ check();
+ try
+ {
+ OUString uri1( expandUri( xId1 ) );
+ OUString uri2( expandUri( xId2 ) );
+ return uri1.compareTo( uri2 );
+ }
+ catch (const ucb::IllegalIdentifierException &)
+ {
+ TOOLS_WARN_EXCEPTION( "ucb", "" );
+ return -1;
+ }
+}
+
+static const ::cppu::ImplementationEntry s_entries [] =
+{
+ {
+ create,
+ implName,
+ supportedServices,
+ ::cppu::createSingleComponentFactory,
+ nullptr, 0
+ },
+ { nullptr, nullptr, nullptr, nullptr, nullptr, 0 }
+};
+
+}
+
+extern "C"
+{
+
+SAL_DLLPUBLIC_EXPORT void * ucpexpand1_component_getFactory(
+ const char * pImplName,
+ void * pServiceManager,
+ void * pRegistryKey )
+{
+ return ::cppu::component_getFactoryHelper(
+ pImplName, pServiceManager, pRegistryKey, s_entries );
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */