1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
22 #include <string_view>
24 #include <strings.hrc>
26 #include <dp_shared.hxx>
27 #include "unopkg_shared.h"
28 #include <i18nlangtag/languagetag.hxx>
29 #include <rtl/ustrbuf.hxx>
30 #include <cppuhelper/implbase.hxx>
31 #include <comphelper/anytostring.hxx>
32 #include <comphelper/diagnose_ex.hxx>
33 #include <unotools/configmgr.hxx>
34 #include <com/sun/star/lang/WrappedTargetException.hpp>
35 #include <com/sun/star/task/XInteractionAbort.hpp>
36 #include <com/sun/star/task/XInteractionApprove.hpp>
37 #include <com/sun/star/deployment/DeploymentException.hpp>
38 #include <com/sun/star/deployment/InstallException.hpp>
39 #include <com/sun/star/deployment/LicenseException.hpp>
40 #include <com/sun/star/deployment/VersionException.hpp>
41 #include <com/sun/star/deployment/PlatformException.hpp>
42 #include <com/sun/star/i18n/Collator.hpp>
43 #include <com/sun/star/i18n/CollatorOptions.hpp>
45 #include <dp_version.hxx>
47 using namespace ::com::sun::star
;
48 using namespace ::com::sun::star::ucb
;
49 using namespace ::com::sun::star::uno
;
50 using namespace ::unopkg
;
56 class CommandEnvironmentImpl
57 : public ::cppu::WeakImplHelper
< XCommandEnvironment
,
58 task::XInteractionHandler
,
62 bool m_option_force_overwrite
;
63 bool m_option_verbose
;
64 bool m_option_suppress_license
;
65 Reference
< XComponentContext
> m_xComponentContext
;
66 Reference
< XProgressHandler
> m_xLogFile
;
68 /// @throws RuntimeException
69 void update_( Any
const & Status
);
70 void printLicense(std::u16string_view sName
,std::u16string_view sLicense
,
71 bool & accept
, bool & decline
);
74 virtual ~CommandEnvironmentImpl() override
;
75 CommandEnvironmentImpl(
76 Reference
<XComponentContext
> const & xComponentContext
,
77 bool option_force_overwrite
,
79 bool option_suppress_license
);
81 // XCommandEnvironment
82 virtual Reference
< task::XInteractionHandler
> SAL_CALL
83 getInteractionHandler() override
;
84 virtual Reference
< XProgressHandler
> SAL_CALL
getProgressHandler() override
;
86 // XInteractionHandler
87 virtual void SAL_CALL
handle(
88 Reference
< task::XInteractionRequest
> const & xRequest
) override
;
91 virtual void SAL_CALL
push( Any
const & Status
) override
;
92 virtual void SAL_CALL
update( Any
const & Status
) override
;
93 virtual void SAL_CALL
pop() override
;
97 CommandEnvironmentImpl::CommandEnvironmentImpl(
98 Reference
<XComponentContext
> const & xComponentContext
,
99 bool option_force_overwrite
,
101 bool option_suppressLicense
)
103 m_option_force_overwrite( option_force_overwrite
),
104 m_option_verbose( option_verbose
),
105 m_option_suppress_license( option_suppressLicense
),
106 m_xComponentContext(xComponentContext
)
109 xComponentContext
->getServiceManager()
110 ->createInstanceWithArgumentsAndContext(
111 u
"com.sun.star.comp.deployment.ProgressLog"_ustr
,
112 Sequence
<Any
>(), xComponentContext
),
117 CommandEnvironmentImpl::~CommandEnvironmentImpl()
120 Reference
< lang::XComponent
> xComp( m_xLogFile
, UNO_QUERY
);
124 catch (const RuntimeException
&) {
125 TOOLS_WARN_EXCEPTION( "desktop", "" );
129 //May throw exceptions
130 void CommandEnvironmentImpl::printLicense(
131 std::u16string_view sName
, std::u16string_view sLicense
, bool & accept
, bool &decline
)
133 OUString
s1tmp(DpResId(RID_STR_UNOPKG_ACCEPT_LIC_1
));
134 OUString
s1(s1tmp
.replaceAll("$NAME", sName
));
135 OUString s2
= DpResId(RID_STR_UNOPKG_ACCEPT_LIC_2
);
136 OUString s3
= DpResId(RID_STR_UNOPKG_ACCEPT_LIC_3
);
137 OUString s4
= DpResId(RID_STR_UNOPKG_ACCEPT_LIC_4
);
138 OUString sYES
= DpResId(RID_STR_UNOPKG_ACCEPT_LIC_YES
);
139 OUString sY
= DpResId(RID_STR_UNOPKG_ACCEPT_LIC_Y
);
140 OUString sNO
= DpResId(RID_STR_UNOPKG_ACCEPT_LIC_NO
);
141 OUString sN
= DpResId(RID_STR_UNOPKG_ACCEPT_LIC_N
);
143 OUString
sNewLine(u
"\n"_ustr
);
145 dp_misc::writeConsole(Concat2View(sNewLine
+ sNewLine
+ s1
+ sNewLine
+ sNewLine
));
146 dp_misc::writeConsole(Concat2View(sLicense
+ sNewLine
+ sNewLine
));
147 dp_misc::writeConsole(Concat2View(s2
+ sNewLine
));
148 dp_misc::writeConsole(s3
);
150 //the user may enter "yes" or "no", we compare in a case insensitive way
151 Reference
< css::i18n::XCollator
> xCollator
=
152 css::i18n::Collator::create( m_xComponentContext
);
153 xCollator
->loadDefaultCollator(
154 LanguageTag(utl::ConfigManager::getUILocale()).getLocale(),
155 css::i18n::CollatorOptions::CollatorOptions_IGNORE_CASE
);
159 OUString sAnswer
= dp_misc::readConsole();
160 if (xCollator
->compareString(sAnswer
, sYES
) == 0
161 || xCollator
->compareString(sAnswer
, sY
) == 0)
166 else if(xCollator
->compareString(sAnswer
, sNO
) == 0
167 || xCollator
->compareString(sAnswer
, sN
) == 0)
174 dp_misc::writeConsole(Concat2View(sNewLine
+ sNewLine
+ s4
+ sNewLine
));
180 // XCommandEnvironment
182 Reference
< task::XInteractionHandler
>
183 CommandEnvironmentImpl::getInteractionHandler()
189 Reference
< XProgressHandler
> CommandEnvironmentImpl::getProgressHandler()
194 // XInteractionHandler
196 void CommandEnvironmentImpl::handle(
197 Reference
<task::XInteractionRequest
> const & xRequest
)
199 Any
request( xRequest
->getRequest() );
200 OSL_ASSERT( request
.getValueTypeClass() == TypeClass_EXCEPTION
);
201 dp_misc::TRACE("[unopkg_cmdenv.cxx] incoming request:\n"
202 + ::comphelper::anyToString(request
) + "\n\n");
205 bool approve
= false;
208 lang::WrappedTargetException wtExc
;
209 deployment::LicenseException licExc
;
210 deployment::InstallException instExc
;
211 deployment::PlatformException platExc
;
213 if (request
>>= wtExc
) {
214 // ignore intermediate errors of legacy packages, i.e.
215 // former pkgchk behaviour:
216 const Reference
<deployment::XPackage
> xPackage(
217 wtExc
.Context
, UNO_QUERY
);
218 OSL_ASSERT( xPackage
.is() );
220 const Reference
<deployment::XPackageTypeInfo
> xPackageType(
221 xPackage
->getPackageType() );
222 OSL_ASSERT( xPackageType
.is() );
223 if (xPackageType
.is()) {
224 approve
= (xPackage
->isBundle() &&
225 xPackageType
->getMediaType().match(
226 "application/vnd.sun.star.legacy-package-bundle") );
231 // notify cause as error:
232 request
= wtExc
.TargetException
;
235 // handable deployment error signalled, e.g.
236 // bundle item registration failed, notify as warning:
237 update_( wtExc
.TargetException
);
240 else if (request
>>= licExc
)
242 if ( !m_option_suppress_license
)
243 printLicense(licExc
.ExtensionName
, licExc
.Text
, approve
, abort
);
250 else if (request
>>= instExc
)
252 //Only if the unopgk was started with gui + extension then the user is asked.
253 //In console mode there is no asking.
256 else if (request
>>= platExc
)
258 OUString
sMsg(DpResId(RID_STR_UNSUPPORTED_PLATFORM
));
259 sMsg
= sMsg
.replaceAll("%Name", platExc
.package
->getDisplayName());
260 dp_misc::writeConsole(Concat2View("\n" + sMsg
+ "\n\n"));
264 deployment::VersionException nc_exc
;
265 if (request
>>= nc_exc
) {
266 approve
= m_option_force_overwrite
||
267 (::dp_misc::compareVersions(nc_exc
.NewVersion
, nc_exc
.Deployed
->getVersion())
268 == ::dp_misc::GREATER
);
272 return; // unknown request => no selection at all
275 if (abort
&& m_option_verbose
)
277 OUString msg
= ::comphelper::anyToString(request
);
278 dp_misc::writeConsoleError(Concat2View("\nERROR: " + msg
+ "\n"));
282 const css::uno::Sequence
<css::uno::Reference
<css::task::XInteractionContinuation
>> xIC
= xRequest
->getContinuations();
283 for ( auto const& rCont
: xIC
)
286 Reference
<task::XInteractionApprove
> xInteractionApprove(
288 if (xInteractionApprove
.is()) {
289 xInteractionApprove
->select();
294 Reference
<task::XInteractionAbort
> xInteractionAbort(
296 if (xInteractionAbort
.is()) {
297 xInteractionAbort
->select();
306 void CommandEnvironmentImpl::push( Any
const & Status
)
309 OSL_ASSERT( m_logLevel
>= 0 );
312 m_xLogFile
->push( Status
);
316 void CommandEnvironmentImpl::update_( Any
const & Status
)
318 if (! Status
.hasValue())
320 bool bUseErr
= false;
322 if (Status
>>= msg
) {
323 if (! m_option_verbose
)
327 OUStringBuffer
buf( "WARNING: " );
328 deployment::DeploymentException dp_exc
;
329 if (Status
>>= dp_exc
) {
330 buf
.append( dp_exc
.Message
+ ", Cause: " + ::comphelper::anyToString(dp_exc
.Cause
) );
333 buf
.append( ::comphelper::anyToString(Status
) );
335 msg
= buf
.makeStringAndClear();
338 OSL_ASSERT( m_logLevel
>= 0 );
339 for ( sal_Int32 n
= 0; n
< m_logLevel
; ++n
)
342 dp_misc::writeConsoleError(u
" ");
344 dp_misc::writeConsole(u
" ");
348 dp_misc::writeConsoleError(Concat2View(msg
+ "\n"));
350 dp_misc::writeConsole(Concat2View(msg
+ "\n"));
354 void CommandEnvironmentImpl::update( Any
const & Status
)
358 m_xLogFile
->update( Status
);
362 void CommandEnvironmentImpl::pop()
364 OSL_ASSERT( m_logLevel
> 0 );
376 Reference
< XCommandEnvironment
> createCmdEnv(
377 Reference
< XComponentContext
> const & xContext
,
378 bool option_force_overwrite
,
380 bool option_suppress_license
)
382 return new CommandEnvironmentImpl(
383 xContext
, option_force_overwrite
, option_verbose
, option_suppress_license
);
387 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */