1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_ucb.hxx"
26
27 /**************************************************************************
28 TODO
29 **************************************************************************
30
31 *************************************************************************/
32
33 #include <hash_map>
34 #include <osl/diagnose.h>
35 #include <cppuhelper/weak.hxx>
36 #include <ucbhelper/contentidentifier.hxx>
37 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
38 #include "pkgprovider.hxx"
39 #include "pkgcontent.hxx"
40 #include "pkguri.hxx"
41
42 using namespace com::sun::star;
43
44 namespace package_ucp
45 {
46
47 //=========================================================================
48 //
49 // class Package.
50 //
51 //=========================================================================
52
53 class Package : public cppu::OWeakObject,
54 public container::XHierarchicalNameAccess
55 {
56 friend class ContentProvider;
57
58 rtl::OUString m_aName;
59 uno::Reference< container::XHierarchicalNameAccess > m_xNA;
60 ContentProvider* m_pOwner;
61
62 public:
Package(const rtl::OUString & rName,const uno::Reference<container::XHierarchicalNameAccess> & xNA,ContentProvider * pOwner)63 Package( const rtl::OUString& rName,
64 const uno::Reference< container::XHierarchicalNameAccess > & xNA,
65 ContentProvider* pOwner )
66 : m_aName( rName ), m_xNA( xNA ), m_pOwner( pOwner ) {}
~Package()67 virtual ~Package() { m_pOwner->removePackage( m_aName ); }
68
69 // XInterface
70 virtual uno::Any SAL_CALL
queryInterface(const uno::Type & aType)71 queryInterface( const uno::Type& aType )
72 throw( uno::RuntimeException )
73 { return m_xNA->queryInterface( aType ); }
74 virtual void SAL_CALL
acquire()75 acquire() throw()
76 { OWeakObject::acquire(); }
77 virtual void SAL_CALL
release()78 release() throw()
79 { OWeakObject::release(); }
80
81 // XHierarchicalNameAccess
82 virtual uno::Any SAL_CALL
getByHierarchicalName(const rtl::OUString & aName)83 getByHierarchicalName( const rtl::OUString& aName )
84 throw( container::NoSuchElementException, uno::RuntimeException )
85 { return m_xNA->getByHierarchicalName( aName ); }
86 virtual sal_Bool SAL_CALL
hasByHierarchicalName(const rtl::OUString & aName)87 hasByHierarchicalName( const rtl::OUString& aName )
88 throw( uno::RuntimeException )
89 { return m_xNA->hasByHierarchicalName( aName ); }
90 };
91
92 //=========================================================================
93 //
94 // Packages.
95 //
96 //=========================================================================
97
98 struct equalString
99 {
operator ()package_ucp::equalString100 bool operator()(
101 const rtl::OUString& rKey1, const rtl::OUString& rKey2 ) const
102 {
103 return !!( rKey1 == rKey2 );
104 }
105 };
106
107 struct hashString
108 {
operator ()package_ucp::hashString109 size_t operator()( const rtl::OUString & rName ) const
110 {
111 return rName.hashCode();
112 }
113 };
114
115 typedef std::hash_map
116 <
117 rtl::OUString,
118 Package*,
119 hashString,
120 equalString
121 >
122 PackageMap;
123
124 class Packages : public PackageMap {};
125
126 }
127
128 using namespace package_ucp;
129
130 //=========================================================================
131 //=========================================================================
132 //
133 // ContentProvider Implementation.
134 //
135 //=========================================================================
136 //=========================================================================
137
ContentProvider(const uno::Reference<lang::XMultiServiceFactory> & rSMgr)138 ContentProvider::ContentProvider(
139 const uno::Reference< lang::XMultiServiceFactory >& rSMgr )
140 : ::ucbhelper::ContentProviderImplHelper( rSMgr ),
141 m_pPackages( 0 )
142 {
143 }
144
145 //=========================================================================
146 // virtual
~ContentProvider()147 ContentProvider::~ContentProvider()
148 {
149 delete m_pPackages;
150 }
151
152 //=========================================================================
153 //
154 // XInterface methods.
155 //
156 //=========================================================================
157
158 XINTERFACE_IMPL_3( ContentProvider,
159 lang::XTypeProvider,
160 lang::XServiceInfo,
161 ucb::XContentProvider );
162
163 //=========================================================================
164 //
165 // XTypeProvider methods.
166 //
167 //=========================================================================
168
169 XTYPEPROVIDER_IMPL_3( ContentProvider,
170 lang::XTypeProvider,
171 lang::XServiceInfo,
172 ucb::XContentProvider );
173
174 //=========================================================================
175 //
176 // XServiceInfo methods.
177 //
178 //=========================================================================
179
180 XSERVICEINFO_IMPL_1( ContentProvider,
181 rtl::OUString::createFromAscii(
182 "com.sun.star.comp.ucb.PackageContentProvider" ),
183 rtl::OUString::createFromAscii(
184 PACKAGE_CONTENT_PROVIDER_SERVICE_NAME ) );
185
186 //=========================================================================
187 //
188 // Service factory implementation.
189 //
190 //=========================================================================
191
192 ONE_INSTANCE_SERVICE_FACTORY_IMPL( ContentProvider );
193
194 //=========================================================================
195 //
196 // XContentProvider methods.
197 //
198 //=========================================================================
199
200 // virtual
queryContent(const uno::Reference<ucb::XContentIdentifier> & Identifier)201 uno::Reference< ucb::XContent > SAL_CALL ContentProvider::queryContent(
202 const uno::Reference< ucb::XContentIdentifier >& Identifier )
203 throw( ucb::IllegalIdentifierException, uno::RuntimeException )
204 {
205 if ( !Identifier.is() )
206 return uno::Reference< ucb::XContent >();
207
208 PackageUri aUri( Identifier->getContentIdentifier() );
209 if ( !aUri.isValid() )
210 throw ucb::IllegalIdentifierException();
211
212 // Create a new identifier for the mormalized URL returned by
213 // PackageUri::getUri().
214 uno::Reference< ucb::XContentIdentifier > xId
215 = new ::ucbhelper::ContentIdentifier( m_xSMgr, aUri.getUri() );
216
217 osl::MutexGuard aGuard( m_aMutex );
218
219 // Check, if a content with given id already exists...
220 uno::Reference< ucb::XContent > xContent
221 = queryExistingContent( xId ).get();
222 if ( xContent.is() )
223 return xContent;
224
225 // Create a new content.
226
227 xContent = Content::create( m_xSMgr, this, Identifier ); // not xId!!!
228 registerNewContent( xContent );
229
230 if ( xContent.is() && !xContent->getIdentifier().is() )
231 throw ucb::IllegalIdentifierException();
232
233 return xContent;
234 }
235
236 //=========================================================================
237 //
238 // Other methods.
239 //
240 //=========================================================================
241
242 uno::Reference< container::XHierarchicalNameAccess >
createPackage(const rtl::OUString & rName,const rtl::OUString & rParam)243 ContentProvider::createPackage( const rtl::OUString & rName, const rtl::OUString & rParam )
244 {
245 osl::MutexGuard aGuard( m_aMutex );
246
247 if ( !rName.getLength() )
248 {
249 OSL_ENSURE( sal_False,
250 "ContentProvider::createPackage - Invalid URL!" );
251 return uno::Reference< container::XHierarchicalNameAccess >();
252 }
253
254 rtl::OUString rURL = rName + rParam;
255
256 if ( m_pPackages )
257 {
258 Packages::const_iterator it = m_pPackages->find( rURL );
259 if ( it != m_pPackages->end() )
260 {
261 // Already instanciated. Return package.
262 return (*it).second->m_xNA;
263 }
264 }
265 else
266 m_pPackages = new Packages;
267
268 // Create new package...
269 try
270 {
271 uno::Sequence< uno::Any > aArguments( 1 );
272 aArguments[ 0 ] <<= rURL;
273
274 uno::Reference< uno::XInterface > xIfc
275 = m_xSMgr->createInstanceWithArguments(
276 rtl::OUString::createFromAscii(
277 "com.sun.star.packages.comp.ZipPackage" ),
278 aArguments );
279
280 if ( xIfc.is() )
281 {
282 uno::Reference<
283 container::XHierarchicalNameAccess > xNameAccess(
284 xIfc, uno::UNO_QUERY );
285
286 OSL_ENSURE( xNameAccess.is(),
287 "ContentProvider::createPackage - "
288 "Got no hierarchical name access!" );
289
290 rtl::Reference< Package> xPackage
291 = new Package( rURL, xNameAccess, this );
292
293 (*m_pPackages)[ rURL ] = xPackage.get();
294
295 return xPackage.get();
296 }
297 }
298 catch ( uno::RuntimeException const & )
299 {
300 // createInstanceWithArguemts
301 }
302 catch ( uno::Exception const & )
303 {
304 // createInstanceWithArguemts
305 }
306
307 return uno::Reference< container::XHierarchicalNameAccess >();
308 }
309
310 //=========================================================================
removePackage(const rtl::OUString & rName)311 sal_Bool ContentProvider::removePackage( const rtl::OUString & rName )
312 {
313 osl::MutexGuard aGuard( m_aMutex );
314
315 if ( m_pPackages )
316 {
317 Packages::iterator it = m_pPackages->find( rName );
318 if ( it != m_pPackages->end() )
319 {
320 m_pPackages->erase( it );
321 return sal_True;
322 }
323 }
324 return sal_False;
325 }
326
327