tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / extensions / source / update / check / updateprotocol.cxx
blob8c71aaecf90a2949064c69d7f1f1549fcbd64fcc
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <config_folders.h>
22 #include <com/sun/star/xml/xpath/XPathAPI.hpp>
23 #include <com/sun/star/xml/xpath/XPathException.hpp>
25 #include "updateprotocol.hxx"
26 #include "updatecheckconfig.hxx"
28 #include <com/sun/star/deployment/UpdateInformationEntry.hpp>
29 #include <com/sun/star/deployment/XPackageInformationProvider.hpp>
32 #include <rtl/ref.hxx>
33 #include <rtl/bootstrap.hxx>
34 #include <osl/diagnose.h>
36 namespace container = css::container ;
37 namespace deployment = css::deployment ;
38 namespace uno = css::uno ;
39 namespace task = css::task ;
40 namespace xml = css::xml ;
43 static bool
44 getBootstrapData(
45 uno::Sequence< OUString > & rRepositoryList,
46 OUString & rGitID,
47 OUString & rInstallSetID)
49 rGitID = "${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE("version") ":buildid}";
50 rtl::Bootstrap::expandMacros( rGitID );
51 if ( rGitID.isEmpty() )
52 return false;
54 rInstallSetID = "${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE("version") ":UpdateID}";
55 rtl::Bootstrap::expandMacros( rInstallSetID );
56 if ( rInstallSetID.isEmpty() )
57 return false;
59 OUString aValue( u"${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE("version") ":UpdateURL}"_ustr );
60 rtl::Bootstrap::expandMacros( aValue );
62 if( !aValue.isEmpty() )
64 rRepositoryList = { aValue };
67 return true;
71 // Returns 'true' if successfully connected to the update server
72 bool
73 checkForUpdates(
74 UpdateInfo& o_rUpdateInfo,
75 uno::Reference< uno::XComponentContext > const & rxContext,
76 uno::Reference< task::XInteractionHandler > const & rxInteractionHandler,
77 const uno::Reference< deployment::XUpdateInformationProvider >& rUpdateInfoProvider)
79 OUString myArch;
80 OUString myOS;
82 rtl::Bootstrap::get(u"_OS"_ustr, myOS);
83 rtl::Bootstrap::get(u"_ARCH"_ustr, myArch);
85 uno::Sequence< OUString > aRepositoryList;
86 OUString aGitID;
87 OUString aInstallSetID;
89 if( ! ( getBootstrapData(aRepositoryList, aGitID, aInstallSetID) && (aRepositoryList.getLength() > 0) ) )
90 return false;
92 return checkForUpdates( o_rUpdateInfo, rxContext, rxInteractionHandler, rUpdateInfoProvider,
93 myOS, myArch,
94 aRepositoryList, aGitID, aInstallSetID );
97 bool
98 checkForUpdates(
99 UpdateInfo& o_rUpdateInfo,
100 const uno::Reference< uno::XComponentContext > & rxContext,
101 const uno::Reference< task::XInteractionHandler > & rxInteractionHandler,
102 const uno::Reference< deployment::XUpdateInformationProvider >& rUpdateInfoProvider,
103 std::u16string_view rOS,
104 std::u16string_view rArch,
105 const uno::Sequence< OUString > &rRepositoryList,
106 std::u16string_view rGitID,
107 const OUString &rInstallSetID )
109 if( !rxContext.is() )
110 throw uno::RuntimeException( u"checkForUpdates: empty component context"_ustr );
112 OSL_ASSERT( rxContext->getServiceManager().is() );
114 // XPath implementation
115 uno::Reference< xml::xpath::XXPathAPI > xXPath = xml::xpath::XPathAPI::create(rxContext);
117 xXPath->registerNS( u"inst"_ustr, u"http://update.libreoffice.org/description"_ustr );
119 if( rxInteractionHandler.is() )
120 rUpdateInfoProvider->setInteractionHandler(rxInteractionHandler);
124 uno::Reference< container::XEnumeration > aUpdateInfoEnumeration =
125 rUpdateInfoProvider->getUpdateInformationEnumeration( rRepositoryList, rInstallSetID );
127 if ( !aUpdateInfoEnumeration.is() )
128 return false; // something went wrong ..
130 OUString aXPathExpression =
131 OUString::Concat("/child::inst:description[inst:os=\'")+
132 rOS +
133 "\' and inst:arch=\'"+
134 rArch +
135 "\' and inst:gitid!=\'"+
136 rGitID +
137 "\']";
140 while( aUpdateInfoEnumeration->hasMoreElements() )
142 deployment::UpdateInformationEntry aEntry;
144 if( aUpdateInfoEnumeration->nextElement() >>= aEntry )
146 uno::Reference< xml::dom::XNode > xNode( aEntry.UpdateDocument );
147 uno::Reference< xml::dom::XNodeList > xNodeList;
148 try {
149 xNodeList = xXPath->selectNodeList(xNode, aXPathExpression
150 + "/inst:update/attribute::src");
151 } catch (const css::xml::xpath::XPathException &) {
152 // ignore
155 sal_Int32 i, imax = xNodeList->getLength();
156 for( i = 0; i < imax; ++i )
158 uno::Reference< xml::dom::XNode > xNode2( xNodeList->item(i) );
160 if( xNode2.is() )
162 uno::Reference< xml::dom::XElement > xParent(xNode2->getParentNode(), uno::UNO_QUERY_THROW);
163 OUString aType = xParent->getAttribute(u"type"_ustr);
164 bool bIsDirect = !aType.equalsIgnoreAsciiCase("text/html");
166 o_rUpdateInfo.Sources.emplace_back(bIsDirect, xNode2->getNodeValue());
170 uno::Reference< xml::dom::XNode > xNode2;
171 try {
172 xNode2 = xXPath->selectSingleNode(xNode, aXPathExpression
173 + "/inst:version/text()");
174 } catch (const css::xml::xpath::XPathException &) {
175 // ignore
178 if( xNode2.is() )
179 o_rUpdateInfo.Version = xNode2->getNodeValue();
181 try {
182 xNode2 = xXPath->selectSingleNode(xNode, aXPathExpression
183 + "/inst:buildid/text()");
184 } catch (const css::xml::xpath::XPathException &) {
185 // ignore
188 if( xNode2.is() )
189 o_rUpdateInfo.BuildId = xNode2->getNodeValue();
191 o_rUpdateInfo.Description = aEntry.Description;
193 // Release Notes
194 try {
195 xNodeList = xXPath->selectNodeList(xNode, aXPathExpression
196 + "/inst:relnote");
197 } catch (const css::xml::xpath::XPathException &) {
198 // ignore
200 imax = xNodeList->getLength();
201 for( i = 0; i < imax; ++i )
203 uno::Reference< xml::dom::XElement > xRelNote(xNodeList->item(i), uno::UNO_QUERY);
204 if( xRelNote.is() )
206 sal_Int32 pos = xRelNote->getAttribute(u"pos"_ustr).toInt32();
208 ReleaseNote aRelNote(static_cast<sal_uInt8>(pos), xRelNote->getAttribute(u"src"_ustr));
210 if( xRelNote->hasAttribute(u"src2"_ustr) )
212 pos = xRelNote->getAttribute(u"pos2"_ustr).toInt32();
213 aRelNote.Pos2 = static_cast<sal_Int8>(pos);
214 aRelNote.URL2 = xRelNote->getAttribute(u"src2"_ustr);
217 o_rUpdateInfo.ReleaseNotes.push_back(aRelNote);
221 if( !o_rUpdateInfo.Sources.empty() )
222 return true;
226 catch( ... )
228 return false;
231 return true;
235 bool storeExtensionUpdateInfos( const uno::Reference< uno::XComponentContext > & rxContext,
236 const uno::Sequence< uno::Sequence< OUString > > &rUpdateInfos )
238 bool bNotify = false;
240 if ( rUpdateInfos.hasElements() )
242 rtl::Reference< UpdateCheckConfig > aConfig = UpdateCheckConfig::get( rxContext );
244 for ( sal_Int32 i = rUpdateInfos.getLength() - 1; i >= 0; i-- )
246 bNotify |= aConfig->storeExtensionVersion( rUpdateInfos[i][0], rUpdateInfos[i][1] );
249 return bNotify;
253 // Returns 'true' if there are updates for any extension
255 bool checkForExtensionUpdates( const uno::Reference< uno::XComponentContext > & rxContext )
257 uno::Sequence< uno::Sequence< OUString > > aUpdateList;
259 uno::Reference< deployment::XPackageInformationProvider > xInfoProvider;
262 uno::Any aValue( rxContext->getValueByName(
263 u"/singletons/com.sun.star.deployment.PackageInformationProvider"_ustr ) );
264 OSL_VERIFY( aValue >>= xInfoProvider );
266 catch( const uno::Exception& )
268 OSL_FAIL( "checkForExtensionUpdates: could not create the PackageInformationProvider!" );
271 if ( !xInfoProvider.is() ) return false;
273 aUpdateList = xInfoProvider->isUpdateAvailable( OUString() );
274 bool bNotify = storeExtensionUpdateInfos( rxContext, aUpdateList );
276 return bNotify;
280 // Returns 'true' if there are any pending updates for any extension (offline check)
282 bool checkForPendingUpdates( const uno::Reference< uno::XComponentContext > & rxContext )
284 uno::Sequence< uno::Sequence< OUString > > aExtensionList;
285 uno::Reference< deployment::XPackageInformationProvider > xInfoProvider;
288 uno::Any aValue( rxContext->getValueByName(
289 u"/singletons/com.sun.star.deployment.PackageInformationProvider"_ustr ) );
290 OSL_VERIFY( aValue >>= xInfoProvider );
292 catch( const uno::Exception& )
294 OSL_FAIL( "checkForExtensionUpdates: could not create the PackageInformationProvider!" );
297 if ( !xInfoProvider.is() ) return false;
299 bool bPendingUpdateFound = false;
301 aExtensionList = xInfoProvider->getExtensionList();
302 if ( aExtensionList.hasElements() )
304 rtl::Reference< UpdateCheckConfig > aConfig = UpdateCheckConfig::get( rxContext );
306 for ( sal_Int32 i = aExtensionList.getLength() - 1; i >= 0; i-- )
308 bPendingUpdateFound = aConfig->checkExtensionVersion( aExtensionList[i][0], aExtensionList[i][1] );
309 if ( bPendingUpdateFound )
310 break;
314 return bPendingUpdateFound;
317 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */