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 
28 #include <cppuhelper/exc_hlp.hxx>
29 #include <cppuhelper/weak.hxx>
33 #include <ucbhelper/macros.hxx>
34 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
35 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
36 #include <com/sun/star/ucb/IllegalIdentifierException.hpp>
37 #include <com/sun/star/uno/XComponentContext.hpp>
38 #include "pkgprovider.hxx"
39 #include "pkgcontent.hxx"
40 #include "pkguri.hxx"
41 #include <unordered_map>
42 
43 using namespace com::sun::star;
44 
45 namespace package_ucp
46 {
47 
48 
49 // class Package.
50 
51 
52 class Package : public cppu::OWeakObject,
53  public container::XHierarchicalNameAccess
54 {
55  friend class ContentProvider;
56 
57  OUString const m_aName;
58  uno::Reference< container::XHierarchicalNameAccess > m_xNA;
60 
61 public:
62  Package( const OUString& rName,
63  const uno::Reference< container::XHierarchicalNameAccess > & xNA,
64  ContentProvider* pOwner )
65  : m_aName( rName ), m_xNA( xNA ), m_pOwner( pOwner ) {}
66  virtual ~Package() override { m_pOwner->removePackage( m_aName ); }
67 
68  // XInterface
69  virtual uno::Any SAL_CALL
70  queryInterface( const uno::Type& aType ) override
71  { return m_xNA->queryInterface( aType ); }
72  virtual void SAL_CALL
73  acquire() throw() override
74  { OWeakObject::acquire(); }
75  virtual void SAL_CALL
76  release() throw() override
77  { OWeakObject::release(); }
78 
79  // XHierarchicalNameAccess
80  virtual uno::Any SAL_CALL
81  getByHierarchicalName( const OUString& aName ) override
82  { return m_xNA->getByHierarchicalName( aName ); }
83  virtual sal_Bool SAL_CALL
84  hasByHierarchicalName( const OUString& aName ) override
85  { return m_xNA->hasByHierarchicalName( aName ); }
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.
97 ContentProvider::ContentProvider(
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  OUString( "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 =
150  static_cast<css::lang::XServiceInfo*>(new ContentProvider( ucbhelper::getComponentContext(rSMgr) ));
151  return css::uno::Reference< css::uno::XInterface >::query( pX );
152 }
153 
154 css::uno::Sequence< OUString >
156 {
157  css::uno::Sequence< OUString > aSNS { "com.sun.star.ucb.PackageContentProvider" };
158  return aSNS;
159 }
160 
161 // Service factory implementation.
162 
163 
165 
166 
167 // XContentProvider methods.
168 
169 
170 // virtual
171 uno::Reference< ucb::XContent > SAL_CALL ContentProvider::queryContent(
172  const uno::Reference< ucb::XContentIdentifier >& Identifier )
173 {
174  if ( !Identifier.is() )
175  return uno::Reference< ucb::XContent >();
176 
177  PackageUri aUri( Identifier->getContentIdentifier() );
178  if ( !aUri.isValid() )
179  throw ucb::IllegalIdentifierException();
180 
181  // Create a new identifier for the mormalized URL returned by
182  // PackageUri::getUri().
183  uno::Reference< ucb::XContentIdentifier > xId = new ::ucbhelper::ContentIdentifier( aUri.getUri() );
184 
185  osl::MutexGuard aGuard( m_aMutex );
186 
187  // Check, if a content with given id already exists...
188  uno::Reference< ucb::XContent > xContent
189  = queryExistingContent( xId ).get();
190  if ( xContent.is() )
191  return xContent;
192 
193  // Create a new content.
194 
195  xContent = Content::create( m_xContext, this, Identifier ); // not xId!!!
196  registerNewContent( xContent );
197 
198  if ( xContent.is() && !xContent->getIdentifier().is() )
199  throw ucb::IllegalIdentifierException();
200 
201  return xContent;
202 }
203 
204 
205 // Other methods.
206 
207 
208 uno::Reference< container::XHierarchicalNameAccess >
210 {
211  osl::MutexGuard aGuard( m_aMutex );
212 
213  OUString rURL = rURI.getPackage() + rURI.getParam();
214 
215  if ( m_pPackages )
216  {
217  Packages::const_iterator it = m_pPackages->find( rURL );
218  if ( it != m_pPackages->end() )
219  {
220  // Already instantiated. Return package.
221  return (*it).second->m_xNA;
222  }
223  }
224  else
225  m_pPackages.reset( new Packages );
226 
227  // Create new package...
228  uno::Sequence< uno::Any > aArguments( 1 );
229  aArguments[ 0 ] <<= rURL;
230  uno::Reference< container::XHierarchicalNameAccess > xNameAccess;
231  try
232  {
233  xNameAccess.set(
234  m_xContext->getServiceManager()->createInstanceWithArgumentsAndContext(
235  "com.sun.star.packages.comp.ZipPackage",
236  aArguments, m_xContext ),
237  css::uno::UNO_QUERY_THROW );
238  }
239  catch ( uno::RuntimeException const & )
240  {
241  throw;
242  }
243  catch ( uno::Exception const & e )
244  {
245  css::uno::Any anyEx = cppu::getCaughtException();
246  throw css::lang::WrappedTargetRuntimeException(
247  e.Message, e.Context, anyEx);
248  }
249 
250  rtl::Reference< Package> xPackage = new Package( rURL, xNameAccess, this );
251  (*m_pPackages)[ rURL ] = xPackage.get();
252  return xPackage.get();
253 }
254 
255 
256 void ContentProvider::removePackage( const OUString & rName )
257 {
258  osl::MutexGuard aGuard( m_aMutex );
259 
260  if ( m_pPackages )
261  {
262  Packages::iterator it = m_pPackages->find( rName );
263  if ( it != m_pPackages->end() )
264  {
265  m_pPackages->erase( it );
266  return;
267  }
268  }
269 }
270 
271 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual uno::Any SAL_CALL queryInterface(const uno::Type &aType) override
Definition: pkgprovider.cxx:70
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:57
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:76
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:81
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:84
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:58
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:62
void registerNewContent(const css::uno::Reference< css::ucb::XContent > &xContent)
virtual void SAL_CALL acquire() override
Definition: pkgprovider.cxx:73
virtual ~Package() override
Definition: pkgprovider.cxx:66
virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type &rType) override
ContentProvider * m_pOwner
Definition: pkgprovider.cxx:59
css::uno::Reference< css::container::XHierarchicalNameAccess > createPackage(const PackageUri &rParam)
XSERVICEINFO_COMMOM_IMPL(ContentProvider, OUString("com.sun.star.comp.ucb.PackageContentProvider")) static css
css::uno::Any SAL_CALL queryInterface(const css::uno::Type &rType, Interface1 *p1)