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_pkg.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 { return m_xNA->queryInterface( aType ); }
73 virtual void SAL_CALL
acquire()74 acquire() throw()
75 { OWeakObject::acquire(); }
76 virtual void SAL_CALL
release()77 release() throw()
78 { OWeakObject::release(); }
79
80 // XHierarchicalNameAccess
81 virtual uno::Any SAL_CALL
getByHierarchicalName(const rtl::OUString & aName)82 getByHierarchicalName( const rtl::OUString& aName )
83 { return m_xNA->getByHierarchicalName( aName ); }
84 virtual sal_Bool SAL_CALL
hasByHierarchicalName(const rtl::OUString & aName)85 hasByHierarchicalName( const rtl::OUString& aName )
86 { return m_xNA->hasByHierarchicalName( aName ); }
87 };
88
89 //=========================================================================
90 //
91 // Packages.
92 //
93 //=========================================================================
94
95 struct equalString
96 {
operator ()package_ucp::equalString97 bool operator()(
98 const rtl::OUString& rKey1, const rtl::OUString& rKey2 ) const
99 {
100 return !!( rKey1 == rKey2 );
101 }
102 };
103
104 struct hashString
105 {
operator ()package_ucp::hashString106 size_t operator()( const rtl::OUString & rName ) const
107 {
108 return rName.hashCode();
109 }
110 };
111
112 typedef std::hash_map
113 <
114 rtl::OUString,
115 Package*,
116 hashString,
117 equalString
118 >
119 PackageMap;
120
121 class Packages : public PackageMap {};
122
123 }
124
125 using namespace package_ucp;
126
127 //=========================================================================
128 //=========================================================================
129 //
130 // ContentProvider Implementation.
131 //
132 //=========================================================================
133 //=========================================================================
134
ContentProvider(const uno::Reference<lang::XMultiServiceFactory> & rSMgr)135 ContentProvider::ContentProvider(
136 const uno::Reference< lang::XMultiServiceFactory >& rSMgr )
137 : ::ucbhelper::ContentProviderImplHelper( rSMgr ),
138 m_pPackages( 0 )
139 {
140 }
141
142 //=========================================================================
143 // virtual
~ContentProvider()144 ContentProvider::~ContentProvider()
145 {
146 delete m_pPackages;
147 }
148
149 //=========================================================================
150 //
151 // XInterface methods.
152 //
153 //=========================================================================
154
155 XINTERFACE_IMPL_3( ContentProvider,
156 lang::XTypeProvider,
157 lang::XServiceInfo,
158 ucb::XContentProvider );
159
160 //=========================================================================
161 //
162 // XTypeProvider methods.
163 //
164 //=========================================================================
165
166 XTYPEPROVIDER_IMPL_3( ContentProvider,
167 lang::XTypeProvider,
168 lang::XServiceInfo,
169 ucb::XContentProvider );
170
171 //=========================================================================
172 //
173 // XServiceInfo methods.
174 //
175 //=========================================================================
176
177 XSERVICEINFO_IMPL_1( ContentProvider,
178 rtl::OUString::createFromAscii(
179 "com.sun.star.comp.ucb.PackageContentProvider" ),
180 rtl::OUString::createFromAscii(
181 PACKAGE_CONTENT_PROVIDER_SERVICE_NAME ) );
182
183 //=========================================================================
184 //
185 // Service factory implementation.
186 //
187 //=========================================================================
188
189 ONE_INSTANCE_SERVICE_FACTORY_IMPL( ContentProvider );
190
191 //=========================================================================
192 //
193 // XContentProvider methods.
194 //
195 //=========================================================================
196
197 // virtual
queryContent(const uno::Reference<ucb::XContentIdentifier> & Identifier)198 uno::Reference< ucb::XContent > SAL_CALL ContentProvider::queryContent(
199 const uno::Reference< ucb::XContentIdentifier >& Identifier )
200 {
201 if ( !Identifier.is() )
202 return uno::Reference< ucb::XContent >();
203
204 PackageUri aUri( Identifier->getContentIdentifier() );
205 if ( !aUri.isValid() )
206 throw ucb::IllegalIdentifierException();
207
208 // Create a new identifier for the mormalized URL returned by
209 // PackageUri::getUri().
210 uno::Reference< ucb::XContentIdentifier > xId
211 = new ::ucbhelper::ContentIdentifier( m_xSMgr, aUri.getUri() );
212
213 osl::MutexGuard aGuard( m_aMutex );
214
215 // Check, if a content with given id already exists...
216 uno::Reference< ucb::XContent > xContent
217 = queryExistingContent( xId ).get();
218 if ( xContent.is() )
219 return xContent;
220
221 // Create a new content.
222
223 xContent = Content::create( m_xSMgr, this, Identifier ); // not xId!!!
224 registerNewContent( xContent );
225
226 if ( xContent.is() && !xContent->getIdentifier().is() )
227 throw ucb::IllegalIdentifierException();
228
229 return xContent;
230 }
231
232 //=========================================================================
233 //
234 // Other methods.
235 //
236 //=========================================================================
237
238 uno::Reference< container::XHierarchicalNameAccess >
createPackage(const rtl::OUString & rName,const rtl::OUString & rParam)239 ContentProvider::createPackage( const rtl::OUString & rName, const rtl::OUString & rParam )
240 {
241 osl::MutexGuard aGuard( m_aMutex );
242
243 if ( !rName.getLength() )
244 {
245 OSL_ENSURE( sal_False,
246 "ContentProvider::createPackage - Invalid URL!" );
247 return uno::Reference< container::XHierarchicalNameAccess >();
248 }
249
250 rtl::OUString rURL = rName + rParam;
251
252 if ( m_pPackages )
253 {
254 Packages::const_iterator it = m_pPackages->find( rURL );
255 if ( it != m_pPackages->end() )
256 {
257 // Already instantiated. Return package.
258 return (*it).second->m_xNA;
259 }
260 }
261 else
262 m_pPackages = new Packages;
263
264 // Create new package...
265 try
266 {
267 uno::Sequence< uno::Any > aArguments( 1 );
268 aArguments[ 0 ] <<= rURL;
269
270 uno::Reference< uno::XInterface > xIfc
271 = m_xSMgr->createInstanceWithArguments(
272 rtl::OUString::createFromAscii(
273 "com.sun.star.packages.comp.ZipPackage" ),
274 aArguments );
275
276 if ( xIfc.is() )
277 {
278 uno::Reference<
279 container::XHierarchicalNameAccess > xNameAccess(
280 xIfc, uno::UNO_QUERY );
281
282 OSL_ENSURE( xNameAccess.is(),
283 "ContentProvider::createPackage - "
284 "Got no hierarchical name access!" );
285
286 rtl::Reference< Package> xPackage
287 = new Package( rURL, xNameAccess, this );
288
289 (*m_pPackages)[ rURL ] = xPackage.get();
290
291 return xPackage.get();
292 }
293 }
294 catch ( uno::RuntimeException const & )
295 {
296 // createInstanceWithArguemts
297 }
298 catch ( uno::Exception const & )
299 {
300 // createInstanceWithArguemts
301 }
302
303 return uno::Reference< container::XHierarchicalNameAccess >();
304 }
305
306 //=========================================================================
removePackage(const rtl::OUString & rName)307 sal_Bool ContentProvider::removePackage( const rtl::OUString & rName )
308 {
309 osl::MutexGuard aGuard( m_aMutex );
310
311 if ( m_pPackages )
312 {
313 Packages::iterator it = m_pPackages->find( rName );
314 if ( it != m_pPackages->end() )
315 {
316 m_pPackages->erase( it );
317 return sal_True;
318 }
319 }
320 return sal_False;
321 }
322