Update ooo320-m1
[ooovba.git] / desktop / source / pkgchk / unopkg / unopkg_cmdenv.cxx
blob5ab6f7142945ef147ad47df628e3c8f918e58d4c
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: unopkg_cmdenv.cxx,v $
10 * $Revision: 1.12.8.3 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_desktop.hxx"
34 #include "../../deployment/gui/dp_gui.hrc"
35 #include "../../deployment/gui/dp_gui_shared.hxx"
36 #include "unopkg_shared.h"
37 #include "osl/thread.h"
38 #include "rtl/memory.h"
39 #include "tools/string.hxx"
40 #include "tools/resmgr.hxx"
41 #include "cppuhelper/implbase3.hxx"
42 #include "cppuhelper/exc_hlp.hxx"
43 #include "comphelper/anytostring.hxx"
44 #include "unotools/configmgr.hxx"
45 #include "com/sun/star/lang/WrappedTargetException.hpp"
46 #include "com/sun/star/task/XInteractionAbort.hpp"
47 #include "com/sun/star/task/XInteractionApprove.hpp"
48 #include "com/sun/star/deployment/InstallException.hpp"
49 #include "com/sun/star/deployment/LinkException.hpp"
50 #include "com/sun/star/container/ElementExistException.hpp"
51 #include "com/sun/star/deployment/LicenseException.hpp"
52 #include "com/sun/star/deployment/VersionException.hpp"
53 #include "com/sun/star/deployment/PlatformException.hpp"
54 #include "com/sun/star/i18n/XCollator.hpp"
55 #include "com/sun/star/i18n/CollatorOptions.hpp"
56 #include "com/sun/star/deployment/LicenseIndividualAgreementException.hpp"
57 #include <stdio.h>
58 #include "deployment.hrc"
59 #include "dp_version.hxx"
61 namespace css = ::com::sun::star;
62 using namespace ::com::sun::star;
63 using namespace ::com::sun::star::ucb;
64 using namespace ::com::sun::star::uno;
65 using namespace ::unopkg;
66 using ::rtl::OUString;
69 namespace {
71 //==============================================================================
72 struct OfficeLocale :
73 public rtl::StaticWithInit<const lang::Locale, OfficeLocale> {
74 const lang::Locale operator () () {
75 OUString slang;
76 if (! (::utl::ConfigManager::GetDirectConfigProperty(
77 ::utl::ConfigManager::LOCALE ) >>= slang))
78 throw RuntimeException( OUSTR("Cannot determine language!"), 0 );
79 return toLocale(slang);
83 //==============================================================================
84 class CommandEnvironmentImpl
85 : public ::cppu::WeakImplHelper3< XCommandEnvironment,
86 task::XInteractionHandler,
87 XProgressHandler >
89 sal_Int32 m_logLevel;
90 bool m_option_force_overwrite;
91 bool m_option_link;
92 bool m_option_verbose;
93 bool m_option_bundled;
94 Reference< XComponentContext > m_xComponentContext;
95 Reference< XProgressHandler > m_xLogFile;
97 void update_( Any const & Status ) throw (RuntimeException);
98 void printLicense(const OUString& sLicense, bool & accept, bool & decline);
100 public:
101 virtual ~CommandEnvironmentImpl();
102 CommandEnvironmentImpl(
103 Reference<XComponentContext> const & xComponentContext,
104 OUString const & log_file,
105 bool option_force_overwrite,
106 bool option_link,
107 bool option_verbose,
108 bool option_bundled);
110 // XCommandEnvironment
111 virtual Reference< task::XInteractionHandler > SAL_CALL
112 getInteractionHandler() throw (RuntimeException);
113 virtual Reference< XProgressHandler > SAL_CALL getProgressHandler()
114 throw (RuntimeException);
116 // XInteractionHandler
117 virtual void SAL_CALL handle(
118 Reference< task::XInteractionRequest > const & xRequest )
119 throw (RuntimeException);
121 // XProgressHandler
122 virtual void SAL_CALL push( Any const & Status ) throw (RuntimeException);
123 virtual void SAL_CALL update( Any const & Status ) throw (RuntimeException);
124 virtual void SAL_CALL pop() throw (RuntimeException);
127 //______________________________________________________________________________
128 CommandEnvironmentImpl::CommandEnvironmentImpl(
129 Reference<XComponentContext> const & xComponentContext,
130 OUString const & log_file,
131 bool option_force_overwrite,
132 bool option_link,
133 bool option_verbose,
134 bool option_bundled)
135 : m_logLevel(0),
136 m_option_force_overwrite( option_force_overwrite ),
137 m_option_link( option_link ),
138 m_option_verbose( option_verbose ),
139 m_option_bundled( option_bundled),
140 m_xComponentContext(xComponentContext)
142 if (log_file.getLength() > 0) {
143 const Any logfile(log_file);
144 m_xLogFile.set(
145 xComponentContext->getServiceManager()
146 ->createInstanceWithArgumentsAndContext(
147 OUSTR("com.sun.star.comp.deployment.ProgressLog"),
148 Sequence<Any>( &logfile, 1 ), xComponentContext ),
149 UNO_QUERY_THROW );
153 //______________________________________________________________________________
154 CommandEnvironmentImpl::~CommandEnvironmentImpl()
156 try {
157 Reference< lang::XComponent > xComp( m_xLogFile, UNO_QUERY );
158 if (xComp.is())
159 xComp->dispose();
161 catch (RuntimeException & exc) {
162 (void) exc;
163 OSL_ENSURE( 0, ::rtl::OUStringToOString(
164 exc.Message, osl_getThreadTextEncoding() ).getStr() );
168 //May throw exceptions
169 void CommandEnvironmentImpl::printLicense(const OUString& sLicense, bool & accept, bool &decline)
171 ResMgr * pResMgr = DeploymentResMgr::get();
172 OUString s1 = String(ResId(RID_STR_UNOPKG_ACCEPT_LIC_1, *pResMgr));
173 OUString s2 = String(ResId(RID_STR_UNOPKG_ACCEPT_LIC_2, *pResMgr));
174 OUString s3 = String(ResId(RID_STR_UNOPKG_ACCEPT_LIC_3, *pResMgr));
175 OUString s4 = String(ResId(RID_STR_UNOPKG_ACCEPT_LIC_4, *pResMgr));
176 OUString sYES = String(ResId(RID_STR_UNOPKG_ACCEPT_LIC_YES, *pResMgr));
177 OUString sY = String(ResId(RID_STR_UNOPKG_ACCEPT_LIC_Y, *pResMgr));
178 OUString sNO = String(ResId(RID_STR_UNOPKG_ACCEPT_LIC_NO, *pResMgr));
179 OUString sN = String(ResId(RID_STR_UNOPKG_ACCEPT_LIC_N, *pResMgr));
181 OUString sNewLine(RTL_CONSTASCII_USTRINGPARAM("\n"));
183 dp_misc::writeConsole(sNewLine + sNewLine + s1 + sNewLine + sNewLine);
184 dp_misc::writeConsole(sLicense + sNewLine + sNewLine);
185 dp_misc::writeConsole(s2 + sNewLine);
186 dp_misc::writeConsole(s3);
188 //the user may enter "yes" or "no", we compare in a case insensitive way
189 Reference< css::i18n::XCollator > xCollator(
190 m_xComponentContext->getServiceManager()
191 ->createInstanceWithContext(
192 OUSTR("com.sun.star.i18n.Collator"),m_xComponentContext),
193 UNO_QUERY_THROW );
194 xCollator->loadDefaultCollator(OfficeLocale::get(),
195 css::i18n::CollatorOptions::CollatorOptions_IGNORE_CASE);
199 OUString sAnswer = dp_misc::readConsole();
200 if (xCollator->compareString(sAnswer, sYES) == 0
201 || xCollator->compareString(sAnswer, sY) == 0)
203 accept = true;
204 break;
206 else if(xCollator->compareString(sAnswer, sNO) == 0
207 || xCollator->compareString(sAnswer, sN) == 0)
209 decline = true;
210 break;
212 else
214 dp_misc::writeConsole(sNewLine + sNewLine + s4 + sNewLine);
217 while(true);
220 // XCommandEnvironment
221 //______________________________________________________________________________
222 Reference< task::XInteractionHandler >
223 CommandEnvironmentImpl::getInteractionHandler() throw (RuntimeException)
225 return this;
228 //______________________________________________________________________________
229 Reference< XProgressHandler > CommandEnvironmentImpl::getProgressHandler()
230 throw (RuntimeException)
232 return this;
235 // XInteractionHandler
236 //______________________________________________________________________________
237 void CommandEnvironmentImpl::handle(
238 Reference<task::XInteractionRequest> const & xRequest )
239 throw (RuntimeException)
241 Any request( xRequest->getRequest() );
242 OSL_ASSERT( request.getValueTypeClass() == TypeClass_EXCEPTION );
243 dp_misc::TRACE(OUSTR("[unopkg_cmdenv.cxx] incoming request:\n")
244 + ::comphelper::anyToString(request) + OUSTR("\n\n"));
246 // selections:
247 bool approve = false;
248 bool abort = false;
250 lang::WrappedTargetException wtExc;
251 deployment::LicenseException licExc;
252 deployment::InstallException instExc;
253 deployment::LinkException linkExc;
254 deployment::LicenseIndividualAgreementException licAgreementExc;
255 deployment::PlatformException platExc;
256 deployment::VersionException verExc;
259 bool bLicenseException = false;
260 if (request >>= wtExc) {
261 // ignore intermediate errors of legacy packages, i.e.
262 // former pkgchk behaviour:
263 const Reference<deployment::XPackage> xPackage(
264 wtExc.Context, UNO_QUERY );
265 OSL_ASSERT( xPackage.is() );
266 if (xPackage.is()) {
267 const Reference<deployment::XPackageTypeInfo> xPackageType(
268 xPackage->getPackageType() );
269 OSL_ASSERT( xPackageType.is() );
270 if (xPackageType.is()) {
271 approve = (xPackage->isBundle() &&
272 xPackageType->getMediaType().matchAsciiL(
273 RTL_CONSTASCII_STRINGPARAM(
274 "application/"
275 "vnd.sun.star.legacy-package-bundle") ));
278 abort = !approve;
279 if (abort) {
280 // notify cause as error:
281 request = wtExc.TargetException;
283 else {
284 // handable deployment error signalled, e.g.
285 // bundle item registration failed, notify as warning:
286 update_( wtExc.TargetException );
289 else if (request >>= licAgreementExc)
291 String sResMsg( ResId( RID_STR_UNOPKG_NO_SHARED_ALLOWED, *DeploymentResMgr::get() ) );
292 sResMsg.SearchAndReplaceAllAscii( "%NAME", licAgreementExc.ExtensionName );
293 dp_misc::writeConsole(OUSTR("\n") + sResMsg + OUSTR("\n\n"));
294 abort = true;
296 else if (request >>= licExc)
298 bLicenseException = true;
299 printLicense(licExc.Text, approve, abort);
301 else if (request >>= linkExc)
303 approve = m_option_link;
305 else if (request >>= instExc)
307 //Only if the unopgk was started with gui + extension then we user is asked.
308 //In console mode there is no asking.
309 approve = true;
311 else if (request >>= platExc)
313 String sMsg(ResId(RID_STR_UNSUPPORTED_PLATFORM, *dp_gui::DeploymentGuiResMgr::get()));
314 sMsg.SearchAndReplaceAllAscii("%Name", platExc.package->getDisplayName());
315 dp_misc::writeConsole(OUSTR("\n") + sMsg + OUSTR("\n\n"));
316 approve = true;
318 else {
319 deployment::VersionException nc_exc;
320 if (request >>= nc_exc) {
321 approve = m_option_force_overwrite ||
322 (::dp_misc::comparePackageVersions(nc_exc.New, nc_exc.Deployed)
323 == ::dp_misc::GREATER);
324 abort = !approve;
326 else
327 return; // unknown request => no selection at all
330 //In case of a user declining a license abort is true but this is intended,
331 //therefore no logging
332 if (abort && m_option_verbose && !bLicenseException)
334 OUString msg = ::comphelper::anyToString(request);
335 dp_misc::writeConsoleError(
336 OUSTR("\nERROR: ") + msg + OUSTR("\n"));
339 // select:
340 Sequence< Reference<task::XInteractionContinuation> > conts(
341 xRequest->getContinuations() );
342 Reference<task::XInteractionContinuation> const * pConts =
343 conts.getConstArray();
344 sal_Int32 len = conts.getLength();
345 for ( sal_Int32 pos = 0; pos < len; ++pos )
347 if (approve) {
348 Reference<task::XInteractionApprove> xInteractionApprove(
349 pConts[ pos ], UNO_QUERY );
350 if (xInteractionApprove.is()) {
351 xInteractionApprove->select();
352 break;
355 else if (abort) {
356 Reference<task::XInteractionAbort> xInteractionAbort(
357 pConts[ pos ], UNO_QUERY );
358 if (xInteractionAbort.is()) {
359 xInteractionAbort->select();
360 break;
366 // XProgressHandler
367 //______________________________________________________________________________
368 void CommandEnvironmentImpl::push( Any const & Status )
369 throw (RuntimeException)
371 update_( Status );
372 OSL_ASSERT( m_logLevel >= 0 );
373 ++m_logLevel;
374 if (m_xLogFile.is())
375 m_xLogFile->push( Status );
378 //______________________________________________________________________________
379 void CommandEnvironmentImpl::update_( Any const & Status )
380 throw (RuntimeException)
382 if (! Status.hasValue())
383 return;
384 bool bUseErr = false;
385 OUString msg;
386 if (Status >>= msg) {
387 if (! m_option_verbose)
388 return;
390 else {
391 ::rtl::OUStringBuffer buf;
392 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("WARNING: ") );
393 deployment::DeploymentException dp_exc;
394 if (Status >>= dp_exc) {
395 buf.append( dp_exc.Message );
396 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", Cause: ") );
397 buf.append( ::comphelper::anyToString(dp_exc.Cause) );
399 else {
400 buf.append( ::comphelper::anyToString(Status) );
402 msg = buf.makeStringAndClear();
403 bUseErr = true;
405 OSL_ASSERT( m_logLevel >= 0 );
406 for ( sal_Int32 n = 0; n < m_logLevel; ++n )
408 if (bUseErr)
409 dp_misc::writeConsoleError(" ");
410 else
411 dp_misc::writeConsole(" ");
414 if (bUseErr)
415 dp_misc::writeConsoleError(msg + OUSTR("\n"));
416 else
417 dp_misc::writeConsole(msg + OUSTR("\n"));
420 //______________________________________________________________________________
421 void CommandEnvironmentImpl::update( Any const & Status )
422 throw (RuntimeException)
424 update_( Status );
425 if (m_xLogFile.is())
426 m_xLogFile->update( Status );
429 //______________________________________________________________________________
430 void CommandEnvironmentImpl::pop() throw (RuntimeException)
432 OSL_ASSERT( m_logLevel > 0 );
433 --m_logLevel;
434 if (m_xLogFile.is())
435 m_xLogFile->pop();
438 } // anon namespace
440 namespace unopkg {
442 //==============================================================================
443 Reference< XCommandEnvironment > createCmdEnv(
444 Reference< XComponentContext > const & xContext,
445 OUString const & logFile,
446 bool option_force_overwrite,
447 bool option_link,
448 bool option_verbose,
449 bool option_bundled)
451 return new CommandEnvironmentImpl(
452 xContext, logFile, option_force_overwrite, option_link, option_verbose, option_bundled);
455 } // unopkg