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 //==============================================================================
singleton_entries(Reference<registry::XRegistryKey> const & xRegistryKey)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 //______________________________________________________________________________
PackageManagerFactoryImpl(Reference<XComponentContext> const & xComponentContext)106 PackageManagerFactoryImpl::PackageManagerFactoryImpl(
107 Reference<XComponentContext> const & xComponentContext )
108 : t_pmfac_helper( getMutex() ),
109 m_xComponentContext( xComponentContext )
110 {
111 }
112
113 //______________________________________________________________________________
~PackageManagerFactoryImpl()114 PackageManagerFactoryImpl::~PackageManagerFactoryImpl()
115 {
116 }
117
118 //______________________________________________________________________________
check()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 //______________________________________________________________________________
disposing()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>
getPackageManager(OUString const & context)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