Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : /**************************************************************************
31 : : TODO
32 : : **************************************************************************
33 : :
34 : : *************************************************************************/
35 : :
36 : : #include <boost/unordered_map.hpp>
37 : : #include <osl/diagnose.h>
38 : : #include <cppuhelper/weak.hxx>
39 : : #include <ucbhelper/contentidentifier.hxx>
40 : : #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
41 : : #include "pkgprovider.hxx"
42 : : #include "pkgcontent.hxx"
43 : : #include "pkguri.hxx"
44 : :
45 : : using namespace com::sun::star;
46 : :
47 : : namespace package_ucp
48 : : {
49 : :
50 : : //=========================================================================
51 : : //
52 : : // class Package.
53 : : //
54 : : //=========================================================================
55 : :
56 : : class Package : public cppu::OWeakObject,
57 : : public container::XHierarchicalNameAccess
58 : : {
59 : : friend class ContentProvider;
60 : :
61 : : rtl::OUString m_aName;
62 : : uno::Reference< container::XHierarchicalNameAccess > m_xNA;
63 : : ContentProvider* m_pOwner;
64 : :
65 : : public:
66 : 105 : Package( const rtl::OUString& rName,
67 : : const uno::Reference< container::XHierarchicalNameAccess > & xNA,
68 : : ContentProvider* pOwner )
69 : 105 : : m_aName( rName ), m_xNA( xNA ), m_pOwner( pOwner ) {}
70 [ + - ][ - + ]: 210 : virtual ~Package() { m_pOwner->removePackage( m_aName ); }
71 : :
72 : : // XInterface
73 : : virtual uno::Any SAL_CALL
74 : 165 : queryInterface( const uno::Type& aType )
75 : : throw( uno::RuntimeException )
76 : 165 : { return m_xNA->queryInterface( aType ); }
77 : : virtual void SAL_CALL
78 : 523 : acquire() throw()
79 : 523 : { OWeakObject::acquire(); }
80 : : virtual void SAL_CALL
81 : 523 : release() throw()
82 : 523 : { OWeakObject::release(); }
83 : :
84 : : // XHierarchicalNameAccess
85 : : virtual uno::Any SAL_CALL
86 : 146 : getByHierarchicalName( const rtl::OUString& aName )
87 : : throw( container::NoSuchElementException, uno::RuntimeException )
88 : 146 : { return m_xNA->getByHierarchicalName( aName ); }
89 : : virtual sal_Bool SAL_CALL
90 : 146 : hasByHierarchicalName( const rtl::OUString& aName )
91 : : throw( uno::RuntimeException )
92 : 146 : { return m_xNA->hasByHierarchicalName( aName ); }
93 : : };
94 : :
95 : : //=========================================================================
96 : : //
97 : : // Packages.
98 : : //
99 : : //=========================================================================
100 : :
101 : : struct equalString
102 : : {
103 : 377 : bool operator()(
104 : : const rtl::OUString& rKey1, const rtl::OUString& rKey2 ) const
105 : : {
106 : 377 : return !!( rKey1 == rKey2 );
107 : : }
108 : : };
109 : :
110 : : struct hashString
111 : : {
112 : 482 : size_t operator()( const rtl::OUString & rName ) const
113 : : {
114 : 482 : return rName.hashCode();
115 : : }
116 : : };
117 : :
118 : : typedef boost::unordered_map
119 : : <
120 : : rtl::OUString,
121 : : Package*,
122 : : hashString,
123 : : equalString
124 : : >
125 : : PackageMap;
126 : :
127 [ + - ]: 158 : class Packages : public PackageMap {};
128 : :
129 : : }
130 : :
131 : : using namespace package_ucp;
132 : :
133 : : //=========================================================================
134 : : //=========================================================================
135 : : //
136 : : // ContentProvider Implementation.
137 : : //
138 : : //=========================================================================
139 : : //=========================================================================
140 : :
141 : 79 : ContentProvider::ContentProvider(
142 : : const uno::Reference< lang::XMultiServiceFactory >& rSMgr )
143 : : : ::ucbhelper::ContentProviderImplHelper( rSMgr ),
144 : 79 : m_pPackages( 0 )
145 : : {
146 : 79 : }
147 : :
148 : : //=========================================================================
149 : : // virtual
150 : 79 : ContentProvider::~ContentProvider()
151 : : {
152 [ + - ][ + - ]: 79 : delete m_pPackages;
153 [ - + ]: 158 : }
154 : :
155 : : //=========================================================================
156 : : //
157 : : // XInterface methods.
158 : : //
159 : : //=========================================================================
160 : :
161 [ + - ][ + + ]: 29871 : XINTERFACE_IMPL_3( ContentProvider,
[ + - ]
162 : : lang::XTypeProvider,
163 : : lang::XServiceInfo,
164 : : ucb::XContentProvider );
165 : :
166 : : //=========================================================================
167 : : //
168 : : // XTypeProvider methods.
169 : : //
170 : : //=========================================================================
171 : :
172 [ # # ][ # # ]: 0 : XTYPEPROVIDER_IMPL_3( ContentProvider,
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
173 : : lang::XTypeProvider,
174 : : lang::XServiceInfo,
175 : : ucb::XContentProvider );
176 : :
177 : : //=========================================================================
178 : : //
179 : : // XServiceInfo methods.
180 : : //
181 : : //=========================================================================
182 : :
183 [ + - ][ + - ]: 320 : XSERVICEINFO_IMPL_1( ContentProvider,
[ + - ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
184 : : rtl::OUString( "com.sun.star.comp.ucb.PackageContentProvider" ),
185 : 79 : rtl::OUString( PACKAGE_CONTENT_PROVIDER_SERVICE_NAME ) );
186 : :
187 : : //=========================================================================
188 : : //
189 : : // Service factory implementation.
190 : : //
191 : : //=========================================================================
192 : :
193 [ + - ][ + - ]: 79 : ONE_INSTANCE_SERVICE_FACTORY_IMPL( ContentProvider );
194 : :
195 : : //=========================================================================
196 : : //
197 : : // XContentProvider methods.
198 : : //
199 : : //=========================================================================
200 : :
201 : : // virtual
202 : 183 : uno::Reference< ucb::XContent > SAL_CALL ContentProvider::queryContent(
203 : : const uno::Reference< ucb::XContentIdentifier >& Identifier )
204 : : throw( ucb::IllegalIdentifierException, uno::RuntimeException )
205 : : {
206 [ - + ]: 183 : if ( !Identifier.is() )
207 : 0 : return uno::Reference< ucb::XContent >();
208 : :
209 [ + - ][ + - ]: 183 : PackageUri aUri( Identifier->getContentIdentifier() );
210 [ - + ][ + - ]: 183 : if ( !aUri.isValid() )
211 [ # # ]: 0 : throw ucb::IllegalIdentifierException();
212 : :
213 : : // Create a new identifier for the mormalized URL returned by
214 : : // PackageUri::getUri().
215 : : uno::Reference< ucb::XContentIdentifier > xId
216 [ + - ][ + - ]: 183 : = new ::ucbhelper::ContentIdentifier( m_xSMgr, aUri.getUri() );
[ + - ][ + - ]
217 : :
218 [ + - ]: 183 : osl::MutexGuard aGuard( m_aMutex );
219 : :
220 : : // Check, if a content with given id already exists...
221 : : uno::Reference< ucb::XContent > xContent
222 [ + - ][ + + ]: 183 : = queryExistingContent( xId ).get();
[ + - ]
223 [ + + ]: 183 : if ( xContent.is() )
224 : 66 : return xContent;
225 : :
226 : : // Create a new content.
227 : :
228 [ + - ][ + - ]: 117 : xContent = Content::create( m_xSMgr, this, Identifier ); // not xId!!!
[ + - ]
229 [ + - ]: 117 : registerNewContent( xContent );
230 : :
231 [ + - ][ + - ]: 117 : if ( xContent.is() && !xContent->getIdentifier().is() )
[ + - ][ - + ]
[ + - ]
[ - + # # ]
232 [ # # ]: 0 : throw ucb::IllegalIdentifierException();
233 : :
234 [ + - ]: 183 : return xContent;
235 : : }
236 : :
237 : : //=========================================================================
238 : : //
239 : : // Other methods.
240 : : //
241 : : //=========================================================================
242 : :
243 : : uno::Reference< container::XHierarchicalNameAccess >
244 : 377 : ContentProvider::createPackage( const rtl::OUString & rName, const rtl::OUString & rParam )
245 : : {
246 [ + - ]: 377 : osl::MutexGuard aGuard( m_aMutex );
247 : :
248 [ - + ]: 377 : if ( rName.isEmpty() )
249 : : {
250 : : OSL_FAIL( "ContentProvider::createPackage - Invalid URL!" );
251 : 0 : return uno::Reference< container::XHierarchicalNameAccess >();
252 : : }
253 : :
254 : 377 : rtl::OUString rURL = rName + rParam;
255 : :
256 [ + + ]: 377 : if ( m_pPackages )
257 : : {
258 [ + - ]: 298 : Packages::const_iterator it = m_pPackages->find( rURL );
259 [ + + ][ + - ]: 298 : if ( it != m_pPackages->end() )
260 : : {
261 : : // Already instanciated. Return package.
262 [ + - ]: 298 : return (*it).second->m_xNA;
263 : : }
264 : : }
265 : : else
266 [ + - ][ + - ]: 79 : m_pPackages = new Packages;
267 : :
268 : : // Create new package...
269 : : try
270 : : {
271 [ + - ]: 105 : uno::Sequence< uno::Any > aArguments( 1 );
272 [ + - ][ + - ]: 105 : aArguments[ 0 ] <<= rURL;
273 : :
274 : : uno::Reference< uno::XInterface > xIfc
275 [ + - ]: 105 : = m_xSMgr->createInstanceWithArguments(
276 : : rtl::OUString( "com.sun.star.packages.comp.ZipPackage" ),
277 [ + - ]: 105 : aArguments );
278 : :
279 [ + - ]: 105 : if ( xIfc.is() )
280 : : {
281 : : uno::Reference<
282 : : container::XHierarchicalNameAccess > xNameAccess(
283 [ + - ]: 105 : xIfc, uno::UNO_QUERY );
284 : :
285 : : OSL_ENSURE( xNameAccess.is(),
286 : : "ContentProvider::createPackage - "
287 : : "Got no hierarchical name access!" );
288 : :
289 : : rtl::Reference< Package> xPackage
290 [ + - ]: 105 : = new Package( rURL, xNameAccess, this );
291 : :
292 [ + - ]: 105 : (*m_pPackages)[ rURL ] = xPackage.get();
293 : :
294 [ + - ][ + - ]: 105 : return xPackage.get();
295 [ + - ][ + - ]: 105 : }
[ - + ]
[ # # # ]
296 : : }
297 [ # # ]: 0 : catch ( uno::RuntimeException const & )
298 : : {
299 : : // createInstanceWithArguemts
300 : : }
301 [ # # ]: 0 : catch ( uno::Exception const & )
302 : : {
303 : : // createInstanceWithArguemts
304 : : }
305 : :
306 [ + - ]: 377 : return uno::Reference< container::XHierarchicalNameAccess >();
307 : : }
308 : :
309 : : //=========================================================================
310 : 105 : sal_Bool ContentProvider::removePackage( const rtl::OUString & rName )
311 : : {
312 [ + - ]: 105 : osl::MutexGuard aGuard( m_aMutex );
313 : :
314 [ + - ]: 105 : if ( m_pPackages )
315 : : {
316 [ + - ]: 105 : Packages::iterator it = m_pPackages->find( rName );
317 [ + - ][ + - ]: 105 : if ( it != m_pPackages->end() )
318 : : {
319 [ + - ]: 105 : m_pPackages->erase( it );
320 : 105 : return sal_True;
321 : : }
322 : : }
323 [ + - ]: 105 : return sal_False;
324 : : }
325 : :
326 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|