xref: /AOO41X/main/desktop/source/deployment/manager/dp_manager.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_desktop.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include "dp_ucb.h"
32*cdf0e10cSrcweir #include "dp_resource.h"
33*cdf0e10cSrcweir #include "dp_platform.hxx"
34*cdf0e10cSrcweir #include "dp_manager.h"
35*cdf0e10cSrcweir #include "dp_identifier.hxx"
36*cdf0e10cSrcweir #include "rtl/ustrbuf.hxx"
37*cdf0e10cSrcweir #include "rtl/string.hxx"
38*cdf0e10cSrcweir #include "rtl/uri.hxx"
39*cdf0e10cSrcweir #include "rtl/bootstrap.hxx"
40*cdf0e10cSrcweir #include "osl/diagnose.h"
41*cdf0e10cSrcweir #include "osl/file.hxx"
42*cdf0e10cSrcweir #include "osl/security.hxx"
43*cdf0e10cSrcweir #include "cppuhelper/weakref.hxx"
44*cdf0e10cSrcweir #include "cppuhelper/exc_hlp.hxx"
45*cdf0e10cSrcweir #include "cppuhelper/implbase1.hxx"
46*cdf0e10cSrcweir #include "cppuhelper/interfacecontainer.hxx"
47*cdf0e10cSrcweir #include "comphelper/servicedecl.hxx"
48*cdf0e10cSrcweir #include "comphelper/sequence.hxx"
49*cdf0e10cSrcweir #include "xmlscript/xml_helper.hxx"
50*cdf0e10cSrcweir #include "svl/inettype.hxx"
51*cdf0e10cSrcweir #include "com/sun/star/lang/DisposedException.hpp"
52*cdf0e10cSrcweir #include "com/sun/star/lang/WrappedTargetRuntimeException.hpp"
53*cdf0e10cSrcweir #include "com/sun/star/beans/UnknownPropertyException.hpp"
54*cdf0e10cSrcweir #include "com/sun/star/util/XUpdatable.hpp"
55*cdf0e10cSrcweir #include "com/sun/star/sdbc/XResultSet.hpp"
56*cdf0e10cSrcweir #include "com/sun/star/sdbc/XRow.hpp"
57*cdf0e10cSrcweir #include "com/sun/star/ucb/XContentAccess.hpp"
58*cdf0e10cSrcweir #include "com/sun/star/ucb/NameClash.hpp"
59*cdf0e10cSrcweir #include "com/sun/star/deployment/VersionException.hpp"
60*cdf0e10cSrcweir #include "com/sun/star/deployment/InstallException.hpp"
61*cdf0e10cSrcweir #include "com/sun/star/deployment/Prerequisites.hpp"
62*cdf0e10cSrcweir #include "com/sun/star/task/XInteractionApprove.hpp"
63*cdf0e10cSrcweir #include "com/sun/star/ucb/UnsupportedCommandException.hpp"
64*cdf0e10cSrcweir #include "boost/bind.hpp"
65*cdf0e10cSrcweir #include "tools/urlobj.hxx"
66*cdf0e10cSrcweir #include "unotools/tempfile.hxx"
67*cdf0e10cSrcweir 
68*cdf0e10cSrcweir #include "osl/file.hxx"
69*cdf0e10cSrcweir #include <vector>
70*cdf0e10cSrcweir #include <list>
71*cdf0e10cSrcweir #include "dp_descriptioninfoset.hxx"
72*cdf0e10cSrcweir #include "dp_commandenvironments.hxx"
73*cdf0e10cSrcweir #include "dp_properties.hxx"
74*cdf0e10cSrcweir 
75*cdf0e10cSrcweir using namespace ::dp_misc;
76*cdf0e10cSrcweir using namespace ::com::sun::star;
77*cdf0e10cSrcweir using namespace ::com::sun::star::uno;
78*cdf0e10cSrcweir using namespace ::com::sun::star::ucb;
79*cdf0e10cSrcweir using ::rtl::OUString;
80*cdf0e10cSrcweir 
81*cdf0e10cSrcweir namespace dp_log {
82*cdf0e10cSrcweir extern comphelper::service_decl::ServiceDecl const serviceDecl;
83*cdf0e10cSrcweir }
84*cdf0e10cSrcweir 
85*cdf0e10cSrcweir namespace dp_registry {
86*cdf0e10cSrcweir Reference<deployment::XPackageRegistry> create(
87*cdf0e10cSrcweir     OUString const & context,
88*cdf0e10cSrcweir     OUString const & cachePath, bool readOnly,
89*cdf0e10cSrcweir     Reference<XComponentContext> const & xComponentContext );
90*cdf0e10cSrcweir }
91*cdf0e10cSrcweir 
92*cdf0e10cSrcweir namespace dp_manager {
93*cdf0e10cSrcweir 
94*cdf0e10cSrcweir struct MatchTempDir
95*cdf0e10cSrcweir {
96*cdf0e10cSrcweir     OUString m_str;
97*cdf0e10cSrcweir     MatchTempDir( OUString const & str ) : m_str( str ) {}
98*cdf0e10cSrcweir     bool operator () ( ActivePackages::Entries::value_type const & v ) const {
99*cdf0e10cSrcweir         return v.second.temporaryName.equalsIgnoreAsciiCase( m_str );
100*cdf0e10cSrcweir     }
101*cdf0e10cSrcweir };
102*cdf0e10cSrcweir 
103*cdf0e10cSrcweir 
104*cdf0e10cSrcweir namespace {
105*cdf0e10cSrcweir OUString getExtensionFolder(OUString const &  parentFolder,
106*cdf0e10cSrcweir                             Reference<ucb::XCommandEnvironment> const & xCmdEnv)
107*cdf0e10cSrcweir {
108*cdf0e10cSrcweir     ::ucbhelper::Content tempFolder(
109*cdf0e10cSrcweir         parentFolder, xCmdEnv );
110*cdf0e10cSrcweir     Reference<sdbc::XResultSet> xResultSet(
111*cdf0e10cSrcweir         tempFolder.createCursor(
112*cdf0e10cSrcweir             Sequence<OUString>( &StrTitle::get(), 1 ),
113*cdf0e10cSrcweir             ::ucbhelper::INCLUDE_FOLDERS_ONLY ) );
114*cdf0e10cSrcweir 
115*cdf0e10cSrcweir     OUString title;
116*cdf0e10cSrcweir     while (xResultSet->next())
117*cdf0e10cSrcweir     {
118*cdf0e10cSrcweir         title = Reference<sdbc::XRow>(
119*cdf0e10cSrcweir             xResultSet, UNO_QUERY_THROW )->getString(1 /* Title */ ) ;
120*cdf0e10cSrcweir         break;
121*cdf0e10cSrcweir     }
122*cdf0e10cSrcweir     return title;
123*cdf0e10cSrcweir }
124*cdf0e10cSrcweir }
125*cdf0e10cSrcweir //______________________________________________________________________________
126*cdf0e10cSrcweir void PackageManagerImpl::initActivationLayer(
127*cdf0e10cSrcweir     Reference<XCommandEnvironment> const & xCmdEnv )
128*cdf0e10cSrcweir {
129*cdf0e10cSrcweir     if (m_activePackages.getLength() == 0)
130*cdf0e10cSrcweir     {
131*cdf0e10cSrcweir         OSL_ASSERT( m_registryCache.getLength() == 0 );
132*cdf0e10cSrcweir         // documents temp activation:
133*cdf0e10cSrcweir         m_activePackagesDB.reset( new ActivePackages );
134*cdf0e10cSrcweir         ::ucbhelper::Content ucbContent;
135*cdf0e10cSrcweir         if (create_ucb_content( &ucbContent, m_context, xCmdEnv,
136*cdf0e10cSrcweir                                 false /* no throw */ ))
137*cdf0e10cSrcweir         {
138*cdf0e10cSrcweir             // scan for all entries in m_packagesDir:
139*cdf0e10cSrcweir             Reference<sdbc::XResultSet> xResultSet(
140*cdf0e10cSrcweir                 ucbContent.createCursor(
141*cdf0e10cSrcweir                     Sequence<OUString>( &StrTitle::get(), 1 ),
142*cdf0e10cSrcweir                     ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS ) );
143*cdf0e10cSrcweir             while (xResultSet->next())
144*cdf0e10cSrcweir             {
145*cdf0e10cSrcweir                 Reference<sdbc::XRow> xRow( xResultSet, UNO_QUERY_THROW );
146*cdf0e10cSrcweir                 OUString title( xRow->getString( 1 /* Title */ ) );
147*cdf0e10cSrcweir                 // xxx todo: remove workaround for tdoc
148*cdf0e10cSrcweir                 if (title.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(
149*cdf0e10cSrcweir                                             "this_is_a_dummy_stream_just_there_"
150*cdf0e10cSrcweir                                             "as_a_workaround_for_a_"
151*cdf0e10cSrcweir                                             "temporary_limitation_of_the_"
152*cdf0e10cSrcweir                                             "storage_api_implementation") ))
153*cdf0e10cSrcweir                     continue;
154*cdf0e10cSrcweir                 if (title.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(
155*cdf0e10cSrcweir                                              "META-INF") ) )
156*cdf0e10cSrcweir                     continue;
157*cdf0e10cSrcweir 
158*cdf0e10cSrcweir                 ::ucbhelper::Content sourceContent(
159*cdf0e10cSrcweir                     Reference<XContentAccess>(
160*cdf0e10cSrcweir                         xResultSet, UNO_QUERY_THROW )->queryContent(),
161*cdf0e10cSrcweir                     xCmdEnv );
162*cdf0e10cSrcweir 
163*cdf0e10cSrcweir                 OUString mediaType( detectMediaType( sourceContent,
164*cdf0e10cSrcweir                                                      false /* no throw */) );
165*cdf0e10cSrcweir                 if (mediaType.getLength() >0)
166*cdf0e10cSrcweir                 {
167*cdf0e10cSrcweir                     ActivePackages::Data dbData;
168*cdf0e10cSrcweir                     insertToActivationLayer(
169*cdf0e10cSrcweir                         Sequence<css::beans::NamedValue>(),mediaType, sourceContent,
170*cdf0e10cSrcweir                         title, &dbData );
171*cdf0e10cSrcweir 
172*cdf0e10cSrcweir                     insertToActivationLayerDB( title, dbData );
173*cdf0e10cSrcweir                         //TODO #i73136#: insertToActivationLayerDB needs id not
174*cdf0e10cSrcweir                         // title, but the whole m_activePackages.getLength()==0
175*cdf0e10cSrcweir                         // case (i.e., document-relative deployment) currently
176*cdf0e10cSrcweir                         // does not work, anyway.
177*cdf0e10cSrcweir                 }
178*cdf0e10cSrcweir             }
179*cdf0e10cSrcweir         }
180*cdf0e10cSrcweir     }
181*cdf0e10cSrcweir     else
182*cdf0e10cSrcweir     {
183*cdf0e10cSrcweir         // user|share:
184*cdf0e10cSrcweir         OSL_ASSERT( m_activePackages.getLength() > 0 );
185*cdf0e10cSrcweir         m_activePackages_expanded = expandUnoRcUrl( m_activePackages );
186*cdf0e10cSrcweir         m_registrationData_expanded = expandUnoRcUrl(m_registrationData);
187*cdf0e10cSrcweir         if (!m_readOnly)
188*cdf0e10cSrcweir             create_folder( 0, m_activePackages_expanded, xCmdEnv, true);
189*cdf0e10cSrcweir 
190*cdf0e10cSrcweir         OUString dbName;
191*cdf0e10cSrcweir         if (m_context.equals(OUSTR("user")))
192*cdf0e10cSrcweir             dbName = m_activePackages_expanded + OUSTR(".db");
193*cdf0e10cSrcweir         else
194*cdf0e10cSrcweir         {
195*cdf0e10cSrcweir             //Create the extension data base in the user installation
196*cdf0e10cSrcweir             create_folder( 0, m_registrationData_expanded, xCmdEnv, true);
197*cdf0e10cSrcweir             dbName = m_registrationData_expanded + OUSTR("/extensions.db");
198*cdf0e10cSrcweir         }
199*cdf0e10cSrcweir         //The data base can always be written because it it always in the user installation
200*cdf0e10cSrcweir         m_activePackagesDB.reset(
201*cdf0e10cSrcweir             new ActivePackages( dbName, false ) );
202*cdf0e10cSrcweir 
203*cdf0e10cSrcweir         if (! m_readOnly && ! m_context.equals(OUSTR("bundled")))
204*cdf0e10cSrcweir         {
205*cdf0e10cSrcweir             // clean up activation layer, scan for zombie temp dirs:
206*cdf0e10cSrcweir             ActivePackages::Entries id2temp( m_activePackagesDB->getEntries() );
207*cdf0e10cSrcweir 
208*cdf0e10cSrcweir             ::ucbhelper::Content tempFolder(
209*cdf0e10cSrcweir                 m_activePackages_expanded, xCmdEnv );
210*cdf0e10cSrcweir             Reference<sdbc::XResultSet> xResultSet(
211*cdf0e10cSrcweir                 tempFolder.createCursor(
212*cdf0e10cSrcweir                     Sequence<OUString>( &StrTitle::get(), 1 ),
213*cdf0e10cSrcweir                     ::ucbhelper::INCLUDE_DOCUMENTS_ONLY ) );
214*cdf0e10cSrcweir             // get all temp directories:
215*cdf0e10cSrcweir             ::std::vector<OUString> tempEntries;
216*cdf0e10cSrcweir             ::std::vector<OUString> removedEntries;
217*cdf0e10cSrcweir             while (xResultSet->next())
218*cdf0e10cSrcweir             {
219*cdf0e10cSrcweir                 OUString title(
220*cdf0e10cSrcweir                     Reference<sdbc::XRow>(
221*cdf0e10cSrcweir                         xResultSet, UNO_QUERY_THROW )->getString(
222*cdf0e10cSrcweir                             1 /* Title */ ) );
223*cdf0e10cSrcweir 
224*cdf0e10cSrcweir                 const char extensionRemoved[] = "removed";
225*cdf0e10cSrcweir                 if (title.endsWithAsciiL(
226*cdf0e10cSrcweir                         extensionRemoved, sizeof(extensionRemoved) - 1))
227*cdf0e10cSrcweir                 {
228*cdf0e10cSrcweir                     //save the file name withouth the "removed" part
229*cdf0e10cSrcweir                     sal_Int32 index = title.lastIndexOfAsciiL(
230*cdf0e10cSrcweir                         extensionRemoved, sizeof(extensionRemoved) - 1);
231*cdf0e10cSrcweir                     OUString remFile = title.copy(0, index);
232*cdf0e10cSrcweir                     removedEntries.push_back(::rtl::Uri::encode(
233*cdf0e10cSrcweir                                                 remFile, rtl_UriCharClassPchar,
234*cdf0e10cSrcweir                                                 rtl_UriEncodeIgnoreEscapes,
235*cdf0e10cSrcweir                                                 RTL_TEXTENCODING_UTF8 ) );
236*cdf0e10cSrcweir                 }
237*cdf0e10cSrcweir                 else
238*cdf0e10cSrcweir                 {
239*cdf0e10cSrcweir                     tempEntries.push_back( ::rtl::Uri::encode(
240*cdf0e10cSrcweir                                                title, rtl_UriCharClassPchar,
241*cdf0e10cSrcweir                                                rtl_UriEncodeIgnoreEscapes,
242*cdf0e10cSrcweir                                                RTL_TEXTENCODING_UTF8 ) );
243*cdf0e10cSrcweir                 }
244*cdf0e10cSrcweir             }
245*cdf0e10cSrcweir 
246*cdf0e10cSrcweir             bool bShared = m_context.equals(OUSTR("shared")) ? true : false;
247*cdf0e10cSrcweir             for ( ::std::size_t pos = 0; pos < tempEntries.size(); ++pos )
248*cdf0e10cSrcweir             {
249*cdf0e10cSrcweir                 OUString const & tempEntry = tempEntries[ pos ];
250*cdf0e10cSrcweir                 const MatchTempDir match( tempEntry );
251*cdf0e10cSrcweir                 if (::std::find_if( id2temp.begin(), id2temp.end(), match ) ==
252*cdf0e10cSrcweir                     id2temp.end())
253*cdf0e10cSrcweir                 {
254*cdf0e10cSrcweir                     const OUString url(
255*cdf0e10cSrcweir                         makeURL(m_activePackages_expanded, tempEntry ) );
256*cdf0e10cSrcweir 
257*cdf0e10cSrcweir                     //In case of shared extensions, new entries are regarded as
258*cdf0e10cSrcweir                     //added extensions if there is no xxx.tmpremoved file.
259*cdf0e10cSrcweir                     if (bShared)
260*cdf0e10cSrcweir                     {
261*cdf0e10cSrcweir                         if (::std::find(removedEntries.begin(), removedEntries.end(), tempEntry) ==
262*cdf0e10cSrcweir                             removedEntries.end())
263*cdf0e10cSrcweir                         {
264*cdf0e10cSrcweir                             continue;
265*cdf0e10cSrcweir                         }
266*cdf0e10cSrcweir                         else
267*cdf0e10cSrcweir                         {
268*cdf0e10cSrcweir                             //Make sure only the same user removes the extension, who
269*cdf0e10cSrcweir                             //previously unregistered it. This is avoid races if multiple instances
270*cdf0e10cSrcweir                             //of OOo are running which all have write access to the shared installation.
271*cdf0e10cSrcweir                             //For example, a user removes the extension, but keeps OOo
272*cdf0e10cSrcweir                             //running. Parts of the extension may still be loaded and used by OOo.
273*cdf0e10cSrcweir                             //Therefore the extension is only deleted the next time the extension manager is
274*cdf0e10cSrcweir                             //run after restarting OOo. While OOo is still running, another user starts OOo
275*cdf0e10cSrcweir                             //which would deleted the extension files. If the same user starts another
276*cdf0e10cSrcweir                             //instance of OOo then the lock file will prevent this.
277*cdf0e10cSrcweir                             OUString aUserName;
278*cdf0e10cSrcweir                             ::osl::Security aSecurity;
279*cdf0e10cSrcweir                             aSecurity.getUserName( aUserName );
280*cdf0e10cSrcweir                             ucbhelper::Content remFileContent(
281*cdf0e10cSrcweir                                 url + OUSTR("removed"), Reference<XCommandEnvironment>());
282*cdf0e10cSrcweir                             ::rtl::ByteSequence data = dp_misc::readFile(remFileContent);
283*cdf0e10cSrcweir                             ::rtl::OString osData(reinterpret_cast<const sal_Char*>(data.getConstArray()),
284*cdf0e10cSrcweir                                                   data.getLength());
285*cdf0e10cSrcweir                             OUString sData = ::rtl::OStringToOUString(
286*cdf0e10cSrcweir                                 osData, RTL_TEXTENCODING_UTF8);
287*cdf0e10cSrcweir                             if (!sData.equals(aUserName))
288*cdf0e10cSrcweir                                 continue;
289*cdf0e10cSrcweir                         }
290*cdf0e10cSrcweir                     }
291*cdf0e10cSrcweir                     // temp entry not needed anymore:
292*cdf0e10cSrcweir                     erase_path( url + OUSTR("_"),
293*cdf0e10cSrcweir                                 Reference<XCommandEnvironment>(),
294*cdf0e10cSrcweir                                 false /* no throw: ignore errors */ );
295*cdf0e10cSrcweir                     erase_path( url, Reference<XCommandEnvironment>(),
296*cdf0e10cSrcweir                                 false /* no throw: ignore errors */ );
297*cdf0e10cSrcweir                     //delete the xxx.tmpremoved file
298*cdf0e10cSrcweir                     erase_path(url + OUSTR("removed"),
299*cdf0e10cSrcweir                                Reference<XCommandEnvironment>(), false);
300*cdf0e10cSrcweir                 }
301*cdf0e10cSrcweir             }
302*cdf0e10cSrcweir         }
303*cdf0e10cSrcweir     }
304*cdf0e10cSrcweir }
305*cdf0e10cSrcweir 
306*cdf0e10cSrcweir //______________________________________________________________________________
307*cdf0e10cSrcweir void PackageManagerImpl::initRegistryBackends()
308*cdf0e10cSrcweir {
309*cdf0e10cSrcweir     if (m_registryCache.getLength() > 0)
310*cdf0e10cSrcweir         create_folder( 0, m_registryCache,
311*cdf0e10cSrcweir                        Reference<XCommandEnvironment>(), false);
312*cdf0e10cSrcweir     m_xRegistry.set( ::dp_registry::create(
313*cdf0e10cSrcweir                          m_context, m_registryCache, false,
314*cdf0e10cSrcweir                          m_xComponentContext ) );
315*cdf0e10cSrcweir }
316*cdf0e10cSrcweir 
317*cdf0e10cSrcweir //______________________________________________________________________________
318*cdf0e10cSrcweir Reference<deployment::XPackageManager> PackageManagerImpl::create(
319*cdf0e10cSrcweir     Reference<XComponentContext> const & xComponentContext,
320*cdf0e10cSrcweir     OUString const & context )
321*cdf0e10cSrcweir {
322*cdf0e10cSrcweir     PackageManagerImpl * that = new PackageManagerImpl(
323*cdf0e10cSrcweir         xComponentContext, context );
324*cdf0e10cSrcweir     Reference<deployment::XPackageManager> xPackageManager( that );
325*cdf0e10cSrcweir 
326*cdf0e10cSrcweir     OUString packages, logFile, stampURL;
327*cdf0e10cSrcweir     if (context.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("user") )) {
328*cdf0e10cSrcweir         that->m_activePackages = OUSTR(
329*cdf0e10cSrcweir             "vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE/uno_packages");
330*cdf0e10cSrcweir         that->m_registrationData = OUSTR(
331*cdf0e10cSrcweir             "vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE");
332*cdf0e10cSrcweir         that->m_registryCache = OUSTR(
333*cdf0e10cSrcweir             "vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE/registry");
334*cdf0e10cSrcweir         logFile = OUSTR(
335*cdf0e10cSrcweir             "vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE/log.txt");
336*cdf0e10cSrcweir         //We use the extension .sys for the file because on Windows Vista a sys
337*cdf0e10cSrcweir         //(as well as exe and dll) file
338*cdf0e10cSrcweir         //will not be written in the VirtualStore. For example if the process has no
339*cdf0e10cSrcweir         //admin right once cannot write to the %programfiles% folder. However, when
340*cdf0e10cSrcweir         //virtualization is used, the file will be written into the VirtualStore and
341*cdf0e10cSrcweir         //it appears as if one could write to %programfiles%. When we test for write
342*cdf0e10cSrcweir         //access to the office/shared folder for shared extensions then this typically
343*cdf0e10cSrcweir         //fails because a normal user typically cannot write to this folder. However,
344*cdf0e10cSrcweir         //using virtualization it appears that he/she can. Then a shared extension can
345*cdf0e10cSrcweir         //be installed but is only visible for the user (because the extension is in
346*cdf0e10cSrcweir         //the virtual store).
347*cdf0e10cSrcweir         stampURL = OUSTR(
348*cdf0e10cSrcweir             "vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE/stamp.sys");
349*cdf0e10cSrcweir     }
350*cdf0e10cSrcweir     else if (context.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("shared") )) {
351*cdf0e10cSrcweir         that->m_activePackages = OUSTR(
352*cdf0e10cSrcweir             "vnd.sun.star.expand:$UNO_SHARED_PACKAGES_CACHE/uno_packages");
353*cdf0e10cSrcweir         that->m_registrationData = OUSTR(
354*cdf0e10cSrcweir             "vnd.sun.star.expand:$SHARED_EXTENSIONS_USER");
355*cdf0e10cSrcweir         that->m_registryCache = OUSTR(
356*cdf0e10cSrcweir             "vnd.sun.star.expand:$SHARED_EXTENSIONS_USER/registry");
357*cdf0e10cSrcweir         logFile = OUSTR(
358*cdf0e10cSrcweir             "vnd.sun.star.expand:$SHARED_EXTENSIONS_USER/log.txt");
359*cdf0e10cSrcweir         stampURL = OUSTR(
360*cdf0e10cSrcweir             "vnd.sun.star.expand:$UNO_SHARED_PACKAGES_CACHE/stamp.sys");
361*cdf0e10cSrcweir     }
362*cdf0e10cSrcweir     else if (context.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("bundled") )) {
363*cdf0e10cSrcweir         that->m_activePackages = OUSTR(
364*cdf0e10cSrcweir             "vnd.sun.star.expand:$BUNDLED_EXTENSIONS");
365*cdf0e10cSrcweir         that->m_registrationData = OUSTR(
366*cdf0e10cSrcweir             "vnd.sun.star.expand:$BUNDLED_EXTENSIONS_USER");
367*cdf0e10cSrcweir         that->m_registryCache = OUSTR(
368*cdf0e10cSrcweir             "vnd.sun.star.expand:$BUNDLED_EXTENSIONS_USER/registry");
369*cdf0e10cSrcweir         logFile = OUSTR(
370*cdf0e10cSrcweir             "vnd.sun.star.expand:$BUNDLED_EXTENSIONS_USER/log.txt");
371*cdf0e10cSrcweir         //No stamp file. We assume that bundled is always readonly. It must not be
372*cdf0e10cSrcweir         //modified from ExtensionManager but only by the installer
373*cdf0e10cSrcweir     }
374*cdf0e10cSrcweir     else if (context.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("bundled_prereg") )) {
375*cdf0e10cSrcweir         //This is a bundled repository but the registration data
376*cdf0e10cSrcweir         //is in the brand layer: share/prereg
377*cdf0e10cSrcweir         //It is special because the registration data are copied at the first startup
378*cdf0e10cSrcweir         //into the user installation. The processed help and xcu files are not
379*cdf0e10cSrcweir         //copied. Instead the backenddb.xml for the help backend references the help
380*cdf0e10cSrcweir         //by using $BUNDLED_EXTENSION_PREREG instead $BUNDLED_EXTENSIONS_USER. The
381*cdf0e10cSrcweir         //configmgr.ini also used $BUNDLED_EXTENSIONS_PREREG to refer to the xcu file
382*cdf0e10cSrcweir         //which contain the replacement for %origin%.
383*cdf0e10cSrcweir         that->m_activePackages = OUSTR(
384*cdf0e10cSrcweir             "vnd.sun.star.expand:$BUNDLED_EXTENSIONS");
385*cdf0e10cSrcweir         that->m_registrationData = OUSTR(
386*cdf0e10cSrcweir             "vnd.sun.star.expand:$BUNDLED_EXTENSIONS_PREREG");
387*cdf0e10cSrcweir         that->m_registryCache = OUSTR(
388*cdf0e10cSrcweir             "vnd.sun.star.expand:$BUNDLED_EXTENSIONS_PREREG/registry");
389*cdf0e10cSrcweir         logFile = OUSTR(
390*cdf0e10cSrcweir             "vnd.sun.star.expand:$BUNDLED_EXTENSIONS_PREREG/log.txt");
391*cdf0e10cSrcweir     }
392*cdf0e10cSrcweir     else if (context.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("tmp") )) {
393*cdf0e10cSrcweir         that->m_activePackages = OUSTR(
394*cdf0e10cSrcweir             "vnd.sun.star.expand:$TMP_EXTENSIONS/extensions");
395*cdf0e10cSrcweir         that->m_registrationData = OUSTR(
396*cdf0e10cSrcweir             "vnd.sun.star.expand:$TMP_EXTENSIONS");
397*cdf0e10cSrcweir         that->m_registryCache = OUSTR(
398*cdf0e10cSrcweir             "vnd.sun.star.expand:$TMP_EXTENSIONS/registry");
399*cdf0e10cSrcweir         stampURL = OUSTR(
400*cdf0e10cSrcweir             "vnd.sun.star.expand:$TMP_EXTENSIONS/stamp.sys");
401*cdf0e10cSrcweir     }
402*cdf0e10cSrcweir     else if (! context.matchAsciiL(
403*cdf0e10cSrcweir                  RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.tdoc:/") )) {
404*cdf0e10cSrcweir         throw lang::IllegalArgumentException(
405*cdf0e10cSrcweir             OUSTR("invalid context given: ") + context,
406*cdf0e10cSrcweir             Reference<XInterface>(), static_cast<sal_Int16>(-1) );
407*cdf0e10cSrcweir     }
408*cdf0e10cSrcweir 
409*cdf0e10cSrcweir     Reference<XCommandEnvironment> xCmdEnv;
410*cdf0e10cSrcweir 
411*cdf0e10cSrcweir     try {
412*cdf0e10cSrcweir         //There is no stampURL for the bundled folder
413*cdf0e10cSrcweir         if (stampURL.getLength() > 0)
414*cdf0e10cSrcweir         {
415*cdf0e10cSrcweir #define CURRENT_STAMP "1"
416*cdf0e10cSrcweir             try {
417*cdf0e10cSrcweir                 //The osl file API does not allow to find out if one can write
418*cdf0e10cSrcweir                 //into a folder. Therefore we try to write a file. Then we delete
419*cdf0e10cSrcweir                 //it, so that it does not hinder uninstallation of OOo
420*cdf0e10cSrcweir                 // probe writing:
421*cdf0e10cSrcweir                 ::ucbhelper::Content ucbStamp( stampURL, xCmdEnv );
422*cdf0e10cSrcweir                 ::rtl::OString stamp(
423*cdf0e10cSrcweir                     RTL_CONSTASCII_STRINGPARAM(CURRENT_STAMP) );
424*cdf0e10cSrcweir                 Reference<io::XInputStream> xData(
425*cdf0e10cSrcweir                     ::xmlscript::createInputStream(
426*cdf0e10cSrcweir                         ::rtl::ByteSequence(
427*cdf0e10cSrcweir                             reinterpret_cast<sal_Int8 const *>(stamp.getStr()),
428*cdf0e10cSrcweir                             stamp.getLength() ) ) );
429*cdf0e10cSrcweir                 ucbStamp.writeStream( xData, true /* replace existing */ );
430*cdf0e10cSrcweir                 that->m_readOnly = false;
431*cdf0e10cSrcweir                 erase_path( stampURL, xCmdEnv );
432*cdf0e10cSrcweir             }
433*cdf0e10cSrcweir             catch (RuntimeException &) {
434*cdf0e10cSrcweir                 try {
435*cdf0e10cSrcweir                     erase_path( stampURL, xCmdEnv );
436*cdf0e10cSrcweir                 } catch (...)
437*cdf0e10cSrcweir                 {
438*cdf0e10cSrcweir                 }
439*cdf0e10cSrcweir                 throw;
440*cdf0e10cSrcweir             }
441*cdf0e10cSrcweir             catch (Exception &) {
442*cdf0e10cSrcweir                 that->m_readOnly = true;
443*cdf0e10cSrcweir             }
444*cdf0e10cSrcweir         }
445*cdf0e10cSrcweir 
446*cdf0e10cSrcweir         if (!that->m_readOnly && logFile.getLength() > 0)
447*cdf0e10cSrcweir         {
448*cdf0e10cSrcweir             const Any any_logFile(logFile);
449*cdf0e10cSrcweir             that->m_xLogFile.set(
450*cdf0e10cSrcweir                 that->m_xComponentContext->getServiceManager()
451*cdf0e10cSrcweir                 ->createInstanceWithArgumentsAndContext(
452*cdf0e10cSrcweir                     dp_log::serviceDecl.getSupportedServiceNames()[0],
453*cdf0e10cSrcweir                     Sequence<Any>( &any_logFile, 1 ),
454*cdf0e10cSrcweir                     that->m_xComponentContext ),
455*cdf0e10cSrcweir                 UNO_QUERY_THROW );
456*cdf0e10cSrcweir             xCmdEnv.set( new CmdEnvWrapperImpl( xCmdEnv, that->m_xLogFile ) );
457*cdf0e10cSrcweir         }
458*cdf0e10cSrcweir 
459*cdf0e10cSrcweir         that->initRegistryBackends();
460*cdf0e10cSrcweir         that->initActivationLayer( xCmdEnv );
461*cdf0e10cSrcweir 
462*cdf0e10cSrcweir         return xPackageManager;
463*cdf0e10cSrcweir 
464*cdf0e10cSrcweir     }
465*cdf0e10cSrcweir     catch (RuntimeException &) {
466*cdf0e10cSrcweir         throw;
467*cdf0e10cSrcweir     }
468*cdf0e10cSrcweir     catch (Exception &) {
469*cdf0e10cSrcweir         Any exc( ::cppu::getCaughtException() );
470*cdf0e10cSrcweir         ::rtl::OUStringBuffer buf;
471*cdf0e10cSrcweir         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[context=\"") );
472*cdf0e10cSrcweir         buf.append( context );
473*cdf0e10cSrcweir         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
474*cdf0e10cSrcweir                              "\"] caught unexpected exception!") );
475*cdf0e10cSrcweir         throw lang::WrappedTargetRuntimeException(
476*cdf0e10cSrcweir             buf.makeStringAndClear(), Reference<XInterface>(), exc );
477*cdf0e10cSrcweir     }
478*cdf0e10cSrcweir }
479*cdf0e10cSrcweir 
480*cdf0e10cSrcweir //______________________________________________________________________________
481*cdf0e10cSrcweir PackageManagerImpl::~PackageManagerImpl()
482*cdf0e10cSrcweir {
483*cdf0e10cSrcweir }
484*cdf0e10cSrcweir 
485*cdf0e10cSrcweir //______________________________________________________________________________
486*cdf0e10cSrcweir void PackageManagerImpl::fireModified()
487*cdf0e10cSrcweir {
488*cdf0e10cSrcweir     ::cppu::OInterfaceContainerHelper * pContainer = rBHelper.getContainer(
489*cdf0e10cSrcweir         util::XModifyListener::static_type() );
490*cdf0e10cSrcweir     if (pContainer != 0) {
491*cdf0e10cSrcweir         pContainer->forEach<util::XModifyListener>(
492*cdf0e10cSrcweir             boost::bind(&util::XModifyListener::modified, _1,
493*cdf0e10cSrcweir                         lang::EventObject(static_cast<OWeakObject *>(this))) );
494*cdf0e10cSrcweir     }
495*cdf0e10cSrcweir }
496*cdf0e10cSrcweir 
497*cdf0e10cSrcweir //______________________________________________________________________________
498*cdf0e10cSrcweir void PackageManagerImpl::disposing()
499*cdf0e10cSrcweir {
500*cdf0e10cSrcweir     try {
501*cdf0e10cSrcweir //     // xxx todo: guarding?
502*cdf0e10cSrcweir //     ::osl::MutexGuard guard( getMutex() );
503*cdf0e10cSrcweir         try_dispose( m_xLogFile );
504*cdf0e10cSrcweir         m_xLogFile.clear();
505*cdf0e10cSrcweir         try_dispose( m_xRegistry );
506*cdf0e10cSrcweir         m_xRegistry.clear();
507*cdf0e10cSrcweir         m_activePackagesDB.reset(0);
508*cdf0e10cSrcweir         m_xComponentContext.clear();
509*cdf0e10cSrcweir 
510*cdf0e10cSrcweir         t_pm_helper::disposing();
511*cdf0e10cSrcweir 
512*cdf0e10cSrcweir     }
513*cdf0e10cSrcweir     catch (RuntimeException &) {
514*cdf0e10cSrcweir         throw;
515*cdf0e10cSrcweir     }
516*cdf0e10cSrcweir     catch (Exception &) {
517*cdf0e10cSrcweir         Any exc( ::cppu::getCaughtException() );
518*cdf0e10cSrcweir         throw lang::WrappedTargetRuntimeException(
519*cdf0e10cSrcweir             OUSTR("caught unexpected exception while disposing..."),
520*cdf0e10cSrcweir             static_cast<OWeakObject *>(this), exc );
521*cdf0e10cSrcweir     }
522*cdf0e10cSrcweir }
523*cdf0e10cSrcweir 
524*cdf0e10cSrcweir // XComponent
525*cdf0e10cSrcweir //______________________________________________________________________________
526*cdf0e10cSrcweir void PackageManagerImpl::dispose() throw (RuntimeException)
527*cdf0e10cSrcweir {
528*cdf0e10cSrcweir     check();
529*cdf0e10cSrcweir     WeakComponentImplHelperBase::dispose();
530*cdf0e10cSrcweir }
531*cdf0e10cSrcweir 
532*cdf0e10cSrcweir //______________________________________________________________________________
533*cdf0e10cSrcweir void PackageManagerImpl::addEventListener(
534*cdf0e10cSrcweir     Reference<lang::XEventListener> const & xListener ) throw (RuntimeException)
535*cdf0e10cSrcweir {
536*cdf0e10cSrcweir     check();
537*cdf0e10cSrcweir     WeakComponentImplHelperBase::addEventListener( xListener );
538*cdf0e10cSrcweir }
539*cdf0e10cSrcweir 
540*cdf0e10cSrcweir //______________________________________________________________________________
541*cdf0e10cSrcweir void PackageManagerImpl::removeEventListener(
542*cdf0e10cSrcweir     Reference<lang::XEventListener> const & xListener ) throw (RuntimeException)
543*cdf0e10cSrcweir {
544*cdf0e10cSrcweir     check();
545*cdf0e10cSrcweir     WeakComponentImplHelperBase::removeEventListener( xListener );
546*cdf0e10cSrcweir }
547*cdf0e10cSrcweir 
548*cdf0e10cSrcweir // XPackageManager
549*cdf0e10cSrcweir //______________________________________________________________________________
550*cdf0e10cSrcweir OUString PackageManagerImpl::getContext() throw (RuntimeException)
551*cdf0e10cSrcweir {
552*cdf0e10cSrcweir     check();
553*cdf0e10cSrcweir     return m_context;
554*cdf0e10cSrcweir }
555*cdf0e10cSrcweir 
556*cdf0e10cSrcweir //______________________________________________________________________________
557*cdf0e10cSrcweir Sequence< Reference<deployment::XPackageTypeInfo> >
558*cdf0e10cSrcweir PackageManagerImpl::getSupportedPackageTypes() throw (RuntimeException)
559*cdf0e10cSrcweir {
560*cdf0e10cSrcweir     OSL_ASSERT( m_xRegistry.is() );
561*cdf0e10cSrcweir     return m_xRegistry->getSupportedPackageTypes();
562*cdf0e10cSrcweir }
563*cdf0e10cSrcweir 
564*cdf0e10cSrcweir //______________________________________________________________________________
565*cdf0e10cSrcweir Reference<task::XAbortChannel> PackageManagerImpl::createAbortChannel()
566*cdf0e10cSrcweir     throw (RuntimeException)
567*cdf0e10cSrcweir {
568*cdf0e10cSrcweir     check();
569*cdf0e10cSrcweir     return new AbortChannel;
570*cdf0e10cSrcweir }
571*cdf0e10cSrcweir 
572*cdf0e10cSrcweir // XModifyBroadcaster
573*cdf0e10cSrcweir //______________________________________________________________________________
574*cdf0e10cSrcweir void PackageManagerImpl::addModifyListener(
575*cdf0e10cSrcweir     Reference<util::XModifyListener> const & xListener )
576*cdf0e10cSrcweir     throw (RuntimeException)
577*cdf0e10cSrcweir {
578*cdf0e10cSrcweir     check();
579*cdf0e10cSrcweir     rBHelper.addListener( ::getCppuType( &xListener ), xListener );
580*cdf0e10cSrcweir }
581*cdf0e10cSrcweir 
582*cdf0e10cSrcweir //______________________________________________________________________________
583*cdf0e10cSrcweir void PackageManagerImpl::removeModifyListener(
584*cdf0e10cSrcweir     Reference<util::XModifyListener> const & xListener )
585*cdf0e10cSrcweir     throw (RuntimeException)
586*cdf0e10cSrcweir {
587*cdf0e10cSrcweir     check();
588*cdf0e10cSrcweir     rBHelper.removeListener( ::getCppuType( &xListener ), xListener );
589*cdf0e10cSrcweir }
590*cdf0e10cSrcweir 
591*cdf0e10cSrcweir //______________________________________________________________________________
592*cdf0e10cSrcweir OUString PackageManagerImpl::detectMediaType(
593*cdf0e10cSrcweir     ::ucbhelper::Content const & ucbContent_, bool throw_exc )
594*cdf0e10cSrcweir {
595*cdf0e10cSrcweir     ::ucbhelper::Content ucbContent(ucbContent_);
596*cdf0e10cSrcweir     OUString url( ucbContent.getURL() );
597*cdf0e10cSrcweir     OUString mediaType;
598*cdf0e10cSrcweir     if (url.matchAsciiL( RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.tdoc:") ) ||
599*cdf0e10cSrcweir         url.matchAsciiL( RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.pkg:") ))
600*cdf0e10cSrcweir     {
601*cdf0e10cSrcweir         try {
602*cdf0e10cSrcweir             ucbContent.getPropertyValue( OUSTR("MediaType") ) >>= mediaType;
603*cdf0e10cSrcweir         }
604*cdf0e10cSrcweir         catch (beans::UnknownPropertyException &) {
605*cdf0e10cSrcweir         }
606*cdf0e10cSrcweir         OSL_ENSURE( mediaType.getLength() > 0, "### no media-type?!" );
607*cdf0e10cSrcweir     }
608*cdf0e10cSrcweir     if (mediaType.getLength() == 0)
609*cdf0e10cSrcweir     {
610*cdf0e10cSrcweir         try {
611*cdf0e10cSrcweir             Reference<deployment::XPackage> xPackage(
612*cdf0e10cSrcweir                 m_xRegistry->bindPackage(
613*cdf0e10cSrcweir                     url, OUString(), false, OUString(), ucbContent.getCommandEnvironment() ) );
614*cdf0e10cSrcweir             const Reference<deployment::XPackageTypeInfo> xPackageType(
615*cdf0e10cSrcweir                 xPackage->getPackageType() );
616*cdf0e10cSrcweir             OSL_ASSERT( xPackageType.is() );
617*cdf0e10cSrcweir             if (xPackageType.is())
618*cdf0e10cSrcweir                 mediaType = xPackageType->getMediaType();
619*cdf0e10cSrcweir         }
620*cdf0e10cSrcweir         catch (lang::IllegalArgumentException & exc) {
621*cdf0e10cSrcweir             if (throw_exc)
622*cdf0e10cSrcweir                 throw;
623*cdf0e10cSrcweir             (void) exc;
624*cdf0e10cSrcweir             OSL_ENSURE( 0, ::rtl::OUStringToOString(
625*cdf0e10cSrcweir                             exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
626*cdf0e10cSrcweir         }
627*cdf0e10cSrcweir     }
628*cdf0e10cSrcweir     return mediaType;
629*cdf0e10cSrcweir }
630*cdf0e10cSrcweir 
631*cdf0e10cSrcweir //______________________________________________________________________________
632*cdf0e10cSrcweir OUString PackageManagerImpl::insertToActivationLayer(
633*cdf0e10cSrcweir     Sequence<beans::NamedValue> const & properties,
634*cdf0e10cSrcweir     OUString const & mediaType, ::ucbhelper::Content const & sourceContent_,
635*cdf0e10cSrcweir     OUString const & title, ActivePackages::Data * dbData )
636*cdf0e10cSrcweir {
637*cdf0e10cSrcweir     ::ucbhelper::Content sourceContent(sourceContent_);
638*cdf0e10cSrcweir     Reference<XCommandEnvironment> xCmdEnv(
639*cdf0e10cSrcweir         sourceContent.getCommandEnvironment() );
640*cdf0e10cSrcweir 
641*cdf0e10cSrcweir     String baseDir(m_activePackages_expanded);
642*cdf0e10cSrcweir     ::utl::TempFile aTemp(&baseDir, sal_False);
643*cdf0e10cSrcweir     OUString tempEntry = aTemp.GetURL();
644*cdf0e10cSrcweir     tempEntry = tempEntry.copy(tempEntry.lastIndexOf('/') + 1);
645*cdf0e10cSrcweir     OUString destFolder = makeURL( m_activePackages, tempEntry);
646*cdf0e10cSrcweir     destFolder += OUSTR("_");
647*cdf0e10cSrcweir 
648*cdf0e10cSrcweir     // prepare activation folder:
649*cdf0e10cSrcweir     ::ucbhelper::Content destFolderContent;
650*cdf0e10cSrcweir     create_folder( &destFolderContent, destFolder, xCmdEnv );
651*cdf0e10cSrcweir 
652*cdf0e10cSrcweir     // copy content into activation temp dir:
653*cdf0e10cSrcweir     if (mediaType.matchIgnoreAsciiCaseAsciiL(
654*cdf0e10cSrcweir             RTL_CONSTASCII_STRINGPARAM(
655*cdf0e10cSrcweir                 "application/vnd.sun.star.package-bundle") ) ||
656*cdf0e10cSrcweir         // xxx todo: more sophisticated parsing
657*cdf0e10cSrcweir         mediaType.matchIgnoreAsciiCaseAsciiL(
658*cdf0e10cSrcweir             RTL_CONSTASCII_STRINGPARAM(
659*cdf0e10cSrcweir                 "application/vnd.sun.star.legacy-package-bundle") ))
660*cdf0e10cSrcweir     {
661*cdf0e10cSrcweir         // inflate content:
662*cdf0e10cSrcweir         ::rtl::OUStringBuffer buf;
663*cdf0e10cSrcweir         if (!sourceContent.isFolder())
664*cdf0e10cSrcweir         {
665*cdf0e10cSrcweir             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.zip://") );
666*cdf0e10cSrcweir             buf.append( ::rtl::Uri::encode( sourceContent.getURL(),
667*cdf0e10cSrcweir                                             rtl_UriCharClassRegName,
668*cdf0e10cSrcweir                                             rtl_UriEncodeIgnoreEscapes,
669*cdf0e10cSrcweir                                             RTL_TEXTENCODING_UTF8 ) );
670*cdf0e10cSrcweir         }
671*cdf0e10cSrcweir         else
672*cdf0e10cSrcweir         {
673*cdf0e10cSrcweir             //Folder. No need to unzip, just copy
674*cdf0e10cSrcweir             buf.append(sourceContent.getURL());
675*cdf0e10cSrcweir         }
676*cdf0e10cSrcweir         buf.append( static_cast<sal_Unicode>('/') );
677*cdf0e10cSrcweir         sourceContent = ::ucbhelper::Content(
678*cdf0e10cSrcweir             buf.makeStringAndClear(), xCmdEnv );
679*cdf0e10cSrcweir     }
680*cdf0e10cSrcweir     if (! destFolderContent.transferContent(
681*cdf0e10cSrcweir             sourceContent, ::ucbhelper::InsertOperation_COPY,
682*cdf0e10cSrcweir             title, NameClash::OVERWRITE ))
683*cdf0e10cSrcweir         throw RuntimeException( OUSTR("UCB transferContent() failed!"), 0 );
684*cdf0e10cSrcweir 
685*cdf0e10cSrcweir 
686*cdf0e10cSrcweir     // write to DB:
687*cdf0e10cSrcweir     //bundled extensions should only be added by the synchronizeAddedExtensions
688*cdf0e10cSrcweir     //functions. Moreover, there is no "temporary folder" for bundled extensions.
689*cdf0e10cSrcweir     OSL_ASSERT(!m_context.equals(OUSTR("bundled")));
690*cdf0e10cSrcweir     OUString sFolderUrl = makeURLAppendSysPathSegment(destFolderContent.getURL(), title);
691*cdf0e10cSrcweir     DescriptionInfoset info =
692*cdf0e10cSrcweir         dp_misc::getDescriptionInfoset(sFolderUrl);
693*cdf0e10cSrcweir     dbData->temporaryName = tempEntry;
694*cdf0e10cSrcweir     dbData->fileName = title;
695*cdf0e10cSrcweir     dbData->mediaType = mediaType;
696*cdf0e10cSrcweir     dbData->version = info.getVersion();
697*cdf0e10cSrcweir 
698*cdf0e10cSrcweir     //No write the properties file next to the extension
699*cdf0e10cSrcweir     ExtensionProperties props(sFolderUrl, properties, xCmdEnv);
700*cdf0e10cSrcweir     props.write();
701*cdf0e10cSrcweir     return destFolder;
702*cdf0e10cSrcweir }
703*cdf0e10cSrcweir 
704*cdf0e10cSrcweir //______________________________________________________________________________
705*cdf0e10cSrcweir void PackageManagerImpl::insertToActivationLayerDB(
706*cdf0e10cSrcweir     OUString const & id, ActivePackages::Data const & dbData )
707*cdf0e10cSrcweir {
708*cdf0e10cSrcweir     //access to the database must be guarded. See removePackage
709*cdf0e10cSrcweir     const ::osl::MutexGuard guard( getMutex() );
710*cdf0e10cSrcweir     m_activePackagesDB->put( id, dbData );
711*cdf0e10cSrcweir }
712*cdf0e10cSrcweir 
713*cdf0e10cSrcweir //______________________________________________________________________________
714*cdf0e10cSrcweir /* The function returns true if there is an extension with the same id already
715*cdf0e10cSrcweir     installed which needs to be uninstalled, before the new extension can be installed.
716*cdf0e10cSrcweir */
717*cdf0e10cSrcweir bool PackageManagerImpl::isInstalled(
718*cdf0e10cSrcweir     Reference<deployment::XPackage> const & package)
719*cdf0e10cSrcweir {
720*cdf0e10cSrcweir     OUString id(dp_misc::getIdentifier(package));
721*cdf0e10cSrcweir     OUString fn(package->getName());
722*cdf0e10cSrcweir     bool bInstalled = false;
723*cdf0e10cSrcweir     if (m_activePackagesDB->has( id, fn ))
724*cdf0e10cSrcweir     {
725*cdf0e10cSrcweir         bInstalled = true;
726*cdf0e10cSrcweir     }
727*cdf0e10cSrcweir     return bInstalled;
728*cdf0e10cSrcweir }
729*cdf0e10cSrcweir 
730*cdf0e10cSrcweir // XPackageManager
731*cdf0e10cSrcweir //______________________________________________________________________________
732*cdf0e10cSrcweir Reference<deployment::XPackage> PackageManagerImpl::importExtension(
733*cdf0e10cSrcweir     Reference<deployment::XPackage> const & extension,
734*cdf0e10cSrcweir     Reference<task::XAbortChannel> const & xAbortChannel,
735*cdf0e10cSrcweir     Reference<XCommandEnvironment> const & xCmdEnv_ )
736*cdf0e10cSrcweir     throw (deployment::DeploymentException, CommandFailedException,
737*cdf0e10cSrcweir            CommandAbortedException, lang::IllegalArgumentException,
738*cdf0e10cSrcweir            RuntimeException)
739*cdf0e10cSrcweir {
740*cdf0e10cSrcweir     return addPackage(extension->getURL(), Sequence<beans::NamedValue>(),
741*cdf0e10cSrcweir                       OUString(), xAbortChannel, xCmdEnv_);
742*cdf0e10cSrcweir }
743*cdf0e10cSrcweir 
744*cdf0e10cSrcweir /* The function adds an extension but does not register it!!!
745*cdf0e10cSrcweir     It may not do any user interaction. This is done in XExtensionManager::addExtension
746*cdf0e10cSrcweir */
747*cdf0e10cSrcweir Reference<deployment::XPackage> PackageManagerImpl::addPackage(
748*cdf0e10cSrcweir     OUString const & url,
749*cdf0e10cSrcweir     css::uno::Sequence<css::beans::NamedValue> const & properties,
750*cdf0e10cSrcweir     OUString const & mediaType_,
751*cdf0e10cSrcweir     Reference<task::XAbortChannel> const & xAbortChannel,
752*cdf0e10cSrcweir     Reference<XCommandEnvironment> const & xCmdEnv_ )
753*cdf0e10cSrcweir     throw (deployment::DeploymentException, CommandFailedException,
754*cdf0e10cSrcweir            CommandAbortedException, lang::IllegalArgumentException,
755*cdf0e10cSrcweir            RuntimeException)
756*cdf0e10cSrcweir {
757*cdf0e10cSrcweir     check();
758*cdf0e10cSrcweir     if (m_readOnly)
759*cdf0e10cSrcweir 	{
760*cdf0e10cSrcweir 		OUString message;
761*cdf0e10cSrcweir 		if (m_context == OUSTR("shared"))
762*cdf0e10cSrcweir 			message = OUSTR("You need write permissions to install a shared extension!");
763*cdf0e10cSrcweir 		else
764*cdf0e10cSrcweir 			message = OUSTR("You need write permissions to install this extension!");
765*cdf0e10cSrcweir         throw deployment::DeploymentException(
766*cdf0e10cSrcweir             message, static_cast<OWeakObject *>(this), Any() );
767*cdf0e10cSrcweir 	}
768*cdf0e10cSrcweir     Reference<XCommandEnvironment> xCmdEnv;
769*cdf0e10cSrcweir     if (m_xLogFile.is())
770*cdf0e10cSrcweir         xCmdEnv.set( new CmdEnvWrapperImpl( xCmdEnv_, m_xLogFile ) );
771*cdf0e10cSrcweir     else
772*cdf0e10cSrcweir         xCmdEnv.set( xCmdEnv_ );
773*cdf0e10cSrcweir 
774*cdf0e10cSrcweir     try {
775*cdf0e10cSrcweir         ::ucbhelper::Content sourceContent;
776*cdf0e10cSrcweir         create_ucb_content( &sourceContent, url, xCmdEnv ); // throws exc
777*cdf0e10cSrcweir         const OUString title(sourceContent.getPropertyValue(
778*cdf0e10cSrcweir                              StrTitle::get() ).get<OUString>() );
779*cdf0e10cSrcweir         const OUString title_enc( ::rtl::Uri::encode(
780*cdf0e10cSrcweir                                       title, rtl_UriCharClassPchar,
781*cdf0e10cSrcweir                                       rtl_UriEncodeIgnoreEscapes,
782*cdf0e10cSrcweir                                       RTL_TEXTENCODING_UTF8 ) );
783*cdf0e10cSrcweir         OUString destFolder;
784*cdf0e10cSrcweir 
785*cdf0e10cSrcweir         OUString mediaType(mediaType_);
786*cdf0e10cSrcweir         if (mediaType.getLength() == 0)
787*cdf0e10cSrcweir             mediaType = detectMediaType( sourceContent );
788*cdf0e10cSrcweir 
789*cdf0e10cSrcweir         Reference<deployment::XPackage> xPackage;
790*cdf0e10cSrcweir         // copy file:
791*cdf0e10cSrcweir         progressUpdate(
792*cdf0e10cSrcweir             getResourceString(RID_STR_COPYING_PACKAGE) + title, xCmdEnv );
793*cdf0e10cSrcweir         if (m_activePackages.getLength() == 0)
794*cdf0e10cSrcweir         {
795*cdf0e10cSrcweir             ::ucbhelper::Content docFolderContent;
796*cdf0e10cSrcweir             create_folder( &docFolderContent, m_context, xCmdEnv );
797*cdf0e10cSrcweir             // copy into document, first:
798*cdf0e10cSrcweir             if (! docFolderContent.transferContent(
799*cdf0e10cSrcweir                     sourceContent, ::ucbhelper::InsertOperation_COPY,
800*cdf0e10cSrcweir                     OUString(),
801*cdf0e10cSrcweir                     NameClash::ASK /* xxx todo: ASK not needed? */))
802*cdf0e10cSrcweir                 throw RuntimeException(
803*cdf0e10cSrcweir                     OUSTR("UCB transferContent() failed!"), 0 );
804*cdf0e10cSrcweir             // set media-type:
805*cdf0e10cSrcweir             ::ucbhelper::Content docContent(
806*cdf0e10cSrcweir                 makeURL( m_context, title_enc ), xCmdEnv );
807*cdf0e10cSrcweir                 //TODO #i73136#: using title instead of id can lead to
808*cdf0e10cSrcweir                 // clashes, but the whole m_activePackages.getLength()==0
809*cdf0e10cSrcweir                 // case (i.e., document-relative deployment) currently does
810*cdf0e10cSrcweir                 // not work, anyway.
811*cdf0e10cSrcweir             docContent.setPropertyValue(
812*cdf0e10cSrcweir                 OUSTR("MediaType"), Any(mediaType) );
813*cdf0e10cSrcweir 
814*cdf0e10cSrcweir             // xxx todo: obsolete in the future
815*cdf0e10cSrcweir             try {
816*cdf0e10cSrcweir                 docFolderContent.executeCommand( OUSTR("flush"), Any() );
817*cdf0e10cSrcweir             }
818*cdf0e10cSrcweir             catch (UnsupportedCommandException &) {
819*cdf0e10cSrcweir             }
820*cdf0e10cSrcweir         }
821*cdf0e10cSrcweir         ActivePackages::Data dbData;
822*cdf0e10cSrcweir         destFolder = insertToActivationLayer(
823*cdf0e10cSrcweir             properties, mediaType, sourceContent, title, &dbData );
824*cdf0e10cSrcweir 
825*cdf0e10cSrcweir 
826*cdf0e10cSrcweir         // bind activation package:
827*cdf0e10cSrcweir         //Because every shared/user extension will be unpacked in a folder,
828*cdf0e10cSrcweir         //which was created with a unique name we will always have two different
829*cdf0e10cSrcweir         //XPackage objects, even if the second extension is the same.
830*cdf0e10cSrcweir         //Therefore bindPackage does not need a guard here.
831*cdf0e10cSrcweir         xPackage = m_xRegistry->bindPackage(
832*cdf0e10cSrcweir             makeURL( destFolder, title_enc ), mediaType, false, OUString(), xCmdEnv );
833*cdf0e10cSrcweir 
834*cdf0e10cSrcweir         OSL_ASSERT( xPackage.is() );
835*cdf0e10cSrcweir         if (xPackage.is())
836*cdf0e10cSrcweir         {
837*cdf0e10cSrcweir             bool install = false;
838*cdf0e10cSrcweir             try
839*cdf0e10cSrcweir             {
840*cdf0e10cSrcweir                 OUString const id = dp_misc::getIdentifier( xPackage );
841*cdf0e10cSrcweir 
842*cdf0e10cSrcweir                 ::osl::MutexGuard g(m_addMutex);
843*cdf0e10cSrcweir                 if (isInstalled(xPackage))
844*cdf0e10cSrcweir                 {
845*cdf0e10cSrcweir                     //Do not guard the complete function with the getMutex
846*cdf0e10cSrcweir                     removePackage(id, xPackage->getName(), xAbortChannel,
847*cdf0e10cSrcweir                                   xCmdEnv);
848*cdf0e10cSrcweir                 }
849*cdf0e10cSrcweir                 install = true;
850*cdf0e10cSrcweir                 insertToActivationLayerDB(id, dbData);
851*cdf0e10cSrcweir             }
852*cdf0e10cSrcweir             catch (...)
853*cdf0e10cSrcweir             {
854*cdf0e10cSrcweir                 deletePackageFromCache( xPackage, destFolder );
855*cdf0e10cSrcweir                 throw;
856*cdf0e10cSrcweir             }
857*cdf0e10cSrcweir             if (!install)
858*cdf0e10cSrcweir             {
859*cdf0e10cSrcweir                 deletePackageFromCache( xPackage, destFolder );
860*cdf0e10cSrcweir             }
861*cdf0e10cSrcweir             //ToDo: We should notify only if the extension is registered
862*cdf0e10cSrcweir             fireModified();
863*cdf0e10cSrcweir         }
864*cdf0e10cSrcweir         return xPackage;
865*cdf0e10cSrcweir     }
866*cdf0e10cSrcweir     catch (RuntimeException &) {
867*cdf0e10cSrcweir         throw;
868*cdf0e10cSrcweir     }
869*cdf0e10cSrcweir     catch (CommandFailedException & exc) {
870*cdf0e10cSrcweir         logIntern( Any(exc) );
871*cdf0e10cSrcweir         throw;
872*cdf0e10cSrcweir     }
873*cdf0e10cSrcweir     catch (CommandAbortedException & exc) {
874*cdf0e10cSrcweir         logIntern( Any(exc) );
875*cdf0e10cSrcweir         throw;
876*cdf0e10cSrcweir     }
877*cdf0e10cSrcweir     catch (deployment::DeploymentException & exc) {
878*cdf0e10cSrcweir         logIntern( Any(exc) );
879*cdf0e10cSrcweir         throw;
880*cdf0e10cSrcweir     }
881*cdf0e10cSrcweir     catch (Exception &) {
882*cdf0e10cSrcweir         Any exc( ::cppu::getCaughtException() );
883*cdf0e10cSrcweir         logIntern( exc );
884*cdf0e10cSrcweir         throw deployment::DeploymentException(
885*cdf0e10cSrcweir             getResourceString(RID_STR_ERROR_WHILE_ADDING) + url,
886*cdf0e10cSrcweir             static_cast<OWeakObject *>(this), exc );
887*cdf0e10cSrcweir     }
888*cdf0e10cSrcweir }
889*cdf0e10cSrcweir void PackageManagerImpl::deletePackageFromCache(
890*cdf0e10cSrcweir     Reference<deployment::XPackage> const & xPackage,
891*cdf0e10cSrcweir     OUString const & destFolder)
892*cdf0e10cSrcweir {
893*cdf0e10cSrcweir     try_dispose( xPackage );
894*cdf0e10cSrcweir 
895*cdf0e10cSrcweir 	//we remove the package from the uno cache
896*cdf0e10cSrcweir 	//no service from the package may be loaded at this time!!!
897*cdf0e10cSrcweir 	erase_path( destFolder, Reference<XCommandEnvironment>(),
898*cdf0e10cSrcweir         false /* no throw: ignore errors */ );
899*cdf0e10cSrcweir 	//rm last character '_'
900*cdf0e10cSrcweir 	OUString url = destFolder.copy(0, destFolder.getLength() - 1);
901*cdf0e10cSrcweir 	erase_path( url, Reference<XCommandEnvironment>(),
902*cdf0e10cSrcweir         false /* no throw: ignore errors */ );
903*cdf0e10cSrcweir 
904*cdf0e10cSrcweir }
905*cdf0e10cSrcweir //______________________________________________________________________________
906*cdf0e10cSrcweir void PackageManagerImpl::removePackage(
907*cdf0e10cSrcweir     OUString const & id, ::rtl::OUString const & fileName,
908*cdf0e10cSrcweir     Reference<task::XAbortChannel> const & /*xAbortChannel*/,
909*cdf0e10cSrcweir     Reference<XCommandEnvironment> const & xCmdEnv_ )
910*cdf0e10cSrcweir     throw (deployment::DeploymentException, CommandFailedException,
911*cdf0e10cSrcweir            CommandAbortedException, lang::IllegalArgumentException,
912*cdf0e10cSrcweir            RuntimeException)
913*cdf0e10cSrcweir {
914*cdf0e10cSrcweir     check();
915*cdf0e10cSrcweir 
916*cdf0e10cSrcweir     Reference<XCommandEnvironment> xCmdEnv;
917*cdf0e10cSrcweir     if (m_xLogFile.is())
918*cdf0e10cSrcweir         xCmdEnv.set( new CmdEnvWrapperImpl( xCmdEnv_, m_xLogFile ) );
919*cdf0e10cSrcweir     else
920*cdf0e10cSrcweir         xCmdEnv.set( xCmdEnv_ );
921*cdf0e10cSrcweir 
922*cdf0e10cSrcweir     try {
923*cdf0e10cSrcweir         Reference<deployment::XPackage> xPackage;
924*cdf0e10cSrcweir         {
925*cdf0e10cSrcweir             const ::osl::MutexGuard guard(getMutex());
926*cdf0e10cSrcweir             //Check if this extension exist and throw an IllegalArgumentException
927*cdf0e10cSrcweir             //if it does not
928*cdf0e10cSrcweir             //If the files of the extension are already removed, or there is a
929*cdf0e10cSrcweir             //different extension at the same place, for example after updating the
930*cdf0e10cSrcweir             //extension, then the returned object is that which uses the database data.
931*cdf0e10cSrcweir             xPackage = getDeployedPackage_(id, fileName, xCmdEnv );
932*cdf0e10cSrcweir 
933*cdf0e10cSrcweir 
934*cdf0e10cSrcweir             //Because the extension is only removed the next time the extension
935*cdf0e10cSrcweir             //manager runs after restarting OOo, we need to indicate that a
936*cdf0e10cSrcweir             //shared extension was "deleted". When a user starts OOo, then it
937*cdf0e10cSrcweir             //will check if something changed in the shared repository. Based on
938*cdf0e10cSrcweir             //the flag file it will then recognize, that the extension was
939*cdf0e10cSrcweir             //deleted and can then update the extnesion database of the shared
940*cdf0e10cSrcweir             //extensions in the user installation.
941*cdf0e10cSrcweir             if ( xPackage.is() && !m_readOnly && !xPackage->isRemoved() && m_context.equals(OUSTR("shared")))
942*cdf0e10cSrcweir             {
943*cdf0e10cSrcweir                 ActivePackages::Data val;
944*cdf0e10cSrcweir                 m_activePackagesDB->get( & val, id, fileName);
945*cdf0e10cSrcweir                 OSL_ASSERT(val.temporaryName.getLength());
946*cdf0e10cSrcweir                 OUString url(makeURL(m_activePackages_expanded,
947*cdf0e10cSrcweir                                      val.temporaryName + OUSTR("removed")));
948*cdf0e10cSrcweir                 ::ucbhelper::Content contentRemoved(url, xCmdEnv );
949*cdf0e10cSrcweir                 OUString aUserName;
950*cdf0e10cSrcweir                 ::osl::Security aSecurity;
951*cdf0e10cSrcweir                 aSecurity.getUserName( aUserName );
952*cdf0e10cSrcweir 
953*cdf0e10cSrcweir                 ::rtl::OString stamp = ::rtl::OUStringToOString(aUserName, RTL_TEXTENCODING_UTF8);
954*cdf0e10cSrcweir                 Reference<css::io::XInputStream> xData(
955*cdf0e10cSrcweir                     ::xmlscript::createInputStream(
956*cdf0e10cSrcweir                         ::rtl::ByteSequence(
957*cdf0e10cSrcweir                             reinterpret_cast<sal_Int8 const *>(stamp.getStr()),
958*cdf0e10cSrcweir                             stamp.getLength() ) ) );
959*cdf0e10cSrcweir                 contentRemoved.writeStream( xData, true /* replace existing */ );
960*cdf0e10cSrcweir             }
961*cdf0e10cSrcweir             m_activePackagesDB->erase( id, fileName ); // to be removed upon next start
962*cdf0e10cSrcweir             //remove any cached data hold by the backend
963*cdf0e10cSrcweir             m_xRegistry->packageRemoved(xPackage->getURL(), xPackage->getPackageType()->getMediaType());
964*cdf0e10cSrcweir         }
965*cdf0e10cSrcweir         try_dispose( xPackage );
966*cdf0e10cSrcweir 
967*cdf0e10cSrcweir         fireModified();
968*cdf0e10cSrcweir     }
969*cdf0e10cSrcweir     catch (RuntimeException &) {
970*cdf0e10cSrcweir         throw;
971*cdf0e10cSrcweir     }
972*cdf0e10cSrcweir     catch (lang::IllegalArgumentException &) {
973*cdf0e10cSrcweir         throw;
974*cdf0e10cSrcweir     }
975*cdf0e10cSrcweir     catch (CommandFailedException & exc) {
976*cdf0e10cSrcweir         logIntern( Any(exc) );
977*cdf0e10cSrcweir         throw;
978*cdf0e10cSrcweir     }
979*cdf0e10cSrcweir     catch (CommandAbortedException & exc) {
980*cdf0e10cSrcweir         logIntern( Any(exc) );
981*cdf0e10cSrcweir         throw;
982*cdf0e10cSrcweir     }
983*cdf0e10cSrcweir     catch (deployment::DeploymentException & exc) {
984*cdf0e10cSrcweir         logIntern( Any(exc) );
985*cdf0e10cSrcweir         throw;
986*cdf0e10cSrcweir     }
987*cdf0e10cSrcweir     catch (Exception &) {
988*cdf0e10cSrcweir         Any exc( ::cppu::getCaughtException() );
989*cdf0e10cSrcweir         logIntern( exc );
990*cdf0e10cSrcweir         throw deployment::DeploymentException(
991*cdf0e10cSrcweir             getResourceString(RID_STR_ERROR_WHILE_REMOVING) + id,
992*cdf0e10cSrcweir             static_cast<OWeakObject *>(this), exc );
993*cdf0e10cSrcweir     }
994*cdf0e10cSrcweir }
995*cdf0e10cSrcweir 
996*cdf0e10cSrcweir //______________________________________________________________________________
997*cdf0e10cSrcweir OUString PackageManagerImpl::getDeployPath( ActivePackages::Data const & data )
998*cdf0e10cSrcweir {
999*cdf0e10cSrcweir     ::rtl::OUStringBuffer buf;
1000*cdf0e10cSrcweir     buf.append( data.temporaryName );
1001*cdf0e10cSrcweir     //The bundled extensions are not contained in an additional folder
1002*cdf0e10cSrcweir     //with a unique name. data.temporaryName contains already the
1003*cdf0e10cSrcweir     //UTF8 encoded folder name. See PackageManagerImpl::synchronize
1004*cdf0e10cSrcweir     if (!m_context.equals(OUSTR("bundled"))
1005*cdf0e10cSrcweir         && !m_context.equals(OUSTR("bundled_prereg")))
1006*cdf0e10cSrcweir     {
1007*cdf0e10cSrcweir         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("_/") );
1008*cdf0e10cSrcweir         buf.append( ::rtl::Uri::encode( data.fileName, rtl_UriCharClassPchar,
1009*cdf0e10cSrcweir                                     rtl_UriEncodeIgnoreEscapes,
1010*cdf0e10cSrcweir                                     RTL_TEXTENCODING_UTF8 ) );
1011*cdf0e10cSrcweir     }
1012*cdf0e10cSrcweir     return makeURL( m_activePackages, buf.makeStringAndClear() );
1013*cdf0e10cSrcweir }
1014*cdf0e10cSrcweir 
1015*cdf0e10cSrcweir //______________________________________________________________________________
1016*cdf0e10cSrcweir Reference<deployment::XPackage> PackageManagerImpl::getDeployedPackage_(
1017*cdf0e10cSrcweir     OUString const & id, OUString const & fileName,
1018*cdf0e10cSrcweir     Reference<XCommandEnvironment> const & xCmdEnv )
1019*cdf0e10cSrcweir {
1020*cdf0e10cSrcweir     ActivePackages::Data val;
1021*cdf0e10cSrcweir     if (m_activePackagesDB->get( &val, id, fileName ))
1022*cdf0e10cSrcweir     {
1023*cdf0e10cSrcweir         return getDeployedPackage_( id, val, xCmdEnv, false );
1024*cdf0e10cSrcweir     }
1025*cdf0e10cSrcweir     throw lang::IllegalArgumentException(
1026*cdf0e10cSrcweir         getResourceString(RID_STR_NO_SUCH_PACKAGE) + id,
1027*cdf0e10cSrcweir         static_cast<OWeakObject *>(this), static_cast<sal_Int16>(-1) );
1028*cdf0e10cSrcweir }
1029*cdf0e10cSrcweir 
1030*cdf0e10cSrcweir //______________________________________________________________________________
1031*cdf0e10cSrcweir Reference<deployment::XPackage> PackageManagerImpl::getDeployedPackage_(
1032*cdf0e10cSrcweir     OUString const & id, ActivePackages::Data const & data,
1033*cdf0e10cSrcweir     Reference<XCommandEnvironment> const & xCmdEnv, bool ignoreAlienPlatforms )
1034*cdf0e10cSrcweir {
1035*cdf0e10cSrcweir     if (ignoreAlienPlatforms)
1036*cdf0e10cSrcweir     {
1037*cdf0e10cSrcweir         String type, subType;
1038*cdf0e10cSrcweir         INetContentTypeParameterList params;
1039*cdf0e10cSrcweir         if (INetContentTypes::parse( data.mediaType, type, subType, &params ))
1040*cdf0e10cSrcweir         {
1041*cdf0e10cSrcweir             INetContentTypeParameter const * param = params.find(
1042*cdf0e10cSrcweir                 ByteString("platform") );
1043*cdf0e10cSrcweir             if (param != 0 && !platform_fits( param->m_sValue ))
1044*cdf0e10cSrcweir                 throw lang::IllegalArgumentException(
1045*cdf0e10cSrcweir                     getResourceString(RID_STR_NO_SUCH_PACKAGE) + id,
1046*cdf0e10cSrcweir                     static_cast<OWeakObject *>(this),
1047*cdf0e10cSrcweir                     static_cast<sal_Int16>(-1) );
1048*cdf0e10cSrcweir         }
1049*cdf0e10cSrcweir     }
1050*cdf0e10cSrcweir     Reference<deployment::XPackage> xExtension;
1051*cdf0e10cSrcweir     try
1052*cdf0e10cSrcweir     {
1053*cdf0e10cSrcweir         //Ignore extensions where XPackage::checkPrerequisites failed.
1054*cdf0e10cSrcweir         //They must not be usable for this user.
1055*cdf0e10cSrcweir         if (data.failedPrerequisites.equals(OUSTR("0")))
1056*cdf0e10cSrcweir         {
1057*cdf0e10cSrcweir             xExtension = m_xRegistry->bindPackage(
1058*cdf0e10cSrcweir                 getDeployPath( data ), data.mediaType, false, OUString(), xCmdEnv );
1059*cdf0e10cSrcweir         }
1060*cdf0e10cSrcweir     }
1061*cdf0e10cSrcweir     catch (deployment::InvalidRemovedParameterException& e)
1062*cdf0e10cSrcweir     {
1063*cdf0e10cSrcweir         xExtension = e.Extension;
1064*cdf0e10cSrcweir     }
1065*cdf0e10cSrcweir     return xExtension;
1066*cdf0e10cSrcweir }
1067*cdf0e10cSrcweir 
1068*cdf0e10cSrcweir //______________________________________________________________________________
1069*cdf0e10cSrcweir Sequence< Reference<deployment::XPackage> >
1070*cdf0e10cSrcweir PackageManagerImpl::getDeployedPackages_(
1071*cdf0e10cSrcweir     Reference<XCommandEnvironment> const & xCmdEnv )
1072*cdf0e10cSrcweir {
1073*cdf0e10cSrcweir     ::std::vector< Reference<deployment::XPackage> > packages;
1074*cdf0e10cSrcweir     ActivePackages::Entries id2temp( m_activePackagesDB->getEntries() );
1075*cdf0e10cSrcweir     ActivePackages::Entries::const_iterator iPos( id2temp.begin() );
1076*cdf0e10cSrcweir     ActivePackages::Entries::const_iterator const iEnd( id2temp.end() );
1077*cdf0e10cSrcweir     for ( ; iPos != iEnd; ++iPos )
1078*cdf0e10cSrcweir     {
1079*cdf0e10cSrcweir         if (! iPos->second.failedPrerequisites.equals(OUSTR("0")))
1080*cdf0e10cSrcweir             continue;
1081*cdf0e10cSrcweir         try {
1082*cdf0e10cSrcweir             packages.push_back(
1083*cdf0e10cSrcweir                 getDeployedPackage_(
1084*cdf0e10cSrcweir                     iPos->first, iPos->second, xCmdEnv,
1085*cdf0e10cSrcweir                     true /* xxx todo: think of GUI:
1086*cdf0e10cSrcweir                             ignore other platforms than the current one */ ) );
1087*cdf0e10cSrcweir         }
1088*cdf0e10cSrcweir         catch (lang::IllegalArgumentException & exc) {
1089*cdf0e10cSrcweir             // ignore
1090*cdf0e10cSrcweir             (void) exc; // avoid warnings
1091*cdf0e10cSrcweir             OSL_ENSURE( 0, ::rtl::OUStringToOString(
1092*cdf0e10cSrcweir                             exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
1093*cdf0e10cSrcweir         }
1094*cdf0e10cSrcweir         catch (deployment::DeploymentException& exc) {
1095*cdf0e10cSrcweir             // ignore
1096*cdf0e10cSrcweir             (void) exc; // avoid warnings
1097*cdf0e10cSrcweir             OSL_ENSURE( 0, ::rtl::OUStringToOString(
1098*cdf0e10cSrcweir                             exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
1099*cdf0e10cSrcweir         }
1100*cdf0e10cSrcweir     }
1101*cdf0e10cSrcweir     return comphelper::containerToSequence(packages);
1102*cdf0e10cSrcweir }
1103*cdf0e10cSrcweir 
1104*cdf0e10cSrcweir //______________________________________________________________________________
1105*cdf0e10cSrcweir Reference<deployment::XPackage> PackageManagerImpl::getDeployedPackage(
1106*cdf0e10cSrcweir     OUString const & id, ::rtl::OUString const & fileName,
1107*cdf0e10cSrcweir     Reference<XCommandEnvironment> const & xCmdEnv_ )
1108*cdf0e10cSrcweir     throw (deployment::DeploymentException, CommandFailedException,
1109*cdf0e10cSrcweir            lang::IllegalArgumentException, RuntimeException)
1110*cdf0e10cSrcweir {
1111*cdf0e10cSrcweir     check();
1112*cdf0e10cSrcweir     Reference<XCommandEnvironment> xCmdEnv;
1113*cdf0e10cSrcweir     if (m_xLogFile.is())
1114*cdf0e10cSrcweir         xCmdEnv.set( new CmdEnvWrapperImpl( xCmdEnv_, m_xLogFile ) );
1115*cdf0e10cSrcweir     else
1116*cdf0e10cSrcweir         xCmdEnv.set( xCmdEnv_ );
1117*cdf0e10cSrcweir 
1118*cdf0e10cSrcweir     try {
1119*cdf0e10cSrcweir         const ::osl::MutexGuard guard( getMutex() );
1120*cdf0e10cSrcweir         return getDeployedPackage_( id, fileName, xCmdEnv );
1121*cdf0e10cSrcweir     }
1122*cdf0e10cSrcweir     catch (RuntimeException &) {
1123*cdf0e10cSrcweir         throw;
1124*cdf0e10cSrcweir     }
1125*cdf0e10cSrcweir     catch (CommandFailedException & exc) {
1126*cdf0e10cSrcweir         logIntern( Any(exc) );
1127*cdf0e10cSrcweir         throw;
1128*cdf0e10cSrcweir     }
1129*cdf0e10cSrcweir     catch (lang::IllegalArgumentException & exc) {
1130*cdf0e10cSrcweir         logIntern( Any(exc) );
1131*cdf0e10cSrcweir         throw;
1132*cdf0e10cSrcweir     }
1133*cdf0e10cSrcweir     catch (deployment::DeploymentException & exc) {
1134*cdf0e10cSrcweir         logIntern( Any(exc) );
1135*cdf0e10cSrcweir         throw;
1136*cdf0e10cSrcweir     }
1137*cdf0e10cSrcweir     catch (Exception &) {
1138*cdf0e10cSrcweir         Any exc( ::cppu::getCaughtException() );
1139*cdf0e10cSrcweir         logIntern( exc );
1140*cdf0e10cSrcweir         throw deployment::DeploymentException(
1141*cdf0e10cSrcweir             // ought never occur...
1142*cdf0e10cSrcweir             OUSTR("error while accessing deployed package: ") + id,
1143*cdf0e10cSrcweir             static_cast<OWeakObject *>(this), exc );
1144*cdf0e10cSrcweir     }
1145*cdf0e10cSrcweir }
1146*cdf0e10cSrcweir 
1147*cdf0e10cSrcweir //______________________________________________________________________________
1148*cdf0e10cSrcweir Sequence< Reference<deployment::XPackage> >
1149*cdf0e10cSrcweir PackageManagerImpl::getDeployedPackages(
1150*cdf0e10cSrcweir     Reference<task::XAbortChannel> const &,
1151*cdf0e10cSrcweir     Reference<XCommandEnvironment> const & xCmdEnv_ )
1152*cdf0e10cSrcweir     throw (deployment::DeploymentException, CommandFailedException,
1153*cdf0e10cSrcweir            CommandAbortedException, lang::IllegalArgumentException,
1154*cdf0e10cSrcweir            RuntimeException)
1155*cdf0e10cSrcweir {
1156*cdf0e10cSrcweir     check();
1157*cdf0e10cSrcweir     Reference<XCommandEnvironment> xCmdEnv;
1158*cdf0e10cSrcweir     if (m_xLogFile.is())
1159*cdf0e10cSrcweir         xCmdEnv.set( new CmdEnvWrapperImpl( xCmdEnv_, m_xLogFile ) );
1160*cdf0e10cSrcweir     else
1161*cdf0e10cSrcweir         xCmdEnv.set( xCmdEnv_ );
1162*cdf0e10cSrcweir 
1163*cdf0e10cSrcweir     try {
1164*cdf0e10cSrcweir         const ::osl::MutexGuard guard( getMutex() );
1165*cdf0e10cSrcweir         return getDeployedPackages_( xCmdEnv );
1166*cdf0e10cSrcweir     }
1167*cdf0e10cSrcweir     catch (RuntimeException &) {
1168*cdf0e10cSrcweir         throw;
1169*cdf0e10cSrcweir     }
1170*cdf0e10cSrcweir     catch (CommandFailedException & exc) {
1171*cdf0e10cSrcweir         logIntern( Any(exc) );
1172*cdf0e10cSrcweir         throw;
1173*cdf0e10cSrcweir     }
1174*cdf0e10cSrcweir     catch (CommandAbortedException & exc) {
1175*cdf0e10cSrcweir         logIntern( Any(exc) );
1176*cdf0e10cSrcweir         throw;
1177*cdf0e10cSrcweir     }
1178*cdf0e10cSrcweir     catch (deployment::DeploymentException & exc) {
1179*cdf0e10cSrcweir         logIntern( Any(exc) );
1180*cdf0e10cSrcweir         throw;
1181*cdf0e10cSrcweir     }
1182*cdf0e10cSrcweir     catch (Exception &) {
1183*cdf0e10cSrcweir         Any exc( ::cppu::getCaughtException() );
1184*cdf0e10cSrcweir         logIntern( exc );
1185*cdf0e10cSrcweir         throw deployment::DeploymentException(
1186*cdf0e10cSrcweir             // ought never occur...
1187*cdf0e10cSrcweir             OUSTR("error while getting all deployed packages: ") + m_context,
1188*cdf0e10cSrcweir             static_cast<OWeakObject *>(this), exc );
1189*cdf0e10cSrcweir     }
1190*cdf0e10cSrcweir }
1191*cdf0e10cSrcweir 
1192*cdf0e10cSrcweir //______________________________________________________________________________
1193*cdf0e10cSrcweir 
1194*cdf0e10cSrcweir 
1195*cdf0e10cSrcweir //ToDo: the function must not call registerPackage, do this in
1196*cdf0e10cSrcweir //XExtensionManager.reinstallDeployedExtensions
1197*cdf0e10cSrcweir void PackageManagerImpl::reinstallDeployedPackages(
1198*cdf0e10cSrcweir     Reference<task::XAbortChannel> const &  /*xAbortChannel*/,
1199*cdf0e10cSrcweir     Reference<XCommandEnvironment> const & xCmdEnv_ )
1200*cdf0e10cSrcweir     throw (deployment::DeploymentException,
1201*cdf0e10cSrcweir            CommandFailedException, CommandAbortedException,
1202*cdf0e10cSrcweir            lang::IllegalArgumentException, RuntimeException)
1203*cdf0e10cSrcweir {
1204*cdf0e10cSrcweir     check();
1205*cdf0e10cSrcweir     if (office_is_running())
1206*cdf0e10cSrcweir         throw RuntimeException(
1207*cdf0e10cSrcweir             OUSTR("You must close any running Office process before "
1208*cdf0e10cSrcweir                   "reinstalling packages!"), static_cast<OWeakObject *>(this) );
1209*cdf0e10cSrcweir 
1210*cdf0e10cSrcweir     Reference<XCommandEnvironment> xCmdEnv;
1211*cdf0e10cSrcweir     if (m_xLogFile.is())
1212*cdf0e10cSrcweir         xCmdEnv.set( new CmdEnvWrapperImpl( xCmdEnv_, m_xLogFile ) );
1213*cdf0e10cSrcweir     else
1214*cdf0e10cSrcweir         xCmdEnv.set( xCmdEnv_ );
1215*cdf0e10cSrcweir 
1216*cdf0e10cSrcweir     try {
1217*cdf0e10cSrcweir         ProgressLevel progress(
1218*cdf0e10cSrcweir             xCmdEnv, OUSTR("Reinstalling all deployed packages...") );
1219*cdf0e10cSrcweir 
1220*cdf0e10cSrcweir         try_dispose( m_xRegistry );
1221*cdf0e10cSrcweir         m_xRegistry.clear();
1222*cdf0e10cSrcweir         if (m_registryCache.getLength() > 0)
1223*cdf0e10cSrcweir             erase_path( m_registryCache, xCmdEnv );
1224*cdf0e10cSrcweir         initRegistryBackends();
1225*cdf0e10cSrcweir         Reference<util::XUpdatable> xUpdatable( m_xRegistry, UNO_QUERY );
1226*cdf0e10cSrcweir         if (xUpdatable.is())
1227*cdf0e10cSrcweir             xUpdatable->update();
1228*cdf0e10cSrcweir 
1229*cdf0e10cSrcweir         //registering is done by the ExtensionManager service.
1230*cdf0e10cSrcweir     }
1231*cdf0e10cSrcweir     catch (RuntimeException &) {
1232*cdf0e10cSrcweir         throw;
1233*cdf0e10cSrcweir     }
1234*cdf0e10cSrcweir     catch (CommandFailedException & exc) {
1235*cdf0e10cSrcweir         logIntern( Any(exc) );
1236*cdf0e10cSrcweir         throw;
1237*cdf0e10cSrcweir     }
1238*cdf0e10cSrcweir     catch (CommandAbortedException & exc) {
1239*cdf0e10cSrcweir         logIntern( Any(exc) );
1240*cdf0e10cSrcweir         throw;
1241*cdf0e10cSrcweir     }
1242*cdf0e10cSrcweir     catch (deployment::DeploymentException & exc) {
1243*cdf0e10cSrcweir         logIntern( Any(exc) );
1244*cdf0e10cSrcweir         throw;
1245*cdf0e10cSrcweir     }
1246*cdf0e10cSrcweir     catch (Exception &) {
1247*cdf0e10cSrcweir         Any exc( ::cppu::getCaughtException() );
1248*cdf0e10cSrcweir         logIntern( exc );
1249*cdf0e10cSrcweir         throw deployment::DeploymentException(
1250*cdf0e10cSrcweir             OUSTR("Error while reinstalling all previously deployed "
1251*cdf0e10cSrcweir                   "packages of context ") + m_context,
1252*cdf0e10cSrcweir             static_cast<OWeakObject *>(this), exc );
1253*cdf0e10cSrcweir     }
1254*cdf0e10cSrcweir }
1255*cdf0e10cSrcweir 
1256*cdf0e10cSrcweir 
1257*cdf0e10cSrcweir ::sal_Bool SAL_CALL PackageManagerImpl::isReadOnly(  )
1258*cdf0e10cSrcweir         throw (::com::sun::star::uno::RuntimeException)
1259*cdf0e10cSrcweir {
1260*cdf0e10cSrcweir     return m_readOnly;
1261*cdf0e10cSrcweir }
1262*cdf0e10cSrcweir bool PackageManagerImpl::synchronizeRemovedExtensions(
1263*cdf0e10cSrcweir     Reference<task::XAbortChannel> const & xAbortChannel,
1264*cdf0e10cSrcweir     Reference<css::ucb::XCommandEnvironment> const & xCmdEnv)
1265*cdf0e10cSrcweir {
1266*cdf0e10cSrcweir 
1267*cdf0e10cSrcweir     //find all which are in the extension data base but which
1268*cdf0e10cSrcweir     //are removed already.
1269*cdf0e10cSrcweir     OSL_ASSERT(!m_context.equals(OUSTR("user")));
1270*cdf0e10cSrcweir     bool bModified = false;
1271*cdf0e10cSrcweir     ActivePackages::Entries id2temp( m_activePackagesDB->getEntries() );
1272*cdf0e10cSrcweir 
1273*cdf0e10cSrcweir     typedef ActivePackages::Entries::const_iterator ITActive;
1274*cdf0e10cSrcweir     bool bShared = m_context.equals(OUSTR("shared"));
1275*cdf0e10cSrcweir 
1276*cdf0e10cSrcweir     for (ITActive i = id2temp.begin(); i != id2temp.end(); i++)
1277*cdf0e10cSrcweir     {
1278*cdf0e10cSrcweir         try
1279*cdf0e10cSrcweir         {
1280*cdf0e10cSrcweir             //Get the URL to the extensions folder, first make the url for the
1281*cdf0e10cSrcweir             //shared repository including the temporary name
1282*cdf0e10cSrcweir             OUString url = makeURL(m_activePackages, i->second.temporaryName);
1283*cdf0e10cSrcweir             if (bShared)
1284*cdf0e10cSrcweir                 url = makeURLAppendSysPathSegment( url + OUSTR("_"), i->second.fileName);
1285*cdf0e10cSrcweir 
1286*cdf0e10cSrcweir             bool bRemoved = false;
1287*cdf0e10cSrcweir             //Check if the URL to the extension is still the same
1288*cdf0e10cSrcweir             ::ucbhelper::Content contentExtension;
1289*cdf0e10cSrcweir 
1290*cdf0e10cSrcweir             if (!create_ucb_content(
1291*cdf0e10cSrcweir                     &contentExtension, url,
1292*cdf0e10cSrcweir                     Reference<XCommandEnvironment>(), false))
1293*cdf0e10cSrcweir             {
1294*cdf0e10cSrcweir                 bRemoved = true;
1295*cdf0e10cSrcweir             }
1296*cdf0e10cSrcweir 
1297*cdf0e10cSrcweir             //The folder is in the extension database, but it can still be deleted.
1298*cdf0e10cSrcweir             //look for the xxx.tmpremoved file
1299*cdf0e10cSrcweir             //There can also be the case that a different extension was installed
1300*cdf0e10cSrcweir             //in a "temp" folder with name that is already used.
1301*cdf0e10cSrcweir             if (!bRemoved && bShared)
1302*cdf0e10cSrcweir             {
1303*cdf0e10cSrcweir                 ::ucbhelper::Content contentRemoved;
1304*cdf0e10cSrcweir 
1305*cdf0e10cSrcweir                 if (create_ucb_content(
1306*cdf0e10cSrcweir                         &contentRemoved,
1307*cdf0e10cSrcweir                         m_activePackages_expanded + OUSTR("/") +
1308*cdf0e10cSrcweir                         i->second.temporaryName + OUSTR("removed"),
1309*cdf0e10cSrcweir                         Reference<XCommandEnvironment>(), false))
1310*cdf0e10cSrcweir                 {
1311*cdf0e10cSrcweir                     bRemoved = true;
1312*cdf0e10cSrcweir                 }
1313*cdf0e10cSrcweir             }
1314*cdf0e10cSrcweir 
1315*cdf0e10cSrcweir             if (!bRemoved)
1316*cdf0e10cSrcweir             {
1317*cdf0e10cSrcweir                 //There may be another extensions at the same place
1318*cdf0e10cSrcweir                 dp_misc::DescriptionInfoset infoset =
1319*cdf0e10cSrcweir                     dp_misc::getDescriptionInfoset(url);
1320*cdf0e10cSrcweir                 OSL_ENSURE(infoset.hasDescription(),
1321*cdf0e10cSrcweir                            "Extension Manager: bundled and shared extensions "
1322*cdf0e10cSrcweir                            "must have an identifer and a version");
1323*cdf0e10cSrcweir                 if (infoset.hasDescription() &&
1324*cdf0e10cSrcweir                     infoset.getIdentifier() &&
1325*cdf0e10cSrcweir                     (! i->first.equals(*(infoset.getIdentifier()))
1326*cdf0e10cSrcweir                      || ! i->second.version.equals(infoset.getVersion())))
1327*cdf0e10cSrcweir                 {
1328*cdf0e10cSrcweir                     bRemoved = true;
1329*cdf0e10cSrcweir                 }
1330*cdf0e10cSrcweir 
1331*cdf0e10cSrcweir             }
1332*cdf0e10cSrcweir             if (bRemoved)
1333*cdf0e10cSrcweir             {
1334*cdf0e10cSrcweir                 Reference<deployment::XPackage> xPackage = m_xRegistry->bindPackage(
1335*cdf0e10cSrcweir                     url, i->second.mediaType, true, i->first, xCmdEnv );
1336*cdf0e10cSrcweir                 OSL_ASSERT(xPackage.is()); //Even if the files are removed, we must get the object.
1337*cdf0e10cSrcweir                 xPackage->revokePackage(xAbortChannel, xCmdEnv);
1338*cdf0e10cSrcweir                 removePackage(xPackage->getIdentifier().Value, xPackage->getName(),
1339*cdf0e10cSrcweir                               xAbortChannel, xCmdEnv);
1340*cdf0e10cSrcweir                 bModified |= true;
1341*cdf0e10cSrcweir             }
1342*cdf0e10cSrcweir         }
1343*cdf0e10cSrcweir         catch( uno::Exception & )
1344*cdf0e10cSrcweir         {
1345*cdf0e10cSrcweir             OSL_ASSERT(0);
1346*cdf0e10cSrcweir         }
1347*cdf0e10cSrcweir     }
1348*cdf0e10cSrcweir     return bModified;
1349*cdf0e10cSrcweir }
1350*cdf0e10cSrcweir 
1351*cdf0e10cSrcweir 
1352*cdf0e10cSrcweir bool PackageManagerImpl::synchronizeAddedExtensions(
1353*cdf0e10cSrcweir     Reference<task::XAbortChannel> const & xAbortChannel,
1354*cdf0e10cSrcweir     Reference<css::ucb::XCommandEnvironment> const & xCmdEnv)
1355*cdf0e10cSrcweir {
1356*cdf0e10cSrcweir     bool bModified = false;
1357*cdf0e10cSrcweir     OSL_ASSERT(!m_context.equals(OUSTR("user")));
1358*cdf0e10cSrcweir 
1359*cdf0e10cSrcweir     ActivePackages::Entries id2temp( m_activePackagesDB->getEntries() );
1360*cdf0e10cSrcweir     //check if the folder exist at all. The shared extension folder
1361*cdf0e10cSrcweir     //may not exist for a normal user.
1362*cdf0e10cSrcweir     if (!create_ucb_content(
1363*cdf0e10cSrcweir             NULL, m_activePackages_expanded, Reference<css::ucb::XCommandEnvironment>(), false))
1364*cdf0e10cSrcweir         return bModified;
1365*cdf0e10cSrcweir     ::ucbhelper::Content tempFolder(
1366*cdf0e10cSrcweir         m_activePackages_expanded, xCmdEnv );
1367*cdf0e10cSrcweir 
1368*cdf0e10cSrcweir     Reference<sdbc::XResultSet> xResultSet(
1369*cdf0e10cSrcweir         tempFolder.createCursor(
1370*cdf0e10cSrcweir             Sequence<OUString>( &StrTitle::get(), 1 ),
1371*cdf0e10cSrcweir             ::ucbhelper::INCLUDE_FOLDERS_ONLY ) );
1372*cdf0e10cSrcweir 
1373*cdf0e10cSrcweir     while (xResultSet->next())
1374*cdf0e10cSrcweir     {
1375*cdf0e10cSrcweir         try
1376*cdf0e10cSrcweir         {
1377*cdf0e10cSrcweir             OUString title(
1378*cdf0e10cSrcweir                 Reference<sdbc::XRow>(
1379*cdf0e10cSrcweir                     xResultSet, UNO_QUERY_THROW )->getString(
1380*cdf0e10cSrcweir                         1 /* Title */ ) );
1381*cdf0e10cSrcweir             //The temporary folders of user and shared have an '_' at then end.
1382*cdf0e10cSrcweir             //But the name in ActivePackages.temporaryName is saved without.
1383*cdf0e10cSrcweir             OUString title2 = title;
1384*cdf0e10cSrcweir             bool bShared = m_context.equals(OUSTR("shared"));
1385*cdf0e10cSrcweir             if (bShared)
1386*cdf0e10cSrcweir             {
1387*cdf0e10cSrcweir                 OSL_ASSERT(title2[title2.getLength() -1] == '_');
1388*cdf0e10cSrcweir                 title2 = title2.copy(0, title2.getLength() -1);
1389*cdf0e10cSrcweir             }
1390*cdf0e10cSrcweir             OUString titleEncoded =  ::rtl::Uri::encode(
1391*cdf0e10cSrcweir                 title2, rtl_UriCharClassPchar,
1392*cdf0e10cSrcweir                 rtl_UriEncodeIgnoreEscapes,
1393*cdf0e10cSrcweir                 RTL_TEXTENCODING_UTF8);
1394*cdf0e10cSrcweir 
1395*cdf0e10cSrcweir             //It it sufficient to check for the folder name, because when the administor
1396*cdf0e10cSrcweir             //installed the extension it was already checked if there is one with the
1397*cdf0e10cSrcweir             //same identifier.
1398*cdf0e10cSrcweir             const MatchTempDir match(titleEncoded);
1399*cdf0e10cSrcweir             if (::std::find_if( id2temp.begin(), id2temp.end(), match ) ==
1400*cdf0e10cSrcweir                 id2temp.end())
1401*cdf0e10cSrcweir             {
1402*cdf0e10cSrcweir 
1403*cdf0e10cSrcweir                 // The folder was not found in the data base, so it must be
1404*cdf0e10cSrcweir                 // an added extension
1405*cdf0e10cSrcweir                 OUString url(m_activePackages_expanded + OUSTR("/") + titleEncoded);
1406*cdf0e10cSrcweir                 OUString sExtFolder;
1407*cdf0e10cSrcweir                 if (bShared) //that is, shared
1408*cdf0e10cSrcweir                 {
1409*cdf0e10cSrcweir                     //Check if the extension was not "deleted" already which is indicated
1410*cdf0e10cSrcweir                     //by a xxx.tmpremoved file
1411*cdf0e10cSrcweir                     ::ucbhelper::Content contentRemoved;
1412*cdf0e10cSrcweir                     if (create_ucb_content(&contentRemoved, url + OUSTR("removed"),
1413*cdf0e10cSrcweir                                            Reference<XCommandEnvironment>(), false))
1414*cdf0e10cSrcweir                         continue;
1415*cdf0e10cSrcweir                     sExtFolder = getExtensionFolder(
1416*cdf0e10cSrcweir                         m_activePackages_expanded +
1417*cdf0e10cSrcweir                         OUString(OUSTR("/")) + titleEncoded + OUSTR("_"), xCmdEnv);
1418*cdf0e10cSrcweir                     url = makeURLAppendSysPathSegment(m_activePackages_expanded, title);
1419*cdf0e10cSrcweir                     url = makeURLAppendSysPathSegment(url, sExtFolder);
1420*cdf0e10cSrcweir                 }
1421*cdf0e10cSrcweir                 Reference<deployment::XPackage> xPackage = m_xRegistry->bindPackage(
1422*cdf0e10cSrcweir                     url, OUString(), false, OUString(), xCmdEnv );
1423*cdf0e10cSrcweir                 if (xPackage.is())
1424*cdf0e10cSrcweir                 {
1425*cdf0e10cSrcweir                     //Prepare the database entry
1426*cdf0e10cSrcweir                     ActivePackages::Data dbData;
1427*cdf0e10cSrcweir 
1428*cdf0e10cSrcweir                     dbData.temporaryName = titleEncoded;
1429*cdf0e10cSrcweir                     if (bShared)
1430*cdf0e10cSrcweir                         dbData.fileName = sExtFolder;
1431*cdf0e10cSrcweir                     else
1432*cdf0e10cSrcweir                         dbData.fileName = title;
1433*cdf0e10cSrcweir                     dbData.mediaType = xPackage->getPackageType()->getMediaType();
1434*cdf0e10cSrcweir                     dbData.version = xPackage->getVersion();
1435*cdf0e10cSrcweir                     OSL_ENSURE(dbData.version.getLength() > 0,
1436*cdf0e10cSrcweir                                "Extension Manager: bundled and shared extensions must have "
1437*cdf0e10cSrcweir                                "an identifier and a version");
1438*cdf0e10cSrcweir 
1439*cdf0e10cSrcweir                     OUString id = dp_misc::getIdentifier( xPackage );
1440*cdf0e10cSrcweir 
1441*cdf0e10cSrcweir                     //We provide a special command environment that will prevent
1442*cdf0e10cSrcweir                     //showing a license if simple-licens/@accept-by = "admin"
1443*cdf0e10cSrcweir                     //It will also prevent showing the license for bundled extensions
1444*cdf0e10cSrcweir                     //which is not supported.
1445*cdf0e10cSrcweir                     OSL_ASSERT(!m_context.equals(OUSTR("user")));
1446*cdf0e10cSrcweir 
1447*cdf0e10cSrcweir                     // shall the license be suppressed?
1448*cdf0e10cSrcweir                     DescriptionInfoset info =
1449*cdf0e10cSrcweir                         dp_misc::getDescriptionInfoset(url);
1450*cdf0e10cSrcweir                     ::boost::optional<dp_misc::SimpleLicenseAttributes>
1451*cdf0e10cSrcweir                           attr = info.getSimpleLicenseAttributes();
1452*cdf0e10cSrcweir                     ExtensionProperties props(url,xCmdEnv);
1453*cdf0e10cSrcweir                     bool bNoLicense = false;
1454*cdf0e10cSrcweir                     if (attr && attr->suppressIfRequired && props.isSuppressedLicense())
1455*cdf0e10cSrcweir                         bNoLicense = true;
1456*cdf0e10cSrcweir 
1457*cdf0e10cSrcweir                     Reference<ucb::XCommandEnvironment> licCmdEnv(
1458*cdf0e10cSrcweir                         new LicenseCommandEnv(xCmdEnv->getInteractionHandler(),
1459*cdf0e10cSrcweir                                               bNoLicense, m_context));
1460*cdf0e10cSrcweir                     sal_Int32 failedPrereq = xPackage->checkPrerequisites(
1461*cdf0e10cSrcweir                         xAbortChannel, licCmdEnv, false);
1462*cdf0e10cSrcweir                     //Remember that this failed. For example, the user
1463*cdf0e10cSrcweir                     //could have declined the license. Then the next time the
1464*cdf0e10cSrcweir                     //extension folder is investigated we do not want to
1465*cdf0e10cSrcweir                     //try to install the extension again.
1466*cdf0e10cSrcweir                     dbData.failedPrerequisites = OUString::valueOf(failedPrereq);
1467*cdf0e10cSrcweir                     insertToActivationLayerDB(id, dbData);
1468*cdf0e10cSrcweir                     bModified |= true;
1469*cdf0e10cSrcweir                 }
1470*cdf0e10cSrcweir             }
1471*cdf0e10cSrcweir         }
1472*cdf0e10cSrcweir         catch (uno::Exception &)
1473*cdf0e10cSrcweir         {
1474*cdf0e10cSrcweir             OSL_ASSERT(0);
1475*cdf0e10cSrcweir         }
1476*cdf0e10cSrcweir     }
1477*cdf0e10cSrcweir     return bModified;
1478*cdf0e10cSrcweir }
1479*cdf0e10cSrcweir 
1480*cdf0e10cSrcweir sal_Bool PackageManagerImpl::synchronize(
1481*cdf0e10cSrcweir     Reference<task::XAbortChannel> const & xAbortChannel,
1482*cdf0e10cSrcweir     Reference<css::ucb::XCommandEnvironment> const & xCmdEnv)
1483*cdf0e10cSrcweir     throw (css::deployment::DeploymentException,
1484*cdf0e10cSrcweir            css::ucb::CommandFailedException,
1485*cdf0e10cSrcweir            css::ucb::CommandAbortedException,
1486*cdf0e10cSrcweir            css::uno::RuntimeException)
1487*cdf0e10cSrcweir {
1488*cdf0e10cSrcweir     check();
1489*cdf0e10cSrcweir     bool bModified = false;
1490*cdf0e10cSrcweir     if (m_context.equals(OUSTR("user")))
1491*cdf0e10cSrcweir         return bModified;
1492*cdf0e10cSrcweir     bModified |=
1493*cdf0e10cSrcweir         synchronizeRemovedExtensions(xAbortChannel, xCmdEnv);
1494*cdf0e10cSrcweir     bModified |= synchronizeAddedExtensions(xAbortChannel, xCmdEnv);
1495*cdf0e10cSrcweir 
1496*cdf0e10cSrcweir     return bModified;
1497*cdf0e10cSrcweir }
1498*cdf0e10cSrcweir 
1499*cdf0e10cSrcweir Sequence< Reference<deployment::XPackage> > PackageManagerImpl::getExtensionsWithUnacceptedLicenses(
1500*cdf0e10cSrcweir     Reference<ucb::XCommandEnvironment> const & xCmdEnv)
1501*cdf0e10cSrcweir     throw (deployment::DeploymentException, RuntimeException)
1502*cdf0e10cSrcweir {
1503*cdf0e10cSrcweir     ::std::vector<Reference<deployment::XPackage> > vec;
1504*cdf0e10cSrcweir 
1505*cdf0e10cSrcweir     try
1506*cdf0e10cSrcweir     {
1507*cdf0e10cSrcweir         const ::osl::MutexGuard guard( getMutex() );
1508*cdf0e10cSrcweir         // clean up activation layer, scan for zombie temp dirs:
1509*cdf0e10cSrcweir         ActivePackages::Entries id2temp( m_activePackagesDB->getEntries() );
1510*cdf0e10cSrcweir 
1511*cdf0e10cSrcweir         ActivePackages::Entries::const_iterator i = id2temp.begin();
1512*cdf0e10cSrcweir         bool bShared = m_context.equals(OUSTR("shared"));
1513*cdf0e10cSrcweir 
1514*cdf0e10cSrcweir         for (; i != id2temp.end(); i++ )
1515*cdf0e10cSrcweir         {
1516*cdf0e10cSrcweir             //Get the database entry
1517*cdf0e10cSrcweir             ActivePackages::Data const & dbData = i->second;
1518*cdf0e10cSrcweir             sal_Int32 failedPrereq = dbData.failedPrerequisites.toInt32();
1519*cdf0e10cSrcweir             //If the installation failed for other reason then the license then we
1520*cdf0e10cSrcweir             //ignore it.
1521*cdf0e10cSrcweir             if (failedPrereq ^= deployment::Prerequisites::LICENSE)
1522*cdf0e10cSrcweir                 continue;
1523*cdf0e10cSrcweir 
1524*cdf0e10cSrcweir             //Prepare the URL to the extension
1525*cdf0e10cSrcweir             OUString url = makeURL(m_activePackages, i->second.temporaryName);
1526*cdf0e10cSrcweir             if (bShared)
1527*cdf0e10cSrcweir                 url = makeURLAppendSysPathSegment( url + OUSTR("_"), i->second.fileName);
1528*cdf0e10cSrcweir 
1529*cdf0e10cSrcweir             Reference<deployment::XPackage> p = m_xRegistry->bindPackage(
1530*cdf0e10cSrcweir                 url, OUString(), false, OUString(), xCmdEnv );
1531*cdf0e10cSrcweir 
1532*cdf0e10cSrcweir             if (p.is())
1533*cdf0e10cSrcweir                 vec.push_back(p);
1534*cdf0e10cSrcweir 
1535*cdf0e10cSrcweir         }
1536*cdf0e10cSrcweir         return ::comphelper::containerToSequence(vec);
1537*cdf0e10cSrcweir     }
1538*cdf0e10cSrcweir     catch (deployment::DeploymentException &)
1539*cdf0e10cSrcweir     {
1540*cdf0e10cSrcweir         throw;
1541*cdf0e10cSrcweir     }
1542*cdf0e10cSrcweir     catch (RuntimeException&)
1543*cdf0e10cSrcweir     {
1544*cdf0e10cSrcweir         throw;
1545*cdf0e10cSrcweir     }
1546*cdf0e10cSrcweir     catch (...)
1547*cdf0e10cSrcweir     {
1548*cdf0e10cSrcweir         Any exc = ::cppu::getCaughtException();
1549*cdf0e10cSrcweir         deployment::DeploymentException de(
1550*cdf0e10cSrcweir             OUSTR("PackageManagerImpl::getExtensionsWithUnacceptedLicenses"),
1551*cdf0e10cSrcweir             static_cast<OWeakObject*>(this), exc);
1552*cdf0e10cSrcweir         exc <<= de;
1553*cdf0e10cSrcweir         ::cppu::throwException(exc);
1554*cdf0e10cSrcweir     }
1555*cdf0e10cSrcweir 
1556*cdf0e10cSrcweir     return ::comphelper::containerToSequence(vec);
1557*cdf0e10cSrcweir }
1558*cdf0e10cSrcweir 
1559*cdf0e10cSrcweir sal_Int32 PackageManagerImpl::checkPrerequisites(
1560*cdf0e10cSrcweir     css::uno::Reference<css::deployment::XPackage> const & extension,
1561*cdf0e10cSrcweir     css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
1562*cdf0e10cSrcweir     css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv )
1563*cdf0e10cSrcweir     throw (css::deployment::DeploymentException,
1564*cdf0e10cSrcweir            css::ucb::CommandFailedException,
1565*cdf0e10cSrcweir            css::ucb::CommandAbortedException,
1566*cdf0e10cSrcweir            css::lang::IllegalArgumentException,
1567*cdf0e10cSrcweir            css::uno::RuntimeException)
1568*cdf0e10cSrcweir {
1569*cdf0e10cSrcweir     try
1570*cdf0e10cSrcweir     {
1571*cdf0e10cSrcweir         if (!extension.is())
1572*cdf0e10cSrcweir             return 0;
1573*cdf0e10cSrcweir         if (!m_context.equals(extension->getRepositoryName()))
1574*cdf0e10cSrcweir             throw lang::IllegalArgumentException(
1575*cdf0e10cSrcweir                 OUSTR("PackageManagerImpl::checkPrerequisites: extension is not"
1576*cdf0e10cSrcweir                       " from this repository."), 0, 0);
1577*cdf0e10cSrcweir 
1578*cdf0e10cSrcweir         ActivePackages::Data dbData;
1579*cdf0e10cSrcweir         OUString id = dp_misc::getIdentifier(extension);
1580*cdf0e10cSrcweir         if (m_activePackagesDB->get( &dbData, id, OUString()))
1581*cdf0e10cSrcweir         {
1582*cdf0e10cSrcweir             //If the license was already displayed, then do not show it again
1583*cdf0e10cSrcweir             Reference<ucb::XCommandEnvironment> _xCmdEnv = xCmdEnv;
1584*cdf0e10cSrcweir             sal_Int32 prereq = dbData.failedPrerequisites.toInt32();
1585*cdf0e10cSrcweir             if ( !(prereq & deployment::Prerequisites::LICENSE))
1586*cdf0e10cSrcweir                 _xCmdEnv = new NoLicenseCommandEnv(xCmdEnv->getInteractionHandler());
1587*cdf0e10cSrcweir 
1588*cdf0e10cSrcweir             sal_Int32 failedPrereq = extension->checkPrerequisites(
1589*cdf0e10cSrcweir                 xAbortChannel, _xCmdEnv, false);
1590*cdf0e10cSrcweir             dbData.failedPrerequisites = OUString::valueOf(failedPrereq);
1591*cdf0e10cSrcweir             insertToActivationLayerDB(id, dbData);
1592*cdf0e10cSrcweir         }
1593*cdf0e10cSrcweir         else
1594*cdf0e10cSrcweir         {
1595*cdf0e10cSrcweir             throw lang::IllegalArgumentException(
1596*cdf0e10cSrcweir                 OUSTR("PackageManagerImpl::checkPrerequisites: unknown extension"),
1597*cdf0e10cSrcweir                 0, 0);
1598*cdf0e10cSrcweir 
1599*cdf0e10cSrcweir         }
1600*cdf0e10cSrcweir         return 0;
1601*cdf0e10cSrcweir     }
1602*cdf0e10cSrcweir     catch (deployment::DeploymentException& ) {
1603*cdf0e10cSrcweir         throw;
1604*cdf0e10cSrcweir     } catch (ucb::CommandFailedException & ) {
1605*cdf0e10cSrcweir         throw;
1606*cdf0e10cSrcweir     } catch (ucb::CommandAbortedException & ) {
1607*cdf0e10cSrcweir         throw;
1608*cdf0e10cSrcweir     } catch (lang::IllegalArgumentException &) {
1609*cdf0e10cSrcweir         throw;
1610*cdf0e10cSrcweir     } catch (uno::RuntimeException &) {
1611*cdf0e10cSrcweir         throw;
1612*cdf0e10cSrcweir     } catch (...) {
1613*cdf0e10cSrcweir         uno::Any excOccurred = ::cppu::getCaughtException();
1614*cdf0e10cSrcweir         deployment::DeploymentException exc(
1615*cdf0e10cSrcweir             OUSTR("PackageManagerImpl::checkPrerequisites: exception "),
1616*cdf0e10cSrcweir             static_cast<OWeakObject*>(this), excOccurred);
1617*cdf0e10cSrcweir         throw exc;
1618*cdf0e10cSrcweir     }
1619*cdf0e10cSrcweir }
1620*cdf0e10cSrcweir 
1621*cdf0e10cSrcweir //##############################################################################
1622*cdf0e10cSrcweir 
1623*cdf0e10cSrcweir //______________________________________________________________________________
1624*cdf0e10cSrcweir PackageManagerImpl::CmdEnvWrapperImpl::~CmdEnvWrapperImpl()
1625*cdf0e10cSrcweir {
1626*cdf0e10cSrcweir }
1627*cdf0e10cSrcweir 
1628*cdf0e10cSrcweir //______________________________________________________________________________
1629*cdf0e10cSrcweir PackageManagerImpl::CmdEnvWrapperImpl::CmdEnvWrapperImpl(
1630*cdf0e10cSrcweir     Reference<XCommandEnvironment> const & xUserCmdEnv,
1631*cdf0e10cSrcweir     Reference<XProgressHandler> const & xLogFile )
1632*cdf0e10cSrcweir     : m_xLogFile( xLogFile )
1633*cdf0e10cSrcweir {
1634*cdf0e10cSrcweir     if (xUserCmdEnv.is()) {
1635*cdf0e10cSrcweir         m_xUserProgress.set( xUserCmdEnv->getProgressHandler() );
1636*cdf0e10cSrcweir         m_xUserInteractionHandler.set( xUserCmdEnv->getInteractionHandler() );
1637*cdf0e10cSrcweir     }
1638*cdf0e10cSrcweir }
1639*cdf0e10cSrcweir 
1640*cdf0e10cSrcweir // XCommandEnvironment
1641*cdf0e10cSrcweir //______________________________________________________________________________
1642*cdf0e10cSrcweir Reference<task::XInteractionHandler>
1643*cdf0e10cSrcweir PackageManagerImpl::CmdEnvWrapperImpl::getInteractionHandler()
1644*cdf0e10cSrcweir     throw (RuntimeException)
1645*cdf0e10cSrcweir {
1646*cdf0e10cSrcweir     return m_xUserInteractionHandler;
1647*cdf0e10cSrcweir }
1648*cdf0e10cSrcweir 
1649*cdf0e10cSrcweir //______________________________________________________________________________
1650*cdf0e10cSrcweir Reference<XProgressHandler>
1651*cdf0e10cSrcweir PackageManagerImpl::CmdEnvWrapperImpl::getProgressHandler()
1652*cdf0e10cSrcweir     throw (RuntimeException)
1653*cdf0e10cSrcweir {
1654*cdf0e10cSrcweir     return this;
1655*cdf0e10cSrcweir }
1656*cdf0e10cSrcweir 
1657*cdf0e10cSrcweir // XProgressHandler
1658*cdf0e10cSrcweir //______________________________________________________________________________
1659*cdf0e10cSrcweir void PackageManagerImpl::CmdEnvWrapperImpl::push( Any const & Status )
1660*cdf0e10cSrcweir     throw (RuntimeException)
1661*cdf0e10cSrcweir {
1662*cdf0e10cSrcweir     if (m_xLogFile.is())
1663*cdf0e10cSrcweir         m_xLogFile->push( Status );
1664*cdf0e10cSrcweir     if (m_xUserProgress.is())
1665*cdf0e10cSrcweir         m_xUserProgress->push( Status );
1666*cdf0e10cSrcweir }
1667*cdf0e10cSrcweir 
1668*cdf0e10cSrcweir //______________________________________________________________________________
1669*cdf0e10cSrcweir void PackageManagerImpl::CmdEnvWrapperImpl::update( Any const & Status )
1670*cdf0e10cSrcweir     throw (RuntimeException)
1671*cdf0e10cSrcweir {
1672*cdf0e10cSrcweir     if (m_xLogFile.is())
1673*cdf0e10cSrcweir         m_xLogFile->update( Status );
1674*cdf0e10cSrcweir     if (m_xUserProgress.is())
1675*cdf0e10cSrcweir         m_xUserProgress->update( Status );
1676*cdf0e10cSrcweir }
1677*cdf0e10cSrcweir 
1678*cdf0e10cSrcweir //______________________________________________________________________________
1679*cdf0e10cSrcweir void PackageManagerImpl::CmdEnvWrapperImpl::pop() throw (RuntimeException)
1680*cdf0e10cSrcweir {
1681*cdf0e10cSrcweir     if (m_xLogFile.is())
1682*cdf0e10cSrcweir         m_xLogFile->pop();
1683*cdf0e10cSrcweir     if (m_xUserProgress.is())
1684*cdf0e10cSrcweir         m_xUserProgress->pop();
1685*cdf0e10cSrcweir }
1686*cdf0e10cSrcweir 
1687*cdf0e10cSrcweir } // namespace dp_manager
1688*cdf0e10cSrcweir 
1689