bump product version to 5.0.4.1
[LibreOffice.git] / ucb / source / ucp / image / ucpimage.cxx
blobda44fd495b068a931071c5584924de6d890d1400
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include <sal/config.h>
12 #include <cassert>
14 #include <com/sun/star/lang/XServiceInfo.hpp>
15 #include <com/sun/star/ucb/XContentProvider.hpp>
16 #include <com/sun/star/uno/XComponentContext.hpp>
17 #include <com/sun/star/uri/UriReferenceFactory.hpp>
18 #include <cppuhelper/compbase.hxx>
19 #include <cppuhelper/supportsservice.hxx>
20 #include <osl/mutex.hxx>
21 #include <rtl/uri.hxx>
22 #include <rtl/ustrbuf.hxx>
23 #include <vcl/implimagetree.hxx>
24 #include <vcl/svapp.hxx>
25 #include <ucbhelper/content.hxx>
27 // A LO-private ("implementation detail") UCP used to access images from help
28 // content, with theme fallback and localization support as provided by VCL's
29 // ImplImageTree.
31 // The URL scheme is
33 // "vnd.libreoffice.image://"<theme><path>["?lang="<language-tag>]
35 namespace {
37 class Provider :
38 private osl::Mutex,
39 public cppu::WeakComponentImplHelper<
40 css::lang::XServiceInfo, css::ucb::XContentProvider>
42 public:
43 explicit Provider(
44 css::uno::Reference<css::uno::XComponentContext> const & context):
45 WeakComponentImplHelper(*static_cast<Mutex *>(this)), context_(context)
48 private:
49 OUString SAL_CALL getImplementationName()
50 throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
51 { return OUString("com.sun.star.comp.ucb.ImageContentProvider"); }
53 sal_Bool SAL_CALL supportsService(OUString const & ServiceName)
54 throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
55 { return cppu::supportsService(this, ServiceName); }
57 css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames()
58 throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
60 return css::uno::Sequence<OUString>{
61 "com.sun.star.ucb.ImageContentProvider"};
64 css::uno::Reference<css::ucb::XContent> SAL_CALL queryContent(
65 css::uno::Reference<css::ucb::XContentIdentifier> const & Identifier)
66 throw (
67 css::ucb::IllegalIdentifierException, css::uno::RuntimeException,
68 std::exception)
69 SAL_OVERRIDE
71 css::uno::Reference<css::uno::XComponentContext> context;
73 osl::MutexGuard g(*this);
74 context = context_;
76 if (!context.is()) {
77 throw css::lang::DisposedException();
79 auto url(Identifier->getContentIdentifier());
80 auto uri(css::uri::UriReferenceFactory::create(context)->parse(url));
81 if (!(uri.is()
82 && uri->getScheme().equalsIgnoreAsciiCase(
83 "vnd.libreoffice.image")))
85 throw css::ucb::IllegalIdentifierException(url);
87 auto auth(
88 rtl::Uri::decode(
89 uri->getAuthority(), rtl_UriDecodeStrict,
90 RTL_TEXTENCODING_UTF8));
91 if (auth.isEmpty()) {
92 throw css::ucb::IllegalIdentifierException(url);
94 auto path(uri->getPath());
95 if (path.isEmpty()) {
96 throw css::ucb::IllegalIdentifierException(url);
98 OUStringBuffer buf;
99 assert(path[0] == '/');
100 for (sal_Int32 i = 1;;) {
101 auto j = path.indexOf('/', i);
102 if (j == -1) {
103 j = path.getLength();
105 auto seg(
106 rtl::Uri::decode(
107 path.copy(i, j - i), rtl_UriDecodeStrict,
108 RTL_TEXTENCODING_UTF8));
109 if (seg.isEmpty()) {
110 throw css::ucb::IllegalIdentifierException(url);
112 if (i != 1) {
113 buf.append('/');
115 buf.append(seg);
116 if (j == path.getLength()) {
117 break;
119 i = j + 1;
121 auto decPath(buf.makeStringAndClear());
122 OUString lang;
123 if (uri->hasQuery()) {
124 if (!uri->getQuery().startsWith("lang=", &lang)) {
125 throw css::ucb::IllegalIdentifierException(url);
127 lang = rtl::Uri::decode(
128 lang, rtl_UriDecodeStrict, RTL_TEXTENCODING_UTF8);
129 if (lang.isEmpty()) {
130 throw css::ucb::IllegalIdentifierException(url);
133 OUString newUrl;
135 SolarMutexGuard g;
136 newUrl = ImplImageTree::get().getImageUrl(decPath, auth, lang);
138 ucbhelper::Content content;
139 return
140 ucbhelper::Content::create(
141 newUrl, css::uno::Reference<css::ucb::XCommandEnvironment>(),
142 context, content)
143 ? content.get() : css::uno::Reference<css::ucb::XContent>();
146 sal_Int32 SAL_CALL compareContentIds(
147 css::uno::Reference<css::ucb::XContentIdentifier> const & Id1,
148 css::uno::Reference<css::ucb::XContentIdentifier> const & Id2)
149 throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
151 return Id1->getContentIdentifier().compareTo(
152 Id2->getContentIdentifier());
155 void SAL_CALL disposing() SAL_OVERRIDE {
156 context_.clear();
159 css::uno::Reference<css::uno::XComponentContext> context_;
164 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
165 com_sun_star_comp_ucb_ImageContentProvider_get_implementation(
166 css::uno::XComponentContext * context,
167 css::uno::Sequence<css::uno::Any> const &)
169 return cppu::acquire(new Provider(context));
172 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */