32#include <com/sun/star/configuration/theDefaultProvider.hpp>
33#include <com/sun/star/container/XNameAccess.hpp>
34#include <com/sun/star/deployment/DeploymentException.hpp>
35#include <com/sun/star/beans/XPropertySet.hpp>
36#include <com/sun/star/io/SequenceInputStream.hpp>
37#include <com/sun/star/lang/XMultiComponentFactory.hpp>
38#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
39#include <com/sun/star/task/XInteractionHandler.hpp>
40#include <com/sun/star/ucb/XCommandEnvironment.hpp>
41#include <com/sun/star/ucb/XProgressHandler.hpp>
42#include <com/sun/star/uno/Reference.hxx>
43#include <com/sun/star/uno/RuntimeException.hpp>
44#include <com/sun/star/uno/Sequence.hxx>
45#include <com/sun/star/uno/XInterface.hpp>
46#include <com/sun/star/xml/dom/DOMException.hpp>
47#include <com/sun/star/xml/dom/XNode.hpp>
48#include <com/sun/star/xml/dom/XNodeList.hpp>
49#include <com/sun/star/xml/dom/DocumentBuilder.hpp>
50#include <com/sun/star/xml/xpath/XPathAPI.hpp>
51#include <com/sun/star/xml/xpath/XPathException.hpp>
52#include <com/sun/star/ucb/InteractiveIOException.hpp>
56#include <rtl/ustring.hxx>
63using css::uno::Reference;
66 public cppu::WeakImplHelper<css::xml::dom::XNodeList>
71 EmptyNodeList(
const EmptyNodeList&) =
delete;
72 const EmptyNodeList& operator=(
const EmptyNodeList&) =
delete;
74 virtual ::sal_Int32 SAL_CALL
getLength()
override;
76 virtual css::uno::Reference< css::xml::dom::XNode > SAL_CALL
77 item(::sal_Int32 index)
override;
80EmptyNodeList::EmptyNodeList() {}
82::sal_Int32 EmptyNodeList::getLength() {
86css::uno::Reference< css::xml::dom::XNode > EmptyNodeList::item(::sal_Int32)
88 throw css::uno::RuntimeException(
"bad EmptyNodeList com.sun.star.xml.dom.XNodeList.item call",
93 css::uno::Reference< css::xml::dom::XNode >
const & node)
95 OSL_ASSERT(node.is());
97 return node->getNodeValue();
98 }
catch (
const css::xml::dom::DOMException & e) {
100 throw css::lang::WrappedTargetRuntimeException(
101 "com.sun.star.xml.dom.DOMException: " + e.Message,
111class ExtensionDescription
123 ExtensionDescription(
124 const css::uno::Reference<css::uno::XComponentContext>&
xContext,
125 std::u16string_view installDir,
126 const css::uno::Reference< css::ucb::XCommandEnvironment >& xCmdEnv);
128 const css::uno::Reference<css::xml::dom::XNode>& getRootElement()
const
134 css::uno::Reference<css::xml::dom::XNode>
m_xRoot;
137class NoDescriptionException
141class FileDoesNotExistFilter
142 :
public ::cppu::WeakImplHelper< css::ucb::XCommandEnvironment,
143 css::task::XInteractionHandler >
147 css::uno::Reference< css::ucb::XCommandEnvironment > m_xCommandEnv;
150 explicit FileDoesNotExistFilter(
151 const css::uno::Reference< css::ucb::XCommandEnvironment >& xCmdEnv);
153 bool exist() {
return m_bExist;}
155 virtual css::uno::Reference<css::task::XInteractionHandler > SAL_CALL
156 getInteractionHandler()
override;
157 virtual css::uno::Reference<css::ucb::XProgressHandler >
158 SAL_CALL getProgressHandler()
override;
161 virtual void SAL_CALL handle(
162 css::uno::Reference<css::task::XInteractionRequest >
const & xRequest )
override;
165ExtensionDescription::ExtensionDescription(
166 const Reference<css::uno::XComponentContext>&
xContext,
167 std::u16string_view installDir,
175 OUString sDescriptionUri(OUString::Concat(installDir) +
"/description.xml");
176 Reference<css::ucb::XCommandEnvironment> xFilter =
new FileDoesNotExistFilter(xCmdEnv);
180 Reference<css::io::XInputStream> xIn;
183 xIn = descContent.openStream();
185 catch (
const css::uno::Exception& )
187 if ( !
static_cast<FileDoesNotExistFilter*
>(xFilter.get())->exist())
188 throw NoDescriptionException();
193 throw css::uno::Exception(
194 "Could not get XInputStream for description.xml of extension " +
195 sDescriptionUri,
nullptr);
199 Reference<css::xml::dom::XDocumentBuilder> xDocBuilder(
202 if (!xDocBuilder->isNamespaceAware())
204 throw css::uno::Exception(
205 "Service com.sun.star.xml.dom.DocumentBuilder is not namespace aware.",
nullptr);
208 Reference<css::xml::dom::XDocument> xDoc = xDocBuilder->parse(xIn);
211 throw css::uno::Exception(sDescriptionUri +
" contains data which cannot be parsed. ",
nullptr);
215 Reference<css::xml::dom::XElement> xRoot = xDoc->getDocumentElement();
218 throw css::uno::Exception(
219 sDescriptionUri +
" contains no root element.",
nullptr);
222 if ( xRoot->getTagName() !=
"description")
224 throw css::uno::Exception(
225 sDescriptionUri +
" does not contain the root element <description>.",
nullptr);
228 m_xRoot.set(xRoot, css::uno::UNO_QUERY_THROW);
229 OUString nsDescription = xRoot->getNamespaceURI();
232 if ( nsDescription !=
"http://openoffice.org/extensions/description/2006")
234 throw css::uno::Exception(sDescriptionUri +
" contains a root element with an unsupported namespace. ",
nullptr);
236 }
catch (
const css::uno::RuntimeException &) {
238 }
catch (
const css::deployment::DeploymentException &) {
240 }
catch (
const css::uno::Exception & e) {
242 throw css::deployment::DeploymentException(
243 e.Message, Reference< css::uno::XInterface >(), a);
247FileDoesNotExistFilter::FileDoesNotExistFilter(
249 m_bExist(true), m_xCommandEnv(xCmdEnv)
253Reference<css::task::XInteractionHandler >
254 FileDoesNotExistFilter::getInteractionHandler()
256 return static_cast<css::task::XInteractionHandler*
>(
this);
259Reference<css::ucb::XProgressHandler >
260 FileDoesNotExistFilter::getProgressHandler()
262 return m_xCommandEnv.is()
263 ? m_xCommandEnv->getProgressHandler()
264 : Reference<css::ucb::XProgressHandler>();
270void FileDoesNotExistFilter::handle(
271 Reference<css::task::XInteractionRequest >
const & xRequest )
273 css::uno::Any request( xRequest->getRequest() );
275 css::ucb::InteractiveIOException ioexc;
276 if ((request>>= ioexc)
277 && (ioexc.Code == css::ucb::IOErrorCode_NOT_EXISTING
278 || ioexc.Code == css::ucb::IOErrorCode_NOT_EXISTING_PATH))
283 Reference<css::task::XInteractionHandler> xInteraction;
284 if (m_xCommandEnv.is()) {
285 xInteraction = m_xCommandEnv->getInteractionHandler();
287 if (xInteraction.is()) {
288 xInteraction->handle(xRequest);
298 Reference< css::xml::dom::XNode > root;
299 Reference<css::uno::XComponentContext> context(
303 ExtensionDescription(
304 context, sExtensionFolderURL,
307 }
catch (
const NoDescriptionException &) {
308 }
catch (
const css::deployment::DeploymentException & e) {
310 throw css::lang::WrappedTargetRuntimeException(
311 "com.sun.star.deployment.DeploymentException: " + e.Message,
318 css::uno::Reference< css::uno::XComponentContext >
const & context,
319 css::uno::Reference< css::xml::dom::XNode >
const & element):
325 m_xpath->registerNS(
"desc", element->getNamespaceURI());
326 m_xpath->registerNS(
"xlink",
"http://www.w3.org/1999/xlink");
338 css::uno::Reference< css::xml::dom::XNode >
n;
342 }
catch (
const css::xml::xpath::XPathException &) {
346 return n.is() ? getNodeValue(
n) : OUString();
358 if (currentversion.getLength() == 0)
363 {
"nodepath", css::uno::Any(OUString(
"/org.openoffice.Office.ExtensionDependencies/Extensions"))}
365 css::uno::Reference< css::container::XNameAccess > denylist(
366 (css::configuration::theDefaultProvider::get(
m_context)
367 ->createInstanceWithArguments(
368 "com.sun.star.configuration.ConfigurationAccess",
args)),
369 css::uno::UNO_QUERY_THROW);
372 if (!(denylist.is() && denylist->hasByName(*
id)))
return;
374 css::uno::Reference< css::beans::XPropertySet > extProps(
375 denylist->getByName(*
id), css::uno::UNO_QUERY_THROW);
377 css::uno::Any anyValue = extProps->getPropertyValue(
"Versions");
379 css::uno::Sequence< OUString > blversions;
380 anyValue >>= blversions;
385 anyValue = extProps->getPropertyValue(
"Dependencies");
389 if (udeps.getLength() == 0)
394 css::uno::Reference< css::xml::dom::XDocumentBuilder> docbuilder(
395 m_context->getServiceManager()->createInstanceWithContext(
"com.sun.star.xml.dom.DocumentBuilder",
m_context),
396 css::uno::UNO_QUERY_THROW);
398 css::uno::Sequence< sal_Int8 > byteSeq(
reinterpret_cast<const sal_Int8*
>(xmlDependencies.getStr()), xmlDependencies.getLength());
400 css::uno::Reference< css::io::XInputStream> inputstream( css::io::SequenceInputStream::createStreamFromSequence(
m_context, byteSeq),
401 css::uno::UNO_QUERY_THROW);
403 css::uno::Reference< css::xml::dom::XDocument > xDocument(docbuilder->parse(inputstream));
404 css::uno::Reference< css::xml::dom::XElement > xElement(xDocument->getDocumentElement());
405 css::uno::Reference< css::xml::dom::XNodeList > xDeps(xElement->getChildNodes());
406 sal_Int32 nLen = xDeps->getLength();
409 css::uno::Reference< css::xml::dom::XDocument > xCurrentDescInfo(
m_element->getOwnerDocument());
412 css::uno::Reference< css::xml::dom::XNode > xCurrentDeps(
416 if (!xCurrentDeps.is()) {
417 css::uno::Reference< css::xml::dom::XNode > xNewDepNode(
418 xCurrentDescInfo->createElementNS(
419 "http://openoffice.org/extensions/description/2006",
420 "dependencies"), css::uno::UNO_QUERY_THROW);
425 for (sal_Int32
i=0;
i<nLen;
i++) {
426 css::uno::Reference< css::xml::dom::XNode > xNode(xDeps->item(
i));
427 css::uno::Reference< css::xml::dom::XElement > xDep(xNode, css::uno::UNO_QUERY);
430 css::uno::Reference< css::xml::dom::XNode > importedNode = xCurrentDescInfo->importNode(xNode,
true);
431 xCurrentDeps->appendChild(importedNode);
437 std::u16string_view currentversion,
438 css::uno::Sequence< OUString >
const & versions)
440 sal_Int32 nLen = versions.getLength();
441 for (sal_Int32
i=0;
i<nLen;
i++) {
442 if (currentversion == versions[
i])
459 return { OUString(
"all") };
463 css::uno::Reference< css::xml::dom::XNode > nodePlatform(
465 if (!nodePlatform.is())
467 return { OUString(
"all") };
473 std::vector< OUString> vec;
478 if (!aToken.isEmpty())
479 vec.push_back(aToken);
487css::uno::Reference< css::xml::dom::XNodeList >
495 }
catch (
const css::xml::xpath::XPathException &) {
499 return new EmptyNodeList;
502css::uno::Sequence< OUString >
504 return getUrls(
"desc:update-information/desc:src/@xlink:href");
507css::uno::Sequence< OUString >
510 return getUrls(
"desc:update-download/desc:src/@xlink:href");
515 css::uno::Sequence< OUString > aStrList =
getUrls(
"desc:icon/desc:default/@xlink:href" );
516 css::uno::Sequence< OUString > aStrListHC =
getUrls(
"desc:icon/desc:high-contrast/@xlink:href" );
518 if ( bHighContrast && aStrListHC.hasElements() && !aStrListHC[0].isEmpty() )
519 return aStrListHC[0];
521 if ( aStrList.hasElements() && !aStrList[0].isEmpty() )
530 bool bParentExists =
false;
534 return ::std::optional< OUString >(sURL);
536 return bParentExists ? ::std::optional< OUString >(OUString()) :
537 ::std::optional< OUString >();
541 OUString
const & expression)
const
543 css::uno::Reference< css::xml::dom::XNode >
n;
547 }
catch (
const css::xml::xpath::XPathException &) {
552 ? ::std::optional< OUString >(getNodeValue(
n))
553 : ::std::optional< OUString >();
557 OUString
const & expression)
const
559 css::uno::Reference< css::xml::dom::XNodeList >
ns;
563 }
catch (
const css::xml::xpath::XPathException &) {
567 css::uno::Sequence< OUString > urls(
ns.is() ?
ns->getLength() : 0);
568 auto urlsRange = asNonConstRange(urls);
569 for (::sal_Int32
i = 0;
i < urls.getLength(); ++
i) {
570 urlsRange[
i] = getNodeValue(
ns->item(
i));
577 css::uno::Reference< css::xml::dom::XNode > node =
580 OUString sPublisherName;
584 css::uno::Reference< css::xml::dom::XNode > xPathName;
586 xPathName =
m_xpath->selectSingleNode(node,
"text()");
587 }
catch (
const css::xml::xpath::XPathException &) {
590 OSL_ASSERT(xPathName.is());
592 sPublisherName = xPathName->getNodeValue();
594 css::uno::Reference< css::xml::dom::XNode > xURL;
596 xURL =
m_xpath->selectSingleNode(node,
"@xlink:href");
597 }
catch (
const css::xml::xpath::XPathException &) {
600 OSL_ASSERT(xURL.is());
602 sURL = xURL->getNodeValue();
604 return std::make_pair(sPublisherName, sURL);
614 css::uno::Reference< css::xml::dom::XNode > node =
618 css::uno::Reference< css::xml::dom::XNode > xtext;
620 xtext =
m_xpath->selectSingleNode(node,
"text()");
621 }
catch (
const css::xml::xpath::XPathException &) {
625 return xtext->getNodeValue();
636::std::optional<SimpleLicenseAttributes>
640 css::uno::Reference< css::xml::dom::XNode >
n;
643 n =
m_xpath->selectSingleNode(
m_element,
"/desc:description/desc:registration/desc:simple-license/@accept-by");
644 }
catch (
const css::xml::xpath::XPathException &) {
653 ::std::optional< OUString > suppressOnUpdate =
getOptionalValue(
"/desc:description/desc:registration/desc:simple-license/@suppress-on-update");
654 if (suppressOnUpdate)
659 ::std::optional< OUString > suppressIfRequired =
getOptionalValue(
"/desc:description/desc:registration/desc:simple-license/@suppress-if-required");
660 if (suppressIfRequired)
665 return ::std::optional<SimpleLicenseAttributes>(attributes);
668 return ::std::optional<SimpleLicenseAttributes>();
676css::uno::Reference< css::xml::dom::XNode >
679 if ( !
m_element.is() || sParent.isEmpty())
680 return css::uno::Reference< css::xml::dom::XNode > ();
682 css::uno::Reference< css::xml::dom::XNode > xParent;
685 }
catch (
const css::xml::xpath::XPathException &) {
688 css::uno::Reference<css::xml::dom::XNode> nodeMatch;
694 if (! nodeMatch.is())
698 for (
auto const& fallback : aFallbacks)
704 if (! nodeMatch.is())
712css::uno::Reference<css::xml::dom::XNode>
714 css::uno::Reference< css::xml::dom::XNode >
const & xParent, std::u16string_view rTag)
const
716 OSL_ASSERT(xParent.is());
717 css::uno::Reference<css::xml::dom::XNode> nodeMatch;
720 const OUString exp1(OUString::Concat(
"*[@lang=\"") + rTag +
"\"]");
722 nodeMatch =
m_xpath->selectSingleNode(xParent, exp1);
723 }
catch (
const css::xml::xpath::XPathException &) {
732 OUString::Concat(
"*[starts-with(@lang,\"") + rTag +
"-\")]");
734 nodeMatch =
m_xpath->selectSingleNode(xParent, exp2);
735 }
catch (
const css::xml::xpath::XPathException &) {
742css::uno::Reference<css::xml::dom::XNode>
744 const & xParent)
const
746 OSL_ASSERT(xParent.is());
747 if ( xParent->getNodeName() ==
"simple-license" )
749 css::uno::Reference<css::xml::dom::XNode> nodeDefault;
751 nodeDefault =
m_xpath->selectSingleNode(xParent,
"@default-license-id");
752 }
catch (
const css::xml::xpath::XPathException &) {
755 if (nodeDefault.is())
758 const OUString exp1(
"desc:license-text[@license-id = \""
759 + nodeDefault->getNodeValue()
762 return m_xpath->selectSingleNode(xParent, exp1);
763 }
catch (
const css::xml::xpath::XPathException &) {
770 return m_xpath->selectSingleNode(xParent,
"*[1]");
771 }
catch (
const css::xml::xpath::XPathException &) {
778 OUString
const & sXPathParent,
bool * out_bParentExists)
781 css::uno::Reference< css::xml::dom::XNode > node =
787 if (out_bParentExists)
788 *out_bParentExists =
true;
789 css::uno::Reference< css::xml::dom::XNode > xURL;
791 xURL =
m_xpath->selectSingleNode(node,
"@xlink:href");
792 }
catch (
const css::xml::xpath::XPathException &) {
795 OSL_ASSERT(xURL.is());
797 sURL = xURL->getNodeValue();
801 if (out_bParentExists)
802 *out_bParentExists =
false;
Access to the content of an XML description element.
SAL_DLLPRIVATE OUString getLocalizedHREFAttrFromChild(OUString const &sXPathParent, bool *out_bParentExists) const
::std::optional< OUString > getLocalizedUpdateWebsiteURL() const
returns the download website URL from the update information.
css::uno::Reference< css::xml::dom::XNodeList > getDependencies() const
Return the dependencies.
css::uno::Sequence< OUString > getSupportedPlatforms() const
Returns a list of supported platforms.
SAL_DLLPRIVATE ::std::optional< OUString > getOptionalValue(OUString const &expression) const
DescriptionInfoset(css::uno::Reference< css::uno::XComponentContext > const &context, css::uno::Reference< css::xml::dom::XNode > const &element)
Create an instance.
OUString getLocalizedLicenseURL() const
returns the relative path to the license file.
css::uno::Sequence< OUString > getUpdateDownloadUrls() const
Return the download URLs from the update information.
css::uno::Reference< css::xml::xpath::XXPathAPI > m_xpath
OUString getLocalizedDisplayName() const
returns the localized display name of the extensions.
OUString getLocalizedDescriptionURL() const
returns the relative URL to the description.
css::uno::Sequence< OUString > getUpdateInformationUrls() const
Return the update information URLs.
SAL_DLLPRIVATE OUString getNodeValueFromExpression(OUString const &expression) const
Gets the node value for a given expression.
css::uno::Reference< css::xml::dom::XNode > m_element
static SAL_DLLPRIVATE bool checkDenylistVersion(std::u16string_view currentversion, css::uno::Sequence< OUString > const &versions)
Helper method to compare the versions with the current version.
::std::optional< SimpleLicenseAttributes > getSimpleLicenseAttributes() const
returns the attributes of the simple-license element
SAL_DLLPRIVATE css::uno::Sequence< OUString > getUrls(OUString const &expression) const
::std::optional< OUString > getIdentifier() const
Return the identifier.
SAL_DLLPRIVATE css::uno::Reference< css::xml::dom::XNode > getLocalizedChild(OUString const &sParent) const
Retrieves a child element which as lang attribute which matches the office locale.
SAL_DLLPRIVATE css::uno::Reference< css::xml::dom::XNode > getChildWithDefaultLocale(css::uno::Reference< css::xml::dom::XNode > const &xParent) const
If there is no child element with a locale matching the office locale, then we use the first child.
css::uno::Reference< css::uno::XComponentContext > m_context
SAL_DLLPRIVATE css::uno::Reference< css::xml::dom::XNode > matchLanguageTag(css::uno::Reference< css::xml::dom::XNode > const &xParent, std::u16string_view rTag) const
std::pair< OUString, OUString > getLocalizedPublisherNameAndURL() const
Returns the localized publisher name and the corresponding URL.
OUString getVersion() const
Return the textual version representation.
OUString getIconURL(bool bHighContrast) const
Returns the URL for the icon image.
OUString getLocalizedReleaseNotesURL() const
Returns the URL for the release notes corresponding to the office's locale.
SAL_DLLPRIVATE void checkDenylist() const
Check the extensions denylist if additional extension meta data (e.g.
static uno::Reference< css::uno::XComponentContext > xContext
double getLength(const B2DPolygon &rCandidate)
css::uno::Sequence< css::uno::Any > InitAnyPropertySequence(::std::initializer_list< ::std::pair< OUString, css::uno::Any > > vInit)
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
Reference< XComponentContext > getProcessComponentContext()
Any SAL_CALL getCaughtException()
DESKTOP_DEPLOYMENTMISC_DLLPUBLIC const LanguageTag & getOfficeLanguageTag()
DESKTOP_DEPLOYMENTMISC_DLLPUBLIC DescriptionInfoset getDescriptionInfoset(std::u16string_view sExtensionFolderURL)
creates a DescriptionInfoset object.
css::uno::Reference< css::deployment::XPackageRegistry > create(css::uno::Reference< css::deployment::XPackageRegistry > const &xRootRegistry, OUString const &context, OUString const &cachePath, css::uno::Reference< css::uno::XComponentContext > const &xComponentContext)
std::basic_string_view< charT, traits > trim(std::basic_string_view< charT, traits > str)
bool equalsIgnoreAsciiCase(std::u16string_view s1, std::u16string_view s2)
std::basic_string_view< charT, traits > getToken(std::basic_string_view< charT, traits > sv, charT delimiter, std::size_t &position)
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
Reference< xml::input::XRoot > m_xRoot