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 <boost/unordered_map.hpp>
28 #include <osl/diagnose.h>
29 #include <comphelper/processfactory.hxx>
30 #include <cppuhelper/weak.hxx>
31 #include <ucbhelper/contentidentifier.hxx>
32 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
33 #include "pkgprovider.hxx"
34 #include "pkgcontent.hxx"
37 using namespace com::sun::star
;
42 //=========================================================================
46 //=========================================================================
48 class Package
: public cppu::OWeakObject
,
49 public container::XHierarchicalNameAccess
51 friend class ContentProvider
;
54 uno::Reference
< container::XHierarchicalNameAccess
> m_xNA
;
55 ContentProvider
* m_pOwner
;
58 Package( const OUString
& rName
,
59 const uno::Reference
< container::XHierarchicalNameAccess
> & xNA
,
60 ContentProvider
* pOwner
)
61 : m_aName( rName
), m_xNA( xNA
), m_pOwner( pOwner
) {}
62 virtual ~Package() { m_pOwner
->removePackage( m_aName
); }
65 virtual uno::Any SAL_CALL
66 queryInterface( const uno::Type
& aType
)
67 throw( uno::RuntimeException
)
68 { return m_xNA
->queryInterface( aType
); }
71 { OWeakObject::acquire(); }
74 { OWeakObject::release(); }
76 // XHierarchicalNameAccess
77 virtual uno::Any SAL_CALL
78 getByHierarchicalName( const OUString
& aName
)
79 throw( container::NoSuchElementException
, uno::RuntimeException
)
80 { return m_xNA
->getByHierarchicalName( aName
); }
81 virtual sal_Bool SAL_CALL
82 hasByHierarchicalName( const OUString
& aName
)
83 throw( uno::RuntimeException
)
84 { return m_xNA
->hasByHierarchicalName( aName
); }
87 //=========================================================================
91 //=========================================================================
96 const OUString
& rKey1
, const OUString
& rKey2
) const
98 return !!( rKey1
== rKey2
);
104 size_t operator()( const OUString
& rName
) const
106 return rName
.hashCode();
110 typedef boost::unordered_map
119 class Packages
: public PackageMap
{};
123 using namespace package_ucp
;
125 //=========================================================================
126 //=========================================================================
128 // ContentProvider Implementation.
130 //=========================================================================
131 //=========================================================================
133 ContentProvider::ContentProvider(
134 const uno::Reference
< uno::XComponentContext
>& rxContext
)
135 : ::ucbhelper::ContentProviderImplHelper( rxContext
),
140 //=========================================================================
142 ContentProvider::~ContentProvider()
147 //=========================================================================
149 // XInterface methods.
151 //=========================================================================
153 XINTERFACE_IMPL_3( ContentProvider
,
156 ucb::XContentProvider
);
158 //=========================================================================
160 // XTypeProvider methods.
162 //=========================================================================
164 XTYPEPROVIDER_IMPL_3( ContentProvider
,
167 ucb::XContentProvider
);
169 //=========================================================================
171 // XServiceInfo methods.
173 //=========================================================================
175 XSERVICEINFO_IMPL_1_CTX( ContentProvider
,
176 OUString( "com.sun.star.comp.ucb.PackageContentProvider" ),
177 OUString( PACKAGE_CONTENT_PROVIDER_SERVICE_NAME
) );
179 //=========================================================================
181 // Service factory implementation.
183 //=========================================================================
185 ONE_INSTANCE_SERVICE_FACTORY_IMPL( ContentProvider
);
187 //=========================================================================
189 // XContentProvider methods.
191 //=========================================================================
194 uno::Reference
< ucb::XContent
> SAL_CALL
ContentProvider::queryContent(
195 const uno::Reference
< ucb::XContentIdentifier
>& Identifier
)
196 throw( ucb::IllegalIdentifierException
, uno::RuntimeException
)
198 if ( !Identifier
.is() )
199 return uno::Reference
< ucb::XContent
>();
201 PackageUri
aUri( Identifier
->getContentIdentifier() );
202 if ( !aUri
.isValid() )
203 throw ucb::IllegalIdentifierException();
205 // Create a new identifier for the mormalized URL returned by
206 // PackageUri::getUri().
207 uno::Reference
< ucb::XContentIdentifier
> xId
= new ::ucbhelper::ContentIdentifier( aUri
.getUri() );
209 osl::MutexGuard
aGuard( m_aMutex
);
211 // Check, if a content with given id already exists...
212 uno::Reference
< ucb::XContent
> xContent
213 = queryExistingContent( xId
).get();
217 // Create a new content.
219 xContent
= Content::create( m_xContext
, this, Identifier
); // not xId!!!
220 registerNewContent( xContent
);
222 if ( xContent
.is() && !xContent
->getIdentifier().is() )
223 throw ucb::IllegalIdentifierException();
228 //=========================================================================
232 //=========================================================================
234 uno::Reference
< container::XHierarchicalNameAccess
>
235 ContentProvider::createPackage( const OUString
& rName
, const OUString
& rParam
)
237 osl::MutexGuard
aGuard( m_aMutex
);
239 if ( rName
.isEmpty() )
241 OSL_FAIL( "ContentProvider::createPackage - Invalid URL!" );
242 return uno::Reference
< container::XHierarchicalNameAccess
>();
245 OUString rURL
= rName
+ rParam
;
249 Packages::const_iterator it
= m_pPackages
->find( rURL
);
250 if ( it
!= m_pPackages
->end() )
252 // Already instanciated. Return package.
253 return (*it
).second
->m_xNA
;
257 m_pPackages
= new Packages
;
259 // Create new package...
262 uno::Sequence
< uno::Any
> aArguments( 1 );
263 aArguments
[ 0 ] <<= rURL
;
265 uno::Reference
< uno::XInterface
> xIfc
266 = m_xContext
->getServiceManager()->createInstanceWithArgumentsAndContext("com.sun.star.packages.comp.ZipPackage",
267 aArguments
, m_xContext
);
272 container::XHierarchicalNameAccess
> xNameAccess(
273 xIfc
, uno::UNO_QUERY
);
275 OSL_ENSURE( xNameAccess
.is(),
276 "ContentProvider::createPackage - "
277 "Got no hierarchical name access!" );
279 rtl::Reference
< Package
> xPackage
280 = new Package( rURL
, xNameAccess
, this );
282 (*m_pPackages
)[ rURL
] = xPackage
.get();
284 return xPackage
.get();
287 catch ( uno::RuntimeException
const & )
289 // createInstanceWithArguemts
291 catch ( uno::Exception
const & )
293 // createInstanceWithArguemts
296 return uno::Reference
< container::XHierarchicalNameAccess
>();
299 //=========================================================================
300 sal_Bool
ContentProvider::removePackage( const OUString
& rName
)
302 osl::MutexGuard
aGuard( m_aMutex
);
306 Packages::iterator it
= m_pPackages
->find( rName
);
307 if ( it
!= m_pPackages
->end() )
309 m_pPackages
->erase( it
);
316 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */