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