22 #include <string_view>
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>
62 using css::uno::Reference;
65 public cppu::WeakImplHelper<css::xml::dom::XNodeList>
70 EmptyNodeList(
const EmptyNodeList&) =
delete;
71 const EmptyNodeList& operator=(
const EmptyNodeList&) =
delete;
73 virtual ::sal_Int32 SAL_CALL
getLength()
override;
75 virtual css::uno::Reference< css::xml::dom::XNode > SAL_CALL
76 item(::sal_Int32 index)
override;
79 EmptyNodeList::EmptyNodeList() {}
81 ::sal_Int32 EmptyNodeList::getLength() {
85 css::uno::Reference< css::xml::dom::XNode > EmptyNodeList::item(::sal_Int32)
87 throw css::uno::RuntimeException(
"bad EmptyNodeList com.sun.star.xml.dom.XNodeList.item call",
88 static_cast< ::cppu::OWeakObject * >(
this));
91 OUString getNodeValue(
92 css::uno::Reference< css::xml::dom::XNode >
const & node)
94 OSL_ASSERT(node.is());
96 return node->getNodeValue();
97 }
catch (
const css::xml::dom::DOMException & e) {
99 throw css::lang::WrappedTargetRuntimeException(
100 "com.sun.star.xml.dom.DOMException: " + e.Message,
110 class ExtensionDescription
122 ExtensionDescription(
123 const css::uno::Reference<css::uno::XComponentContext>&
xContext,
124 std::u16string_view installDir,
125 const css::uno::Reference< css::ucb::XCommandEnvironment >& xCmdEnv);
127 const css::uno::Reference<css::xml::dom::XNode>& getRootElement()
const
133 css::uno::Reference<css::xml::dom::XNode>
m_xRoot;
136 class NoDescriptionException
140 class FileDoesNotExistFilter
141 :
public ::cppu::WeakImplHelper< css::ucb::XCommandEnvironment,
142 css::task::XInteractionHandler >
146 css::uno::Reference< css::ucb::XCommandEnvironment > m_xCommandEnv;
149 explicit FileDoesNotExistFilter(
150 const css::uno::Reference< css::ucb::XCommandEnvironment >& xCmdEnv);
152 bool exist() {
return m_bExist;}
154 virtual css::uno::Reference<css::task::XInteractionHandler > SAL_CALL
155 getInteractionHandler()
override;
156 virtual css::uno::Reference<css::ucb::XProgressHandler >
157 SAL_CALL getProgressHandler()
override;
160 virtual void SAL_CALL handle(
161 css::uno::Reference<css::task::XInteractionRequest >
const & xRequest )
override;
164 ExtensionDescription::ExtensionDescription(
165 const Reference<css::uno::XComponentContext>&
xContext,
166 std::u16string_view installDir,
174 OUString sDescriptionUri(OUString::Concat(installDir) +
"/description.xml");
179 Reference<css::io::XInputStream> xIn;
182 xIn = descContent.openStream();
184 catch (
const css::uno::Exception& )
186 if ( ! static_cast<FileDoesNotExistFilter*>(xFilter.get())->exist())
187 throw NoDescriptionException();
192 throw css::uno::Exception(
193 "Could not get XInputStream for description.xml of extension " +
194 sDescriptionUri,
nullptr);
198 Reference<css::xml::dom::XDocumentBuilder> xDocBuilder(
201 if (!xDocBuilder->isNamespaceAware())
203 throw css::uno::Exception(
204 "Service com.sun.star.xml.dom.DocumentBuilder is not namespace aware.",
nullptr);
207 Reference<css::xml::dom::XDocument> xDoc = xDocBuilder->parse(xIn);
210 throw css::uno::Exception(sDescriptionUri +
" contains data which cannot be parsed. ",
nullptr);
214 Reference<css::xml::dom::XElement> xRoot = xDoc->getDocumentElement();
217 throw css::uno::Exception(
218 sDescriptionUri +
" contains no root element.",
nullptr);
221 if ( xRoot->getTagName() !=
"description")
223 throw css::uno::Exception(
224 sDescriptionUri +
" does not contain the root element <description>.",
nullptr);
227 m_xRoot.set(xRoot, css::uno::UNO_QUERY_THROW);
228 OUString nsDescription = xRoot->getNamespaceURI();
231 if ( nsDescription !=
"http://openoffice.org/extensions/description/2006")
233 throw css::uno::Exception(sDescriptionUri +
" contains a root element with an unsupported namespace. ",
nullptr);
235 }
catch (
const css::uno::RuntimeException &) {
237 }
catch (
const css::deployment::DeploymentException &) {
239 }
catch (
const css::uno::Exception & e) {
241 throw css::deployment::DeploymentException(
242 e.Message, Reference< css::uno::XInterface >(), a);
246 FileDoesNotExistFilter::FileDoesNotExistFilter(
248 m_bExist(true), m_xCommandEnv(xCmdEnv)
252 Reference<css::task::XInteractionHandler >
253 FileDoesNotExistFilter::getInteractionHandler()
255 return static_cast<css::task::XInteractionHandler*
>(
this);
258 Reference<css::ucb::XProgressHandler >
259 FileDoesNotExistFilter::getProgressHandler()
261 return m_xCommandEnv.is()
262 ? m_xCommandEnv->getProgressHandler()
263 : Reference<css::ucb::XProgressHandler>();
269 void FileDoesNotExistFilter::handle(
270 Reference<css::task::XInteractionRequest >
const & xRequest )
272 css::uno::Any request( xRequest->getRequest() );
274 css::ucb::InteractiveIOException ioexc;
275 if ((request>>= ioexc)
276 && (ioexc.Code == css::ucb::IOErrorCode_NOT_EXISTING
277 || ioexc.Code == css::ucb::IOErrorCode_NOT_EXISTING_PATH))
282 Reference<css::task::XInteractionHandler> xInteraction;
283 if (m_xCommandEnv.is()) {
284 xInteraction = m_xCommandEnv->getInteractionHandler();
286 if (xInteraction.is()) {
287 xInteraction->handle(xRequest);
297 Reference< css::xml::dom::XNode > root;
298 Reference<css::uno::XComponentContext> context(
302 ExtensionDescription(
303 context, sExtensionFolderURL,
306 }
catch (
const NoDescriptionException &) {
307 }
catch (
const css::deployment::DeploymentException & e) {
309 throw css::lang::WrappedTargetRuntimeException(
310 "com.sun.star.deployment.DeploymentException: " + e.Message,
317 css::uno::Reference< css::uno::XComponentContext >
const & context,
318 css::uno::Reference< css::xml::dom::XNode >
const & element):
324 m_xpath->registerNS(
"desc", element->getNamespaceURI());
325 m_xpath->registerNS(
"xlink",
"http://www.w3.org/1999/xlink");
337 css::uno::Reference< css::xml::dom::XNode >
n;
341 }
catch (
const css::xml::xpath::XPathException &) {
345 return n.is() ? getNodeValue(n) : OUString();
357 if (currentversion.getLength() == 0)
362 {
"nodepath", css::uno::Any(OUString(
"/org.openoffice.Office.ExtensionDependencies/Extensions"))}
364 css::uno::Reference< css::container::XNameAccess > denylist(
365 (css::configuration::theDefaultProvider::get(
m_context)
366 ->createInstanceWithArguments(
367 "com.sun.star.configuration.ConfigurationAccess", args)),
368 css::uno::UNO_QUERY_THROW);
371 if (!(denylist.is() && denylist->hasByName(*
id)))
return;
373 css::uno::Reference< css::beans::XPropertySet > extProps(
374 denylist->getByName(*
id), css::uno::UNO_QUERY_THROW);
376 css::uno::Any anyValue = extProps->getPropertyValue(
"Versions");
378 css::uno::Sequence< OUString > blversions;
379 anyValue >>= blversions;
384 anyValue = extProps->getPropertyValue(
"Dependencies");
388 if (udeps.getLength() == 0)
393 css::uno::Reference< css::xml::dom::XDocumentBuilder> docbuilder(
394 m_context->getServiceManager()->createInstanceWithContext(
"com.sun.star.xml.dom.DocumentBuilder",
m_context),
395 css::uno::UNO_QUERY_THROW);
397 css::uno::Sequence< sal_Int8 > byteSeq(reinterpret_cast<const sal_Int8*>(xmlDependencies.getStr()), xmlDependencies.getLength());
399 css::uno::Reference< css::io::XInputStream> inputstream( css::io::SequenceInputStream::createStreamFromSequence(
m_context, byteSeq),
400 css::uno::UNO_QUERY_THROW);
402 css::uno::Reference< css::xml::dom::XDocument > xDocument(docbuilder->parse(inputstream));
403 css::uno::Reference< css::xml::dom::XElement > xElement(xDocument->getDocumentElement());
404 css::uno::Reference< css::xml::dom::XNodeList > xDeps(xElement->getChildNodes());
405 sal_Int32 nLen = xDeps->getLength();
408 css::uno::Reference< css::xml::dom::XDocument > xCurrentDescInfo(
m_element->getOwnerDocument());
411 css::uno::Reference< css::xml::dom::XNode > xCurrentDeps(
415 if (!xCurrentDeps.is()) {
416 css::uno::Reference< css::xml::dom::XNode > xNewDepNode(
417 xCurrentDescInfo->createElementNS(
418 "http://openoffice.org/extensions/description/2006",
419 "dependencies"), css::uno::UNO_QUERY_THROW);
424 for (sal_Int32
i=0;
i<nLen;
i++) {
425 css::uno::Reference< css::xml::dom::XNode > xNode(xDeps->item(
i));
426 css::uno::Reference< css::xml::dom::XElement > xDep(xNode, css::uno::UNO_QUERY);
429 css::uno::Reference< css::xml::dom::XNode > importedNode = xCurrentDescInfo->importNode(xNode,
true);
430 xCurrentDeps->appendChild(importedNode);
436 std::u16string_view currentversion,
437 css::uno::Sequence< OUString >
const & versions)
439 sal_Int32 nLen = versions.getLength();
440 for (sal_Int32
i=0;
i<nLen;
i++) {
441 if (currentversion == versions[
i])
458 return { OUString(
"all") };
462 css::uno::Reference< css::xml::dom::XNode > nodePlatform(
464 if (!nodePlatform.is())
466 return { OUString(
"all") };
472 std::vector< OUString> vec;
476 const OUString aToken = value.getToken( 0,
',', nIndex ).trim();
477 if (!aToken.isEmpty())
478 vec.push_back(aToken);
486 css::uno::Reference< css::xml::dom::XNodeList >
494 }
catch (
const css::xml::xpath::XPathException &) {
498 return new EmptyNodeList;
501 css::uno::Sequence< OUString >
503 return getUrls(
"desc:update-information/desc:src/@xlink:href");
506 css::uno::Sequence< OUString >
509 return getUrls(
"desc:update-download/desc:src/@xlink:href");
514 css::uno::Sequence< OUString > aStrList =
getUrls(
"desc:icon/desc:default/@xlink:href" );
515 css::uno::Sequence< OUString > aStrListHC =
getUrls(
"desc:icon/desc:high-contrast/@xlink:href" );
517 if ( bHighContrast && aStrListHC.hasElements() && !aStrListHC[0].isEmpty() )
518 return aStrListHC[0];
520 if ( aStrList.hasElements() && !aStrList[0].isEmpty() )
529 bool bParentExists =
false;
533 return ::std::optional< OUString >(sURL);
535 return bParentExists ? ::std::optional< OUString >(OUString()) :
536 ::std::optional< OUString >();
540 OUString
const & expression)
const
542 css::uno::Reference< css::xml::dom::XNode >
n;
546 }
catch (
const css::xml::xpath::XPathException &) {
551 ? ::std::optional< OUString >(getNodeValue(n))
552 : ::std::optional< OUString >();
556 OUString
const & expression)
const
558 css::uno::Reference< css::xml::dom::XNodeList >
ns;
562 }
catch (
const css::xml::xpath::XPathException &) {
566 css::uno::Sequence< OUString > urls(ns.is() ? ns->getLength() : 0);
567 for (::sal_Int32
i = 0;
i < urls.getLength(); ++
i) {
568 urls[
i] = getNodeValue(ns->item(
i));
575 css::uno::Reference< css::xml::dom::XNode > node =
578 OUString sPublisherName;
582 css::uno::Reference< css::xml::dom::XNode > xPathName;
584 xPathName =
m_xpath->selectSingleNode(node,
"text()");
585 }
catch (
const css::xml::xpath::XPathException &) {
588 OSL_ASSERT(xPathName.is());
590 sPublisherName = xPathName->getNodeValue();
592 css::uno::Reference< css::xml::dom::XNode > xURL;
594 xURL =
m_xpath->selectSingleNode(node,
"@xlink:href");
595 }
catch (
const css::xml::xpath::XPathException &) {
598 OSL_ASSERT(xURL.is());
600 sURL = xURL->getNodeValue();
602 return std::make_pair(sPublisherName, sURL);
612 css::uno::Reference< css::xml::dom::XNode > node =
616 css::uno::Reference< css::xml::dom::XNode > xtext;
618 xtext =
m_xpath->selectSingleNode(node,
"text()");
619 }
catch (
const css::xml::xpath::XPathException &) {
623 return xtext->getNodeValue();
634 ::std::optional<SimpleLicenseAttributes>
638 css::uno::Reference< css::xml::dom::XNode >
n;
641 n =
m_xpath->selectSingleNode(
m_element,
"/desc:description/desc:registration/desc:simple-license/@accept-by");
642 }
catch (
const css::xml::xpath::XPathException &) {
651 ::std::optional< OUString > suppressOnUpdate =
getOptionalValue(
"/desc:description/desc:registration/desc:simple-license/@suppress-on-update");
652 if (suppressOnUpdate)
653 attributes.
suppressOnUpdate = (*suppressOnUpdate).trim().equalsIgnoreAsciiCase(
"true");
657 ::std::optional< OUString > suppressIfRequired =
getOptionalValue(
"/desc:description/desc:registration/desc:simple-license/@suppress-if-required");
658 if (suppressIfRequired)
659 attributes.
suppressIfRequired = (*suppressIfRequired).trim().equalsIgnoreAsciiCase(
"true");
663 return ::std::optional<SimpleLicenseAttributes>(attributes);
666 return ::std::optional<SimpleLicenseAttributes>();
674 css::uno::Reference< css::xml::dom::XNode >
677 if ( !
m_element.is() || sParent.isEmpty())
678 return css::uno::Reference< css::xml::dom::XNode > ();
680 css::uno::Reference< css::xml::dom::XNode > xParent;
683 }
catch (
const css::xml::xpath::XPathException &) {
686 css::uno::Reference<css::xml::dom::XNode> nodeMatch;
692 if (! nodeMatch.is())
696 for (
auto const& fallback : aFallbacks)
702 if (! nodeMatch.is())
710 css::uno::Reference<css::xml::dom::XNode>
712 css::uno::Reference< css::xml::dom::XNode >
const & xParent, std::u16string_view rTag)
const
714 OSL_ASSERT(xParent.is());
715 css::uno::Reference<css::xml::dom::XNode> nodeMatch;
718 const OUString exp1(OUString::Concat(
"*[@lang=\"") + rTag +
"\"]");
720 nodeMatch =
m_xpath->selectSingleNode(xParent, exp1);
721 }
catch (
const css::xml::xpath::XPathException &) {
730 OUString::Concat(
"*[starts-with(@lang,\"") + rTag +
"-\")]");
732 nodeMatch =
m_xpath->selectSingleNode(xParent, exp2);
733 }
catch (
const css::xml::xpath::XPathException &) {
740 css::uno::Reference<css::xml::dom::XNode>
742 const & xParent)
const
744 OSL_ASSERT(xParent.is());
745 if ( xParent->getNodeName() ==
"simple-license" )
747 css::uno::Reference<css::xml::dom::XNode> nodeDefault;
749 nodeDefault =
m_xpath->selectSingleNode(xParent,
"@default-license-id");
750 }
catch (
const css::xml::xpath::XPathException &) {
753 if (nodeDefault.is())
756 const OUString exp1(
"desc:license-text[@license-id = \""
757 + nodeDefault->getNodeValue()
760 return m_xpath->selectSingleNode(xParent, exp1);
761 }
catch (
const css::xml::xpath::XPathException &) {
768 return m_xpath->selectSingleNode(xParent,
"*[1]");
769 }
catch (
const css::xml::xpath::XPathException &) {
776 OUString
const & sXPathParent,
bool * out_bParentExists)
779 css::uno::Reference< css::xml::dom::XNode > node =
785 if (out_bParentExists)
786 *out_bParentExists =
true;
787 css::uno::Reference< css::xml::dom::XNode > xURL;
789 xURL =
m_xpath->selectSingleNode(node,
"@xlink:href");
790 }
catch (
const css::xml::xpath::XPathException &) {
793 OSL_ASSERT(xURL.is());
795 sURL = xURL->getNodeValue();
799 if (out_bParentExists)
800 *out_bParentExists =
false;
DESKTOP_DEPLOYMENTMISC_DLLPUBLIC const LanguageTag & getOfficeLanguageTag()
OUString getLocalizedLicenseURL() const
returns the relative path to the license file.
OUString getLocalizedReleaseNotesURL() const
Returns the URL for the release notes corresponding to the office's locale.
css::uno::Sequence< OUString > getUpdateInformationUrls() const
Return the update information URLs.
css::uno::Sequence< OUString > getUpdateDownloadUrls() const
Return the download URLs from the update information.
css::uno::Reference< css::xml::dom::XNodeList > getDependencies() const
Return the dependencies.
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::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::pair< OUString, OUString > getLocalizedPublisherNameAndURL() const
Returns the localized publisher name and the corresponding URL.
OUString getVersion() const
Return the textual version representation.
DescriptionInfoset(css::uno::Reference< css::uno::XComponentContext > const &context, css::uno::Reference< css::xml::dom::XNode > const &element)
Create an instance.
Any SAL_CALL getCaughtException()
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
OUString getLocalizedDisplayName() const
returns the localized display name of the extensions.
css::uno::Reference< css::xml::xpath::XXPathAPI > m_xpath
DESKTOP_DEPLOYMENTMISC_DLLPUBLIC DescriptionInfoset getDescriptionInfoset(std::u16string_view sExtensionFolderURL)
creates a DescriptionInfoset object.
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.
css::uno::Sequence< css::uno::Any > InitAnyPropertySequence(::std::initializer_list< ::std::pair< OUString, css::uno::Any > > vInit)
SAL_DLLPRIVATE OUString getNodeValueFromExpression(OUString const &expression) const
Gets the node value for a given expression.
::std::optional< OUString > getIdentifier() const
Return the identifier.
SAL_DLLPRIVATE OUString getLocalizedHREFAttrFromChild(OUString const &sXPathParent, bool *out_bParentExists) const
SAL_DLLPRIVATE::std::optional< OUString > getOptionalValue(OUString const &expression) const
static uno::Reference< css::uno::XComponentContext > xContext
Reference< xml::input::XRoot > m_xRoot
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
SAL_DLLPRIVATE css::uno::Sequence< OUString > getUrls(OUString const &expression) const
Reference< XComponentContext > getProcessComponentContext()
double getLength(const B2DPolygon &rCandidate)
::std::optional< SimpleLicenseAttributes > getSimpleLicenseAttributes() const
returns the attributes of the simple-license element
css::uno::Reference< css::xml::dom::XNode > m_element
css::uno::Sequence< OUString > getSupportedPlatforms() const
Returns a list of supported platforms.
SAL_DLLPRIVATE css::uno::Reference< css::xml::dom::XNode > matchLanguageTag(css::uno::Reference< css::xml::dom::XNode > const &xParent, std::u16string_view rTag) const
OUString getLocalizedDescriptionURL() const
returns the relative URL to the description.
css::uno::Reference< css::uno::XComponentContext > m_context
OUString getIconURL(bool bHighContrast) const
Returns the URL for the icon image.
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 void checkDenylist() const
Check the extensions denylist if additional extension meta data (e.g.
::std::optional< OUString > getLocalizedUpdateWebsiteURL() const
returns the download website URL from the update information.
Access to the content of an XML description element.