1cdf0e10cSrcweir /************************************************************************* 2cdf0e10cSrcweir * 3cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4cdf0e10cSrcweir * 5cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6cdf0e10cSrcweir * 7cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8cdf0e10cSrcweir * 9cdf0e10cSrcweir * This file is part of OpenOffice.org. 10cdf0e10cSrcweir * 11cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14cdf0e10cSrcweir * 15cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20cdf0e10cSrcweir * 21cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25cdf0e10cSrcweir * 26cdf0e10cSrcweir ************************************************************************/ 27cdf0e10cSrcweir 28cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29cdf0e10cSrcweir #include "precompiled_desktop.hxx" 30cdf0e10cSrcweir 31cdf0e10cSrcweir #include "dp_descriptioninfoset.hxx" 32cdf0e10cSrcweir 33cdf0e10cSrcweir #include "dp_resource.h" 34cdf0e10cSrcweir #include "sal/config.h" 35cdf0e10cSrcweir 36cdf0e10cSrcweir #include "comphelper/sequence.hxx" 379e813386SMichael Stahl #include "comphelper/seqstream.hxx" 38cdf0e10cSrcweir #include "comphelper/makesequence.hxx" 39cdf0e10cSrcweir #include "comphelper/processfactory.hxx" 40cdf0e10cSrcweir #include "boost/optional.hpp" 419e813386SMichael Stahl #include "com/sun/star/container/XNameAccess.hpp" 42cdf0e10cSrcweir #include "com/sun/star/beans/Optional.hpp" 439e813386SMichael Stahl #include "com/sun/star/beans/PropertyValue.hpp" 449e813386SMichael Stahl #include "com/sun/star/beans/XPropertySet.hpp" 459e813386SMichael Stahl #include "com/sun/star/io/SequenceInputStream.hpp" 46cdf0e10cSrcweir #include "com/sun/star/lang/XMultiComponentFactory.hpp" 47cdf0e10cSrcweir #include "com/sun/star/lang/Locale.hpp" 48cdf0e10cSrcweir #include "com/sun/star/uno/Reference.hxx" 49cdf0e10cSrcweir #include "com/sun/star/uno/RuntimeException.hpp" 50cdf0e10cSrcweir #include "com/sun/star/uno/Sequence.hxx" 51cdf0e10cSrcweir #include "com/sun/star/uno/XComponentContext.hpp" 52cdf0e10cSrcweir #include "com/sun/star/uno/XInterface.hpp" 53cdf0e10cSrcweir #include "com/sun/star/xml/dom/DOMException.hpp" 54cdf0e10cSrcweir #include "com/sun/star/xml/dom/XNode.hpp" 55cdf0e10cSrcweir #include "com/sun/star/xml/dom/XNodeList.hpp" 56cdf0e10cSrcweir #include "com/sun/star/xml/dom/XDocumentBuilder.hpp" 57cdf0e10cSrcweir #include "com/sun/star/xml/xpath/XXPathAPI.hpp" 58cdf0e10cSrcweir #include "com/sun/star/ucb/InteractiveAugmentedIOException.hpp" 59cdf0e10cSrcweir #include "cppuhelper/implbase1.hxx" 60cdf0e10cSrcweir #include "cppuhelper/implbase2.hxx" 61cdf0e10cSrcweir #include "cppuhelper/weak.hxx" 62cdf0e10cSrcweir #include "cppuhelper/exc_hlp.hxx" 63cdf0e10cSrcweir #include "rtl/ustring.h" 64cdf0e10cSrcweir #include "rtl/ustring.hxx" 65cdf0e10cSrcweir #include "sal/types.h" 66cdf0e10cSrcweir #include "ucbhelper/content.hxx" 67cdf0e10cSrcweir 68cdf0e10cSrcweir namespace { 69cdf0e10cSrcweir 70cdf0e10cSrcweir namespace css = ::com::sun::star; 71cdf0e10cSrcweir using css::uno::Reference; 72cdf0e10cSrcweir using ::rtl::OUString; 73cdf0e10cSrcweir 74cdf0e10cSrcweir class EmptyNodeList: public ::cppu::WeakImplHelper1< css::xml::dom::XNodeList > 75cdf0e10cSrcweir { 76cdf0e10cSrcweir public: 77cdf0e10cSrcweir EmptyNodeList(); 78cdf0e10cSrcweir 79cdf0e10cSrcweir virtual ~EmptyNodeList(); 80cdf0e10cSrcweir 81cdf0e10cSrcweir virtual ::sal_Int32 SAL_CALL getLength() throw (css::uno::RuntimeException); 82cdf0e10cSrcweir 83cdf0e10cSrcweir virtual css::uno::Reference< css::xml::dom::XNode > SAL_CALL 84cdf0e10cSrcweir item(::sal_Int32 index) throw (css::uno::RuntimeException); 85cdf0e10cSrcweir 86cdf0e10cSrcweir private: 87cdf0e10cSrcweir EmptyNodeList(EmptyNodeList &); // not defined 88cdf0e10cSrcweir void operator =(EmptyNodeList &); // not defined 89cdf0e10cSrcweir }; 90cdf0e10cSrcweir 91cdf0e10cSrcweir EmptyNodeList::EmptyNodeList() {} 92cdf0e10cSrcweir 93cdf0e10cSrcweir EmptyNodeList::~EmptyNodeList() {} 94cdf0e10cSrcweir 95cdf0e10cSrcweir ::sal_Int32 EmptyNodeList::getLength() throw (css::uno::RuntimeException) { 96cdf0e10cSrcweir return 0; 97cdf0e10cSrcweir } 98cdf0e10cSrcweir 99cdf0e10cSrcweir css::uno::Reference< css::xml::dom::XNode > EmptyNodeList::item(::sal_Int32) 100cdf0e10cSrcweir throw (css::uno::RuntimeException) 101cdf0e10cSrcweir { 102cdf0e10cSrcweir throw css::uno::RuntimeException( 103cdf0e10cSrcweir ::rtl::OUString( 104cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 105cdf0e10cSrcweir "bad EmptyNodeList com.sun.star.xml.dom.XNodeList.item call")), 106cdf0e10cSrcweir static_cast< ::cppu::OWeakObject * >(this)); 107cdf0e10cSrcweir } 108cdf0e10cSrcweir 109cdf0e10cSrcweir ::rtl::OUString getNodeValue( 110cdf0e10cSrcweir css::uno::Reference< css::xml::dom::XNode > const & node) 111cdf0e10cSrcweir { 112cdf0e10cSrcweir OSL_ASSERT(node.is()); 113cdf0e10cSrcweir try { 114cdf0e10cSrcweir return node->getNodeValue(); 115cdf0e10cSrcweir } catch (css::xml::dom::DOMException & e) { 116cdf0e10cSrcweir throw css::uno::RuntimeException( 117cdf0e10cSrcweir (::rtl::OUString( 118cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 119cdf0e10cSrcweir "com.sun.star.xml.dom.DOMException: ")) + 120cdf0e10cSrcweir e.Message), 121cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 122cdf0e10cSrcweir } 123cdf0e10cSrcweir } 124cdf0e10cSrcweir 125cdf0e10cSrcweir /**The class uses the UCB to access the description.xml file in an 126cdf0e10cSrcweir extension. The UCB must have been initialized already. It also 127cdf0e10cSrcweir requires that the extension has already be unzipped to a particular 128cdf0e10cSrcweir location. 129cdf0e10cSrcweir */ 130cdf0e10cSrcweir class ExtensionDescription 131cdf0e10cSrcweir { 132cdf0e10cSrcweir public: 133cdf0e10cSrcweir /**throws an exception if the description.xml is not 134cdf0e10cSrcweir available, cannot be read, does not contain the expected data, 135cdf0e10cSrcweir or any other error occured. Therefore it shoult only be used with 136cdf0e10cSrcweir new extensions. 137cdf0e10cSrcweir 138cdf0e10cSrcweir Throws com::sun::star::uno::RuntimeException, 139cdf0e10cSrcweir com::sun::star::deployment::DeploymentException, 140cdf0e10cSrcweir dp_registry::backend::bundle::NoDescriptionException. 141cdf0e10cSrcweir */ 142cdf0e10cSrcweir ExtensionDescription( 143cdf0e10cSrcweir const css::uno::Reference<css::uno::XComponentContext>& xContext, 144cdf0e10cSrcweir const ::rtl::OUString& installDir, 145cdf0e10cSrcweir const css::uno::Reference< css::ucb::XCommandEnvironment >& xCmdEnv); 146cdf0e10cSrcweir 147cdf0e10cSrcweir ~ExtensionDescription(); 148cdf0e10cSrcweir 149cdf0e10cSrcweir css::uno::Reference<css::xml::dom::XNode> getRootElement() const 150cdf0e10cSrcweir { 151cdf0e10cSrcweir return m_xRoot; 152cdf0e10cSrcweir } 153cdf0e10cSrcweir 154cdf0e10cSrcweir ::rtl::OUString getExtensionRootUrl() const 155cdf0e10cSrcweir { 156cdf0e10cSrcweir return m_sExtensionRootUrl; 157cdf0e10cSrcweir } 158cdf0e10cSrcweir 159cdf0e10cSrcweir 160cdf0e10cSrcweir private: 161cdf0e10cSrcweir css::uno::Reference<css::xml::dom::XNode> m_xRoot; 162cdf0e10cSrcweir ::rtl::OUString m_sExtensionRootUrl; 163cdf0e10cSrcweir }; 164cdf0e10cSrcweir 165cdf0e10cSrcweir class NoDescriptionException 166cdf0e10cSrcweir { 167cdf0e10cSrcweir }; 168cdf0e10cSrcweir 169cdf0e10cSrcweir class FileDoesNotExistFilter 170cdf0e10cSrcweir : public ::cppu::WeakImplHelper2< css::ucb::XCommandEnvironment, 171cdf0e10cSrcweir css::task::XInteractionHandler > 172cdf0e10cSrcweir 173cdf0e10cSrcweir { 174cdf0e10cSrcweir //css::uno::Reference<css::task::XInteractionHandler> m_xHandler; 175cdf0e10cSrcweir bool m_bExist; 176cdf0e10cSrcweir css::uno::Reference< css::ucb::XCommandEnvironment > m_xCommandEnv; 177cdf0e10cSrcweir 178cdf0e10cSrcweir public: 179cdf0e10cSrcweir virtual ~FileDoesNotExistFilter(); 180cdf0e10cSrcweir FileDoesNotExistFilter( 181cdf0e10cSrcweir const css::uno::Reference< css::ucb::XCommandEnvironment >& xCmdEnv); 182cdf0e10cSrcweir 183cdf0e10cSrcweir bool exist(); 184cdf0e10cSrcweir // XCommandEnvironment 185cdf0e10cSrcweir virtual css::uno::Reference<css::task::XInteractionHandler > SAL_CALL 186cdf0e10cSrcweir getInteractionHandler() throw (css::uno::RuntimeException); 187cdf0e10cSrcweir virtual css::uno::Reference<css::ucb::XProgressHandler > 188cdf0e10cSrcweir SAL_CALL getProgressHandler() throw (css::uno::RuntimeException); 189cdf0e10cSrcweir 190cdf0e10cSrcweir // XInteractionHandler 191cdf0e10cSrcweir virtual void SAL_CALL handle( 192cdf0e10cSrcweir css::uno::Reference<css::task::XInteractionRequest > const & xRequest ) 193cdf0e10cSrcweir throw (css::uno::RuntimeException); 194cdf0e10cSrcweir }; 195cdf0e10cSrcweir 196cdf0e10cSrcweir ExtensionDescription::ExtensionDescription( 197cdf0e10cSrcweir const Reference<css::uno::XComponentContext>& xContext, 198cdf0e10cSrcweir const OUString& installDir, 199cdf0e10cSrcweir const Reference< css::ucb::XCommandEnvironment >& xCmdEnv) 200cdf0e10cSrcweir { 201cdf0e10cSrcweir try { 202cdf0e10cSrcweir m_sExtensionRootUrl = installDir; 203cdf0e10cSrcweir //may throw ::com::sun::star::ucb::ContentCreationException 204cdf0e10cSrcweir //If there is no description.xml then ucb will start an interaction which 205cdf0e10cSrcweir //brings up a dialog.We want to prevent this. Therefore we wrap the xCmdEnv 206cdf0e10cSrcweir //and filter the respective exception out. 207cdf0e10cSrcweir OUString sDescriptionUri(installDir + OUSTR("/description.xml")); 208cdf0e10cSrcweir Reference<css::ucb::XCommandEnvironment> xFilter = 209cdf0e10cSrcweir static_cast<css::ucb::XCommandEnvironment*>( 210cdf0e10cSrcweir new FileDoesNotExistFilter(xCmdEnv)); 211cdf0e10cSrcweir ::ucbhelper::Content descContent(sDescriptionUri, xFilter); 212cdf0e10cSrcweir 213cdf0e10cSrcweir //throws an com::sun::star::uno::Exception if the file is not available 214cdf0e10cSrcweir Reference<css::io::XInputStream> xIn; 215cdf0e10cSrcweir try 216cdf0e10cSrcweir { //throws com.sun.star.ucb.InteractiveAugmentedIOException 217cdf0e10cSrcweir xIn = descContent.openStream(); 218cdf0e10cSrcweir } 219cdf0e10cSrcweir catch (css::uno::Exception& ) 220cdf0e10cSrcweir { 221cdf0e10cSrcweir if ( ! static_cast<FileDoesNotExistFilter*>(xFilter.get())->exist()) 222cdf0e10cSrcweir throw NoDescriptionException(); 223cdf0e10cSrcweir throw; 224cdf0e10cSrcweir } 225cdf0e10cSrcweir if (!xIn.is()) 226cdf0e10cSrcweir { 227cdf0e10cSrcweir throw css::uno::Exception( 228cdf0e10cSrcweir OUSTR("Could not get XInputStream for description.xml of extension ") + 229cdf0e10cSrcweir sDescriptionUri, 0); 230cdf0e10cSrcweir } 231cdf0e10cSrcweir 232cdf0e10cSrcweir //get root node of description.xml 233cdf0e10cSrcweir Reference<css::xml::dom::XDocumentBuilder> xDocBuilder( 234cdf0e10cSrcweir xContext->getServiceManager()->createInstanceWithContext( 235cdf0e10cSrcweir OUSTR("com.sun.star.xml.dom.DocumentBuilder"), 236cdf0e10cSrcweir xContext ), css::uno::UNO_QUERY); 237cdf0e10cSrcweir if (!xDocBuilder.is()) 238cdf0e10cSrcweir throw css::uno::Exception(OUSTR(" Could not create service com.sun.star.xml.dom.DocumentBuilder"), 0); 239cdf0e10cSrcweir 240cdf0e10cSrcweir if (xDocBuilder->isNamespaceAware() == sal_False) 241cdf0e10cSrcweir { 242cdf0e10cSrcweir throw css::uno::Exception( 243cdf0e10cSrcweir OUSTR("Service com.sun.star.xml.dom.DocumentBuilder is not namespace aware."), 0); 244cdf0e10cSrcweir } 245cdf0e10cSrcweir 246cdf0e10cSrcweir Reference<css::xml::dom::XDocument> xDoc = xDocBuilder->parse(xIn); 247cdf0e10cSrcweir if (!xDoc.is()) 248cdf0e10cSrcweir { 249cdf0e10cSrcweir throw css::uno::Exception(sDescriptionUri + OUSTR(" contains data which cannot be parsed. "), 0); 250cdf0e10cSrcweir } 251cdf0e10cSrcweir 252cdf0e10cSrcweir //check for proper root element and namespace 253cdf0e10cSrcweir Reference<css::xml::dom::XElement> xRoot = xDoc->getDocumentElement(); 254cdf0e10cSrcweir if (!xRoot.is()) 255cdf0e10cSrcweir { 256cdf0e10cSrcweir throw css::uno::Exception( 257cdf0e10cSrcweir sDescriptionUri + OUSTR(" contains no root element."), 0); 258cdf0e10cSrcweir } 259cdf0e10cSrcweir 260cdf0e10cSrcweir if ( ! xRoot->getTagName().equals(OUSTR("description"))) 261cdf0e10cSrcweir { 262cdf0e10cSrcweir throw css::uno::Exception( 263cdf0e10cSrcweir sDescriptionUri + OUSTR(" does not contain the root element <description>."), 0); 264cdf0e10cSrcweir } 265cdf0e10cSrcweir 266cdf0e10cSrcweir m_xRoot = Reference<css::xml::dom::XNode>( 267cdf0e10cSrcweir xRoot, css::uno::UNO_QUERY_THROW); 268cdf0e10cSrcweir OUString nsDescription = xRoot->getNamespaceURI(); 269cdf0e10cSrcweir 270cdf0e10cSrcweir //check if this namespace is supported 271cdf0e10cSrcweir if ( ! nsDescription.equals(OUSTR("http://openoffice.org/extensions/description/2006"))) 272cdf0e10cSrcweir { 273cdf0e10cSrcweir throw css::uno::Exception(sDescriptionUri + OUSTR(" contains a root element with an unsupported namespace. "), 0); 274cdf0e10cSrcweir } 275cdf0e10cSrcweir } catch (css::uno::RuntimeException &) { 276cdf0e10cSrcweir throw; 277cdf0e10cSrcweir } catch (css::deployment::DeploymentException &) { 278cdf0e10cSrcweir throw; 279cdf0e10cSrcweir } catch (css::uno::Exception & e) { 280cdf0e10cSrcweir css::uno::Any a(cppu::getCaughtException()); 281cdf0e10cSrcweir throw css::deployment::DeploymentException( 282cdf0e10cSrcweir e.Message, Reference< css::uno::XInterface >(), a); 283cdf0e10cSrcweir } 284cdf0e10cSrcweir } 285cdf0e10cSrcweir 286cdf0e10cSrcweir ExtensionDescription::~ExtensionDescription() 287cdf0e10cSrcweir { 288cdf0e10cSrcweir } 289cdf0e10cSrcweir 290cdf0e10cSrcweir //====================================================================== 291cdf0e10cSrcweir FileDoesNotExistFilter::FileDoesNotExistFilter( 292cdf0e10cSrcweir const Reference< css::ucb::XCommandEnvironment >& xCmdEnv): 293cdf0e10cSrcweir m_bExist(true), m_xCommandEnv(xCmdEnv) 294cdf0e10cSrcweir {} 295cdf0e10cSrcweir 296cdf0e10cSrcweir FileDoesNotExistFilter::~FileDoesNotExistFilter() 297cdf0e10cSrcweir { 298cdf0e10cSrcweir }; 299cdf0e10cSrcweir 300cdf0e10cSrcweir bool FileDoesNotExistFilter::exist() 301cdf0e10cSrcweir { 302cdf0e10cSrcweir return m_bExist; 303cdf0e10cSrcweir } 304cdf0e10cSrcweir // XCommandEnvironment 305cdf0e10cSrcweir Reference<css::task::XInteractionHandler > 306cdf0e10cSrcweir FileDoesNotExistFilter::getInteractionHandler() throw (css::uno::RuntimeException) 307cdf0e10cSrcweir { 308cdf0e10cSrcweir return static_cast<css::task::XInteractionHandler*>(this); 309cdf0e10cSrcweir } 310cdf0e10cSrcweir 311cdf0e10cSrcweir Reference<css::ucb::XProgressHandler > 312cdf0e10cSrcweir FileDoesNotExistFilter::getProgressHandler() throw (css::uno::RuntimeException) 313cdf0e10cSrcweir { 314cdf0e10cSrcweir return m_xCommandEnv.is() 315cdf0e10cSrcweir ? m_xCommandEnv->getProgressHandler() 316cdf0e10cSrcweir : Reference<css::ucb::XProgressHandler>(); 317cdf0e10cSrcweir } 318cdf0e10cSrcweir 319cdf0e10cSrcweir // XInteractionHandler 320cdf0e10cSrcweir //If the interaction was caused by a non-existing file which is specified in the ctor 321cdf0e10cSrcweir //of FileDoesNotExistFilter, then we do nothing 322cdf0e10cSrcweir void FileDoesNotExistFilter::handle( 323cdf0e10cSrcweir Reference<css::task::XInteractionRequest > const & xRequest ) 324cdf0e10cSrcweir throw (css::uno::RuntimeException) 325cdf0e10cSrcweir { 326cdf0e10cSrcweir css::uno::Any request( xRequest->getRequest() ); 327cdf0e10cSrcweir 328cdf0e10cSrcweir css::ucb::InteractiveAugmentedIOException ioexc; 329cdf0e10cSrcweir if ((request>>= ioexc) && ioexc.Code == css::ucb::IOErrorCode_NOT_EXISTING ) 330cdf0e10cSrcweir { 331cdf0e10cSrcweir m_bExist = false; 332cdf0e10cSrcweir return; 333cdf0e10cSrcweir } 334cdf0e10cSrcweir Reference<css::task::XInteractionHandler> xInteraction; 335cdf0e10cSrcweir if (m_xCommandEnv.is()) { 336cdf0e10cSrcweir xInteraction = m_xCommandEnv->getInteractionHandler(); 337cdf0e10cSrcweir } 338cdf0e10cSrcweir if (xInteraction.is()) { 339cdf0e10cSrcweir xInteraction->handle(xRequest); 340cdf0e10cSrcweir } 341cdf0e10cSrcweir } 342cdf0e10cSrcweir 343cdf0e10cSrcweir } 344cdf0e10cSrcweir 345cdf0e10cSrcweir namespace dp_misc { 346cdf0e10cSrcweir 347cdf0e10cSrcweir DescriptionInfoset getDescriptionInfoset(OUString const & sExtensionFolderURL) 348cdf0e10cSrcweir { 349cdf0e10cSrcweir Reference< css::xml::dom::XNode > root; 350cdf0e10cSrcweir Reference<css::uno::XComponentContext> context = 351cdf0e10cSrcweir comphelper_getProcessComponentContext(); 352cdf0e10cSrcweir OSL_ASSERT(context.is()); 353cdf0e10cSrcweir try { 354cdf0e10cSrcweir root = 355cdf0e10cSrcweir ExtensionDescription( 356cdf0e10cSrcweir context, sExtensionFolderURL, 357cdf0e10cSrcweir Reference< css::ucb::XCommandEnvironment >()). 358cdf0e10cSrcweir getRootElement(); 359cdf0e10cSrcweir } catch (NoDescriptionException &) { 360cdf0e10cSrcweir } catch (css::deployment::DeploymentException & e) { 361cdf0e10cSrcweir throw css::uno::RuntimeException( 362cdf0e10cSrcweir (OUString( 363cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 364cdf0e10cSrcweir "com.sun.star.deployment.DeploymentException: ")) + 365cdf0e10cSrcweir e.Message), 0); 366cdf0e10cSrcweir } 367cdf0e10cSrcweir return DescriptionInfoset(context, root); 368cdf0e10cSrcweir } 369cdf0e10cSrcweir 370cdf0e10cSrcweir DescriptionInfoset::DescriptionInfoset( 371cdf0e10cSrcweir css::uno::Reference< css::uno::XComponentContext > const & context, 372cdf0e10cSrcweir css::uno::Reference< css::xml::dom::XNode > const & element): 3739e813386SMichael Stahl m_context(context), 374cdf0e10cSrcweir m_element(element) 375cdf0e10cSrcweir { 376cdf0e10cSrcweir css::uno::Reference< css::lang::XMultiComponentFactory > manager( 377cdf0e10cSrcweir context->getServiceManager(), css::uno::UNO_QUERY_THROW); 378cdf0e10cSrcweir if (m_element.is()) { 379cdf0e10cSrcweir m_xpath = css::uno::Reference< css::xml::xpath::XXPathAPI >( 380cdf0e10cSrcweir manager->createInstanceWithContext( 381cdf0e10cSrcweir ::rtl::OUString( 382cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 383cdf0e10cSrcweir "com.sun.star.xml.xpath.XPathAPI")), 384cdf0e10cSrcweir context), 385cdf0e10cSrcweir css::uno::UNO_QUERY_THROW); 386cdf0e10cSrcweir m_xpath->registerNS( 387cdf0e10cSrcweir ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("desc")), 388cdf0e10cSrcweir element->getNamespaceURI()); 389cdf0e10cSrcweir m_xpath->registerNS( 390cdf0e10cSrcweir ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("xlink")), 391cdf0e10cSrcweir ::rtl::OUString( 392cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("http://www.w3.org/1999/xlink"))); 393cdf0e10cSrcweir } 394cdf0e10cSrcweir } 395cdf0e10cSrcweir 396cdf0e10cSrcweir DescriptionInfoset::~DescriptionInfoset() {} 397cdf0e10cSrcweir 398cdf0e10cSrcweir ::boost::optional< ::rtl::OUString > DescriptionInfoset::getIdentifier() const { 399cdf0e10cSrcweir return getOptionalValue( 400cdf0e10cSrcweir ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("desc:identifier/@value"))); 401cdf0e10cSrcweir } 402cdf0e10cSrcweir 403cdf0e10cSrcweir ::rtl::OUString DescriptionInfoset::getNodeValueFromExpression(::rtl::OUString const & expression) const 404cdf0e10cSrcweir { 405cdf0e10cSrcweir css::uno::Reference< css::xml::dom::XNode > n; 406cdf0e10cSrcweir if (m_element.is()) { 407cdf0e10cSrcweir try { 408cdf0e10cSrcweir n = m_xpath->selectSingleNode(m_element, expression); 409cdf0e10cSrcweir } catch (css::xml::xpath::XPathException &) { 410cdf0e10cSrcweir // ignore 411cdf0e10cSrcweir } 412cdf0e10cSrcweir } 413cdf0e10cSrcweir return n.is() ? getNodeValue(n) : ::rtl::OUString(); 414cdf0e10cSrcweir } 415cdf0e10cSrcweir 4169e813386SMichael Stahl void DescriptionInfoset::checkBlacklist() const 4179e813386SMichael Stahl { 4189e813386SMichael Stahl if (m_element.is()) { 4199e813386SMichael Stahl boost::optional< OUString > id(getIdentifier()); 4209e813386SMichael Stahl if (!id) 4219e813386SMichael Stahl return; // nothing to check 4229e813386SMichael Stahl OUString currentversion(getVersion()); 4239e813386SMichael Stahl if (currentversion.getLength() == 0) 4249e813386SMichael Stahl return; // nothing to check 4259e813386SMichael Stahl 4269e813386SMichael Stahl css::uno::Reference< css::lang::XMultiComponentFactory > manager( 4279e813386SMichael Stahl m_context->getServiceManager(), css::uno::UNO_QUERY_THROW); 4289e813386SMichael Stahl css::uno::Reference< css::lang::XMultiServiceFactory> provider( 4299e813386SMichael Stahl manager->createInstanceWithContext( 4309e813386SMichael Stahl ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.ConfigurationProvider")), m_context), 4319e813386SMichael Stahl css::uno::UNO_QUERY_THROW); 4329e813386SMichael Stahl 4339e813386SMichael Stahl css::uno::Sequence< css::uno::Any > args = css::uno::Sequence< css::uno::Any >(1); 4349e813386SMichael Stahl css::beans::PropertyValue prop; 4359e813386SMichael Stahl prop.Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("nodepath")); 4369e813386SMichael Stahl prop.Value <<= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/org.openoffice.Office.ExtensionDependencies/Extensions")); 4379e813386SMichael Stahl args[0] <<= prop; 4389e813386SMichael Stahl 4399e813386SMichael Stahl css::uno::Reference< css::container::XNameAccess > blacklist( 4409e813386SMichael Stahl provider->createInstanceWithArguments( 4419e813386SMichael Stahl ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.ConfigurationAccess")), args), 4429e813386SMichael Stahl css::uno::UNO_QUERY_THROW); 4439e813386SMichael Stahl 4449e813386SMichael Stahl // check first if a blacklist entry is available 4459e813386SMichael Stahl if (blacklist.is() && blacklist->hasByName(*id)) { 4469e813386SMichael Stahl css::uno::Reference< css::beans::XPropertySet > extProps( 4479e813386SMichael Stahl blacklist->getByName(*id), css::uno::UNO_QUERY_THROW); 4489e813386SMichael Stahl 4499e813386SMichael Stahl css::uno::Any anyValue = extProps->getPropertyValue( 4509e813386SMichael Stahl ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Versions"))); 4519e813386SMichael Stahl 4529e813386SMichael Stahl css::uno::Sequence< ::rtl::OUString > blversions; 4539e813386SMichael Stahl anyValue >>= blversions; 4549e813386SMichael Stahl 4559e813386SMichael Stahl // check if the current version requires further dependency checks from the blacklist 4569e813386SMichael Stahl if (checkBlacklistVersion(currentversion, blversions)) { 4579e813386SMichael Stahl anyValue = extProps->getPropertyValue( 4589e813386SMichael Stahl ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Dependencies"))); 4599e813386SMichael Stahl ::rtl::OUString udeps; 4609e813386SMichael Stahl anyValue >>= udeps; 4619e813386SMichael Stahl 4629e813386SMichael Stahl if (udeps.getLength() == 0) 4639e813386SMichael Stahl return; // nothing todo 4649e813386SMichael Stahl 4659e813386SMichael Stahl ::rtl::OString xmlDependencies = ::rtl::OUStringToOString(udeps, RTL_TEXTENCODING_UNICODE); 4669e813386SMichael Stahl 4679e813386SMichael Stahl css::uno::Reference< css::xml::dom::XDocumentBuilder> docbuilder( 4689e813386SMichael Stahl manager->createInstanceWithContext( 4699e813386SMichael Stahl ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.dom.DocumentBuilder")), m_context), 4709e813386SMichael Stahl css::uno::UNO_QUERY_THROW); 4719e813386SMichael Stahl 4729e813386SMichael Stahl css::uno::Sequence< sal_Int8 > byteSeq((const sal_Int8*)xmlDependencies.getStr(), xmlDependencies.getLength()); 4739e813386SMichael Stahl 4749e813386SMichael Stahl css::uno::Reference< css::io::XInputStream> inputstream( css::io::SequenceInputStream::createStreamFromSequence(m_context, byteSeq), 4759e813386SMichael Stahl css::uno::UNO_QUERY_THROW); 4769e813386SMichael Stahl 4779e813386SMichael Stahl css::uno::Reference< css::xml::dom::XDocument > xDocument(docbuilder->parse(inputstream)); 4789e813386SMichael Stahl css::uno::Reference< css::xml::dom::XElement > xElement(xDocument->getDocumentElement()); 4799e813386SMichael Stahl css::uno::Reference< css::xml::dom::XNodeList > xDeps(xElement->getChildNodes()); 4809e813386SMichael Stahl sal_Int32 nLen = xDeps->getLength(); 4819e813386SMichael Stahl 482*2bc1ebb7SMichael Stahl // get the parent xml document of current description info for the import 483*2bc1ebb7SMichael Stahl css::uno::Reference< css::xml::dom::XDocument > xCurrentDescInfo(m_element->getOwnerDocument()); 484*2bc1ebb7SMichael Stahl 4859e813386SMichael Stahl // get dependency node of current description info to merge the new dependencies from the blacklist 4869e813386SMichael Stahl css::uno::Reference< css::xml::dom::XNode > xCurrentDeps( 4879e813386SMichael Stahl m_xpath->selectSingleNode(m_element, ::rtl::OUString( 4889e813386SMichael Stahl RTL_CONSTASCII_USTRINGPARAM("desc:dependencies")))); 4899e813386SMichael Stahl 490*2bc1ebb7SMichael Stahl // if no dependency node exists, create a new one in the current description info 491*2bc1ebb7SMichael Stahl if (!xCurrentDeps.is()) { 492*2bc1ebb7SMichael Stahl css::uno::Reference< css::xml::dom::XNode > xNewDepNode( 493*2bc1ebb7SMichael Stahl xCurrentDescInfo->createElementNS( 494*2bc1ebb7SMichael Stahl ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("http://openoffice.org/extensions/description/2006")), 495*2bc1ebb7SMichael Stahl ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("dependencies"))), css::uno::UNO_QUERY_THROW); 496*2bc1ebb7SMichael Stahl m_element->appendChild(xNewDepNode); 497*2bc1ebb7SMichael Stahl xCurrentDeps = m_xpath->selectSingleNode(m_element, ::rtl::OUString( 498*2bc1ebb7SMichael Stahl RTL_CONSTASCII_USTRINGPARAM("desc:dependencies"))); 499*2bc1ebb7SMichael Stahl } 5009e813386SMichael Stahl 5019e813386SMichael Stahl for (sal_Int32 i=0; i<nLen; i++) { 5029e813386SMichael Stahl css::uno::Reference< css::xml::dom::XNode > xNode(xDeps->item(i)); 5039e813386SMichael Stahl css::uno::Reference< css::xml::dom::XElement > xDep(xNode, css::uno::UNO_QUERY); 5049e813386SMichael Stahl if (xDep.is()) { 5059e813386SMichael Stahl // found valid blacklist dependency, import the node first and append it to the existing dependency node 5069e813386SMichael Stahl css::uno::Reference< css::xml::dom::XNode > importedNode = xCurrentDescInfo->importNode(xNode, true); 5079e813386SMichael Stahl xCurrentDeps->appendChild(importedNode); 5089e813386SMichael Stahl } 5099e813386SMichael Stahl } 5109e813386SMichael Stahl } 5119e813386SMichael Stahl } 5129e813386SMichael Stahl } 5139e813386SMichael Stahl } 5149e813386SMichael Stahl 5159e813386SMichael Stahl bool DescriptionInfoset::checkBlacklistVersion( 5169e813386SMichael Stahl ::rtl::OUString currentversion, 5179e813386SMichael Stahl ::com::sun::star::uno::Sequence< ::rtl::OUString > const & versions) const 5189e813386SMichael Stahl { 5199e813386SMichael Stahl sal_Int32 nLen = versions.getLength(); 5209e813386SMichael Stahl for (sal_Int32 i=0; i<nLen; i++) { 5219e813386SMichael Stahl if (currentversion.equals(versions[i])) 5229e813386SMichael Stahl return true; 5239e813386SMichael Stahl } 5249e813386SMichael Stahl 5259e813386SMichael Stahl return false; 5269e813386SMichael Stahl } 527cdf0e10cSrcweir 528cdf0e10cSrcweir ::rtl::OUString DescriptionInfoset::getVersion() const 529cdf0e10cSrcweir { 530cdf0e10cSrcweir return getNodeValueFromExpression( ::rtl::OUString( 531cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("desc:version/@value"))); 532cdf0e10cSrcweir } 533cdf0e10cSrcweir 534cdf0e10cSrcweir css::uno::Sequence< ::rtl::OUString > DescriptionInfoset::getSupportedPlaforms() const 535cdf0e10cSrcweir { 536cdf0e10cSrcweir //When there is no description.xml then we assume that we support all platforms 537cdf0e10cSrcweir if (! m_element.is()) 538cdf0e10cSrcweir { 539cdf0e10cSrcweir return comphelper::makeSequence( 540cdf0e10cSrcweir ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("all"))); 541cdf0e10cSrcweir } 542cdf0e10cSrcweir 543cdf0e10cSrcweir //Check if the <platform> element was provided. If not the default is "all" platforms 544cdf0e10cSrcweir css::uno::Reference< css::xml::dom::XNode > nodePlatform( 545cdf0e10cSrcweir m_xpath->selectSingleNode(m_element, ::rtl::OUString( 546cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("desc:platform")))); 547cdf0e10cSrcweir if (!nodePlatform.is()) 548cdf0e10cSrcweir { 549cdf0e10cSrcweir return comphelper::makeSequence( 550cdf0e10cSrcweir ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("all"))); 551cdf0e10cSrcweir } 552cdf0e10cSrcweir 553cdf0e10cSrcweir //There is a platform element. 554cdf0e10cSrcweir const ::rtl::OUString value = getNodeValueFromExpression(::rtl::OUString( 555cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("desc:platform/@value"))); 556cdf0e10cSrcweir //parse the string, it can contained multiple strings separated by commas 557cdf0e10cSrcweir ::std::vector< ::rtl::OUString> vec; 558cdf0e10cSrcweir sal_Int32 nIndex = 0; 559cdf0e10cSrcweir do 560cdf0e10cSrcweir { 561cdf0e10cSrcweir ::rtl::OUString aToken = value.getToken( 0, ',', nIndex ); 562cdf0e10cSrcweir aToken = aToken.trim(); 563cdf0e10cSrcweir if (aToken.getLength()) 564cdf0e10cSrcweir vec.push_back(aToken); 5659e813386SMichael Stahl 566cdf0e10cSrcweir } 567cdf0e10cSrcweir while (nIndex >= 0); 568cdf0e10cSrcweir 569cdf0e10cSrcweir return comphelper::containerToSequence(vec); 570cdf0e10cSrcweir } 571cdf0e10cSrcweir 572cdf0e10cSrcweir css::uno::Reference< css::xml::dom::XNodeList > 573cdf0e10cSrcweir DescriptionInfoset::getDependencies() const { 574cdf0e10cSrcweir if (m_element.is()) { 575cdf0e10cSrcweir try { 5769e813386SMichael Stahl // check the extension blacklist first and expand the dependencies if applicable 5779e813386SMichael Stahl checkBlacklist(); 5789e813386SMichael Stahl 579cdf0e10cSrcweir return m_xpath->selectNodeList(m_element, ::rtl::OUString( 580cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("desc:dependencies/*"))); 581cdf0e10cSrcweir } catch (css::xml::xpath::XPathException &) { 582cdf0e10cSrcweir // ignore 583cdf0e10cSrcweir } 584cdf0e10cSrcweir } 585cdf0e10cSrcweir return new EmptyNodeList; 586cdf0e10cSrcweir } 587cdf0e10cSrcweir 588cdf0e10cSrcweir css::uno::Sequence< ::rtl::OUString > 589cdf0e10cSrcweir DescriptionInfoset::getUpdateInformationUrls() const { 590cdf0e10cSrcweir return getUrls( 591cdf0e10cSrcweir ::rtl::OUString( 592cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 593cdf0e10cSrcweir "desc:update-information/desc:src/@xlink:href"))); 594cdf0e10cSrcweir } 595cdf0e10cSrcweir 596cdf0e10cSrcweir css::uno::Sequence< ::rtl::OUString > 597cdf0e10cSrcweir DescriptionInfoset::getUpdateDownloadUrls() const 598cdf0e10cSrcweir { 599cdf0e10cSrcweir return getUrls( 600cdf0e10cSrcweir ::rtl::OUString( 601cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 602cdf0e10cSrcweir "desc:update-download/desc:src/@xlink:href"))); 603cdf0e10cSrcweir } 604cdf0e10cSrcweir 605cdf0e10cSrcweir ::rtl::OUString DescriptionInfoset::getIconURL( sal_Bool bHighContrast ) const 606cdf0e10cSrcweir { 607cdf0e10cSrcweir css::uno::Sequence< ::rtl::OUString > aStrList = getUrls( ::rtl::OUString( 608cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( "desc:icon/desc:default/@xlink:href"))); 609cdf0e10cSrcweir css::uno::Sequence< ::rtl::OUString > aStrListHC = getUrls( ::rtl::OUString( 610cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( "desc:icon/desc:high-contrast/@xlink:href"))); 611cdf0e10cSrcweir 612cdf0e10cSrcweir if ( bHighContrast && aStrListHC.hasElements() && aStrListHC[0].getLength() ) 613cdf0e10cSrcweir return aStrListHC[0]; 614cdf0e10cSrcweir 615cdf0e10cSrcweir if ( aStrList.hasElements() && aStrList[0].getLength() ) 616cdf0e10cSrcweir return aStrList[0]; 617cdf0e10cSrcweir 618cdf0e10cSrcweir return ::rtl::OUString(); 619cdf0e10cSrcweir } 620cdf0e10cSrcweir 621cdf0e10cSrcweir ::boost::optional< ::rtl::OUString > DescriptionInfoset::getLocalizedUpdateWebsiteURL() 622cdf0e10cSrcweir const 623cdf0e10cSrcweir { 624cdf0e10cSrcweir bool bParentExists = false; 625cdf0e10cSrcweir const ::rtl::OUString sURL (getLocalizedHREFAttrFromChild(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 626cdf0e10cSrcweir "/desc:description/desc:update-website")), &bParentExists )); 627cdf0e10cSrcweir 628cdf0e10cSrcweir if (sURL.getLength() > 0) 629cdf0e10cSrcweir return ::boost::optional< ::rtl::OUString >(sURL); 630cdf0e10cSrcweir else 631cdf0e10cSrcweir return bParentExists ? ::boost::optional< ::rtl::OUString >(::rtl::OUString()) : 632cdf0e10cSrcweir ::boost::optional< ::rtl::OUString >(); 633cdf0e10cSrcweir } 634cdf0e10cSrcweir 635cdf0e10cSrcweir ::boost::optional< ::rtl::OUString > DescriptionInfoset::getOptionalValue( 636cdf0e10cSrcweir ::rtl::OUString const & expression) const 637cdf0e10cSrcweir { 638cdf0e10cSrcweir css::uno::Reference< css::xml::dom::XNode > n; 639cdf0e10cSrcweir if (m_element.is()) { 640cdf0e10cSrcweir try { 641cdf0e10cSrcweir n = m_xpath->selectSingleNode(m_element, expression); 642cdf0e10cSrcweir } catch (css::xml::xpath::XPathException &) { 643cdf0e10cSrcweir // ignore 644cdf0e10cSrcweir } 645cdf0e10cSrcweir } 646cdf0e10cSrcweir return n.is() 647cdf0e10cSrcweir ? ::boost::optional< ::rtl::OUString >(getNodeValue(n)) 648cdf0e10cSrcweir : ::boost::optional< ::rtl::OUString >(); 649cdf0e10cSrcweir } 650cdf0e10cSrcweir 651cdf0e10cSrcweir css::uno::Sequence< ::rtl::OUString > DescriptionInfoset::getUrls( 652cdf0e10cSrcweir ::rtl::OUString const & expression) const 653cdf0e10cSrcweir { 654cdf0e10cSrcweir css::uno::Reference< css::xml::dom::XNodeList > ns; 655cdf0e10cSrcweir if (m_element.is()) { 656cdf0e10cSrcweir try { 657cdf0e10cSrcweir ns = m_xpath->selectNodeList(m_element, expression); 658cdf0e10cSrcweir } catch (css::xml::xpath::XPathException &) { 659cdf0e10cSrcweir // ignore 660cdf0e10cSrcweir } 661cdf0e10cSrcweir } 662cdf0e10cSrcweir css::uno::Sequence< ::rtl::OUString > urls(ns.is() ? ns->getLength() : 0); 663cdf0e10cSrcweir for (::sal_Int32 i = 0; i < urls.getLength(); ++i) { 664cdf0e10cSrcweir urls[i] = getNodeValue(ns->item(i)); 665cdf0e10cSrcweir } 666cdf0e10cSrcweir return urls; 667cdf0e10cSrcweir } 668cdf0e10cSrcweir 669cdf0e10cSrcweir ::std::pair< ::rtl::OUString, ::rtl::OUString > DescriptionInfoset::getLocalizedPublisherNameAndURL() const 670cdf0e10cSrcweir { 671cdf0e10cSrcweir css::uno::Reference< css::xml::dom::XNode > node = 672cdf0e10cSrcweir getLocalizedChild(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("desc:publisher"))); 673cdf0e10cSrcweir 674cdf0e10cSrcweir ::rtl::OUString sPublisherName; 675cdf0e10cSrcweir ::rtl::OUString sURL; 676cdf0e10cSrcweir if (node.is()) 677cdf0e10cSrcweir { 678cdf0e10cSrcweir const ::rtl::OUString exp1(RTL_CONSTASCII_USTRINGPARAM("text()")); 679cdf0e10cSrcweir css::uno::Reference< css::xml::dom::XNode > xPathName; 680cdf0e10cSrcweir try { 681cdf0e10cSrcweir xPathName = m_xpath->selectSingleNode(node, exp1); 682cdf0e10cSrcweir } catch (css::xml::xpath::XPathException &) { 683cdf0e10cSrcweir // ignore 684cdf0e10cSrcweir } 685cdf0e10cSrcweir OSL_ASSERT(xPathName.is()); 686cdf0e10cSrcweir if (xPathName.is()) 687cdf0e10cSrcweir sPublisherName = xPathName->getNodeValue(); 688cdf0e10cSrcweir 689cdf0e10cSrcweir const ::rtl::OUString exp2(RTL_CONSTASCII_USTRINGPARAM("@xlink:href")); 690cdf0e10cSrcweir css::uno::Reference< css::xml::dom::XNode > xURL; 691cdf0e10cSrcweir try { 692cdf0e10cSrcweir xURL = m_xpath->selectSingleNode(node, exp2); 693cdf0e10cSrcweir } catch (css::xml::xpath::XPathException &) { 694cdf0e10cSrcweir // ignore 695cdf0e10cSrcweir } 696cdf0e10cSrcweir OSL_ASSERT(xURL.is()); 697cdf0e10cSrcweir if (xURL.is()) 698cdf0e10cSrcweir sURL = xURL->getNodeValue(); 699cdf0e10cSrcweir } 700cdf0e10cSrcweir return ::std::make_pair(sPublisherName, sURL); 701cdf0e10cSrcweir } 702cdf0e10cSrcweir 703cdf0e10cSrcweir ::rtl::OUString DescriptionInfoset::getLocalizedReleaseNotesURL() const 704cdf0e10cSrcweir { 705cdf0e10cSrcweir return getLocalizedHREFAttrFromChild(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 706cdf0e10cSrcweir "/desc:description/desc:release-notes")), NULL); 707cdf0e10cSrcweir } 708cdf0e10cSrcweir 709cdf0e10cSrcweir ::rtl::OUString DescriptionInfoset::getLocalizedDisplayName() const 710cdf0e10cSrcweir { 711cdf0e10cSrcweir css::uno::Reference< css::xml::dom::XNode > node = 712cdf0e10cSrcweir getLocalizedChild(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("desc:display-name"))); 713cdf0e10cSrcweir if (node.is()) 714cdf0e10cSrcweir { 715cdf0e10cSrcweir const ::rtl::OUString exp(RTL_CONSTASCII_USTRINGPARAM("text()")); 716cdf0e10cSrcweir css::uno::Reference< css::xml::dom::XNode > xtext; 717cdf0e10cSrcweir try { 718cdf0e10cSrcweir xtext = m_xpath->selectSingleNode(node, exp); 719cdf0e10cSrcweir } catch (css::xml::xpath::XPathException &) { 720cdf0e10cSrcweir // ignore 721cdf0e10cSrcweir } 722cdf0e10cSrcweir if (xtext.is()) 723cdf0e10cSrcweir return xtext->getNodeValue(); 724cdf0e10cSrcweir } 725cdf0e10cSrcweir return ::rtl::OUString(); 726cdf0e10cSrcweir } 727cdf0e10cSrcweir 728cdf0e10cSrcweir ::rtl::OUString DescriptionInfoset::getLocalizedLicenseURL() const 729cdf0e10cSrcweir { 730cdf0e10cSrcweir return getLocalizedHREFAttrFromChild(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 731cdf0e10cSrcweir "/desc:description/desc:registration/desc:simple-license")), NULL); 732cdf0e10cSrcweir 733cdf0e10cSrcweir } 734cdf0e10cSrcweir 735cdf0e10cSrcweir ::boost::optional<SimpleLicenseAttributes> 736cdf0e10cSrcweir DescriptionInfoset::getSimpleLicenseAttributes() const 737cdf0e10cSrcweir { 738cdf0e10cSrcweir //Check if the node exist 739cdf0e10cSrcweir css::uno::Reference< css::xml::dom::XNode > n; 740cdf0e10cSrcweir if (m_element.is()) { 741cdf0e10cSrcweir try { 742cdf0e10cSrcweir n = m_xpath->selectSingleNode(m_element, 743cdf0e10cSrcweir ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 744cdf0e10cSrcweir "/desc:description/desc:registration/desc:simple-license/@accept-by"))); 745cdf0e10cSrcweir } catch (css::xml::xpath::XPathException &) { 746cdf0e10cSrcweir // ignore 747cdf0e10cSrcweir } 748cdf0e10cSrcweir if (n.is()) 749cdf0e10cSrcweir { 750cdf0e10cSrcweir SimpleLicenseAttributes attributes; 751cdf0e10cSrcweir attributes.acceptBy = 752cdf0e10cSrcweir getNodeValueFromExpression(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 753cdf0e10cSrcweir "/desc:description/desc:registration/desc:simple-license/@accept-by"))); 754cdf0e10cSrcweir 755cdf0e10cSrcweir ::boost::optional< ::rtl::OUString > suppressOnUpdate = getOptionalValue( 756cdf0e10cSrcweir ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 757cdf0e10cSrcweir "/desc:description/desc:registration/desc:simple-license/@suppress-on-update"))); 758cdf0e10cSrcweir if (suppressOnUpdate) 759cdf0e10cSrcweir attributes.suppressOnUpdate = (*suppressOnUpdate).trim().equalsIgnoreAsciiCase( 760cdf0e10cSrcweir ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("true"))); 761cdf0e10cSrcweir else 762cdf0e10cSrcweir attributes.suppressOnUpdate = false; 763cdf0e10cSrcweir 764cdf0e10cSrcweir ::boost::optional< ::rtl::OUString > suppressIfRequired = getOptionalValue( 765cdf0e10cSrcweir ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 766cdf0e10cSrcweir "/desc:description/desc:registration/desc:simple-license/@suppress-if-required"))); 767cdf0e10cSrcweir if (suppressIfRequired) 768cdf0e10cSrcweir attributes.suppressIfRequired = (*suppressIfRequired).trim().equalsIgnoreAsciiCase( 769cdf0e10cSrcweir ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("true"))); 770cdf0e10cSrcweir else 771cdf0e10cSrcweir attributes.suppressIfRequired = false; 772cdf0e10cSrcweir 773cdf0e10cSrcweir return ::boost::optional<SimpleLicenseAttributes>(attributes); 774cdf0e10cSrcweir } 775cdf0e10cSrcweir } 776cdf0e10cSrcweir return ::boost::optional<SimpleLicenseAttributes>(); 777cdf0e10cSrcweir } 778cdf0e10cSrcweir 779cdf0e10cSrcweir ::rtl::OUString DescriptionInfoset::getLocalizedDescriptionURL() const 780cdf0e10cSrcweir { 781cdf0e10cSrcweir return getLocalizedHREFAttrFromChild(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 782cdf0e10cSrcweir "/desc:description/desc:extension-description")), NULL); 783cdf0e10cSrcweir } 784cdf0e10cSrcweir 785cdf0e10cSrcweir css::uno::Reference< css::xml::dom::XNode > 786cdf0e10cSrcweir DescriptionInfoset::getLocalizedChild( const ::rtl::OUString & sParent) const 787cdf0e10cSrcweir { 788cdf0e10cSrcweir if ( ! m_element.is() || !sParent.getLength()) 789cdf0e10cSrcweir return css::uno::Reference< css::xml::dom::XNode > (); 790cdf0e10cSrcweir 791cdf0e10cSrcweir css::uno::Reference< css::xml::dom::XNode > xParent; 792cdf0e10cSrcweir try { 793cdf0e10cSrcweir xParent = m_xpath->selectSingleNode(m_element, sParent); 794cdf0e10cSrcweir } catch (css::xml::xpath::XPathException &) { 795cdf0e10cSrcweir // ignore 796cdf0e10cSrcweir } 797cdf0e10cSrcweir css::uno::Reference<css::xml::dom::XNode> nodeMatch; 798cdf0e10cSrcweir if (xParent.is()) 799cdf0e10cSrcweir { 800cdf0e10cSrcweir const ::rtl::OUString sLocale = getOfficeLocaleString(); 801cdf0e10cSrcweir nodeMatch = matchFullLocale(xParent, sLocale); 802cdf0e10cSrcweir 803cdf0e10cSrcweir //office: en-DE, en, en-DE-altmark 804cdf0e10cSrcweir if (! nodeMatch.is()) 805cdf0e10cSrcweir { 806cdf0e10cSrcweir const css::lang::Locale officeLocale = getOfficeLocale(); 807cdf0e10cSrcweir nodeMatch = matchCountryAndLanguage(xParent, officeLocale); 808cdf0e10cSrcweir if ( ! nodeMatch.is()) 809cdf0e10cSrcweir { 810cdf0e10cSrcweir nodeMatch = matchLanguage(xParent, officeLocale); 811cdf0e10cSrcweir if (! nodeMatch.is()) 812cdf0e10cSrcweir nodeMatch = getChildWithDefaultLocale(xParent); 813cdf0e10cSrcweir } 814cdf0e10cSrcweir } 815cdf0e10cSrcweir } 816cdf0e10cSrcweir 817cdf0e10cSrcweir return nodeMatch; 818cdf0e10cSrcweir } 819cdf0e10cSrcweir 820cdf0e10cSrcweir css::uno::Reference<css::xml::dom::XNode> 821cdf0e10cSrcweir DescriptionInfoset::matchFullLocale(css::uno::Reference< css::xml::dom::XNode > 822cdf0e10cSrcweir const & xParent, ::rtl::OUString const & sLocale) const 823cdf0e10cSrcweir { 824cdf0e10cSrcweir OSL_ASSERT(xParent.is()); 825cdf0e10cSrcweir const ::rtl::OUString exp1( 826cdf0e10cSrcweir ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("*[@lang=\"")) 827cdf0e10cSrcweir + sLocale + 828cdf0e10cSrcweir ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\"]"))); 829cdf0e10cSrcweir try { 830cdf0e10cSrcweir return m_xpath->selectSingleNode(xParent, exp1); 831cdf0e10cSrcweir } catch (css::xml::xpath::XPathException &) { 832cdf0e10cSrcweir // ignore 833cdf0e10cSrcweir return 0; 834cdf0e10cSrcweir } 835cdf0e10cSrcweir } 836cdf0e10cSrcweir 837cdf0e10cSrcweir css::uno::Reference<css::xml::dom::XNode> 838cdf0e10cSrcweir DescriptionInfoset::matchCountryAndLanguage( 839cdf0e10cSrcweir css::uno::Reference< css::xml::dom::XNode > const & xParent, css::lang::Locale const & officeLocale) const 840cdf0e10cSrcweir { 841cdf0e10cSrcweir OSL_ASSERT(xParent.is()); 842cdf0e10cSrcweir css::uno::Reference<css::xml::dom::XNode> nodeMatch; 843cdf0e10cSrcweir 844cdf0e10cSrcweir if (officeLocale.Country.getLength()) 845cdf0e10cSrcweir { 846cdf0e10cSrcweir const ::rtl::OUString sLangCountry(officeLocale.Language + 847cdf0e10cSrcweir ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("-")) + 848cdf0e10cSrcweir officeLocale.Country); 849cdf0e10cSrcweir //first try exact match for lang-country 850cdf0e10cSrcweir const ::rtl::OUString exp1( 851cdf0e10cSrcweir ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("*[@lang=\"")) 852cdf0e10cSrcweir + sLangCountry + 853cdf0e10cSrcweir ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\"]"))); 854cdf0e10cSrcweir try { 855cdf0e10cSrcweir nodeMatch = m_xpath->selectSingleNode(xParent, exp1); 856cdf0e10cSrcweir } catch (css::xml::xpath::XPathException &) { 857cdf0e10cSrcweir // ignore 858cdf0e10cSrcweir } 859cdf0e10cSrcweir 860cdf0e10cSrcweir //try to match in strings that also have a variant, for example en-US matches in 861cdf0e10cSrcweir //en-US-montana 862cdf0e10cSrcweir if (!nodeMatch.is()) 863cdf0e10cSrcweir { 864cdf0e10cSrcweir const ::rtl::OUString exp2( 865cdf0e10cSrcweir ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("*[starts-with(@lang,\"")) 866cdf0e10cSrcweir + sLangCountry + 867cdf0e10cSrcweir ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("-\")]"))); 868cdf0e10cSrcweir try { 869cdf0e10cSrcweir nodeMatch = m_xpath->selectSingleNode(xParent, exp2); 870cdf0e10cSrcweir } catch (css::xml::xpath::XPathException &) { 871cdf0e10cSrcweir // ignore 872cdf0e10cSrcweir } 873cdf0e10cSrcweir } 874cdf0e10cSrcweir } 875cdf0e10cSrcweir 876cdf0e10cSrcweir return nodeMatch; 877cdf0e10cSrcweir } 878cdf0e10cSrcweir 879cdf0e10cSrcweir 880cdf0e10cSrcweir css::uno::Reference<css::xml::dom::XNode> 881cdf0e10cSrcweir DescriptionInfoset::matchLanguage( 882cdf0e10cSrcweir css::uno::Reference< css::xml::dom::XNode > const & xParent, css::lang::Locale const & officeLocale) const 883cdf0e10cSrcweir { 884cdf0e10cSrcweir OSL_ASSERT(xParent.is()); 885cdf0e10cSrcweir css::uno::Reference<css::xml::dom::XNode> nodeMatch; 886cdf0e10cSrcweir 887cdf0e10cSrcweir //first try exact match for lang 888cdf0e10cSrcweir const ::rtl::OUString exp1( 889cdf0e10cSrcweir ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("*[@lang=\"")) 890cdf0e10cSrcweir + officeLocale.Language 891cdf0e10cSrcweir + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\"]"))); 892cdf0e10cSrcweir try { 893cdf0e10cSrcweir nodeMatch = m_xpath->selectSingleNode(xParent, exp1); 894cdf0e10cSrcweir } catch (css::xml::xpath::XPathException &) { 895cdf0e10cSrcweir // ignore 896cdf0e10cSrcweir } 897cdf0e10cSrcweir 898cdf0e10cSrcweir //try to match in strings that also have a country and/orvariant, for example en matches in 899cdf0e10cSrcweir //en-US-montana, en-US, en-montana 900cdf0e10cSrcweir if (!nodeMatch.is()) 901cdf0e10cSrcweir { 902cdf0e10cSrcweir const ::rtl::OUString exp2( 903cdf0e10cSrcweir ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("*[starts-with(@lang,\"")) 904cdf0e10cSrcweir + officeLocale.Language 905cdf0e10cSrcweir + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("-\")]"))); 906cdf0e10cSrcweir try { 907cdf0e10cSrcweir nodeMatch = m_xpath->selectSingleNode(xParent, exp2); 908cdf0e10cSrcweir } catch (css::xml::xpath::XPathException &) { 909cdf0e10cSrcweir // ignore 910cdf0e10cSrcweir } 911cdf0e10cSrcweir } 912cdf0e10cSrcweir return nodeMatch; 913cdf0e10cSrcweir } 914cdf0e10cSrcweir 915cdf0e10cSrcweir css::uno::Reference<css::xml::dom::XNode> 916cdf0e10cSrcweir DescriptionInfoset::getChildWithDefaultLocale(css::uno::Reference< css::xml::dom::XNode > 917cdf0e10cSrcweir const & xParent) const 918cdf0e10cSrcweir { 919cdf0e10cSrcweir OSL_ASSERT(xParent.is()); 920cdf0e10cSrcweir if (xParent->getNodeName().equals(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("simple-license")))) 921cdf0e10cSrcweir { 922cdf0e10cSrcweir css::uno::Reference<css::xml::dom::XNode> nodeDefault; 923cdf0e10cSrcweir try { 924cdf0e10cSrcweir nodeDefault = m_xpath->selectSingleNode(xParent, ::rtl::OUString( 925cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("@default-license-id"))); 926cdf0e10cSrcweir } catch (css::xml::xpath::XPathException &) { 927cdf0e10cSrcweir // ignore 928cdf0e10cSrcweir } 929cdf0e10cSrcweir if (nodeDefault.is()) 930cdf0e10cSrcweir { 931cdf0e10cSrcweir //The old way 932cdf0e10cSrcweir const ::rtl::OUString exp1( 933cdf0e10cSrcweir ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("desc:license-text[@license-id = \"")) 934cdf0e10cSrcweir + nodeDefault->getNodeValue() 935cdf0e10cSrcweir + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\"]"))); 936cdf0e10cSrcweir try { 937cdf0e10cSrcweir return m_xpath->selectSingleNode(xParent, exp1); 938cdf0e10cSrcweir } catch (css::xml::xpath::XPathException &) { 939cdf0e10cSrcweir // ignore 940cdf0e10cSrcweir } 941cdf0e10cSrcweir } 942cdf0e10cSrcweir } 943cdf0e10cSrcweir 944cdf0e10cSrcweir const ::rtl::OUString exp2(RTL_CONSTASCII_USTRINGPARAM("*[1]")); 945cdf0e10cSrcweir try { 946cdf0e10cSrcweir return m_xpath->selectSingleNode(xParent, exp2); 947cdf0e10cSrcweir } catch (css::xml::xpath::XPathException &) { 948cdf0e10cSrcweir // ignore 949cdf0e10cSrcweir return 0; 950cdf0e10cSrcweir } 951cdf0e10cSrcweir } 952cdf0e10cSrcweir 953cdf0e10cSrcweir ::rtl::OUString DescriptionInfoset::getLocalizedHREFAttrFromChild( 954cdf0e10cSrcweir ::rtl::OUString const & sXPathParent, bool * out_bParentExists) 955cdf0e10cSrcweir const 956cdf0e10cSrcweir { 957cdf0e10cSrcweir css::uno::Reference< css::xml::dom::XNode > node = 958cdf0e10cSrcweir getLocalizedChild(sXPathParent); 959cdf0e10cSrcweir 960cdf0e10cSrcweir ::rtl::OUString sURL; 961cdf0e10cSrcweir if (node.is()) 962cdf0e10cSrcweir { 963cdf0e10cSrcweir if (out_bParentExists) 964cdf0e10cSrcweir *out_bParentExists = true; 965cdf0e10cSrcweir const ::rtl::OUString exp(RTL_CONSTASCII_USTRINGPARAM("@xlink:href")); 966cdf0e10cSrcweir css::uno::Reference< css::xml::dom::XNode > xURL; 967cdf0e10cSrcweir try { 968cdf0e10cSrcweir xURL = m_xpath->selectSingleNode(node, exp); 969cdf0e10cSrcweir } catch (css::xml::xpath::XPathException &) { 970cdf0e10cSrcweir // ignore 971cdf0e10cSrcweir } 972cdf0e10cSrcweir OSL_ASSERT(xURL.is()); 973cdf0e10cSrcweir if (xURL.is()) 974cdf0e10cSrcweir sURL = xURL->getNodeValue(); 975cdf0e10cSrcweir } 976cdf0e10cSrcweir else 977cdf0e10cSrcweir { 978cdf0e10cSrcweir if (out_bParentExists) 979cdf0e10cSrcweir *out_bParentExists = false; 980cdf0e10cSrcweir } 981cdf0e10cSrcweir return sURL; 982cdf0e10cSrcweir } 983cdf0e10cSrcweir 984cdf0e10cSrcweir } 985