Update ooo320-m1
[ooovba.git] / desktop / source / deployment / misc / dp_descriptioninfoset.cxx
blobd3c7f281159e357e040d20cdd2c7e7a3261ed392
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: dp_descriptioninfoset.cxx,v $
10 * $Revision: 1.7.34.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_desktop.hxx"
34 #include "dp_descriptioninfoset.hxx"
36 #include "dp_resource.h"
37 #include "sal/config.h"
39 #include "comphelper/sequence.hxx"
40 #include "comphelper/makesequence.hxx"
41 #include "boost/optional.hpp"
42 #include "com/sun/star/beans/Optional.hpp"
43 #include "com/sun/star/lang/XMultiComponentFactory.hpp"
44 #include "com/sun/star/lang/Locale.hpp"
45 #include "com/sun/star/uno/Reference.hxx"
46 #include "com/sun/star/uno/RuntimeException.hpp"
47 #include "com/sun/star/uno/Sequence.hxx"
48 #include "com/sun/star/uno/XComponentContext.hpp"
49 #include "com/sun/star/uno/XInterface.hpp"
50 #include "com/sun/star/xml/dom/DOMException.hpp"
51 #include "com/sun/star/xml/dom/XNode.hpp"
52 #include "com/sun/star/xml/dom/XNodeList.hpp"
53 #include "com/sun/star/xml/xpath/XXPathAPI.hpp"
54 #include "cppuhelper/implbase1.hxx"
55 #include "cppuhelper/weak.hxx"
56 #include "rtl/ustring.h"
57 #include "rtl/ustring.hxx"
58 #include "sal/types.h"
61 namespace {
63 namespace css = ::com::sun::star;
65 class EmptyNodeList: public ::cppu::WeakImplHelper1< css::xml::dom::XNodeList >
67 public:
68 EmptyNodeList();
70 virtual ~EmptyNodeList();
72 virtual ::sal_Int32 SAL_CALL getLength() throw (css::uno::RuntimeException);
74 virtual css::uno::Reference< css::xml::dom::XNode > SAL_CALL
75 item(::sal_Int32 index) throw (css::uno::RuntimeException);
77 private:
78 EmptyNodeList(EmptyNodeList &); // not defined
79 void operator =(EmptyNodeList &); // not defined
82 EmptyNodeList::EmptyNodeList() {}
84 EmptyNodeList::~EmptyNodeList() {}
86 ::sal_Int32 EmptyNodeList::getLength() throw (css::uno::RuntimeException) {
87 return 0;
90 css::uno::Reference< css::xml::dom::XNode > EmptyNodeList::item(::sal_Int32)
91 throw (css::uno::RuntimeException)
93 throw css::uno::RuntimeException(
94 ::rtl::OUString(
95 RTL_CONSTASCII_USTRINGPARAM(
96 "bad EmptyNodeList com.sun.star.xml.dom.XNodeList.item call")),
97 static_cast< ::cppu::OWeakObject * >(this));
100 ::rtl::OUString getNodeValue(
101 css::uno::Reference< css::xml::dom::XNode > const & node)
103 OSL_ASSERT(node.is());
104 try {
105 return node->getNodeValue();
106 } catch (css::xml::dom::DOMException & e) {
107 throw css::uno::RuntimeException(
108 (::rtl::OUString(
109 RTL_CONSTASCII_USTRINGPARAM(
110 "com.sun.star.xml.dom.DOMException: ")) +
111 e.Message),
112 css::uno::Reference< css::uno::XInterface >());
118 namespace dp_misc {
120 DescriptionInfoset::DescriptionInfoset(
121 css::uno::Reference< css::uno::XComponentContext > const & context,
122 css::uno::Reference< css::xml::dom::XNode > const & element):
123 m_element(element)
125 css::uno::Reference< css::lang::XMultiComponentFactory > manager(
126 context->getServiceManager(), css::uno::UNO_QUERY_THROW);
127 if (m_element.is()) {
128 m_xpath = css::uno::Reference< css::xml::xpath::XXPathAPI >(
129 manager->createInstanceWithContext(
130 ::rtl::OUString(
131 RTL_CONSTASCII_USTRINGPARAM(
132 "com.sun.star.xml.xpath.XPathAPI")),
133 context),
134 css::uno::UNO_QUERY_THROW);
135 m_xpath->registerNS(
136 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("desc")),
137 element->getNamespaceURI());
138 m_xpath->registerNS(
139 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("xlink")),
140 ::rtl::OUString(
141 RTL_CONSTASCII_USTRINGPARAM("http://www.w3.org/1999/xlink")));
145 DescriptionInfoset::~DescriptionInfoset() {}
147 ::boost::optional< ::rtl::OUString > DescriptionInfoset::getIdentifier() const {
148 return getOptionalValue(
149 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("desc:identifier/@value")));
152 ::rtl::OUString DescriptionInfoset::getNodeValueFromExpression(::rtl::OUString const & expression) const
154 css::uno::Reference< css::xml::dom::XNode > n;
155 if (m_element.is()) {
156 try {
157 n = m_xpath->selectSingleNode(m_element, expression);
158 } catch (css::xml::xpath::XPathException &) {
159 // ignore
162 return n.is() ? getNodeValue(n) : ::rtl::OUString();
166 ::rtl::OUString DescriptionInfoset::getVersion() const
168 return getNodeValueFromExpression( ::rtl::OUString(
169 RTL_CONSTASCII_USTRINGPARAM("desc:version/@value")));
172 css::uno::Sequence< ::rtl::OUString > DescriptionInfoset::getSupportedPlaforms() const
174 //When there is no description.xml then we assume that we support all platforms
175 if (! m_element.is())
177 return comphelper::makeSequence(
178 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("all")));
181 //Check if the <platform> element was provided. If not the default is "all" platforms
182 css::uno::Reference< css::xml::dom::XNode > nodePlatform(
183 m_xpath->selectSingleNode(m_element, ::rtl::OUString(
184 RTL_CONSTASCII_USTRINGPARAM("desc:platform"))));
185 if (!nodePlatform.is())
187 return comphelper::makeSequence(
188 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("all")));
191 //There is a platform element.
192 const ::rtl::OUString value = getNodeValueFromExpression(::rtl::OUString(
193 RTL_CONSTASCII_USTRINGPARAM("desc:platform/@value")));
194 //parse the string, it can contained multiple strings separated by commas
195 ::std::vector< ::rtl::OUString> vec;
196 sal_Int32 nIndex = 0;
199 ::rtl::OUString aToken = value.getToken( 0, ',', nIndex );
200 aToken = aToken.trim();
201 if (aToken.getLength())
202 vec.push_back(aToken);
205 while (nIndex >= 0);
207 return comphelper::containerToSequence(vec);
210 css::uno::Reference< css::xml::dom::XNodeList >
211 DescriptionInfoset::getDependencies() const {
212 if (m_element.is()) {
213 try {
214 return m_xpath->selectNodeList(m_element, ::rtl::OUString(
215 RTL_CONSTASCII_USTRINGPARAM("desc:dependencies/*")));
216 } catch (css::xml::xpath::XPathException &) {
217 // ignore
220 return new EmptyNodeList;
223 css::uno::Sequence< ::rtl::OUString >
224 DescriptionInfoset::getUpdateInformationUrls() const {
225 return getUrls(
226 ::rtl::OUString(
227 RTL_CONSTASCII_USTRINGPARAM(
228 "desc:update-information/desc:src/@xlink:href")));
231 css::uno::Sequence< ::rtl::OUString >
232 DescriptionInfoset::getUpdateDownloadUrls() const
234 return getUrls(
235 ::rtl::OUString(
236 RTL_CONSTASCII_USTRINGPARAM(
237 "desc:update-download/desc:src/@xlink:href")));
240 ::rtl::OUString DescriptionInfoset::getIconURL( sal_Bool bHighContrast ) const
242 css::uno::Sequence< ::rtl::OUString > aStrList = getUrls( ::rtl::OUString(
243 RTL_CONSTASCII_USTRINGPARAM( "desc:icon/desc:default/@xlink:href")));
244 css::uno::Sequence< ::rtl::OUString > aStrListHC = getUrls( ::rtl::OUString(
245 RTL_CONSTASCII_USTRINGPARAM( "desc:icon/desc:high-contrast/@xlink:href")));
247 if ( bHighContrast && aStrListHC.hasElements() && aStrListHC[0].getLength() )
248 return aStrListHC[0];
250 if ( aStrList.hasElements() && aStrList[0].getLength() )
251 return aStrList[0];
253 return ::rtl::OUString();
256 ::boost::optional< ::rtl::OUString > DescriptionInfoset::getLocalizedUpdateWebsiteURL()
257 const
259 bool bParentExists = false;
260 const ::rtl::OUString sURL (getLocalizedHREFAttrFromChild(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
261 "/desc:description/desc:update-website")), &bParentExists ));
263 if (sURL.getLength() > 0)
264 return ::boost::optional< ::rtl::OUString >(sURL);
265 else
266 return bParentExists ? ::boost::optional< ::rtl::OUString >(::rtl::OUString()) :
267 ::boost::optional< ::rtl::OUString >();
270 css::uno::Reference< css::xml::xpath::XXPathAPI > DescriptionInfoset::getXpath()
271 const
273 return m_xpath;
276 ::boost::optional< ::rtl::OUString > DescriptionInfoset::getOptionalValue(
277 ::rtl::OUString const & expression) const
279 css::uno::Reference< css::xml::dom::XNode > n;
280 if (m_element.is()) {
281 try {
282 n = m_xpath->selectSingleNode(m_element, expression);
283 } catch (css::xml::xpath::XPathException &) {
284 // ignore
287 return n.is()
288 ? ::boost::optional< ::rtl::OUString >(getNodeValue(n))
289 : ::boost::optional< ::rtl::OUString >();
292 css::uno::Sequence< ::rtl::OUString > DescriptionInfoset::getUrls(
293 ::rtl::OUString const & expression) const
295 css::uno::Reference< css::xml::dom::XNodeList > ns;
296 if (m_element.is()) {
297 try {
298 ns = m_xpath->selectNodeList(m_element, expression);
299 } catch (css::xml::xpath::XPathException &) {
300 // ignore
303 css::uno::Sequence< ::rtl::OUString > urls(ns.is() ? ns->getLength() : 0);
304 for (::sal_Int32 i = 0; i < urls.getLength(); ++i) {
305 urls[i] = getNodeValue(ns->item(i));
307 return urls;
310 ::std::pair< ::rtl::OUString, ::rtl::OUString > DescriptionInfoset::getLocalizedPublisherNameAndURL() const
312 css::uno::Reference< css::xml::dom::XNode > node =
313 getLocalizedChild(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("desc:publisher")));
315 ::rtl::OUString sPublisherName;
316 ::rtl::OUString sURL;
317 if (node.is())
319 const ::rtl::OUString exp1(RTL_CONSTASCII_USTRINGPARAM("text()"));
320 css::uno::Reference< css::xml::dom::XNode > xPathName;
321 try {
322 xPathName = m_xpath->selectSingleNode(node, exp1);
323 } catch (css::xml::xpath::XPathException &) {
324 // ignore
326 OSL_ASSERT(xPathName.is());
327 if (xPathName.is())
328 sPublisherName = xPathName->getNodeValue();
330 const ::rtl::OUString exp2(RTL_CONSTASCII_USTRINGPARAM("@xlink:href"));
331 css::uno::Reference< css::xml::dom::XNode > xURL;
332 try {
333 xURL = m_xpath->selectSingleNode(node, exp2);
334 } catch (css::xml::xpath::XPathException &) {
335 // ignore
337 OSL_ASSERT(xURL.is());
338 if (xURL.is())
339 sURL = xURL->getNodeValue();
341 return ::std::make_pair(sPublisherName, sURL);
344 ::rtl::OUString DescriptionInfoset::getLocalizedReleaseNotesURL() const
346 return getLocalizedHREFAttrFromChild(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
347 "/desc:description/desc:release-notes")), NULL);
350 ::rtl::OUString DescriptionInfoset::getLocalizedDisplayName() const
352 css::uno::Reference< css::xml::dom::XNode > node =
353 getLocalizedChild(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("desc:display-name")));
354 if (node.is())
356 const ::rtl::OUString exp(RTL_CONSTASCII_USTRINGPARAM("text()"));
357 css::uno::Reference< css::xml::dom::XNode > xtext;
358 try {
359 xtext = m_xpath->selectSingleNode(node, exp);
360 } catch (css::xml::xpath::XPathException &) {
361 // ignore
363 if (xtext.is())
364 return xtext->getNodeValue();
366 return ::rtl::OUString();
369 ::rtl::OUString DescriptionInfoset::getLocalizedLicenseURL() const
371 return getLocalizedHREFAttrFromChild(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
372 "/desc:description/desc:registration/desc:simple-license")), NULL);
376 ::rtl::OUString DescriptionInfoset::getLocalizedDescriptionURL() const
378 return getLocalizedHREFAttrFromChild(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
379 "/desc:description/desc:extension-description")), NULL);
382 css::uno::Reference< css::xml::dom::XNode >
383 DescriptionInfoset::getLocalizedChild( const ::rtl::OUString & sParent) const
385 if ( ! m_element.is() || !sParent.getLength())
386 return css::uno::Reference< css::xml::dom::XNode > ();
388 css::uno::Reference< css::xml::dom::XNode > xParent;
389 try {
390 xParent = m_xpath->selectSingleNode(m_element, sParent);
391 } catch (css::xml::xpath::XPathException &) {
392 // ignore
394 css::uno::Reference<css::xml::dom::XNode> nodeMatch;
395 if (xParent.is())
397 const ::rtl::OUString sLocale = getOfficeLocaleString();
398 nodeMatch = matchFullLocale(xParent, sLocale);
400 //office: en-DE, en, en-DE-altmark
401 if (! nodeMatch.is())
403 const css::lang::Locale officeLocale = getOfficeLocale();
404 nodeMatch = matchCountryAndLanguage(xParent, officeLocale);
405 if ( ! nodeMatch.is())
407 nodeMatch = matchLanguage(xParent, officeLocale);
408 if (! nodeMatch.is())
409 nodeMatch = getChildWithDefaultLocale(xParent);
414 return nodeMatch;
417 css::uno::Reference<css::xml::dom::XNode>
418 DescriptionInfoset::matchFullLocale(css::uno::Reference< css::xml::dom::XNode >
419 const & xParent, ::rtl::OUString const & sLocale) const
421 OSL_ASSERT(xParent.is());
422 const ::rtl::OUString exp1(
423 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("*[@lang=\""))
424 + sLocale +
425 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\"]")));
426 try {
427 return m_xpath->selectSingleNode(xParent, exp1);
428 } catch (css::xml::xpath::XPathException &) {
429 // ignore
430 return 0;
434 css::uno::Reference<css::xml::dom::XNode>
435 DescriptionInfoset::matchCountryAndLanguage(
436 css::uno::Reference< css::xml::dom::XNode > const & xParent, css::lang::Locale const & officeLocale) const
438 OSL_ASSERT(xParent.is());
439 css::uno::Reference<css::xml::dom::XNode> nodeMatch;
441 if (officeLocale.Country.getLength())
443 const ::rtl::OUString sLangCountry(officeLocale.Language +
444 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("-")) +
445 officeLocale.Country);
446 //first try exact match for lang-country
447 const ::rtl::OUString exp1(
448 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("*[@lang=\""))
449 + sLangCountry +
450 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\"]")));
451 try {
452 nodeMatch = m_xpath->selectSingleNode(xParent, exp1);
453 } catch (css::xml::xpath::XPathException &) {
454 // ignore
457 //try to match in strings that also have a variant, for example en-US matches in
458 //en-US-montana
459 if (!nodeMatch.is())
461 const ::rtl::OUString exp2(
462 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("*[starts-with(@lang,\""))
463 + sLangCountry +
464 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("-\")]")));
465 try {
466 nodeMatch = m_xpath->selectSingleNode(xParent, exp2);
467 } catch (css::xml::xpath::XPathException &) {
468 // ignore
473 return nodeMatch;
477 css::uno::Reference<css::xml::dom::XNode>
478 DescriptionInfoset::matchLanguage(
479 css::uno::Reference< css::xml::dom::XNode > const & xParent, css::lang::Locale const & officeLocale) const
481 OSL_ASSERT(xParent.is());
482 css::uno::Reference<css::xml::dom::XNode> nodeMatch;
484 //first try exact match for lang
485 const ::rtl::OUString exp1(
486 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("*[@lang=\""))
487 + officeLocale.Language
488 + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\"]")));
489 try {
490 nodeMatch = m_xpath->selectSingleNode(xParent, exp1);
491 } catch (css::xml::xpath::XPathException &) {
492 // ignore
495 //try to match in strings that also have a country and/orvariant, for example en matches in
496 //en-US-montana, en-US, en-montana
497 if (!nodeMatch.is())
499 const ::rtl::OUString exp2(
500 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("*[starts-with(@lang,\""))
501 + officeLocale.Language
502 + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("-\")]")));
503 try {
504 nodeMatch = m_xpath->selectSingleNode(xParent, exp2);
505 } catch (css::xml::xpath::XPathException &) {
506 // ignore
509 return nodeMatch;
512 css::uno::Reference<css::xml::dom::XNode>
513 DescriptionInfoset::getChildWithDefaultLocale(css::uno::Reference< css::xml::dom::XNode >
514 const & xParent) const
516 OSL_ASSERT(xParent.is());
517 if (xParent->getNodeName().equals(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("simple-license"))))
519 css::uno::Reference<css::xml::dom::XNode> nodeDefault;
520 try {
521 nodeDefault = m_xpath->selectSingleNode(xParent, ::rtl::OUString(
522 RTL_CONSTASCII_USTRINGPARAM("@default-license-id")));
523 } catch (css::xml::xpath::XPathException &) {
524 // ignore
526 if (nodeDefault.is())
528 //The old way
529 const ::rtl::OUString exp1(
530 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("desc:license-text[@license-id = \""))
531 + nodeDefault->getNodeValue()
532 + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\"]")));
533 try {
534 return m_xpath->selectSingleNode(xParent, exp1);
535 } catch (css::xml::xpath::XPathException &) {
536 // ignore
541 const ::rtl::OUString exp2(RTL_CONSTASCII_USTRINGPARAM("*[1]"));
542 try {
543 return m_xpath->selectSingleNode(xParent, exp2);
544 } catch (css::xml::xpath::XPathException &) {
545 // ignore
546 return 0;
550 ::rtl::OUString DescriptionInfoset::getLocalizedHREFAttrFromChild(
551 ::rtl::OUString const & sXPathParent, bool * out_bParentExists)
552 const
554 css::uno::Reference< css::xml::dom::XNode > node =
555 getLocalizedChild(sXPathParent);
557 ::rtl::OUString sURL;
558 if (node.is())
560 if (out_bParentExists)
561 *out_bParentExists = true;
562 const ::rtl::OUString exp(RTL_CONSTASCII_USTRINGPARAM("@xlink:href"));
563 css::uno::Reference< css::xml::dom::XNode > xURL;
564 try {
565 xURL = m_xpath->selectSingleNode(node, exp);
566 } catch (css::xml::xpath::XPathException &) {
567 // ignore
569 OSL_ASSERT(xURL.is());
570 if (xURL.is())
571 sURL = xURL->getNodeValue();
573 else
575 if (out_bParentExists)
576 *out_bParentExists = false;
578 return sURL;