Bump version to 24.04.3.4
[LibreOffice.git] / ucb / source / ucp / package / pkgprovider.cxx
blob636ecb3333e3b71d07f18a951f30edf88496d338
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/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 /**************************************************************************
22 TODO
23 **************************************************************************
25 *************************************************************************/
27 #include <cppuhelper/exc_hlp.hxx>
28 #include <cppuhelper/weak.hxx>
29 #include <cppuhelper/queryinterface.hxx>
30 #include <ucbhelper/contentidentifier.hxx>
31 #include <ucbhelper/macros.hxx>
32 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
33 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
34 #include <com/sun/star/ucb/IllegalIdentifierException.hpp>
35 #include <com/sun/star/uno/XComponentContext.hpp>
36 #include "pkgprovider.hxx"
37 #include "pkgcontent.hxx"
38 #include "pkguri.hxx"
39 #include <unordered_map>
40 #include <utility>
42 using namespace com::sun::star;
44 namespace package_ucp
49 namespace {
51 class Package : public cppu::OWeakObject,
52 public container::XHierarchicalNameAccess
54 friend ContentProvider;
56 OUString m_aName;
57 uno::Reference< container::XHierarchicalNameAccess > m_xNA;
58 ContentProvider* m_pOwner;
60 public:
61 Package( OUString aName,
62 uno::Reference< container::XHierarchicalNameAccess > xNA,
63 ContentProvider* pOwner )
64 : m_aName(std::move( aName )), m_xNA(std::move( xNA )), m_pOwner( pOwner ) {}
65 virtual ~Package() override { m_pOwner->removePackage( m_aName ); }
67 // XInterface
68 virtual uno::Any SAL_CALL
69 queryInterface( const uno::Type& aType ) override
70 { return m_xNA->queryInterface( aType ); }
71 virtual void SAL_CALL
72 acquire() noexcept override
73 { OWeakObject::acquire(); }
74 virtual void SAL_CALL
75 release() noexcept override
76 { OWeakObject::release(); }
78 // XHierarchicalNameAccess
79 virtual uno::Any SAL_CALL
80 getByHierarchicalName( const OUString& aName ) override
81 { return m_xNA->getByHierarchicalName( aName ); }
82 virtual sal_Bool SAL_CALL
83 hasByHierarchicalName( const OUString& aName ) override
84 { return m_xNA->hasByHierarchicalName( aName ); }
89 class Packages : public std::unordered_map<OUString, Package*> {};
93 using namespace package_ucp;
96 // ContentProvider Implementation.
97 ContentProvider::ContentProvider(
98 const uno::Reference< uno::XComponentContext >& rxContext )
99 : ::ucbhelper::ContentProviderImplHelper( rxContext )
104 // virtual
105 ContentProvider::~ContentProvider()
109 // XInterface methods.
110 void SAL_CALL ContentProvider::acquire()
111 noexcept
113 OWeakObject::acquire();
116 void SAL_CALL ContentProvider::release()
117 noexcept
119 OWeakObject::release();
122 css::uno::Any SAL_CALL ContentProvider::queryInterface( const css::uno::Type & rType )
124 css::uno::Any aRet = cppu::queryInterface( rType,
125 static_cast< lang::XTypeProvider* >(this),
126 static_cast< lang::XServiceInfo* >(this),
127 static_cast< ucb::XContentProvider* >(this)
129 return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
132 // XTypeProvider methods.
135 XTYPEPROVIDER_IMPL_3( ContentProvider,
136 lang::XTypeProvider,
137 lang::XServiceInfo,
138 ucb::XContentProvider );
141 // XServiceInfo methods.
143 OUString
144 ContentProvider::getImplementationName()
146 return "com.sun.star.comp.ucb.PackageContentProvider";
149 sal_Bool
150 ContentProvider::supportsService(const OUString& s)
152 return cppu::supportsService(this, s);
155 css::uno::Sequence< OUString >
156 ContentProvider::getSupportedServiceNames()
158 return { "com.sun.star.ucb.PackageContentProvider" };
162 // XContentProvider methods.
165 // virtual
166 uno::Reference< ucb::XContent > SAL_CALL ContentProvider::queryContent(
167 const uno::Reference< ucb::XContentIdentifier >& Identifier )
169 if ( !Identifier.is() )
170 return uno::Reference< ucb::XContent >();
172 PackageUri aUri( Identifier->getContentIdentifier() );
173 if ( !aUri.isValid() )
174 throw ucb::IllegalIdentifierException();
176 // Create a new identifier for the normalized URL returned by
177 // PackageUri::getUri().
178 uno::Reference< ucb::XContentIdentifier > xId = new ::ucbhelper::ContentIdentifier( aUri.getUri() );
180 osl::MutexGuard aGuard( m_aMutex );
182 // Check, if a content with given id already exists...
183 uno::Reference< ucb::XContent > xContent
184 = queryExistingContent( xId );
185 if ( xContent.is() )
186 return xContent;
188 // Create a new content.
190 xContent = Content::create( m_xContext, this, Identifier ); // not xId!!!
191 registerNewContent( xContent );
193 if ( xContent.is() && !xContent->getIdentifier().is() )
194 throw ucb::IllegalIdentifierException();
196 return xContent;
200 // Other methods.
203 uno::Reference< container::XHierarchicalNameAccess >
204 ContentProvider::createPackage( const PackageUri & rURI )
206 osl::MutexGuard aGuard( m_aMutex );
208 OUString rURL = rURI.getPackage() + rURI.getParam();
210 if ( m_pPackages )
212 Packages::const_iterator it = m_pPackages->find( rURL );
213 if ( it != m_pPackages->end() )
215 // Already instantiated. Return package.
216 return (*it).second->m_xNA;
219 else
220 m_pPackages.reset( new Packages );
222 // Create new package...
223 uno::Sequence< uno::Any > aArguments{ uno::Any(rURL) };
224 uno::Reference< container::XHierarchicalNameAccess > xNameAccess;
227 xNameAccess.set(
228 m_xContext->getServiceManager()->createInstanceWithArgumentsAndContext(
229 "com.sun.star.packages.comp.ZipPackage",
230 aArguments, m_xContext ),
231 css::uno::UNO_QUERY_THROW );
233 catch ( uno::RuntimeException const & )
235 throw;
237 catch ( uno::Exception const & e )
239 css::uno::Any anyEx = cppu::getCaughtException();
240 throw css::lang::WrappedTargetRuntimeException(
241 e.Message, e.Context, anyEx);
244 rtl::Reference< Package> xPackage = new Package( rURL, xNameAccess, this );
245 (*m_pPackages)[ rURL ] = xPackage.get();
246 return xPackage;
250 void ContentProvider::removePackage( const OUString & rName )
252 osl::MutexGuard aGuard( m_aMutex );
254 if ( m_pPackages )
256 Packages::iterator it = m_pPackages->find( rName );
257 if ( it != m_pPackages->end() )
259 m_pPackages->erase( it );
260 return;
265 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
266 ucb_package_ContentProvider_get_implementation(
267 css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&)
269 return cppu::acquire(new ContentProvider(context));
272 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */