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