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_desktop.hxx" 30 31 #include "dp_manager.h" 32 #include "dp_resource.h" 33 #include "cppuhelper/compbase1.hxx" 34 #include "comphelper/servicedecl.hxx" 35 #include "com/sun/star/deployment/thePackageManagerFactory.hpp" 36 37 38 using namespace ::dp_misc; 39 using namespace ::com::sun::star; 40 using namespace ::com::sun::star::uno; 41 using ::rtl::OUString; 42 43 namespace dp_manager { 44 namespace factory { 45 46 typedef ::cppu::WeakComponentImplHelper1< 47 deployment::XPackageManagerFactory > t_pmfac_helper; 48 49 //============================================================================== 50 class PackageManagerFactoryImpl : private MutexHolder, public t_pmfac_helper 51 { 52 Reference<XComponentContext> m_xComponentContext; 53 54 Reference<deployment::XPackageManager> m_xUserMgr; 55 Reference<deployment::XPackageManager> m_xSharedMgr; 56 Reference<deployment::XPackageManager> m_xBundledMgr; 57 typedef ::std::hash_map< 58 OUString, WeakReference<deployment::XPackageManager>, 59 ::rtl::OUStringHash > t_string2weakref; 60 t_string2weakref m_managers; 61 62 protected: 63 inline void check(); 64 virtual void SAL_CALL disposing(); 65 66 public: 67 virtual ~PackageManagerFactoryImpl(); 68 PackageManagerFactoryImpl( 69 Reference<XComponentContext> const & xComponentContext ); 70 71 // XPackageManagerFactory 72 virtual Reference<deployment::XPackageManager> SAL_CALL getPackageManager( 73 OUString const & context ) throw (RuntimeException); 74 }; 75 76 //============================================================================== 77 namespace sdecl = comphelper::service_decl; 78 sdecl::class_<PackageManagerFactoryImpl> servicePMFI; 79 extern sdecl::ServiceDecl const serviceDecl( 80 servicePMFI, 81 // a private one: 82 "com.sun.star.comp.deployment.PackageManagerFactory", 83 "com.sun.star.comp.deployment.PackageManagerFactory" ); 84 85 //============================================================================== 86 bool singleton_entries( 87 Reference<registry::XRegistryKey> const & xRegistryKey ) 88 { 89 try { 90 Reference<registry::XRegistryKey> xKey( 91 xRegistryKey->createKey( 92 serviceDecl.getImplementationName() + 93 // xxx todo: use future generated function to get singleton name 94 OUSTR("/UNO/SINGLETONS/" 95 "com.sun.star.deployment.thePackageManagerFactory") ) ); 96 xKey->setStringValue( serviceDecl.getSupportedServiceNames()[0] ); 97 return true; 98 } 99 catch (registry::InvalidRegistryException & exc) { 100 (void) exc; // avoid warnings 101 OSL_ENSURE( 0, ::rtl::OUStringToOString( 102 exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() ); 103 return false; 104 } 105 } 106 107 //______________________________________________________________________________ 108 PackageManagerFactoryImpl::PackageManagerFactoryImpl( 109 Reference<XComponentContext> const & xComponentContext ) 110 : t_pmfac_helper( getMutex() ), 111 m_xComponentContext( xComponentContext ) 112 { 113 } 114 115 //______________________________________________________________________________ 116 PackageManagerFactoryImpl::~PackageManagerFactoryImpl() 117 { 118 } 119 120 //______________________________________________________________________________ 121 inline void PackageManagerFactoryImpl::check() 122 { 123 ::osl::MutexGuard guard( getMutex() ); 124 if (rBHelper.bInDispose || rBHelper.bDisposed) 125 { 126 throw lang::DisposedException( 127 OUSTR("PackageManagerFactory instance has already been disposed!"), 128 static_cast<OWeakObject *>(this) ); 129 } 130 } 131 132 //______________________________________________________________________________ 133 void PackageManagerFactoryImpl::disposing() 134 { 135 // dispose all managers: 136 ::osl::MutexGuard guard( getMutex() ); 137 t_string2weakref::const_iterator iPos( m_managers.begin() ); 138 t_string2weakref::const_iterator const iEnd( m_managers.end() ); 139 for ( ; iPos != iEnd; ++iPos ) 140 try_dispose( iPos->second ); 141 m_managers = t_string2weakref(); 142 // the below are already disposed: 143 m_xUserMgr.clear(); 144 m_xSharedMgr.clear(); 145 m_xBundledMgr.clear(); 146 } 147 148 // XPackageManagerFactory 149 //______________________________________________________________________________ 150 Reference<deployment::XPackageManager> 151 PackageManagerFactoryImpl::getPackageManager( OUString const & context ) 152 throw (RuntimeException) 153 { 154 Reference< deployment::XPackageManager > xRet; 155 ::osl::ResettableMutexGuard guard( getMutex() ); 156 check(); 157 t_string2weakref::const_iterator const iFind( m_managers.find( context ) ); 158 if (iFind != m_managers.end()) { 159 xRet = iFind->second; 160 if (xRet.is()) 161 return xRet; 162 } 163 164 guard.clear(); 165 xRet.set( PackageManagerImpl::create( m_xComponentContext, context ) ); 166 guard.reset(); 167 ::std::pair< t_string2weakref::iterator, bool > insertion( 168 m_managers.insert( t_string2weakref::value_type( context, xRet ) ) ); 169 if (insertion.second) 170 { 171 OSL_ASSERT( insertion.first->second.get() == xRet ); 172 // hold user, shared mgrs for whole process: live deployment 173 if (context.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("user") )) 174 m_xUserMgr = xRet; 175 else if (context.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("shared") )) 176 m_xSharedMgr = xRet; 177 else if (context.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("bundled") )) 178 m_xBundledMgr = xRet; 179 } 180 else 181 { 182 Reference< deployment::XPackageManager > xAlreadyIn( 183 insertion.first->second ); 184 if (xAlreadyIn.is()) 185 { 186 guard.clear(); 187 try_dispose( xRet ); 188 xRet = xAlreadyIn; 189 } 190 else 191 { 192 insertion.first->second = xRet; 193 } 194 } 195 return xRet; 196 } 197 198 } // namespace factory 199 } // namespace dp_manager 200 201