merged tag ooo/DEV300_m102
[LibreOffice.git] / desktop / source / pkgchk / unopkg / unopkg_cmdenv.cxx
blob69a973b90a42251d7e8625ab018511b0c5be990c
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_desktop.hxx"
31 #include "../../deployment/gui/dp_gui.hrc"
32 #include "../../deployment/gui/dp_gui_shared.hxx"
33 #include "unopkg_shared.h"
34 #include "osl/thread.h"
35 #include "rtl/memory.h"
36 #include "tools/string.hxx"
37 #include "tools/resmgr.hxx"
38 #include "cppuhelper/implbase3.hxx"
39 #include "cppuhelper/exc_hlp.hxx"
40 #include "comphelper/anytostring.hxx"
41 #include "unotools/configmgr.hxx"
42 #include "com/sun/star/lang/WrappedTargetException.hpp"
43 #include "com/sun/star/task/XInteractionAbort.hpp"
44 #include "com/sun/star/task/XInteractionApprove.hpp"
45 #include "com/sun/star/deployment/InstallException.hpp"
46 #include "com/sun/star/container/ElementExistException.hpp"
47 #include "com/sun/star/deployment/LicenseException.hpp"
48 #include "com/sun/star/deployment/VersionException.hpp"
49 #include "com/sun/star/deployment/PlatformException.hpp"
50 #include "com/sun/star/i18n/XCollator.hpp"
51 #include "com/sun/star/i18n/CollatorOptions.hpp"
53 #include <stdio.h>
54 #include "deployment.hrc"
55 #include "dp_version.hxx"
57 namespace css = ::com::sun::star;
58 using namespace ::com::sun::star;
59 using namespace ::com::sun::star::ucb;
60 using namespace ::com::sun::star::uno;
61 using namespace ::unopkg;
62 using ::rtl::OUString;
65 namespace {
67 //==============================================================================
68 struct OfficeLocale :
69 public rtl::StaticWithInit<const lang::Locale, OfficeLocale> {
70 const lang::Locale operator () () {
71 OUString slang;
72 if (! (::utl::ConfigManager::GetDirectConfigProperty(
73 ::utl::ConfigManager::LOCALE ) >>= slang))
74 throw RuntimeException( OUSTR("Cannot determine language!"), 0 );
75 return toLocale(slang);
79 //==============================================================================
80 class CommandEnvironmentImpl
81 : public ::cppu::WeakImplHelper3< XCommandEnvironment,
82 task::XInteractionHandler,
83 XProgressHandler >
85 sal_Int32 m_logLevel;
86 bool m_option_force_overwrite;
87 bool m_option_verbose;
88 Reference< XComponentContext > m_xComponentContext;
89 Reference< XProgressHandler > m_xLogFile;
91 void update_( Any const & Status ) throw (RuntimeException);
92 void printLicense(const OUString & sName,const OUString& sLicense,
93 bool & accept, bool & decline);
95 public:
96 virtual ~CommandEnvironmentImpl();
97 CommandEnvironmentImpl(
98 Reference<XComponentContext> const & xComponentContext,
99 OUString const & log_file,
100 bool option_force_overwrite,
101 bool option_verbose);
103 // XCommandEnvironment
104 virtual Reference< task::XInteractionHandler > SAL_CALL
105 getInteractionHandler() throw (RuntimeException);
106 virtual Reference< XProgressHandler > SAL_CALL getProgressHandler()
107 throw (RuntimeException);
109 // XInteractionHandler
110 virtual void SAL_CALL handle(
111 Reference< task::XInteractionRequest > const & xRequest )
112 throw (RuntimeException);
114 // XProgressHandler
115 virtual void SAL_CALL push( Any const & Status ) throw (RuntimeException);
116 virtual void SAL_CALL update( Any const & Status ) throw (RuntimeException);
117 virtual void SAL_CALL pop() throw (RuntimeException);
121 //______________________________________________________________________________
122 CommandEnvironmentImpl::CommandEnvironmentImpl(
123 Reference<XComponentContext> const & xComponentContext,
124 OUString const & log_file,
125 bool option_force_overwrite,
126 bool option_verbose)
127 : m_logLevel(0),
128 m_option_force_overwrite( option_force_overwrite ),
129 m_option_verbose( option_verbose ),
130 m_xComponentContext(xComponentContext)
132 if (log_file.getLength() > 0) {
133 const Any logfile(log_file);
134 m_xLogFile.set(
135 xComponentContext->getServiceManager()
136 ->createInstanceWithArgumentsAndContext(
137 OUSTR("com.sun.star.comp.deployment.ProgressLog"),
138 Sequence<Any>( &logfile, 1 ), xComponentContext ),
139 UNO_QUERY_THROW );
143 //______________________________________________________________________________
144 CommandEnvironmentImpl::~CommandEnvironmentImpl()
146 try {
147 Reference< lang::XComponent > xComp( m_xLogFile, UNO_QUERY );
148 if (xComp.is())
149 xComp->dispose();
151 catch (RuntimeException & exc) {
152 (void) exc;
153 OSL_ENSURE( 0, ::rtl::OUStringToOString(
154 exc.Message, osl_getThreadTextEncoding() ).getStr() );
158 //May throw exceptions
159 void CommandEnvironmentImpl::printLicense(
160 const OUString & sName, const OUString& sLicense, bool & accept, bool &decline)
162 ResMgr * pResMgr = DeploymentResMgr::get();
163 String s1tmp(ResId(RID_STR_UNOPKG_ACCEPT_LIC_1, *pResMgr));
164 s1tmp.SearchAndReplaceAllAscii( "$NAME", sName );
165 OUString s1(s1tmp);
166 OUString s2 = String(ResId(RID_STR_UNOPKG_ACCEPT_LIC_2, *pResMgr));
167 OUString s3 = String(ResId(RID_STR_UNOPKG_ACCEPT_LIC_3, *pResMgr));
168 OUString s4 = String(ResId(RID_STR_UNOPKG_ACCEPT_LIC_4, *pResMgr));
169 OUString sYES = String(ResId(RID_STR_UNOPKG_ACCEPT_LIC_YES, *pResMgr));
170 OUString sY = String(ResId(RID_STR_UNOPKG_ACCEPT_LIC_Y, *pResMgr));
171 OUString sNO = String(ResId(RID_STR_UNOPKG_ACCEPT_LIC_NO, *pResMgr));
172 OUString sN = String(ResId(RID_STR_UNOPKG_ACCEPT_LIC_N, *pResMgr));
174 OUString sNewLine(RTL_CONSTASCII_USTRINGPARAM("\n"));
176 dp_misc::writeConsole(sNewLine + sNewLine + s1 + sNewLine + sNewLine);
177 dp_misc::writeConsole(sLicense + sNewLine + sNewLine);
178 dp_misc::writeConsole(s2 + sNewLine);
179 dp_misc::writeConsole(s3);
181 //the user may enter "yes" or "no", we compare in a case insensitive way
182 Reference< css::i18n::XCollator > xCollator(
183 m_xComponentContext->getServiceManager()
184 ->createInstanceWithContext(
185 OUSTR("com.sun.star.i18n.Collator"),m_xComponentContext),
186 UNO_QUERY_THROW );
187 xCollator->loadDefaultCollator(OfficeLocale::get(),
188 css::i18n::CollatorOptions::CollatorOptions_IGNORE_CASE);
192 OUString sAnswer = dp_misc::readConsole();
193 if (xCollator->compareString(sAnswer, sYES) == 0
194 || xCollator->compareString(sAnswer, sY) == 0)
196 accept = true;
197 break;
199 else if(xCollator->compareString(sAnswer, sNO) == 0
200 || xCollator->compareString(sAnswer, sN) == 0)
202 decline = true;
203 break;
205 else
207 dp_misc::writeConsole(sNewLine + sNewLine + s4 + sNewLine);
210 while(true);
213 // XCommandEnvironment
214 //______________________________________________________________________________
215 Reference< task::XInteractionHandler >
216 CommandEnvironmentImpl::getInteractionHandler() throw (RuntimeException)
218 return this;
221 //______________________________________________________________________________
222 Reference< XProgressHandler > CommandEnvironmentImpl::getProgressHandler()
223 throw (RuntimeException)
225 return this;
228 // XInteractionHandler
229 //______________________________________________________________________________
230 void CommandEnvironmentImpl::handle(
231 Reference<task::XInteractionRequest> const & xRequest )
232 throw (RuntimeException)
234 Any request( xRequest->getRequest() );
235 OSL_ASSERT( request.getValueTypeClass() == TypeClass_EXCEPTION );
236 dp_misc::TRACE(OUSTR("[unopkg_cmdenv.cxx] incoming request:\n")
237 + ::comphelper::anyToString(request) + OUSTR("\n\n"));
239 // selections:
240 bool approve = false;
241 bool abort = false;
243 lang::WrappedTargetException wtExc;
244 deployment::LicenseException licExc;
245 deployment::InstallException instExc;
246 deployment::PlatformException platExc;
247 deployment::VersionException verExc;
250 bool bLicenseException = false;
251 if (request >>= wtExc) {
252 // ignore intermediate errors of legacy packages, i.e.
253 // former pkgchk behaviour:
254 const Reference<deployment::XPackage> xPackage(
255 wtExc.Context, UNO_QUERY );
256 OSL_ASSERT( xPackage.is() );
257 if (xPackage.is()) {
258 const Reference<deployment::XPackageTypeInfo> xPackageType(
259 xPackage->getPackageType() );
260 OSL_ASSERT( xPackageType.is() );
261 if (xPackageType.is()) {
262 approve = (xPackage->isBundle() &&
263 xPackageType->getMediaType().matchAsciiL(
264 RTL_CONSTASCII_STRINGPARAM(
265 "application/"
266 "vnd.sun.star.legacy-package-bundle") ));
269 abort = !approve;
270 if (abort) {
271 // notify cause as error:
272 request = wtExc.TargetException;
274 else {
275 // handable deployment error signalled, e.g.
276 // bundle item registration failed, notify as warning:
277 update_( wtExc.TargetException );
280 else if (request >>= licExc)
282 printLicense(licExc.ExtensionName, licExc.Text, approve, abort);
284 else if (request >>= instExc)
286 //Only if the unopgk was started with gui + extension then we user is asked.
287 //In console mode there is no asking.
288 approve = true;
290 else if (request >>= platExc)
292 String sMsg(ResId(RID_STR_UNSUPPORTED_PLATFORM, *dp_gui::DeploymentGuiResMgr::get()));
293 sMsg.SearchAndReplaceAllAscii("%Name", platExc.package->getDisplayName());
294 dp_misc::writeConsole(OUSTR("\n") + sMsg + OUSTR("\n\n"));
295 approve = true;
297 else {
298 deployment::VersionException nc_exc;
299 if (request >>= nc_exc) {
300 approve = m_option_force_overwrite ||
301 (::dp_misc::compareVersions(nc_exc.NewVersion, nc_exc.Deployed->getVersion())
302 == ::dp_misc::GREATER);
303 abort = !approve;
305 else
306 return; // unknown request => no selection at all
309 //In case of a user declining a license abort is true but this is intended,
310 //therefore no logging
311 if (abort && m_option_verbose && !bLicenseException)
313 OUString msg = ::comphelper::anyToString(request);
314 dp_misc::writeConsoleError(
315 OUSTR("\nERROR: ") + msg + OUSTR("\n"));
318 // select:
319 Sequence< Reference<task::XInteractionContinuation> > conts(
320 xRequest->getContinuations() );
321 Reference<task::XInteractionContinuation> const * pConts =
322 conts.getConstArray();
323 sal_Int32 len = conts.getLength();
324 for ( sal_Int32 pos = 0; pos < len; ++pos )
326 if (approve) {
327 Reference<task::XInteractionApprove> xInteractionApprove(
328 pConts[ pos ], UNO_QUERY );
329 if (xInteractionApprove.is()) {
330 xInteractionApprove->select();
331 break;
334 else if (abort) {
335 Reference<task::XInteractionAbort> xInteractionAbort(
336 pConts[ pos ], UNO_QUERY );
337 if (xInteractionAbort.is()) {
338 xInteractionAbort->select();
339 break;
345 // XProgressHandler
346 //______________________________________________________________________________
347 void CommandEnvironmentImpl::push( Any const & Status )
348 throw (RuntimeException)
350 update_( Status );
351 OSL_ASSERT( m_logLevel >= 0 );
352 ++m_logLevel;
353 if (m_xLogFile.is())
354 m_xLogFile->push( Status );
357 //______________________________________________________________________________
358 void CommandEnvironmentImpl::update_( Any const & Status )
359 throw (RuntimeException)
361 if (! Status.hasValue())
362 return;
363 bool bUseErr = false;
364 OUString msg;
365 if (Status >>= msg) {
366 if (! m_option_verbose)
367 return;
369 else {
370 ::rtl::OUStringBuffer buf;
371 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("WARNING: ") );
372 deployment::DeploymentException dp_exc;
373 if (Status >>= dp_exc) {
374 buf.append( dp_exc.Message );
375 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", Cause: ") );
376 buf.append( ::comphelper::anyToString(dp_exc.Cause) );
378 else {
379 buf.append( ::comphelper::anyToString(Status) );
381 msg = buf.makeStringAndClear();
382 bUseErr = true;
384 OSL_ASSERT( m_logLevel >= 0 );
385 for ( sal_Int32 n = 0; n < m_logLevel; ++n )
387 if (bUseErr)
388 dp_misc::writeConsoleError(" ");
389 else
390 dp_misc::writeConsole(" ");
393 if (bUseErr)
394 dp_misc::writeConsoleError(msg + OUSTR("\n"));
395 else
396 dp_misc::writeConsole(msg + OUSTR("\n"));
399 //______________________________________________________________________________
400 void CommandEnvironmentImpl::update( Any const & Status )
401 throw (RuntimeException)
403 update_( Status );
404 if (m_xLogFile.is())
405 m_xLogFile->update( Status );
408 //______________________________________________________________________________
409 void CommandEnvironmentImpl::pop() throw (RuntimeException)
411 OSL_ASSERT( m_logLevel > 0 );
412 --m_logLevel;
413 if (m_xLogFile.is())
414 m_xLogFile->pop();
418 } // anon namespace
420 namespace unopkg {
422 //==============================================================================
423 Reference< XCommandEnvironment > createCmdEnv(
424 Reference< XComponentContext > const & xContext,
425 OUString const & logFile,
426 bool option_force_overwrite,
427 bool option_verbose)
429 return new CommandEnvironmentImpl(
430 xContext, logFile, option_force_overwrite, option_verbose);
432 } // unopkg