1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 /**************************************************************************
23 **************************************************************************
25 *************************************************************************/
27 #include <osl/diagnose.h>
28 #include <comphelper/processfactory.hxx>
29 #include <cppuhelper/weak.hxx>
30 #include <ucbhelper/contentidentifier.hxx>
31 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
32 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
33 #include "pkgprovider.hxx"
34 #include "pkgcontent.hxx"
36 #include <unordered_map>
38 using namespace com::sun::star
;
49 class Package
: public cppu::OWeakObject
,
50 public container::XHierarchicalNameAccess
52 friend class ContentProvider
;
55 uno::Reference
< container::XHierarchicalNameAccess
> m_xNA
;
56 ContentProvider
* m_pOwner
;
59 Package( const OUString
& rName
,
60 const uno::Reference
< container::XHierarchicalNameAccess
> & xNA
,
61 ContentProvider
* pOwner
)
62 : m_aName( rName
), m_xNA( xNA
), m_pOwner( pOwner
) {}
63 virtual ~Package() { m_pOwner
->removePackage( m_aName
); }
66 virtual uno::Any SAL_CALL
67 queryInterface( const uno::Type
& aType
)
68 throw( uno::RuntimeException
, std::exception
) SAL_OVERRIDE
69 { return m_xNA
->queryInterface( aType
); }
71 acquire() throw() SAL_OVERRIDE
72 { OWeakObject::acquire(); }
74 release() throw() SAL_OVERRIDE
75 { OWeakObject::release(); }
77 // XHierarchicalNameAccess
78 virtual uno::Any SAL_CALL
79 getByHierarchicalName( const OUString
& aName
)
80 throw( container::NoSuchElementException
, uno::RuntimeException
, std::exception
) SAL_OVERRIDE
81 { return m_xNA
->getByHierarchicalName( aName
); }
82 virtual sal_Bool SAL_CALL
83 hasByHierarchicalName( const OUString
& aName
)
84 throw( uno::RuntimeException
, std::exception
) SAL_OVERRIDE
85 { return m_xNA
->hasByHierarchicalName( aName
); }
90 typedef std::unordered_map
98 class Packages
: public PackageMap
{};
102 using namespace package_ucp
;
105 // ContentProvider Implementation.
106 ContentProvider::ContentProvider(
107 const uno::Reference
< uno::XComponentContext
>& rxContext
)
108 : ::ucbhelper::ContentProviderImplHelper( rxContext
),
115 ContentProvider::~ContentProvider()
120 // XInterface methods.
121 void SAL_CALL
ContentProvider::acquire()
124 OWeakObject::acquire();
127 void SAL_CALL
ContentProvider::release()
130 OWeakObject::release();
133 css::uno::Any SAL_CALL
ContentProvider::queryInterface( const css::uno::Type
& rType
)
134 throw( css::uno::RuntimeException
, std::exception
)
136 css::uno::Any aRet
= cppu::queryInterface( rType
,
137 (static_cast< lang::XTypeProvider
* >(this)),
138 (static_cast< lang::XServiceInfo
* >(this)),
139 (static_cast< ucb::XContentProvider
* >(this))
141 return aRet
.hasValue() ? aRet
: OWeakObject::queryInterface( rType
);
144 // XTypeProvider methods.
148 XTYPEPROVIDER_IMPL_3( ContentProvider
,
151 ucb::XContentProvider
);
155 // XServiceInfo methods.
159 XSERVICEINFO_IMPL_1_CTX( ContentProvider
,
160 OUString( "com.sun.star.comp.ucb.PackageContentProvider" ),
161 PACKAGE_CONTENT_PROVIDER_SERVICE_NAME
);
165 // Service factory implementation.
169 ONE_INSTANCE_SERVICE_FACTORY_IMPL( ContentProvider
);
173 // XContentProvider methods.
178 uno::Reference
< ucb::XContent
> SAL_CALL
ContentProvider::queryContent(
179 const uno::Reference
< ucb::XContentIdentifier
>& Identifier
)
180 throw( ucb::IllegalIdentifierException
, uno::RuntimeException
, std::exception
)
182 if ( !Identifier
.is() )
183 return uno::Reference
< ucb::XContent
>();
185 PackageUri
aUri( Identifier
->getContentIdentifier() );
186 if ( !aUri
.isValid() )
187 throw ucb::IllegalIdentifierException();
189 // Create a new identifier for the mormalized URL returned by
190 // PackageUri::getUri().
191 uno::Reference
< ucb::XContentIdentifier
> xId
= new ::ucbhelper::ContentIdentifier( aUri
.getUri() );
193 osl::MutexGuard
aGuard( m_aMutex
);
195 // Check, if a content with given id already exists...
196 uno::Reference
< ucb::XContent
> xContent
197 = queryExistingContent( xId
).get();
201 // Create a new content.
203 xContent
= Content::create( m_xContext
, this, Identifier
); // not xId!!!
204 registerNewContent( xContent
);
206 if ( xContent
.is() && !xContent
->getIdentifier().is() )
207 throw ucb::IllegalIdentifierException();
218 uno::Reference
< container::XHierarchicalNameAccess
>
219 ContentProvider::createPackage( const PackageUri
& rURI
)
221 osl::MutexGuard
aGuard( m_aMutex
);
223 OUString rURL
= rURI
.getPackage() + rURI
.getParam();
227 Packages::const_iterator it
= m_pPackages
->find( rURL
);
228 if ( it
!= m_pPackages
->end() )
230 // Already instantiated. Return package.
231 return (*it
).second
->m_xNA
;
235 m_pPackages
= new Packages
;
237 // Create new package...
238 uno::Sequence
< uno::Any
> aArguments( 1 );
239 aArguments
[ 0 ] <<= rURL
;
240 uno::Reference
< container::XHierarchicalNameAccess
> xNameAccess
;
243 xNameAccess
= uno::Reference
< container::XHierarchicalNameAccess
>(
244 m_xContext
->getServiceManager()->createInstanceWithArgumentsAndContext(
245 "com.sun.star.packages.comp.ZipPackage",
246 aArguments
, m_xContext
),
247 css::uno::UNO_QUERY_THROW
);
249 catch ( uno::RuntimeException
const & )
253 catch ( uno::Exception
const & e
)
255 throw css::lang::WrappedTargetRuntimeException(
256 e
.Message
, e
.Context
, css::uno::makeAny(e
));
259 rtl::Reference
< Package
> xPackage
= new Package( rURL
, xNameAccess
, this );
260 (*m_pPackages
)[ rURL
] = xPackage
.get();
261 return xPackage
.get();
265 bool ContentProvider::removePackage( const OUString
& rName
)
267 osl::MutexGuard
aGuard( m_aMutex
);
271 Packages::iterator it
= m_pPackages
->find( rName
);
272 if ( it
!= m_pPackages
->end() )
274 m_pPackages
->erase( it
);
281 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */