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