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" 37*9e813386SMichael Stahl #include "comphelper/seqstream.hxx" 38cdf0e10cSrcweir #include "comphelper/makesequence.hxx" 39cdf0e10cSrcweir #include "comphelper/processfactory.hxx" 40cdf0e10cSrcweir #include "boost/optional.hpp" 41*9e813386SMichael Stahl #include "com/sun/star/container/XNameAccess.hpp" 42cdf0e10cSrcweir #include "com/sun/star/beans/Optional.hpp" 43*9e813386SMichael Stahl #include "com/sun/star/beans/PropertyValue.hpp" 44*9e813386SMichael Stahl #include "com/sun/star/beans/XPropertySet.hpp" 45*9e813386SMichael 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): 373*9e813386SMichael 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 416*9e813386SMichael Stahl void DescriptionInfoset::checkBlacklist() const 417*9e813386SMichael Stahl { 418*9e813386SMichael Stahl if (m_element.is()) { 419*9e813386SMichael Stahl boost::optional< OUString > id(getIdentifier()); 420*9e813386SMichael Stahl if (!id) 421*9e813386SMichael Stahl return; // nothing to check 422*9e813386SMichael Stahl OUString currentversion(getVersion()); 423*9e813386SMichael Stahl if (currentversion.getLength() == 0) 424*9e813386SMichael Stahl return; // nothing to check 425*9e813386SMichael Stahl 426*9e813386SMichael Stahl css::uno::Reference< css::lang::XMultiComponentFactory > manager( 427*9e813386SMichael Stahl m_context->getServiceManager(), css::uno::UNO_QUERY_THROW); 428*9e813386SMichael Stahl css::uno::Reference< css::lang::XMultiServiceFactory> provider( 429*9e813386SMichael Stahl manager->createInstanceWithContext( 430*9e813386SMichael Stahl ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.ConfigurationProvider")), m_context), 431*9e813386SMichael Stahl css::uno::UNO_QUERY_THROW); 432*9e813386SMichael Stahl 433*9e813386SMichael Stahl css::uno::Sequence< css::uno::Any > args = css::uno::Sequence< css::uno::Any >(1); 434*9e813386SMichael Stahl css::beans::PropertyValue prop; 435*9e813386SMichael Stahl prop.Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("nodepath")); 436*9e813386SMichael Stahl prop.Value <<= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/org.openoffice.Office.ExtensionDependencies/Extensions")); 437*9e813386SMichael Stahl args[0] <<= prop; 438*9e813386SMichael Stahl 439*9e813386SMichael Stahl css::uno::Reference< css::container::XNameAccess > blacklist( 440*9e813386SMichael Stahl provider->createInstanceWithArguments( 441*9e813386SMichael Stahl ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.ConfigurationAccess")), args), 442*9e813386SMichael Stahl css::uno::UNO_QUERY_THROW); 443*9e813386SMichael Stahl 444*9e813386SMichael Stahl // check first if a blacklist entry is available 445*9e813386SMichael Stahl if (blacklist.is() && blacklist->hasByName(*id)) { 446*9e813386SMichael Stahl css::uno::Reference< css::beans::XPropertySet > extProps( 447*9e813386SMichael Stahl blacklist->getByName(*id), css::uno::UNO_QUERY_THROW); 448*9e813386SMichael Stahl 449*9e813386SMichael Stahl css::uno::Any anyValue = extProps->getPropertyValue( 450*9e813386SMichael Stahl ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Versions"))); 451*9e813386SMichael Stahl 452*9e813386SMichael Stahl css::uno::Sequence< ::rtl::OUString > blversions; 453*9e813386SMichael Stahl anyValue >>= blversions; 454*9e813386SMichael Stahl 455*9e813386SMichael Stahl // check if the current version requires further dependency checks from the blacklist 456*9e813386SMichael Stahl if (checkBlacklistVersion(currentversion, blversions)) { 457*9e813386SMichael Stahl anyValue = extProps->getPropertyValue( 458*9e813386SMichael Stahl ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Dependencies"))); 459*9e813386SMichael Stahl ::rtl::OUString udeps; 460*9e813386SMichael Stahl anyValue >>= udeps; 461*9e813386SMichael Stahl 462*9e813386SMichael Stahl if (udeps.getLength() == 0) 463*9e813386SMichael Stahl return; // nothing todo 464*9e813386SMichael Stahl 465*9e813386SMichael Stahl ::rtl::OString xmlDependencies = ::rtl::OUStringToOString(udeps, RTL_TEXTENCODING_UNICODE); 466*9e813386SMichael Stahl 467*9e813386SMichael Stahl css::uno::Reference< css::xml::dom::XDocumentBuilder> docbuilder( 468*9e813386SMichael Stahl manager->createInstanceWithContext( 469*9e813386SMichael Stahl ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.dom.DocumentBuilder")), m_context), 470*9e813386SMichael Stahl css::uno::UNO_QUERY_THROW); 471*9e813386SMichael Stahl 472*9e813386SMichael Stahl css::uno::Sequence< sal_Int8 > byteSeq((const sal_Int8*)xmlDependencies.getStr(), xmlDependencies.getLength()); 473*9e813386SMichael Stahl 474*9e813386SMichael Stahl css::uno::Reference< css::io::XInputStream> inputstream( css::io::SequenceInputStream::createStreamFromSequence(m_context, byteSeq), 475*9e813386SMichael Stahl css::uno::UNO_QUERY_THROW); 476*9e813386SMichael Stahl 477*9e813386SMichael Stahl css::uno::Reference< css::xml::dom::XDocument > xDocument(docbuilder->parse(inputstream)); 478*9e813386SMichael Stahl css::uno::Reference< css::xml::dom::XElement > xElement(xDocument->getDocumentElement()); 479*9e813386SMichael Stahl css::uno::Reference< css::xml::dom::XNodeList > xDeps(xElement->getChildNodes()); 480*9e813386SMichael Stahl sal_Int32 nLen = xDeps->getLength(); 481*9e813386SMichael Stahl 482*9e813386SMichael Stahl // get dependency node of current description info to merge the new dependencies from the blacklist 483*9e813386SMichael Stahl css::uno::Reference< css::xml::dom::XNode > xCurrentDeps( 484*9e813386SMichael Stahl m_xpath->selectSingleNode(m_element, ::rtl::OUString( 485*9e813386SMichael Stahl RTL_CONSTASCII_USTRINGPARAM("desc:dependencies")))); 486*9e813386SMichael Stahl 487*9e813386SMichael Stahl css::uno::Reference< css::xml::dom::XDocument > xCurrentDescInfo(xCurrentDeps->getOwnerDocument()); 488*9e813386SMichael Stahl 489*9e813386SMichael Stahl for (sal_Int32 i=0; i<nLen; i++) { 490*9e813386SMichael Stahl css::uno::Reference< css::xml::dom::XNode > xNode(xDeps->item(i)); 491*9e813386SMichael Stahl css::uno::Reference< css::xml::dom::XElement > xDep(xNode, css::uno::UNO_QUERY); 492*9e813386SMichael Stahl if (xDep.is()) { 493*9e813386SMichael Stahl // found valid blacklist dependency, import the node first and append it to the existing dependency node 494*9e813386SMichael Stahl css::uno::Reference< css::xml::dom::XNode > importedNode = xCurrentDescInfo->importNode(xNode, true); 495*9e813386SMichael Stahl xCurrentDeps->appendChild(importedNode); 496*9e813386SMichael Stahl } 497*9e813386SMichael Stahl } 498*9e813386SMichael Stahl } 499*9e813386SMichael Stahl } 500*9e813386SMichael Stahl } 501*9e813386SMichael Stahl } 502*9e813386SMichael Stahl 503*9e813386SMichael Stahl bool DescriptionInfoset::checkBlacklistVersion( 504*9e813386SMichael Stahl ::rtl::OUString currentversion, 505*9e813386SMichael Stahl ::com::sun::star::uno::Sequence< ::rtl::OUString > const & versions) const 506*9e813386SMichael Stahl { 507*9e813386SMichael Stahl sal_Int32 nLen = versions.getLength(); 508*9e813386SMichael Stahl for (sal_Int32 i=0; i<nLen; i++) { 509*9e813386SMichael Stahl if (currentversion.equals(versions[i])) 510*9e813386SMichael Stahl return true; 511*9e813386SMichael Stahl } 512*9e813386SMichael Stahl 513*9e813386SMichael Stahl return false; 514*9e813386SMichael Stahl } 515cdf0e10cSrcweir 516cdf0e10cSrcweir ::rtl::OUString DescriptionInfoset::getVersion() const 517cdf0e10cSrcweir { 518cdf0e10cSrcweir return getNodeValueFromExpression( ::rtl::OUString( 519cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("desc:version/@value"))); 520cdf0e10cSrcweir } 521cdf0e10cSrcweir 522cdf0e10cSrcweir css::uno::Sequence< ::rtl::OUString > DescriptionInfoset::getSupportedPlaforms() const 523cdf0e10cSrcweir { 524cdf0e10cSrcweir //When there is no description.xml then we assume that we support all platforms 525cdf0e10cSrcweir if (! m_element.is()) 526cdf0e10cSrcweir { 527cdf0e10cSrcweir return comphelper::makeSequence( 528cdf0e10cSrcweir ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("all"))); 529cdf0e10cSrcweir } 530cdf0e10cSrcweir 531cdf0e10cSrcweir //Check if the <platform> element was provided. If not the default is "all" platforms 532cdf0e10cSrcweir css::uno::Reference< css::xml::dom::XNode > nodePlatform( 533cdf0e10cSrcweir m_xpath->selectSingleNode(m_element, ::rtl::OUString( 534cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("desc:platform")))); 535cdf0e10cSrcweir if (!nodePlatform.is()) 536cdf0e10cSrcweir { 537cdf0e10cSrcweir return comphelper::makeSequence( 538cdf0e10cSrcweir ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("all"))); 539cdf0e10cSrcweir } 540cdf0e10cSrcweir 541cdf0e10cSrcweir //There is a platform element. 542cdf0e10cSrcweir const ::rtl::OUString value = getNodeValueFromExpression(::rtl::OUString( 543cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("desc:platform/@value"))); 544cdf0e10cSrcweir //parse the string, it can contained multiple strings separated by commas 545cdf0e10cSrcweir ::std::vector< ::rtl::OUString> vec; 546cdf0e10cSrcweir sal_Int32 nIndex = 0; 547cdf0e10cSrcweir do 548cdf0e10cSrcweir { 549cdf0e10cSrcweir ::rtl::OUString aToken = value.getToken( 0, ',', nIndex ); 550cdf0e10cSrcweir aToken = aToken.trim(); 551cdf0e10cSrcweir if (aToken.getLength()) 552cdf0e10cSrcweir vec.push_back(aToken); 553*9e813386SMichael Stahl 554cdf0e10cSrcweir } 555cdf0e10cSrcweir while (nIndex >= 0); 556cdf0e10cSrcweir 557cdf0e10cSrcweir return comphelper::containerToSequence(vec); 558cdf0e10cSrcweir } 559cdf0e10cSrcweir 560cdf0e10cSrcweir css::uno::Reference< css::xml::dom::XNodeList > 561cdf0e10cSrcweir DescriptionInfoset::getDependencies() const { 562cdf0e10cSrcweir if (m_element.is()) { 563cdf0e10cSrcweir try { 564*9e813386SMichael Stahl // check the extension blacklist first and expand the dependencies if applicable 565*9e813386SMichael Stahl checkBlacklist(); 566*9e813386SMichael Stahl 567cdf0e10cSrcweir return m_xpath->selectNodeList(m_element, ::rtl::OUString( 568cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("desc:dependencies/*"))); 569cdf0e10cSrcweir } catch (css::xml::xpath::XPathException &) { 570cdf0e10cSrcweir // ignore 571cdf0e10cSrcweir } 572cdf0e10cSrcweir } 573cdf0e10cSrcweir return new EmptyNodeList; 574cdf0e10cSrcweir } 575cdf0e10cSrcweir 576cdf0e10cSrcweir css::uno::Sequence< ::rtl::OUString > 577cdf0e10cSrcweir DescriptionInfoset::getUpdateInformationUrls() const { 578cdf0e10cSrcweir return getUrls( 579cdf0e10cSrcweir ::rtl::OUString( 580cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 581cdf0e10cSrcweir "desc:update-information/desc:src/@xlink:href"))); 582cdf0e10cSrcweir } 583cdf0e10cSrcweir 584cdf0e10cSrcweir css::uno::Sequence< ::rtl::OUString > 585cdf0e10cSrcweir DescriptionInfoset::getUpdateDownloadUrls() const 586cdf0e10cSrcweir { 587cdf0e10cSrcweir return getUrls( 588cdf0e10cSrcweir ::rtl::OUString( 589cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 590cdf0e10cSrcweir "desc:update-download/desc:src/@xlink:href"))); 591cdf0e10cSrcweir } 592cdf0e10cSrcweir 593cdf0e10cSrcweir ::rtl::OUString DescriptionInfoset::getIconURL( sal_Bool bHighContrast ) const 594cdf0e10cSrcweir { 595cdf0e10cSrcweir css::uno::Sequence< ::rtl::OUString > aStrList = getUrls( ::rtl::OUString( 596cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( "desc:icon/desc:default/@xlink:href"))); 597cdf0e10cSrcweir css::uno::Sequence< ::rtl::OUString > aStrListHC = getUrls( ::rtl::OUString( 598cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( "desc:icon/desc:high-contrast/@xlink:href"))); 599cdf0e10cSrcweir 600cdf0e10cSrcweir if ( bHighContrast && aStrListHC.hasElements() && aStrListHC[0].getLength() ) 601cdf0e10cSrcweir return aStrListHC[0]; 602cdf0e10cSrcweir 603cdf0e10cSrcweir if ( aStrList.hasElements() && aStrList[0].getLength() ) 604cdf0e10cSrcweir return aStrList[0]; 605cdf0e10cSrcweir 606cdf0e10cSrcweir return ::rtl::OUString(); 607cdf0e10cSrcweir } 608cdf0e10cSrcweir 609cdf0e10cSrcweir ::boost::optional< ::rtl::OUString > DescriptionInfoset::getLocalizedUpdateWebsiteURL() 610cdf0e10cSrcweir const 611cdf0e10cSrcweir { 612cdf0e10cSrcweir bool bParentExists = false; 613cdf0e10cSrcweir const ::rtl::OUString sURL (getLocalizedHREFAttrFromChild(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 614cdf0e10cSrcweir "/desc:description/desc:update-website")), &bParentExists )); 615cdf0e10cSrcweir 616cdf0e10cSrcweir if (sURL.getLength() > 0) 617cdf0e10cSrcweir return ::boost::optional< ::rtl::OUString >(sURL); 618cdf0e10cSrcweir else 619cdf0e10cSrcweir return bParentExists ? ::boost::optional< ::rtl::OUString >(::rtl::OUString()) : 620cdf0e10cSrcweir ::boost::optional< ::rtl::OUString >(); 621cdf0e10cSrcweir } 622cdf0e10cSrcweir 623cdf0e10cSrcweir ::boost::optional< ::rtl::OUString > DescriptionInfoset::getOptionalValue( 624cdf0e10cSrcweir ::rtl::OUString const & expression) const 625cdf0e10cSrcweir { 626cdf0e10cSrcweir css::uno::Reference< css::xml::dom::XNode > n; 627cdf0e10cSrcweir if (m_element.is()) { 628cdf0e10cSrcweir try { 629cdf0e10cSrcweir n = m_xpath->selectSingleNode(m_element, expression); 630cdf0e10cSrcweir } catch (css::xml::xpath::XPathException &) { 631cdf0e10cSrcweir // ignore 632cdf0e10cSrcweir } 633cdf0e10cSrcweir } 634cdf0e10cSrcweir return n.is() 635cdf0e10cSrcweir ? ::boost::optional< ::rtl::OUString >(getNodeValue(n)) 636cdf0e10cSrcweir : ::boost::optional< ::rtl::OUString >(); 637cdf0e10cSrcweir } 638cdf0e10cSrcweir 639cdf0e10cSrcweir css::uno::Sequence< ::rtl::OUString > DescriptionInfoset::getUrls( 640cdf0e10cSrcweir ::rtl::OUString const & expression) const 641cdf0e10cSrcweir { 642cdf0e10cSrcweir css::uno::Reference< css::xml::dom::XNodeList > ns; 643cdf0e10cSrcweir if (m_element.is()) { 644cdf0e10cSrcweir try { 645cdf0e10cSrcweir ns = m_xpath->selectNodeList(m_element, expression); 646cdf0e10cSrcweir } catch (css::xml::xpath::XPathException &) { 647cdf0e10cSrcweir // ignore 648cdf0e10cSrcweir } 649cdf0e10cSrcweir } 650cdf0e10cSrcweir css::uno::Sequence< ::rtl::OUString > urls(ns.is() ? ns->getLength() : 0); 651cdf0e10cSrcweir for (::sal_Int32 i = 0; i < urls.getLength(); ++i) { 652cdf0e10cSrcweir urls[i] = getNodeValue(ns->item(i)); 653cdf0e10cSrcweir } 654cdf0e10cSrcweir return urls; 655cdf0e10cSrcweir } 656cdf0e10cSrcweir 657cdf0e10cSrcweir ::std::pair< ::rtl::OUString, ::rtl::OUString > DescriptionInfoset::getLocalizedPublisherNameAndURL() const 658cdf0e10cSrcweir { 659cdf0e10cSrcweir css::uno::Reference< css::xml::dom::XNode > node = 660cdf0e10cSrcweir getLocalizedChild(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("desc:publisher"))); 661cdf0e10cSrcweir 662cdf0e10cSrcweir ::rtl::OUString sPublisherName; 663cdf0e10cSrcweir ::rtl::OUString sURL; 664cdf0e10cSrcweir if (node.is()) 665cdf0e10cSrcweir { 666cdf0e10cSrcweir const ::rtl::OUString exp1(RTL_CONSTASCII_USTRINGPARAM("text()")); 667cdf0e10cSrcweir css::uno::Reference< css::xml::dom::XNode > xPathName; 668cdf0e10cSrcweir try { 669cdf0e10cSrcweir xPathName = m_xpath->selectSingleNode(node, exp1); 670cdf0e10cSrcweir } catch (css::xml::xpath::XPathException &) { 671cdf0e10cSrcweir // ignore 672cdf0e10cSrcweir } 673cdf0e10cSrcweir OSL_ASSERT(xPathName.is()); 674cdf0e10cSrcweir if (xPathName.is()) 675cdf0e10cSrcweir sPublisherName = xPathName->getNodeValue(); 676cdf0e10cSrcweir 677cdf0e10cSrcweir const ::rtl::OUString exp2(RTL_CONSTASCII_USTRINGPARAM("@xlink:href")); 678cdf0e10cSrcweir css::uno::Reference< css::xml::dom::XNode > xURL; 679cdf0e10cSrcweir try { 680cdf0e10cSrcweir xURL = m_xpath->selectSingleNode(node, exp2); 681cdf0e10cSrcweir } catch (css::xml::xpath::XPathException &) { 682cdf0e10cSrcweir // ignore 683cdf0e10cSrcweir } 684cdf0e10cSrcweir OSL_ASSERT(xURL.is()); 685cdf0e10cSrcweir if (xURL.is()) 686cdf0e10cSrcweir sURL = xURL->getNodeValue(); 687cdf0e10cSrcweir } 688cdf0e10cSrcweir return ::std::make_pair(sPublisherName, sURL); 689cdf0e10cSrcweir } 690cdf0e10cSrcweir 691cdf0e10cSrcweir ::rtl::OUString DescriptionInfoset::getLocalizedReleaseNotesURL() const 692cdf0e10cSrcweir { 693cdf0e10cSrcweir return getLocalizedHREFAttrFromChild(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 694cdf0e10cSrcweir "/desc:description/desc:release-notes")), NULL); 695cdf0e10cSrcweir } 696cdf0e10cSrcweir 697cdf0e10cSrcweir ::rtl::OUString DescriptionInfoset::getLocalizedDisplayName() const 698cdf0e10cSrcweir { 699cdf0e10cSrcweir css::uno::Reference< css::xml::dom::XNode > node = 700cdf0e10cSrcweir getLocalizedChild(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("desc:display-name"))); 701cdf0e10cSrcweir if (node.is()) 702cdf0e10cSrcweir { 703cdf0e10cSrcweir const ::rtl::OUString exp(RTL_CONSTASCII_USTRINGPARAM("text()")); 704cdf0e10cSrcweir css::uno::Reference< css::xml::dom::XNode > xtext; 705cdf0e10cSrcweir try { 706cdf0e10cSrcweir xtext = m_xpath->selectSingleNode(node, exp); 707cdf0e10cSrcweir } catch (css::xml::xpath::XPathException &) { 708cdf0e10cSrcweir // ignore 709cdf0e10cSrcweir } 710cdf0e10cSrcweir if (xtext.is()) 711cdf0e10cSrcweir return xtext->getNodeValue(); 712cdf0e10cSrcweir } 713cdf0e10cSrcweir return ::rtl::OUString(); 714cdf0e10cSrcweir } 715cdf0e10cSrcweir 716cdf0e10cSrcweir ::rtl::OUString DescriptionInfoset::getLocalizedLicenseURL() const 717cdf0e10cSrcweir { 718cdf0e10cSrcweir return getLocalizedHREFAttrFromChild(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 719cdf0e10cSrcweir "/desc:description/desc:registration/desc:simple-license")), NULL); 720cdf0e10cSrcweir 721cdf0e10cSrcweir } 722cdf0e10cSrcweir 723cdf0e10cSrcweir ::boost::optional<SimpleLicenseAttributes> 724cdf0e10cSrcweir DescriptionInfoset::getSimpleLicenseAttributes() const 725cdf0e10cSrcweir { 726cdf0e10cSrcweir //Check if the node exist 727cdf0e10cSrcweir css::uno::Reference< css::xml::dom::XNode > n; 728cdf0e10cSrcweir if (m_element.is()) { 729cdf0e10cSrcweir try { 730cdf0e10cSrcweir n = m_xpath->selectSingleNode(m_element, 731cdf0e10cSrcweir ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 732cdf0e10cSrcweir "/desc:description/desc:registration/desc:simple-license/@accept-by"))); 733cdf0e10cSrcweir } catch (css::xml::xpath::XPathException &) { 734cdf0e10cSrcweir // ignore 735cdf0e10cSrcweir } 736cdf0e10cSrcweir if (n.is()) 737cdf0e10cSrcweir { 738cdf0e10cSrcweir SimpleLicenseAttributes attributes; 739cdf0e10cSrcweir attributes.acceptBy = 740cdf0e10cSrcweir getNodeValueFromExpression(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 741cdf0e10cSrcweir "/desc:description/desc:registration/desc:simple-license/@accept-by"))); 742cdf0e10cSrcweir 743cdf0e10cSrcweir ::boost::optional< ::rtl::OUString > suppressOnUpdate = getOptionalValue( 744cdf0e10cSrcweir ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 745cdf0e10cSrcweir "/desc:description/desc:registration/desc:simple-license/@suppress-on-update"))); 746cdf0e10cSrcweir if (suppressOnUpdate) 747cdf0e10cSrcweir attributes.suppressOnUpdate = (*suppressOnUpdate).trim().equalsIgnoreAsciiCase( 748cdf0e10cSrcweir ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("true"))); 749cdf0e10cSrcweir else 750cdf0e10cSrcweir attributes.suppressOnUpdate = false; 751cdf0e10cSrcweir 752cdf0e10cSrcweir ::boost::optional< ::rtl::OUString > suppressIfRequired = getOptionalValue( 753cdf0e10cSrcweir ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 754cdf0e10cSrcweir "/desc:description/desc:registration/desc:simple-license/@suppress-if-required"))); 755cdf0e10cSrcweir if (suppressIfRequired) 756cdf0e10cSrcweir attributes.suppressIfRequired = (*suppressIfRequired).trim().equalsIgnoreAsciiCase( 757cdf0e10cSrcweir ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("true"))); 758cdf0e10cSrcweir else 759cdf0e10cSrcweir attributes.suppressIfRequired = false; 760cdf0e10cSrcweir 761cdf0e10cSrcweir return ::boost::optional<SimpleLicenseAttributes>(attributes); 762cdf0e10cSrcweir } 763cdf0e10cSrcweir } 764cdf0e10cSrcweir return ::boost::optional<SimpleLicenseAttributes>(); 765cdf0e10cSrcweir } 766cdf0e10cSrcweir 767cdf0e10cSrcweir ::rtl::OUString DescriptionInfoset::getLocalizedDescriptionURL() const 768cdf0e10cSrcweir { 769cdf0e10cSrcweir return getLocalizedHREFAttrFromChild(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 770cdf0e10cSrcweir "/desc:description/desc:extension-description")), NULL); 771cdf0e10cSrcweir } 772cdf0e10cSrcweir 773cdf0e10cSrcweir css::uno::Reference< css::xml::dom::XNode > 774cdf0e10cSrcweir DescriptionInfoset::getLocalizedChild( const ::rtl::OUString & sParent) const 775cdf0e10cSrcweir { 776cdf0e10cSrcweir if ( ! m_element.is() || !sParent.getLength()) 777cdf0e10cSrcweir return css::uno::Reference< css::xml::dom::XNode > (); 778cdf0e10cSrcweir 779cdf0e10cSrcweir css::uno::Reference< css::xml::dom::XNode > xParent; 780cdf0e10cSrcweir try { 781cdf0e10cSrcweir xParent = m_xpath->selectSingleNode(m_element, sParent); 782cdf0e10cSrcweir } catch (css::xml::xpath::XPathException &) { 783cdf0e10cSrcweir // ignore 784cdf0e10cSrcweir } 785cdf0e10cSrcweir css::uno::Reference<css::xml::dom::XNode> nodeMatch; 786cdf0e10cSrcweir if (xParent.is()) 787cdf0e10cSrcweir { 788cdf0e10cSrcweir const ::rtl::OUString sLocale = getOfficeLocaleString(); 789cdf0e10cSrcweir nodeMatch = matchFullLocale(xParent, sLocale); 790cdf0e10cSrcweir 791cdf0e10cSrcweir //office: en-DE, en, en-DE-altmark 792cdf0e10cSrcweir if (! nodeMatch.is()) 793cdf0e10cSrcweir { 794cdf0e10cSrcweir const css::lang::Locale officeLocale = getOfficeLocale(); 795cdf0e10cSrcweir nodeMatch = matchCountryAndLanguage(xParent, officeLocale); 796cdf0e10cSrcweir if ( ! nodeMatch.is()) 797cdf0e10cSrcweir { 798cdf0e10cSrcweir nodeMatch = matchLanguage(xParent, officeLocale); 799cdf0e10cSrcweir if (! nodeMatch.is()) 800cdf0e10cSrcweir nodeMatch = getChildWithDefaultLocale(xParent); 801cdf0e10cSrcweir } 802cdf0e10cSrcweir } 803cdf0e10cSrcweir } 804cdf0e10cSrcweir 805cdf0e10cSrcweir return nodeMatch; 806cdf0e10cSrcweir } 807cdf0e10cSrcweir 808cdf0e10cSrcweir css::uno::Reference<css::xml::dom::XNode> 809cdf0e10cSrcweir DescriptionInfoset::matchFullLocale(css::uno::Reference< css::xml::dom::XNode > 810cdf0e10cSrcweir const & xParent, ::rtl::OUString const & sLocale) const 811cdf0e10cSrcweir { 812cdf0e10cSrcweir OSL_ASSERT(xParent.is()); 813cdf0e10cSrcweir const ::rtl::OUString exp1( 814cdf0e10cSrcweir ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("*[@lang=\"")) 815cdf0e10cSrcweir + sLocale + 816cdf0e10cSrcweir ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\"]"))); 817cdf0e10cSrcweir try { 818cdf0e10cSrcweir return m_xpath->selectSingleNode(xParent, exp1); 819cdf0e10cSrcweir } catch (css::xml::xpath::XPathException &) { 820cdf0e10cSrcweir // ignore 821cdf0e10cSrcweir return 0; 822cdf0e10cSrcweir } 823cdf0e10cSrcweir } 824cdf0e10cSrcweir 825cdf0e10cSrcweir css::uno::Reference<css::xml::dom::XNode> 826cdf0e10cSrcweir DescriptionInfoset::matchCountryAndLanguage( 827cdf0e10cSrcweir css::uno::Reference< css::xml::dom::XNode > const & xParent, css::lang::Locale const & officeLocale) const 828cdf0e10cSrcweir { 829cdf0e10cSrcweir OSL_ASSERT(xParent.is()); 830cdf0e10cSrcweir css::uno::Reference<css::xml::dom::XNode> nodeMatch; 831cdf0e10cSrcweir 832cdf0e10cSrcweir if (officeLocale.Country.getLength()) 833cdf0e10cSrcweir { 834cdf0e10cSrcweir const ::rtl::OUString sLangCountry(officeLocale.Language + 835cdf0e10cSrcweir ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("-")) + 836cdf0e10cSrcweir officeLocale.Country); 837cdf0e10cSrcweir //first try exact match for lang-country 838cdf0e10cSrcweir const ::rtl::OUString exp1( 839cdf0e10cSrcweir ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("*[@lang=\"")) 840cdf0e10cSrcweir + sLangCountry + 841cdf0e10cSrcweir ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\"]"))); 842cdf0e10cSrcweir try { 843cdf0e10cSrcweir nodeMatch = m_xpath->selectSingleNode(xParent, exp1); 844cdf0e10cSrcweir } catch (css::xml::xpath::XPathException &) { 845cdf0e10cSrcweir // ignore 846cdf0e10cSrcweir } 847cdf0e10cSrcweir 848cdf0e10cSrcweir //try to match in strings that also have a variant, for example en-US matches in 849cdf0e10cSrcweir //en-US-montana 850cdf0e10cSrcweir if (!nodeMatch.is()) 851cdf0e10cSrcweir { 852cdf0e10cSrcweir const ::rtl::OUString exp2( 853cdf0e10cSrcweir ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("*[starts-with(@lang,\"")) 854cdf0e10cSrcweir + sLangCountry + 855cdf0e10cSrcweir ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("-\")]"))); 856cdf0e10cSrcweir try { 857cdf0e10cSrcweir nodeMatch = m_xpath->selectSingleNode(xParent, exp2); 858cdf0e10cSrcweir } catch (css::xml::xpath::XPathException &) { 859cdf0e10cSrcweir // ignore 860cdf0e10cSrcweir } 861cdf0e10cSrcweir } 862cdf0e10cSrcweir } 863cdf0e10cSrcweir 864cdf0e10cSrcweir return nodeMatch; 865cdf0e10cSrcweir } 866cdf0e10cSrcweir 867cdf0e10cSrcweir 868cdf0e10cSrcweir css::uno::Reference<css::xml::dom::XNode> 869cdf0e10cSrcweir DescriptionInfoset::matchLanguage( 870cdf0e10cSrcweir css::uno::Reference< css::xml::dom::XNode > const & xParent, css::lang::Locale const & officeLocale) const 871cdf0e10cSrcweir { 872cdf0e10cSrcweir OSL_ASSERT(xParent.is()); 873cdf0e10cSrcweir css::uno::Reference<css::xml::dom::XNode> nodeMatch; 874cdf0e10cSrcweir 875cdf0e10cSrcweir //first try exact match for lang 876cdf0e10cSrcweir const ::rtl::OUString exp1( 877cdf0e10cSrcweir ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("*[@lang=\"")) 878cdf0e10cSrcweir + officeLocale.Language 879cdf0e10cSrcweir + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\"]"))); 880cdf0e10cSrcweir try { 881cdf0e10cSrcweir nodeMatch = m_xpath->selectSingleNode(xParent, exp1); 882cdf0e10cSrcweir } catch (css::xml::xpath::XPathException &) { 883cdf0e10cSrcweir // ignore 884cdf0e10cSrcweir } 885cdf0e10cSrcweir 886cdf0e10cSrcweir //try to match in strings that also have a country and/orvariant, for example en matches in 887cdf0e10cSrcweir //en-US-montana, en-US, en-montana 888cdf0e10cSrcweir if (!nodeMatch.is()) 889cdf0e10cSrcweir { 890cdf0e10cSrcweir const ::rtl::OUString exp2( 891cdf0e10cSrcweir ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("*[starts-with(@lang,\"")) 892cdf0e10cSrcweir + officeLocale.Language 893cdf0e10cSrcweir + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("-\")]"))); 894cdf0e10cSrcweir try { 895cdf0e10cSrcweir nodeMatch = m_xpath->selectSingleNode(xParent, exp2); 896cdf0e10cSrcweir } catch (css::xml::xpath::XPathException &) { 897cdf0e10cSrcweir // ignore 898cdf0e10cSrcweir } 899cdf0e10cSrcweir } 900cdf0e10cSrcweir return nodeMatch; 901cdf0e10cSrcweir } 902cdf0e10cSrcweir 903cdf0e10cSrcweir css::uno::Reference<css::xml::dom::XNode> 904cdf0e10cSrcweir DescriptionInfoset::getChildWithDefaultLocale(css::uno::Reference< css::xml::dom::XNode > 905cdf0e10cSrcweir const & xParent) const 906cdf0e10cSrcweir { 907cdf0e10cSrcweir OSL_ASSERT(xParent.is()); 908cdf0e10cSrcweir if (xParent->getNodeName().equals(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("simple-license")))) 909cdf0e10cSrcweir { 910cdf0e10cSrcweir css::uno::Reference<css::xml::dom::XNode> nodeDefault; 911cdf0e10cSrcweir try { 912cdf0e10cSrcweir nodeDefault = m_xpath->selectSingleNode(xParent, ::rtl::OUString( 913cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("@default-license-id"))); 914cdf0e10cSrcweir } catch (css::xml::xpath::XPathException &) { 915cdf0e10cSrcweir // ignore 916cdf0e10cSrcweir } 917cdf0e10cSrcweir if (nodeDefault.is()) 918cdf0e10cSrcweir { 919cdf0e10cSrcweir //The old way 920cdf0e10cSrcweir const ::rtl::OUString exp1( 921cdf0e10cSrcweir ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("desc:license-text[@license-id = \"")) 922cdf0e10cSrcweir + nodeDefault->getNodeValue() 923cdf0e10cSrcweir + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\"]"))); 924cdf0e10cSrcweir try { 925cdf0e10cSrcweir return m_xpath->selectSingleNode(xParent, exp1); 926cdf0e10cSrcweir } catch (css::xml::xpath::XPathException &) { 927cdf0e10cSrcweir // ignore 928cdf0e10cSrcweir } 929cdf0e10cSrcweir } 930cdf0e10cSrcweir } 931cdf0e10cSrcweir 932cdf0e10cSrcweir const ::rtl::OUString exp2(RTL_CONSTASCII_USTRINGPARAM("*[1]")); 933cdf0e10cSrcweir try { 934cdf0e10cSrcweir return m_xpath->selectSingleNode(xParent, exp2); 935cdf0e10cSrcweir } catch (css::xml::xpath::XPathException &) { 936cdf0e10cSrcweir // ignore 937cdf0e10cSrcweir return 0; 938cdf0e10cSrcweir } 939cdf0e10cSrcweir } 940cdf0e10cSrcweir 941cdf0e10cSrcweir ::rtl::OUString DescriptionInfoset::getLocalizedHREFAttrFromChild( 942cdf0e10cSrcweir ::rtl::OUString const & sXPathParent, bool * out_bParentExists) 943cdf0e10cSrcweir const 944cdf0e10cSrcweir { 945cdf0e10cSrcweir css::uno::Reference< css::xml::dom::XNode > node = 946cdf0e10cSrcweir getLocalizedChild(sXPathParent); 947cdf0e10cSrcweir 948cdf0e10cSrcweir ::rtl::OUString sURL; 949cdf0e10cSrcweir if (node.is()) 950cdf0e10cSrcweir { 951cdf0e10cSrcweir if (out_bParentExists) 952cdf0e10cSrcweir *out_bParentExists = true; 953cdf0e10cSrcweir const ::rtl::OUString exp(RTL_CONSTASCII_USTRINGPARAM("@xlink:href")); 954cdf0e10cSrcweir css::uno::Reference< css::xml::dom::XNode > xURL; 955cdf0e10cSrcweir try { 956cdf0e10cSrcweir xURL = m_xpath->selectSingleNode(node, exp); 957cdf0e10cSrcweir } catch (css::xml::xpath::XPathException &) { 958cdf0e10cSrcweir // ignore 959cdf0e10cSrcweir } 960cdf0e10cSrcweir OSL_ASSERT(xURL.is()); 961cdf0e10cSrcweir if (xURL.is()) 962cdf0e10cSrcweir sURL = xURL->getNodeValue(); 963cdf0e10cSrcweir } 964cdf0e10cSrcweir else 965cdf0e10cSrcweir { 966cdf0e10cSrcweir if (out_bParentExists) 967cdf0e10cSrcweir *out_bParentExists = false; 968cdf0e10cSrcweir } 969cdf0e10cSrcweir return sURL; 970cdf0e10cSrcweir } 971cdf0e10cSrcweir 972cdf0e10cSrcweir } 973