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 "../../deployment/gui/dp_gui.hrc"
31 : : #include "../../deployment/gui/dp_gui_shared.hxx"
32 : : #include "unopkg_shared.h"
33 : : #include "osl/thread.h"
34 : : #include "rtl/memory.h"
35 : : #include "tools/string.hxx"
36 : : #include "tools/resmgr.hxx"
37 : : #include "cppuhelper/implbase3.hxx"
38 : : #include "cppuhelper/exc_hlp.hxx"
39 : : #include "comphelper/anytostring.hxx"
40 : : #include "unotools/configmgr.hxx"
41 : : #include "com/sun/star/lang/WrappedTargetException.hpp"
42 : : #include "com/sun/star/task/XInteractionAbort.hpp"
43 : : #include "com/sun/star/task/XInteractionApprove.hpp"
44 : : #include "com/sun/star/deployment/InstallException.hpp"
45 : : #include "com/sun/star/container/ElementExistException.hpp"
46 : : #include "com/sun/star/deployment/LicenseException.hpp"
47 : : #include "com/sun/star/deployment/VersionException.hpp"
48 : : #include "com/sun/star/deployment/PlatformException.hpp"
49 : : #include "com/sun/star/i18n/XCollator.hpp"
50 : : #include "com/sun/star/i18n/CollatorOptions.hpp"
51 : :
52 : : #include <stdio.h>
53 : : #include "deployment.hrc"
54 : : #include "dp_version.hxx"
55 : :
56 : : namespace css = ::com::sun::star;
57 : : using namespace ::com::sun::star;
58 : : using namespace ::com::sun::star::ucb;
59 : : using namespace ::com::sun::star::uno;
60 : : using namespace ::unopkg;
61 : : using ::rtl::OUString;
62 : :
63 : :
64 : : namespace {
65 : :
66 : : //==============================================================================
67 : : class CommandEnvironmentImpl
68 : : : public ::cppu::WeakImplHelper3< XCommandEnvironment,
69 : : task::XInteractionHandler,
70 : : XProgressHandler >
71 : : {
72 : : sal_Int32 m_logLevel;
73 : : bool m_option_force_overwrite;
74 : : bool m_option_verbose;
75 : : bool m_option_suppress_license;
76 : : Reference< XComponentContext > m_xComponentContext;
77 : : Reference< XProgressHandler > m_xLogFile;
78 : :
79 : : void update_( Any const & Status ) throw (RuntimeException);
80 : : void printLicense(const OUString & sName,const OUString& sLicense,
81 : : bool & accept, bool & decline);
82 : :
83 : : public:
84 : : virtual ~CommandEnvironmentImpl();
85 : : CommandEnvironmentImpl(
86 : : Reference<XComponentContext> const & xComponentContext,
87 : : OUString const & log_file,
88 : : bool option_force_overwrite,
89 : : bool option_verbose,
90 : : bool option_suppress_license);
91 : :
92 : : // XCommandEnvironment
93 : : virtual Reference< task::XInteractionHandler > SAL_CALL
94 : : getInteractionHandler() throw (RuntimeException);
95 : : virtual Reference< XProgressHandler > SAL_CALL getProgressHandler()
96 : : throw (RuntimeException);
97 : :
98 : : // XInteractionHandler
99 : : virtual void SAL_CALL handle(
100 : : Reference< task::XInteractionRequest > const & xRequest )
101 : : throw (RuntimeException);
102 : :
103 : : // XProgressHandler
104 : : virtual void SAL_CALL push( Any const & Status ) throw (RuntimeException);
105 : : virtual void SAL_CALL update( Any const & Status ) throw (RuntimeException);
106 : : virtual void SAL_CALL pop() throw (RuntimeException);
107 : : };
108 : :
109 : :
110 : : //______________________________________________________________________________
111 : 0 : CommandEnvironmentImpl::CommandEnvironmentImpl(
112 : : Reference<XComponentContext> const & xComponentContext,
113 : : OUString const & log_file,
114 : : bool option_force_overwrite,
115 : : bool option_verbose,
116 : : bool option_suppressLicense)
117 : : : m_logLevel(0),
118 : : m_option_force_overwrite( option_force_overwrite ),
119 : : m_option_verbose( option_verbose ),
120 : : m_option_suppress_license( option_suppressLicense ),
121 : 0 : m_xComponentContext(xComponentContext)
122 : : {
123 : 0 : if (!log_file.isEmpty()) {
124 : 0 : const Any logfile(log_file);
125 : : m_xLogFile.set(
126 : 0 : xComponentContext->getServiceManager()
127 : 0 : ->createInstanceWithArgumentsAndContext(
128 : : OUSTR("com.sun.star.comp.deployment.ProgressLog"),
129 : 0 : Sequence<Any>( &logfile, 1 ), xComponentContext ),
130 : 0 : UNO_QUERY_THROW );
131 : : }
132 : 0 : }
133 : :
134 : : //______________________________________________________________________________
135 : 0 : CommandEnvironmentImpl::~CommandEnvironmentImpl()
136 : : {
137 : : try {
138 : 0 : Reference< lang::XComponent > xComp( m_xLogFile, UNO_QUERY );
139 : 0 : if (xComp.is())
140 : 0 : xComp->dispose();
141 : : }
142 : 0 : catch (const RuntimeException & exc) {
143 : : (void) exc;
144 : : OSL_FAIL( ::rtl::OUStringToOString(
145 : : exc.Message, osl_getThreadTextEncoding() ).getStr() );
146 : : }
147 : 0 : }
148 : :
149 : : //May throw exceptions
150 : 0 : void CommandEnvironmentImpl::printLicense(
151 : : const OUString & sName, const OUString& sLicense, bool & accept, bool &decline)
152 : : {
153 : 0 : ResMgr * pResMgr = DeploymentResMgr::get();
154 : 0 : String s1tmp(ResId(RID_STR_UNOPKG_ACCEPT_LIC_1, *pResMgr));
155 : 0 : s1tmp.SearchAndReplaceAllAscii( "$NAME", sName );
156 : 0 : OUString s1(s1tmp);
157 : 0 : OUString s2 = String(ResId(RID_STR_UNOPKG_ACCEPT_LIC_2, *pResMgr));
158 : 0 : OUString s3 = String(ResId(RID_STR_UNOPKG_ACCEPT_LIC_3, *pResMgr));
159 : 0 : OUString s4 = String(ResId(RID_STR_UNOPKG_ACCEPT_LIC_4, *pResMgr));
160 : 0 : OUString sYES = String(ResId(RID_STR_UNOPKG_ACCEPT_LIC_YES, *pResMgr));
161 : 0 : OUString sY = String(ResId(RID_STR_UNOPKG_ACCEPT_LIC_Y, *pResMgr));
162 : 0 : OUString sNO = String(ResId(RID_STR_UNOPKG_ACCEPT_LIC_NO, *pResMgr));
163 : 0 : OUString sN = String(ResId(RID_STR_UNOPKG_ACCEPT_LIC_N, *pResMgr));
164 : :
165 : 0 : OUString sNewLine(RTL_CONSTASCII_USTRINGPARAM("\n"));
166 : :
167 : 0 : dp_misc::writeConsole(sNewLine + sNewLine + s1 + sNewLine + sNewLine);
168 : 0 : dp_misc::writeConsole(sLicense + sNewLine + sNewLine);
169 : 0 : dp_misc::writeConsole(s2 + sNewLine);
170 : 0 : dp_misc::writeConsole(s3);
171 : :
172 : : //the user may enter "yes" or "no", we compare in a case insensitive way
173 : : Reference< css::i18n::XCollator > xCollator(
174 : 0 : m_xComponentContext->getServiceManager()
175 : 0 : ->createInstanceWithContext(
176 : 0 : OUSTR("com.sun.star.i18n.Collator"),m_xComponentContext),
177 : 0 : UNO_QUERY_THROW );
178 : 0 : xCollator->loadDefaultCollator(
179 : : toLocale(utl::ConfigManager::getLocale()),
180 : 0 : css::i18n::CollatorOptions::CollatorOptions_IGNORE_CASE);
181 : :
182 : 0 : do
183 : : {
184 : 0 : OUString sAnswer = dp_misc::readConsole();
185 : 0 : if (xCollator->compareString(sAnswer, sYES) == 0
186 : 0 : || xCollator->compareString(sAnswer, sY) == 0)
187 : : {
188 : 0 : accept = true;
189 : : break;
190 : : }
191 : 0 : else if(xCollator->compareString(sAnswer, sNO) == 0
192 : 0 : || xCollator->compareString(sAnswer, sN) == 0)
193 : : {
194 : 0 : decline = true;
195 : : break;
196 : : }
197 : : else
198 : : {
199 : 0 : dp_misc::writeConsole(sNewLine + sNewLine + s4 + sNewLine);
200 : 0 : }
201 : : }
202 : 0 : while(true);
203 : 0 : }
204 : :
205 : : // XCommandEnvironment
206 : : //______________________________________________________________________________
207 : : Reference< task::XInteractionHandler >
208 : 0 : CommandEnvironmentImpl::getInteractionHandler() throw (RuntimeException)
209 : : {
210 : 0 : return this;
211 : : }
212 : :
213 : : //______________________________________________________________________________
214 : 0 : Reference< XProgressHandler > CommandEnvironmentImpl::getProgressHandler()
215 : : throw (RuntimeException)
216 : : {
217 : 0 : return this;
218 : : }
219 : :
220 : : // XInteractionHandler
221 : : //______________________________________________________________________________
222 : 0 : void CommandEnvironmentImpl::handle(
223 : : Reference<task::XInteractionRequest> const & xRequest )
224 : : throw (RuntimeException)
225 : : {
226 : 0 : Any request( xRequest->getRequest() );
227 : : OSL_ASSERT( request.getValueTypeClass() == TypeClass_EXCEPTION );
228 : : dp_misc::TRACE(OUSTR("[unopkg_cmdenv.cxx] incoming request:\n")
229 : 0 : + ::comphelper::anyToString(request) + OUSTR("\n\n"));
230 : :
231 : : // selections:
232 : 0 : bool approve = false;
233 : 0 : bool abort = false;
234 : :
235 : 0 : lang::WrappedTargetException wtExc;
236 : 0 : deployment::LicenseException licExc;
237 : 0 : deployment::InstallException instExc;
238 : 0 : deployment::PlatformException platExc;
239 : 0 : deployment::VersionException verExc;
240 : :
241 : :
242 : 0 : bool bLicenseException = false;
243 : 0 : if (request >>= wtExc) {
244 : : // ignore intermediate errors of legacy packages, i.e.
245 : : // former pkgchk behaviour:
246 : : const Reference<deployment::XPackage> xPackage(
247 : 0 : wtExc.Context, UNO_QUERY );
248 : : OSL_ASSERT( xPackage.is() );
249 : 0 : if (xPackage.is()) {
250 : : const Reference<deployment::XPackageTypeInfo> xPackageType(
251 : 0 : xPackage->getPackageType() );
252 : : OSL_ASSERT( xPackageType.is() );
253 : 0 : if (xPackageType.is()) {
254 : 0 : approve = (xPackage->isBundle() &&
255 : 0 : xPackageType->getMediaType().matchAsciiL(
256 : : RTL_CONSTASCII_STRINGPARAM(
257 : : "application/"
258 : 0 : "vnd.sun.star.legacy-package-bundle") ));
259 : 0 : }
260 : : }
261 : 0 : abort = !approve;
262 : 0 : if (abort) {
263 : : // notify cause as error:
264 : 0 : request = wtExc.TargetException;
265 : : }
266 : : else {
267 : : // handable deployment error signalled, e.g.
268 : : // bundle item registration failed, notify as warning:
269 : 0 : update_( wtExc.TargetException );
270 : 0 : }
271 : : }
272 : 0 : else if (request >>= licExc)
273 : : {
274 : 0 : if ( !m_option_suppress_license )
275 : 0 : printLicense(licExc.ExtensionName, licExc.Text, approve, abort);
276 : : else
277 : : {
278 : 0 : approve = true;
279 : 0 : abort = false;
280 : : }
281 : : }
282 : 0 : else if (request >>= instExc)
283 : : {
284 : : //Only if the unopgk was started with gui + extension then we user is asked.
285 : : //In console mode there is no asking.
286 : 0 : approve = true;
287 : : }
288 : 0 : else if (request >>= platExc)
289 : : {
290 : 0 : String sMsg(ResId(RID_STR_UNSUPPORTED_PLATFORM, *dp_gui::DeploymentGuiResMgr::get()));
291 : 0 : sMsg.SearchAndReplaceAllAscii("%Name", platExc.package->getDisplayName());
292 : 0 : dp_misc::writeConsole(OUSTR("\n") + sMsg + OUSTR("\n\n"));
293 : 0 : approve = true;
294 : : }
295 : : else {
296 : 0 : deployment::VersionException nc_exc;
297 : 0 : if (request >>= nc_exc) {
298 : : approve = m_option_force_overwrite ||
299 : 0 : (::dp_misc::compareVersions(nc_exc.NewVersion, nc_exc.Deployed->getVersion())
300 : 0 : == ::dp_misc::GREATER);
301 : 0 : abort = !approve;
302 : : }
303 : : else
304 : 0 : return; // unknown request => no selection at all
305 : : }
306 : :
307 : : //In case of a user declining a license abort is true but this is intended,
308 : : //therefore no logging
309 : 0 : if (abort && m_option_verbose && !bLicenseException)
310 : : {
311 : 0 : OUString msg = ::comphelper::anyToString(request);
312 : : dp_misc::writeConsoleError(
313 : 0 : OUSTR("\nERROR: ") + msg + OUSTR("\n"));
314 : : }
315 : :
316 : : // select:
317 : : Sequence< Reference<task::XInteractionContinuation> > conts(
318 : 0 : xRequest->getContinuations() );
319 : : Reference<task::XInteractionContinuation> const * pConts =
320 : 0 : conts.getConstArray();
321 : 0 : sal_Int32 len = conts.getLength();
322 : 0 : for ( sal_Int32 pos = 0; pos < len; ++pos )
323 : : {
324 : 0 : if (approve) {
325 : : Reference<task::XInteractionApprove> xInteractionApprove(
326 : 0 : pConts[ pos ], UNO_QUERY );
327 : 0 : if (xInteractionApprove.is()) {
328 : 0 : xInteractionApprove->select();
329 : : break;
330 : 0 : }
331 : : }
332 : 0 : else if (abort) {
333 : : Reference<task::XInteractionAbort> xInteractionAbort(
334 : 0 : pConts[ pos ], UNO_QUERY );
335 : 0 : if (xInteractionAbort.is()) {
336 : 0 : xInteractionAbort->select();
337 : : break;
338 : 0 : }
339 : : }
340 : 0 : }
341 : : }
342 : :
343 : : // XProgressHandler
344 : : //______________________________________________________________________________
345 : 0 : void CommandEnvironmentImpl::push( Any const & Status )
346 : : throw (RuntimeException)
347 : : {
348 : 0 : update_( Status );
349 : : OSL_ASSERT( m_logLevel >= 0 );
350 : 0 : ++m_logLevel;
351 : 0 : if (m_xLogFile.is())
352 : 0 : m_xLogFile->push( Status );
353 : 0 : }
354 : :
355 : : //______________________________________________________________________________
356 : 0 : void CommandEnvironmentImpl::update_( Any const & Status )
357 : : throw (RuntimeException)
358 : : {
359 : 0 : if (! Status.hasValue())
360 : : return;
361 : 0 : bool bUseErr = false;
362 : 0 : OUString msg;
363 : 0 : if (Status >>= msg) {
364 : 0 : if (! m_option_verbose)
365 : : return;
366 : : }
367 : : else {
368 : 0 : ::rtl::OUStringBuffer buf;
369 : 0 : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("WARNING: ") );
370 : 0 : deployment::DeploymentException dp_exc;
371 : 0 : if (Status >>= dp_exc) {
372 : 0 : buf.append( dp_exc.Message );
373 : 0 : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", Cause: ") );
374 : 0 : buf.append( ::comphelper::anyToString(dp_exc.Cause) );
375 : : }
376 : : else {
377 : 0 : buf.append( ::comphelper::anyToString(Status) );
378 : : }
379 : 0 : msg = buf.makeStringAndClear();
380 : 0 : bUseErr = true;
381 : : }
382 : : OSL_ASSERT( m_logLevel >= 0 );
383 : 0 : for ( sal_Int32 n = 0; n < m_logLevel; ++n )
384 : : {
385 : 0 : if (bUseErr)
386 : 0 : dp_misc::writeConsoleError(" ");
387 : : else
388 : 0 : dp_misc::writeConsole(" ");
389 : : }
390 : :
391 : 0 : if (bUseErr)
392 : 0 : dp_misc::writeConsoleError(msg + OUSTR("\n"));
393 : : else
394 : 0 : dp_misc::writeConsole(msg + OUSTR("\n"));
395 : : }
396 : :
397 : : //______________________________________________________________________________
398 : 0 : void CommandEnvironmentImpl::update( Any const & Status )
399 : : throw (RuntimeException)
400 : : {
401 : 0 : update_( Status );
402 : 0 : if (m_xLogFile.is())
403 : 0 : m_xLogFile->update( Status );
404 : 0 : }
405 : :
406 : : //______________________________________________________________________________
407 : 0 : void CommandEnvironmentImpl::pop() throw (RuntimeException)
408 : : {
409 : : OSL_ASSERT( m_logLevel > 0 );
410 : 0 : --m_logLevel;
411 : 0 : if (m_xLogFile.is())
412 : 0 : m_xLogFile->pop();
413 : 0 : }
414 : :
415 : :
416 : : } // anon namespace
417 : :
418 : : namespace unopkg {
419 : :
420 : : //==============================================================================
421 : 0 : Reference< XCommandEnvironment > createCmdEnv(
422 : : Reference< XComponentContext > const & xContext,
423 : : OUString const & logFile,
424 : : bool option_force_overwrite,
425 : : bool option_verbose,
426 : : bool option_suppress_license)
427 : : {
428 : : return new CommandEnvironmentImpl(
429 : 0 : xContext, logFile, option_force_overwrite, option_verbose, option_suppress_license);
430 : : }
431 : : } // unopkg
432 : :
433 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|