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