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