1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_extensions.hxx" 30*cdf0e10cSrcweir #include <com/sun/star/xml/xpath/XXPathAPI.hpp> 31*cdf0e10cSrcweir 32*cdf0e10cSrcweir #include "updateprotocol.hxx" 33*cdf0e10cSrcweir #include "updatecheckconfig.hxx" 34*cdf0e10cSrcweir 35*cdf0e10cSrcweir #ifndef _COM_SUN_STAR_DEPLOYMENT_UPDATEINFORMATINENTRY_HPP_ 36*cdf0e10cSrcweir #include <com/sun/star/deployment/UpdateInformationEntry.hpp> 37*cdf0e10cSrcweir #endif 38*cdf0e10cSrcweir #include <com/sun/star/deployment/XPackageInformationProvider.hpp> 39*cdf0e10cSrcweir 40*cdf0e10cSrcweir 41*cdf0e10cSrcweir #include <rtl/ref.hxx> 42*cdf0e10cSrcweir #include <rtl/uri.hxx> 43*cdf0e10cSrcweir #include <rtl/strbuf.hxx> 44*cdf0e10cSrcweir #include <rtl/ustrbuf.hxx> 45*cdf0e10cSrcweir #include <rtl/bootstrap.hxx> 46*cdf0e10cSrcweir #include <osl/process.h> 47*cdf0e10cSrcweir 48*cdf0e10cSrcweir #include <cppuhelper/implbase1.hxx> 49*cdf0e10cSrcweir 50*cdf0e10cSrcweir namespace css = com::sun::star ; 51*cdf0e10cSrcweir namespace container = css::container ; 52*cdf0e10cSrcweir namespace deployment = css::deployment ; 53*cdf0e10cSrcweir namespace lang = css::lang ; 54*cdf0e10cSrcweir namespace uno = css::uno ; 55*cdf0e10cSrcweir namespace task = css::task ; 56*cdf0e10cSrcweir namespace xml = css::xml ; 57*cdf0e10cSrcweir 58*cdf0e10cSrcweir #define UNISTRING(s) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s)) 59*cdf0e10cSrcweir 60*cdf0e10cSrcweir //------------------------------------------------------------------------------ 61*cdf0e10cSrcweir 62*cdf0e10cSrcweir static bool 63*cdf0e10cSrcweir getBootstrapData( 64*cdf0e10cSrcweir uno::Sequence< ::rtl::OUString > & rRepositoryList, 65*cdf0e10cSrcweir ::rtl::OUString & rBuildID, 66*cdf0e10cSrcweir ::rtl::OUString & rInstallSetID) 67*cdf0e10cSrcweir { 68*cdf0e10cSrcweir rBuildID = UNISTRING( "${$OOO_BASE_DIR/program/" SAL_CONFIGFILE("version") ":ProductBuildid}" ); 69*cdf0e10cSrcweir rtl::Bootstrap::expandMacros( rBuildID ); 70*cdf0e10cSrcweir if ( ! rBuildID.getLength() ) 71*cdf0e10cSrcweir return false; 72*cdf0e10cSrcweir 73*cdf0e10cSrcweir rInstallSetID = UNISTRING( "${$BRAND_BASE_DIR/program/" SAL_CONFIGFILE("version") ":UpdateID}" ); 74*cdf0e10cSrcweir rtl::Bootstrap::expandMacros( rInstallSetID ); 75*cdf0e10cSrcweir if ( ! rInstallSetID.getLength() ) 76*cdf0e10cSrcweir return false; 77*cdf0e10cSrcweir 78*cdf0e10cSrcweir rtl::OUString aValue( UNISTRING( "${$BRAND_BASE_DIR/program/" SAL_CONFIGFILE("version") ":UpdateURL}" ) ); 79*cdf0e10cSrcweir rtl::Bootstrap::expandMacros( aValue ); 80*cdf0e10cSrcweir 81*cdf0e10cSrcweir if( aValue.getLength() > 0 ) 82*cdf0e10cSrcweir { 83*cdf0e10cSrcweir rRepositoryList.realloc(1); 84*cdf0e10cSrcweir rRepositoryList[0] = aValue; 85*cdf0e10cSrcweir } 86*cdf0e10cSrcweir 87*cdf0e10cSrcweir return true; 88*cdf0e10cSrcweir } 89*cdf0e10cSrcweir 90*cdf0e10cSrcweir //------------------------------------------------------------------------------ 91*cdf0e10cSrcweir 92*cdf0e10cSrcweir // Returns 'true' if successfully connected to the update server 93*cdf0e10cSrcweir bool 94*cdf0e10cSrcweir checkForUpdates( 95*cdf0e10cSrcweir UpdateInfo& o_rUpdateInfo, 96*cdf0e10cSrcweir uno::Reference< uno::XComponentContext > const & rxContext, 97*cdf0e10cSrcweir uno::Reference< task::XInteractionHandler > const & rxInteractionHandler, 98*cdf0e10cSrcweir const uno::Reference< deployment::XUpdateInformationProvider >& rUpdateInfoProvider) 99*cdf0e10cSrcweir { 100*cdf0e10cSrcweir OSL_TRACE("checking for updates ..\n"); 101*cdf0e10cSrcweir 102*cdf0e10cSrcweir ::rtl::OUString myArch; 103*cdf0e10cSrcweir ::rtl::OUString myOS; 104*cdf0e10cSrcweir 105*cdf0e10cSrcweir rtl::Bootstrap::get(UNISTRING("_OS"), myOS); 106*cdf0e10cSrcweir rtl::Bootstrap::get(UNISTRING("_ARCH"), myArch); 107*cdf0e10cSrcweir 108*cdf0e10cSrcweir uno::Sequence< ::rtl::OUString > aRepositoryList; 109*cdf0e10cSrcweir ::rtl::OUString aBuildID; 110*cdf0e10cSrcweir ::rtl::OUString aInstallSetID; 111*cdf0e10cSrcweir 112*cdf0e10cSrcweir if( ! ( getBootstrapData(aRepositoryList, aBuildID, aInstallSetID) && (aRepositoryList.getLength() > 0) ) ) 113*cdf0e10cSrcweir return false; 114*cdf0e10cSrcweir 115*cdf0e10cSrcweir if( !rxContext.is() ) 116*cdf0e10cSrcweir throw uno::RuntimeException( 117*cdf0e10cSrcweir UNISTRING( "checkForUpdates: empty component context" ), uno::Reference< uno::XInterface >() ); 118*cdf0e10cSrcweir 119*cdf0e10cSrcweir OSL_ASSERT( rxContext->getServiceManager().is() ); 120*cdf0e10cSrcweir 121*cdf0e10cSrcweir // XPath implementation 122*cdf0e10cSrcweir uno::Reference< xml::xpath::XXPathAPI > xXPath( 123*cdf0e10cSrcweir rxContext->getServiceManager()->createInstanceWithContext( UNISTRING( "com.sun.star.xml.xpath.XPathAPI" ), rxContext ), 124*cdf0e10cSrcweir uno::UNO_QUERY_THROW); 125*cdf0e10cSrcweir 126*cdf0e10cSrcweir xXPath->registerNS( UNISTRING("inst"), UNISTRING("http://installation.openoffice.org/description") ); 127*cdf0e10cSrcweir 128*cdf0e10cSrcweir if( rxInteractionHandler.is() ) 129*cdf0e10cSrcweir rUpdateInfoProvider->setInteractionHandler(rxInteractionHandler); 130*cdf0e10cSrcweir 131*cdf0e10cSrcweir try 132*cdf0e10cSrcweir { 133*cdf0e10cSrcweir uno::Reference< container::XEnumeration > aUpdateInfoEnumeration = 134*cdf0e10cSrcweir rUpdateInfoProvider->getUpdateInformationEnumeration( aRepositoryList, aInstallSetID ); 135*cdf0e10cSrcweir 136*cdf0e10cSrcweir if ( !aUpdateInfoEnumeration.is() ) 137*cdf0e10cSrcweir return false; // something went wrong .. 138*cdf0e10cSrcweir 139*cdf0e10cSrcweir rtl::OUStringBuffer aBuffer; 140*cdf0e10cSrcweir aBuffer.appendAscii("/child::inst:description[inst:os=\'"); 141*cdf0e10cSrcweir aBuffer.append( myOS ); 142*cdf0e10cSrcweir aBuffer.appendAscii("\' and inst:arch=\'"); 143*cdf0e10cSrcweir aBuffer.append( myArch ); 144*cdf0e10cSrcweir aBuffer.appendAscii("\' and inst:buildid>"); 145*cdf0e10cSrcweir aBuffer.append( aBuildID ); 146*cdf0e10cSrcweir aBuffer.appendAscii("]"); 147*cdf0e10cSrcweir 148*cdf0e10cSrcweir rtl::OUString aXPathExpression = aBuffer.makeStringAndClear(); 149*cdf0e10cSrcweir 150*cdf0e10cSrcweir while( aUpdateInfoEnumeration->hasMoreElements() ) 151*cdf0e10cSrcweir { 152*cdf0e10cSrcweir deployment::UpdateInformationEntry aEntry; 153*cdf0e10cSrcweir 154*cdf0e10cSrcweir if( aUpdateInfoEnumeration->nextElement() >>= aEntry ) 155*cdf0e10cSrcweir { 156*cdf0e10cSrcweir uno::Reference< xml::dom::XNode > xNode( aEntry.UpdateDocument.get() ); 157*cdf0e10cSrcweir uno::Reference< xml::dom::XNodeList > xNodeList; 158*cdf0e10cSrcweir try { 159*cdf0e10cSrcweir xNodeList = xXPath->selectNodeList(xNode, aXPathExpression 160*cdf0e10cSrcweir + UNISTRING("/inst:update/attribute::src")); 161*cdf0e10cSrcweir } catch (css::xml::xpath::XPathException &) { 162*cdf0e10cSrcweir // ignore 163*cdf0e10cSrcweir } 164*cdf0e10cSrcweir 165*cdf0e10cSrcweir /* 166*cdf0e10cSrcweir o_rUpdateInfo.Sources.push_back( DownloadSource(true, 167*cdf0e10cSrcweir UNISTRING("http://openoffice.bouncer.osuosl.org/?product=OpenOffice.org&os=solarissparcwjre&lang=en-US&version=2.2.1") ) ); 168*cdf0e10cSrcweir */ 169*cdf0e10cSrcweir 170*cdf0e10cSrcweir sal_Int32 i, imax = xNodeList->getLength(); 171*cdf0e10cSrcweir for( i = 0; i < imax; ++i ) 172*cdf0e10cSrcweir { 173*cdf0e10cSrcweir uno::Reference< xml::dom::XNode > xNode2( xNodeList->item(i) ); 174*cdf0e10cSrcweir 175*cdf0e10cSrcweir if( xNode2.is() ) 176*cdf0e10cSrcweir { 177*cdf0e10cSrcweir uno::Reference< xml::dom::XElement > xParent(xNode2->getParentNode(), uno::UNO_QUERY_THROW); 178*cdf0e10cSrcweir rtl::OUString aType = xParent->getAttribute(UNISTRING("type")); 179*cdf0e10cSrcweir bool bIsDirect = ( sal_False == aType.equalsIgnoreAsciiCaseAscii("text/html") ); 180*cdf0e10cSrcweir 181*cdf0e10cSrcweir o_rUpdateInfo.Sources.push_back( DownloadSource(bIsDirect, xNode2->getNodeValue()) ); 182*cdf0e10cSrcweir } 183*cdf0e10cSrcweir } 184*cdf0e10cSrcweir 185*cdf0e10cSrcweir uno::Reference< xml::dom::XNode > xNode2; 186*cdf0e10cSrcweir try { 187*cdf0e10cSrcweir xNode2 = xXPath->selectSingleNode(xNode, aXPathExpression 188*cdf0e10cSrcweir + UNISTRING("/inst:version/text()")); 189*cdf0e10cSrcweir } catch (css::xml::xpath::XPathException &) { 190*cdf0e10cSrcweir // ignore 191*cdf0e10cSrcweir } 192*cdf0e10cSrcweir 193*cdf0e10cSrcweir if( xNode2.is() ) 194*cdf0e10cSrcweir o_rUpdateInfo.Version = xNode2->getNodeValue(); 195*cdf0e10cSrcweir 196*cdf0e10cSrcweir try { 197*cdf0e10cSrcweir xNode2 = xXPath->selectSingleNode(xNode, aXPathExpression 198*cdf0e10cSrcweir + UNISTRING("/inst:buildid/text()")); 199*cdf0e10cSrcweir } catch (css::xml::xpath::XPathException &) { 200*cdf0e10cSrcweir // ignore 201*cdf0e10cSrcweir } 202*cdf0e10cSrcweir 203*cdf0e10cSrcweir if( xNode2.is() ) 204*cdf0e10cSrcweir o_rUpdateInfo.BuildId = xNode2->getNodeValue(); 205*cdf0e10cSrcweir 206*cdf0e10cSrcweir o_rUpdateInfo.Description = aEntry.Description; 207*cdf0e10cSrcweir 208*cdf0e10cSrcweir // Release Notes 209*cdf0e10cSrcweir try { 210*cdf0e10cSrcweir xNodeList = xXPath->selectNodeList(xNode, aXPathExpression 211*cdf0e10cSrcweir + UNISTRING("/inst:relnote")); 212*cdf0e10cSrcweir } catch (css::xml::xpath::XPathException &) { 213*cdf0e10cSrcweir // ignore 214*cdf0e10cSrcweir } 215*cdf0e10cSrcweir imax = xNodeList->getLength(); 216*cdf0e10cSrcweir for( i = 0; i < imax; ++i ) 217*cdf0e10cSrcweir { 218*cdf0e10cSrcweir uno::Reference< xml::dom::XElement > xRelNote(xNodeList->item(i), uno::UNO_QUERY); 219*cdf0e10cSrcweir if( xRelNote.is() ) 220*cdf0e10cSrcweir { 221*cdf0e10cSrcweir sal_Int32 pos = xRelNote->getAttribute(UNISTRING("pos")).toInt32(); 222*cdf0e10cSrcweir 223*cdf0e10cSrcweir ReleaseNote aRelNote((sal_uInt8) pos, xRelNote->getAttribute(UNISTRING("src"))); 224*cdf0e10cSrcweir 225*cdf0e10cSrcweir if( xRelNote->hasAttribute(UNISTRING("src2")) ) 226*cdf0e10cSrcweir { 227*cdf0e10cSrcweir pos = xRelNote->getAttribute(UNISTRING("pos2")).toInt32(); 228*cdf0e10cSrcweir aRelNote.Pos2 = (sal_Int8) pos; 229*cdf0e10cSrcweir aRelNote.URL2 = xRelNote->getAttribute(UNISTRING("src2")); 230*cdf0e10cSrcweir } 231*cdf0e10cSrcweir 232*cdf0e10cSrcweir o_rUpdateInfo.ReleaseNotes.push_back(aRelNote); 233*cdf0e10cSrcweir } 234*cdf0e10cSrcweir } 235*cdf0e10cSrcweir /* 236*cdf0e10cSrcweir o_rUpdateInfo.ReleaseNotes.push_back( 237*cdf0e10cSrcweir ReleaseNote(1, UNISTRING("http://qa.openoffice.org/tests/online_update_test.html")) 238*cdf0e10cSrcweir ); 239*cdf0e10cSrcweir */ 240*cdf0e10cSrcweir 241*cdf0e10cSrcweir if( o_rUpdateInfo.Sources.size() > 0 ) 242*cdf0e10cSrcweir return true; 243*cdf0e10cSrcweir } 244*cdf0e10cSrcweir } 245*cdf0e10cSrcweir } 246*cdf0e10cSrcweir catch( ... ) 247*cdf0e10cSrcweir { 248*cdf0e10cSrcweir return false; 249*cdf0e10cSrcweir } 250*cdf0e10cSrcweir 251*cdf0e10cSrcweir return true; 252*cdf0e10cSrcweir } 253*cdf0e10cSrcweir 254*cdf0e10cSrcweir //------------------------------------------------------------------------------ 255*cdf0e10cSrcweir bool storeExtensionUpdateInfos( const uno::Reference< uno::XComponentContext > & rxContext, 256*cdf0e10cSrcweir const uno::Sequence< uno::Sequence< rtl::OUString > > &rUpdateInfos ) 257*cdf0e10cSrcweir { 258*cdf0e10cSrcweir bool bNotify = false; 259*cdf0e10cSrcweir 260*cdf0e10cSrcweir if ( rUpdateInfos.hasElements() ) 261*cdf0e10cSrcweir { 262*cdf0e10cSrcweir rtl::Reference< UpdateCheckConfig > aConfig = UpdateCheckConfig::get( rxContext ); 263*cdf0e10cSrcweir 264*cdf0e10cSrcweir for ( sal_Int32 i = rUpdateInfos.getLength() - 1; i >= 0; i-- ) 265*cdf0e10cSrcweir { 266*cdf0e10cSrcweir bNotify |= aConfig->storeExtensionVersion( rUpdateInfos[i][0], rUpdateInfos[i][1] ); 267*cdf0e10cSrcweir } 268*cdf0e10cSrcweir } 269*cdf0e10cSrcweir return bNotify; 270*cdf0e10cSrcweir } 271*cdf0e10cSrcweir 272*cdf0e10cSrcweir //------------------------------------------------------------------------------ 273*cdf0e10cSrcweir // Returns 'true' if there are updates for any extension 274*cdf0e10cSrcweir 275*cdf0e10cSrcweir bool checkForExtensionUpdates( const uno::Reference< uno::XComponentContext > & rxContext ) 276*cdf0e10cSrcweir { 277*cdf0e10cSrcweir uno::Sequence< uno::Sequence< rtl::OUString > > aUpdateList; 278*cdf0e10cSrcweir 279*cdf0e10cSrcweir uno::Reference< deployment::XPackageInformationProvider > xInfoProvider; 280*cdf0e10cSrcweir try 281*cdf0e10cSrcweir { 282*cdf0e10cSrcweir uno::Any aValue( rxContext->getValueByName( 283*cdf0e10cSrcweir UNISTRING( "/singletons/com.sun.star.deployment.PackageInformationProvider" ) ) ); 284*cdf0e10cSrcweir OSL_VERIFY( aValue >>= xInfoProvider ); 285*cdf0e10cSrcweir } 286*cdf0e10cSrcweir catch( const uno::Exception& ) 287*cdf0e10cSrcweir { 288*cdf0e10cSrcweir OSL_ENSURE( false, "checkForExtensionUpdates: could not create the PackageInformationProvider!" ); 289*cdf0e10cSrcweir } 290*cdf0e10cSrcweir 291*cdf0e10cSrcweir if ( !xInfoProvider.is() ) return false; 292*cdf0e10cSrcweir 293*cdf0e10cSrcweir aUpdateList = xInfoProvider->isUpdateAvailable( ::rtl::OUString() ); 294*cdf0e10cSrcweir bool bNotify = storeExtensionUpdateInfos( rxContext, aUpdateList ); 295*cdf0e10cSrcweir 296*cdf0e10cSrcweir return bNotify; 297*cdf0e10cSrcweir } 298*cdf0e10cSrcweir 299*cdf0e10cSrcweir //------------------------------------------------------------------------------ 300*cdf0e10cSrcweir // Returns 'true' if there are any pending updates for any extension (offline check) 301*cdf0e10cSrcweir 302*cdf0e10cSrcweir bool checkForPendingUpdates( const uno::Reference< uno::XComponentContext > & rxContext ) 303*cdf0e10cSrcweir { 304*cdf0e10cSrcweir uno::Sequence< uno::Sequence< rtl::OUString > > aExtensionList; 305*cdf0e10cSrcweir uno::Reference< deployment::XPackageInformationProvider > xInfoProvider; 306*cdf0e10cSrcweir try 307*cdf0e10cSrcweir { 308*cdf0e10cSrcweir uno::Any aValue( rxContext->getValueByName( 309*cdf0e10cSrcweir UNISTRING( "/singletons/com.sun.star.deployment.PackageInformationProvider" ) ) ); 310*cdf0e10cSrcweir OSL_VERIFY( aValue >>= xInfoProvider ); 311*cdf0e10cSrcweir } 312*cdf0e10cSrcweir catch( const uno::Exception& ) 313*cdf0e10cSrcweir { 314*cdf0e10cSrcweir OSL_ENSURE( false, "checkForExtensionUpdates: could not create the PackageInformationProvider!" ); 315*cdf0e10cSrcweir } 316*cdf0e10cSrcweir 317*cdf0e10cSrcweir if ( !xInfoProvider.is() ) return false; 318*cdf0e10cSrcweir 319*cdf0e10cSrcweir bool bPendingUpdateFound = false; 320*cdf0e10cSrcweir 321*cdf0e10cSrcweir aExtensionList = xInfoProvider->getExtensionList(); 322*cdf0e10cSrcweir if ( aExtensionList.hasElements() ) 323*cdf0e10cSrcweir { 324*cdf0e10cSrcweir rtl::Reference< UpdateCheckConfig > aConfig = UpdateCheckConfig::get( rxContext ); 325*cdf0e10cSrcweir 326*cdf0e10cSrcweir for ( sal_Int32 i = aExtensionList.getLength() - 1; i >= 0; i-- ) 327*cdf0e10cSrcweir { 328*cdf0e10cSrcweir bPendingUpdateFound = aConfig->checkExtensionVersion( aExtensionList[i][0], aExtensionList[i][1] ); 329*cdf0e10cSrcweir if ( bPendingUpdateFound ) 330*cdf0e10cSrcweir break; 331*cdf0e10cSrcweir } 332*cdf0e10cSrcweir } 333*cdf0e10cSrcweir 334*cdf0e10cSrcweir return bPendingUpdateFound; 335*cdf0e10cSrcweir } 336