LibreOffice Module ucb (master)  1
pkgprovider.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 
21 /**************************************************************************
22  TODO
23  **************************************************************************
24 
25  *************************************************************************/
26 
27 #include <cppuhelper/exc_hlp.hxx>
28 #include <cppuhelper/weak.hxx>
32 #include <ucbhelper/macros.hxx>
33 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
34 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
35 #include <com/sun/star/ucb/IllegalIdentifierException.hpp>
36 #include <com/sun/star/uno/XComponentContext.hpp>
37 #include "pkgprovider.hxx"
38 #include "pkgcontent.hxx"
39 #include "pkguri.hxx"
40 #include <unordered_map>
41 
42 using namespace com::sun::star;
43 
44 namespace package_ucp
45 {
46 
47 
48 // class Package.
49 
50 
51 class Package : public cppu::OWeakObject,
52  public container::XHierarchicalNameAccess
53 {
54  friend class ContentProvider;
55 
56  OUString const m_aName;
57  uno::Reference< container::XHierarchicalNameAccess > m_xNA;
59 
60 public:
61  Package( const OUString& rName,
62  const uno::Reference< container::XHierarchicalNameAccess > & xNA,
63  ContentProvider* pOwner )
64  : m_aName( rName ), m_xNA( xNA ), m_pOwner( pOwner ) {}
65  virtual ~Package() override { m_pOwner->removePackage( m_aName ); }
66 
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() throw() override
73  { OWeakObject::acquire(); }
74  virtual void SAL_CALL
75  release() throw() override
76  { OWeakObject::release(); }
77 
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 ); }
85 };
86 
87 
88 class Packages : public std::unordered_map<OUString, Package*> {};
89 
90 }
91 
92 using namespace package_ucp;
93 
94 
95 // ContentProvider Implementation.
96 ContentProvider::ContentProvider(
97  const uno::Reference< uno::XComponentContext >& rxContext )
98 : ::ucbhelper::ContentProviderImplHelper( rxContext )
99 {
100 }
101 
102 
103 // virtual
105 {
106 }
107 
108 // XInterface methods.
110  throw()
111 {
112  OWeakObject::acquire();
113 }
114 
116  throw()
117 {
118  OWeakObject::release();
119 }
120 
121 css::uno::Any SAL_CALL ContentProvider::queryInterface( const css::uno::Type & rType )
122 {
123  css::uno::Any aRet = cppu::queryInterface( rType,
124  static_cast< lang::XTypeProvider* >(this),
125  static_cast< lang::XServiceInfo* >(this),
126  static_cast< ucb::XContentProvider* >(this)
127  );
128  return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
129 }
130 
131 // XTypeProvider methods.
132 
133 
135  lang::XTypeProvider,
136  lang::XServiceInfo,
137  ucb::XContentProvider );
138 
139 
140 // XServiceInfo methods.
141 
143  "com.sun.star.comp.ucb.PackageContentProvider" )
145 static css::uno::Reference< css::uno::XInterface >
146 ContentProvider_CreateInstance( const css::uno::Reference< css::lang::XMultiServiceFactory> & rSMgr )
147 {
148  css::lang::XServiceInfo* pX = new ContentProvider( ucbhelper::getComponentContext(rSMgr) );
149  return css::uno::Reference< css::uno::XInterface >::query( pX );
150 }
151 
152 css::uno::Sequence< OUString >
154 {
155  css::uno::Sequence< OUString > aSNS { "com.sun.star.ucb.PackageContentProvider" };
156  return aSNS;
157 }
158 
159 // Service factory implementation.
160 
161 
163 
164 
165 // XContentProvider methods.
166 
167 
168 // virtual
169 uno::Reference< ucb::XContent > SAL_CALL ContentProvider::queryContent(
170  const uno::Reference< ucb::XContentIdentifier >& Identifier )
171 {
172  if ( !Identifier.is() )
173  return uno::Reference< ucb::XContent >();
174 
175  PackageUri aUri( Identifier->getContentIdentifier() );
176  if ( !aUri.isValid() )
177  throw ucb::IllegalIdentifierException();
178 
179  // Create a new identifier for the normalized URL returned by
180  // PackageUri::getUri().
181  uno::Reference< ucb::XContentIdentifier > xId = new ::ucbhelper::ContentIdentifier( aUri.getUri() );
182 
183  osl::MutexGuard aGuard( m_aMutex );
184 
185  // Check, if a content with given id already exists...
186  uno::Reference< ucb::XContent > xContent
187  = queryExistingContent( xId ).get();
188  if ( xContent.is() )
189  return xContent;
190 
191  // Create a new content.
192 
193  xContent = Content::create( m_xContext, this, Identifier ); // not xId!!!
194  registerNewContent( xContent );
195 
196  if ( xContent.is() && !xContent->getIdentifier().is() )
197  throw ucb::IllegalIdentifierException();
198 
199  return xContent;
200 }
201 
202 
203 // Other methods.
204 
205 
206 uno::Reference< container::XHierarchicalNameAccess >
208 {
209  osl::MutexGuard aGuard( m_aMutex );
210 
211  OUString rURL = rURI.getPackage() + rURI.getParam();
212 
213  if ( m_pPackages )
214  {
215  Packages::const_iterator it = m_pPackages->find( rURL );
216  if ( it != m_pPackages->end() )
217  {
218  // Already instantiated. Return package.
219  return (*it).second->m_xNA;
220  }
221  }
222  else
223  m_pPackages.reset( new Packages );
224 
225  // Create new package...
226  uno::Sequence< uno::Any > aArguments( 1 );
227  aArguments[ 0 ] <<= rURL;
228  uno::Reference< container::XHierarchicalNameAccess > xNameAccess;
229  try
230  {
231  xNameAccess.set(
232  m_xContext->getServiceManager()->createInstanceWithArgumentsAndContext(
233  "com.sun.star.packages.comp.ZipPackage",
234  aArguments, m_xContext ),
235  css::uno::UNO_QUERY_THROW );
236  }
237  catch ( uno::RuntimeException const & )
238  {
239  throw;
240  }
241  catch ( uno::Exception const & e )
242  {
243  css::uno::Any anyEx = cppu::getCaughtException();
244  throw css::lang::WrappedTargetRuntimeException(
245  e.Message, e.Context, anyEx);
246  }
247 
248  rtl::Reference< Package> xPackage = new Package( rURL, xNameAccess, this );
249  (*m_pPackages)[ rURL ] = xPackage.get();
250  return xPackage.get();
251 }
252 
253 
254 void ContentProvider::removePackage( const OUString & rName )
255 {
256  osl::MutexGuard aGuard( m_aMutex );
257 
258  if ( m_pPackages )
259  {
260  Packages::iterator it = m_pPackages->find( rName );
261  if ( it != m_pPackages->end() )
262  {
263  m_pPackages->erase( it );
264  return;
265  }
266  }
267 }
268 
269 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
XSERVICEINFO_COMMOM_IMPL(ContentProvider,"com.sun.star.comp.ucb.PackageContentProvider") static css
virtual uno::Any SAL_CALL queryInterface(const uno::Type &aType) override
Definition: pkgprovider.cxx:69
const OUString & getParam() const
Definition: pkguri.hxx:72
static css::uno::Sequence< OUString > getSupportedServiceNames_Static()
void removePackage(const OUString &rName)
OUString const m_aName
Definition: pkgprovider.cxx:56
ONE_INSTANCE_SERVICE_FACTORY_IMPL(ContentProvider)
std::unique_ptr< Packages > m_pPackages
Definition: pkgprovider.hxx:51
XTYPEPROVIDER_IMPL_3(ContentProvider, lang::XTypeProvider, lang::XServiceInfo, ucb::XContentProvider)
virtual void SAL_CALL release() override
Definition: pkgprovider.cxx:75
UCBHELPER_DLLPUBLIC css::uno::Reference< css::uno::XComponentContext > getComponentContext(css::uno::Reference< css::lang::XMultiServiceFactory > const &factory)
virtual uno::Any SAL_CALL getByHierarchicalName(const OUString &aName) override
Definition: pkgprovider.cxx:80
virtual void SAL_CALL release() override
virtual css::uno::Reference< css::ucb::XContent > SAL_CALL queryContent(const css::uno::Reference< css::ucb::XContentIdentifier > &Identifier) override
Any SAL_CALL getCaughtException()
virtual sal_Bool SAL_CALL hasByHierarchicalName(const OUString &aName) override
Definition: pkgprovider.cxx:83
const OUString & getPackage() const
Definition: pkguri.hxx:63
virtual void SAL_CALL acquire() override
static Content * create(const css::uno::Reference< css::uno::XComponentContext > &rxContext, ContentProvider *pProvider, const css::uno::Reference< css::ucb::XContentIdentifier > &Identifier)
unsigned char sal_Bool
rtl::Reference< ContentImplHelper > queryExistingContent(const css::uno::Reference< css::ucb::XContentIdentifier > &Identifier)
uno::Reference< container::XHierarchicalNameAccess > m_xNA
Definition: pkgprovider.cxx:57
css::uno::Reference< css::uno::XComponentContext > m_xContext
virtual ~ContentProvider() override
Package(const OUString &rName, const uno::Reference< container::XHierarchicalNameAccess > &xNA, ContentProvider *pOwner)
Definition: pkgprovider.cxx:61
void registerNewContent(const css::uno::Reference< css::ucb::XContent > &xContent)
virtual void SAL_CALL acquire() override
Definition: pkgprovider.cxx:72
virtual ~Package() override
Definition: pkgprovider.cxx:65
virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type &rType) override
ContentProvider * m_pOwner
Definition: pkgprovider.cxx:58
css::uno::Reference< css::container::XHierarchicalNameAccess > createPackage(const PackageUri &rParam)
css::uno::Any SAL_CALL queryInterface(const css::uno::Type &rType, Interface1 *p1)