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 
49 namespace {
50 
51 class Package : public cppu::OWeakObject,
52  public container::XHierarchicalNameAccess
53 {
55 
56  OUString 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 
89 class Packages : public std::unordered_map<OUString, Package*> {};
90 
91 }
92 
93 using namespace package_ucp;
94 
95 
96 // ContentProvider Implementation.
98  const uno::Reference< uno::XComponentContext >& rxContext )
99 : ::ucbhelper::ContentProviderImplHelper( rxContext )
100 {
101 }
102 
103 
104 // virtual
106 {
107 }
108 
109 // XInterface methods.
111  throw()
112 {
113  OWeakObject::acquire();
114 }
115 
117  throw()
118 {
119  OWeakObject::release();
120 }
121 
122 css::uno::Any SAL_CALL ContentProvider::queryInterface( const css::uno::Type & rType )
123 {
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)
128  );
129  return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
130 }
131 
132 // XTypeProvider methods.
133 
134 
136  lang::XTypeProvider,
137  lang::XServiceInfo,
138  ucb::XContentProvider );
139 
140 
141 // XServiceInfo methods.
142 
144  "com.sun.star.comp.ucb.PackageContentProvider" )
146 static css::uno::Reference< css::uno::XInterface >
147 ContentProvider_CreateInstance( const css::uno::Reference< css::lang::XMultiServiceFactory> & rSMgr )
148 {
149  css::lang::XServiceInfo* pX = new ContentProvider( ucbhelper::getComponentContext(rSMgr) );
150  return css::uno::Reference< css::uno::XInterface >::query( pX );
151 }
152 
153 css::uno::Sequence< OUString >
155 {
156  css::uno::Sequence< OUString > aSNS { "com.sun.star.ucb.PackageContentProvider" };
157  return aSNS;
158 }
159 
160 // Service factory implementation.
161 
162 
164 
165 
166 // XContentProvider methods.
167 
168 
169 // virtual
170 uno::Reference< ucb::XContent > SAL_CALL ContentProvider::queryContent(
171  const uno::Reference< ucb::XContentIdentifier >& Identifier )
172 {
173  if ( !Identifier.is() )
174  return uno::Reference< ucb::XContent >();
175 
176  PackageUri aUri( Identifier->getContentIdentifier() );
177  if ( !aUri.isValid() )
178  throw ucb::IllegalIdentifierException();
179 
180  // Create a new identifier for the normalized URL returned by
181  // PackageUri::getUri().
182  uno::Reference< ucb::XContentIdentifier > xId = new ::ucbhelper::ContentIdentifier( aUri.getUri() );
183 
184  osl::MutexGuard aGuard( m_aMutex );
185 
186  // Check, if a content with given id already exists...
187  uno::Reference< ucb::XContent > xContent
188  = queryExistingContent( xId ).get();
189  if ( xContent.is() )
190  return xContent;
191 
192  // Create a new content.
193 
194  xContent = Content::create( m_xContext, this, Identifier ); // not xId!!!
195  registerNewContent( xContent );
196 
197  if ( xContent.is() && !xContent->getIdentifier().is() )
198  throw ucb::IllegalIdentifierException();
199 
200  return xContent;
201 }
202 
203 
204 // Other methods.
205 
206 
207 uno::Reference< container::XHierarchicalNameAccess >
209 {
210  osl::MutexGuard aGuard( m_aMutex );
211 
212  OUString rURL = rURI.getPackage() + rURI.getParam();
213 
214  if ( m_pPackages )
215  {
216  Packages::const_iterator it = m_pPackages->find( rURL );
217  if ( it != m_pPackages->end() )
218  {
219  // Already instantiated. Return package.
220  return (*it).second->m_xNA;
221  }
222  }
223  else
224  m_pPackages.reset( new Packages );
225 
226  // Create new package...
227  uno::Sequence< uno::Any > aArguments( 1 );
228  aArguments[ 0 ] <<= rURL;
229  uno::Reference< container::XHierarchicalNameAccess > xNameAccess;
230  try
231  {
232  xNameAccess.set(
233  m_xContext->getServiceManager()->createInstanceWithArgumentsAndContext(
234  "com.sun.star.packages.comp.ZipPackage",
235  aArguments, m_xContext ),
236  css::uno::UNO_QUERY_THROW );
237  }
238  catch ( uno::RuntimeException const & )
239  {
240  throw;
241  }
242  catch ( uno::Exception const & e )
243  {
244  css::uno::Any anyEx = cppu::getCaughtException();
245  throw css::lang::WrappedTargetRuntimeException(
246  e.Message, e.Context, anyEx);
247  }
248 
249  rtl::Reference< Package> xPackage = new Package( rURL, xNameAccess, this );
250  (*m_pPackages)[ rURL ] = xPackage.get();
251  return xPackage.get();
252 }
253 
254 
255 void ContentProvider::removePackage( const OUString & rName )
256 {
257  osl::MutexGuard aGuard( m_aMutex );
258 
259  if ( m_pPackages )
260  {
261  Packages::iterator it = m_pPackages->find( rName );
262  if ( it != m_pPackages->end() )
263  {
264  m_pPackages->erase( it );
265  return;
266  }
267  }
268 }
269 
270 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
XSERVICEINFO_COMMOM_IMPL(ContentProvider,"com.sun.star.comp.ucb.PackageContentProvider") static css
const OUString & getParam() const
Definition: pkguri.hxx:72
static css::uno::Sequence< OUString > getSupportedServiceNames_Static()
OUString m_aName
Definition: pkgprovider.cxx:56
void removePackage(const OUString &rName)
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)
UCBHELPER_DLLPUBLIC css::uno::Reference< css::uno::XComponentContext > getComponentContext(css::uno::Reference< css::lang::XMultiServiceFactory > const &factory)
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
uno::Reference< container::XHierarchicalNameAccess > m_xNA
Definition: pkgprovider.cxx:57
Sequence< PropertyValue > aArguments
Any SAL_CALL getCaughtException()
const OUString & getPackage() const
Definition: pkguri.hxx:63
virtual void SAL_CALL acquire() override
ContentProvider * m_pOwner
Definition: pkgprovider.cxx:58
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)
css::uno::Reference< css::uno::XComponentContext > m_xContext
virtual ~ContentProvider() override
void registerNewContent(const css::uno::Reference< css::ucb::XContent > &xContent)
friend ContentProvider
Definition: pkgprovider.cxx:54
Reference< XContentIdentifier > xId
virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type &rType) override
uno::Reference< ucb::XContent > xContent
css::uno::Reference< css::container::XHierarchicalNameAccess > createPackage(const PackageUri &rParam)
css::uno::Any SAL_CALL queryInterface(const css::uno::Type &rType, Interface1 *p1)