Coverage Report

Created: 2026-02-14 09:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/desktop/source/deployment/registry/dp_backenddb.cxx
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
5
 * This Source Code Form is subject to the terms of the Mozilla Public
6
 * License, v. 2.0. If a copy of the MPL was not distributed with this
7
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
 *
9
 * This file incorporates work covered by the following license notice:
10
 *
11
 *   Licensed to the Apache Software Foundation (ASF) under one or more
12
 *   contributor license agreements. See the NOTICE file distributed
13
 *   with this work for additional information regarding copyright
14
 *   ownership. The ASF licenses this file to you under the Apache
15
 *   License, Version 2.0 (the "License"); you may not use this file
16
 *   except in compliance with the License. You may obtain a copy of
17
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18
 */
19
20
21
#include <cppuhelper/exc_hlp.hxx>
22
#include <osl/diagnose.h>
23
#include <osl/file.hxx>
24
#include <com/sun/star/deployment/DeploymentException.hpp>
25
#include <com/sun/star/uno/XComponentContext.hpp>
26
#include <com/sun/star/xml/dom/DocumentBuilder.hpp>
27
#include <com/sun/star/xml/xpath/XPathAPI.hpp>
28
#include <com/sun/star/io/XActiveDataSource.hpp>
29
#include <com/sun/star/io/XActiveDataControl.hpp>
30
#include <dp_misc.h>
31
#include <ucbhelper/content.hxx>
32
#include <xmlscript/xml_helper.hxx>
33
#include <dp_backenddb.hxx>
34
35
36
using namespace ::com::sun::star::uno;
37
38
39
namespace dp_registry::backend {
40
41
BackendDb::BackendDb(
42
    Reference<css::uno::XComponentContext> const &  xContext,
43
    OUString const & url):
44
0
    m_xContext(xContext)
45
0
{
46
0
    m_urlDb = dp_misc::expandUnoRcUrl(url);
47
0
}
48
49
void BackendDb::save()
50
0
{
51
0
    const Reference<css::io::XActiveDataSource> xDataSource(m_doc,css::uno::UNO_QUERY_THROW);
52
0
    std::vector<sal_Int8> bytes;
53
0
    xDataSource->setOutputStream(::xmlscript::createOutputStream(&bytes));
54
0
    const Reference<css::io::XActiveDataControl> xDataControl(m_doc,css::uno::UNO_QUERY_THROW);
55
0
    xDataControl->start();
56
57
0
    const Reference<css::io::XInputStream> xData(
58
0
        ::xmlscript::createInputStream(std::move(bytes)));
59
0
    ::ucbhelper::Content ucbDb(m_urlDb, nullptr, m_xContext);
60
0
    ucbDb.writeStream(xData, true /*replace existing*/);
61
0
}
62
63
css::uno::Reference<css::xml::dom::XDocument> const & BackendDb::getDocument()
64
0
{
65
0
    if (!m_doc.is())
66
0
    {
67
0
        const Reference<css::xml::dom::XDocumentBuilder> xDocBuilder(
68
0
            css::xml::dom::DocumentBuilder::create(m_xContext) );
69
70
0
        ::osl::DirectoryItem item;
71
0
        ::osl::File::RC err = ::osl::DirectoryItem::get(m_urlDb, item);
72
0
        if (err == ::osl::File::E_None)
73
0
        {
74
0
            ::ucbhelper::Content descContent(
75
0
                m_urlDb, css::uno::Reference<css::ucb::XCommandEnvironment>(),
76
0
                m_xContext);
77
0
            Reference<css::io::XInputStream> xIn = descContent.openStream();
78
0
            m_doc = xDocBuilder->parse(xIn);
79
0
        }
80
0
        else if (err == ::osl::File::E_NOENT)
81
0
        {
82
            //Create a new document and insert some basic stuff
83
0
            m_doc = xDocBuilder->newDocument();
84
0
            const Reference<css::xml::dom::XElement> rootNode =
85
0
                m_doc->createElementNS(getDbNSName(), getNSPrefix() +
86
0
                                       ":" + getRootElementName());
87
88
0
            m_doc->appendChild(Reference<css::xml::dom::XNode>(
89
0
                                   rootNode, UNO_QUERY_THROW));
90
0
            save();
91
0
        }
92
0
        else
93
0
            throw css::uno::RuntimeException(
94
0
                "Extension manager could not access database file:"
95
0
                + m_urlDb, nullptr);
96
97
0
        if (!m_doc.is())
98
0
            throw css::uno::RuntimeException(
99
0
                "Extension manager could not get root node of data base file: "
100
0
                      + m_urlDb, nullptr);
101
0
    }
102
103
0
    return m_doc;
104
0
}
105
106
Reference<css::xml::xpath::XXPathAPI> const & BackendDb::getXPathAPI()
107
0
{
108
0
    if (!m_xpathApi.is())
109
0
    {
110
0
        m_xpathApi = css::xml::xpath::XPathAPI::create( m_xContext );
111
112
0
        m_xpathApi->registerNS( getNSPrefix(), getDbNSName() );
113
0
    }
114
115
0
    return m_xpathApi;
116
0
}
117
118
void BackendDb::removeElement(OUString const & sXPathExpression)
119
0
{
120
0
    try
121
0
    {
122
0
        const Reference<css::xml::dom::XDocument> doc = getDocument();
123
0
        const Reference<css::xml::dom::XNode> root = doc->getFirstChild();
124
0
        const Reference<css::xml::xpath::XXPathAPI> xpathApi = getXPathAPI();
125
        //find the extension element that is to be removed
126
0
        const Reference<css::xml::dom::XNode> aNode =
127
0
            xpathApi->selectSingleNode(root, sXPathExpression);
128
129
0
        if (aNode.is())
130
0
        {
131
0
            root->removeChild(aNode);
132
0
            save();
133
0
        }
134
135
#if    OSL_DEBUG_LEVEL > 0
136
        //There must not be any other entry with the same url
137
        const Reference<css::xml::dom::XNode> nextNode =
138
            xpathApi->selectSingleNode(root, sXPathExpression);
139
        OSL_ASSERT(! nextNode.is());
140
#endif
141
0
    }
142
0
    catch(const css::uno::Exception &)
143
0
    {
144
0
        Any exc( ::cppu::getCaughtException() );
145
0
        throw css::deployment::DeploymentException(
146
0
            "Extension Manager: failed to write data entry in backend db: " +
147
0
            m_urlDb, nullptr, exc);
148
0
    }
149
0
}
150
151
void BackendDb::removeEntry(std::u16string_view url)
152
0
{
153
0
    const OUString sKeyElement = getKeyElementName();
154
0
    const OUString sPrefix = getNSPrefix();
155
0
    OUString sExpression =
156
0
        sPrefix +
157
0
        ":" +
158
0
        sKeyElement +
159
0
        "[@url = \"" +
160
0
        url +
161
0
        "\"]";
162
163
0
    removeElement(sExpression);
164
0
}
165
166
void BackendDb::revokeEntry(std::u16string_view url)
167
0
{
168
0
    try
169
0
    {
170
0
        Reference<css::xml::dom::XElement> entry(getKeyElement(url), UNO_QUERY);
171
0
        if (entry.is())
172
0
        {
173
0
            entry->setAttribute(u"revoked"_ustr, u"true"_ustr);
174
0
            save();
175
0
        }
176
0
    }
177
0
    catch(const css::uno::Exception &)
178
0
    {
179
0
        Any exc( ::cppu::getCaughtException() );
180
0
        throw css::deployment::DeploymentException(
181
0
            "Extension Manager: failed to revoke data entry in backend db: " +
182
0
            m_urlDb, nullptr, exc);
183
0
    }
184
0
}
185
186
bool BackendDb::activateEntry(std::u16string_view url)
187
0
{
188
0
    try
189
0
    {
190
0
        bool ret = false;
191
0
        Reference<css::xml::dom::XElement> entry(getKeyElement(url), UNO_QUERY);
192
0
        if (entry.is())
193
0
        {
194
            //no attribute "active" means it is active, that is, registered.
195
0
            entry->removeAttribute(u"revoked"_ustr);
196
0
            save();
197
0
            ret = true;
198
0
        }
199
0
        return ret;
200
0
    }
201
0
    catch(const css::uno::Exception &)
202
0
    {
203
0
        Any exc( ::cppu::getCaughtException() );
204
0
        throw css::deployment::DeploymentException(
205
0
            "Extension Manager: failed to revoke data entry in backend db: " +
206
0
            m_urlDb, nullptr, exc);
207
0
    }
208
0
}
209
210
bool BackendDb::hasActiveEntry(std::u16string_view url)
211
0
{
212
0
    try
213
0
    {
214
0
        bool ret = false;
215
0
        Reference<css::xml::dom::XElement> entry(getKeyElement(url), UNO_QUERY);
216
0
        if (entry.is())
217
0
        {
218
0
            OUString sActive = entry->getAttribute(u"revoked"_ustr);
219
0
            if (!(sActive == "true"))
220
0
                ret = true;
221
0
        }
222
0
        return ret;
223
224
0
    }
225
0
    catch(const css::uno::Exception &)
226
0
    {
227
0
        Any exc( ::cppu::getCaughtException() );
228
0
        throw css::deployment::DeploymentException(
229
0
            "Extension Manager: failed to determine an active entry in backend db: " +
230
0
            m_urlDb, nullptr, exc);
231
0
    }
232
0
}
233
234
Reference<css::xml::dom::XNode> BackendDb::getKeyElement(
235
    std::u16string_view url)
236
0
{
237
0
    try
238
0
    {
239
0
        const OUString sPrefix = getNSPrefix();
240
0
        const OUString sKeyElement = getKeyElementName();
241
0
        OUString sExpression =
242
0
            sPrefix +
243
0
            ":" +
244
0
            sKeyElement +
245
0
            "[@url = \"" +
246
0
            url +
247
0
            "\"]";
248
249
0
        const Reference<css::xml::dom::XDocument> doc = getDocument();
250
0
        const Reference<css::xml::dom::XNode> root = doc->getFirstChild();
251
0
        const Reference<css::xml::xpath::XXPathAPI> xpathApi = getXPathAPI();
252
0
        return xpathApi->selectSingleNode(root, sExpression);
253
0
    }
254
0
    catch(const css::uno::Exception &)
255
0
    {
256
0
        Any exc( ::cppu::getCaughtException() );
257
0
        throw css::deployment::DeploymentException(
258
0
            "Extension Manager: failed to read key element in backend db: " +
259
0
            m_urlDb, nullptr, exc);
260
0
    }
261
0
}
262
263
//Only writes the data if there is at least one entry
264
void BackendDb::writeVectorOfPair(
265
    std::vector< std::pair< OUString, OUString > > const & vecPairs,
266
    std::u16string_view sVectorTagName,
267
    std::u16string_view sPairTagName,
268
    std::u16string_view sFirstTagName,
269
    std::u16string_view sSecondTagName,
270
    css::uno::Reference<css::xml::dom::XNode> const & xParent)
271
0
{
272
0
    try{
273
0
        if (vecPairs.empty())
274
0
            return;
275
0
        const OUString sNameSpace = getDbNSName();
276
0
        OSL_ASSERT(!sNameSpace.isEmpty());
277
0
        const OUString sPrefix(getNSPrefix() + ":");
278
0
        const Reference<css::xml::dom::XDocument> doc = getDocument();
279
280
0
        const Reference<css::xml::dom::XElement> vectorNode(
281
0
            doc->createElementNS(sNameSpace, sPrefix + sVectorTagName));
282
283
0
        xParent->appendChild(
284
0
            Reference<css::xml::dom::XNode>(
285
0
                vectorNode, css::uno::UNO_QUERY_THROW));
286
0
        for (auto const& vecPair : vecPairs)
287
0
        {
288
0
            const Reference<css::xml::dom::XElement> pairNode(
289
0
                doc->createElementNS(sNameSpace, sPrefix + sPairTagName));
290
291
0
            vectorNode->appendChild(
292
0
                Reference<css::xml::dom::XNode>(
293
0
                    pairNode, css::uno::UNO_QUERY_THROW));
294
295
0
            const Reference<css::xml::dom::XElement> firstNode(
296
0
                doc->createElementNS(sNameSpace, sPrefix + sFirstTagName));
297
298
0
            pairNode->appendChild(
299
0
                Reference<css::xml::dom::XNode>(
300
0
                    firstNode, css::uno::UNO_QUERY_THROW));
301
302
0
            const Reference<css::xml::dom::XText> firstTextNode(
303
0
                doc->createTextNode( vecPair.first));
304
305
0
            firstNode->appendChild(
306
0
                Reference<css::xml::dom::XNode>(
307
0
                    firstTextNode, css::uno::UNO_QUERY_THROW));
308
309
0
            const Reference<css::xml::dom::XElement> secondNode(
310
0
                doc->createElementNS(sNameSpace, sPrefix + sSecondTagName));
311
312
0
            pairNode->appendChild(
313
0
                Reference<css::xml::dom::XNode>(
314
0
                    secondNode, css::uno::UNO_QUERY_THROW));
315
316
0
            const Reference<css::xml::dom::XText> secondTextNode(
317
0
                doc->createTextNode( vecPair.second));
318
319
0
            secondNode->appendChild(
320
0
                Reference<css::xml::dom::XNode>(
321
0
                    secondTextNode, css::uno::UNO_QUERY_THROW));
322
0
        }
323
0
    }
324
0
    catch(const css::uno::Exception &)
325
0
    {
326
0
        Any exc( ::cppu::getCaughtException() );
327
0
        throw css::deployment::DeploymentException(
328
0
            "Extension Manager: failed to write data entry in backend db: " +
329
0
            m_urlDb, nullptr, exc);
330
0
    }
331
0
}
332
333
std::vector< std::pair< OUString, OUString > >
334
BackendDb::readVectorOfPair(
335
    Reference<css::xml::dom::XNode> const & parent,
336
    std::u16string_view sListTagName,
337
    std::u16string_view sPairTagName,
338
    std::u16string_view sFirstTagName,
339
    std::u16string_view sSecondTagName)
340
0
{
341
0
    try
342
0
    {
343
0
        OSL_ASSERT(parent.is());
344
0
        const OUString sPrefix(getNSPrefix() + ":");
345
0
        const Reference<css::xml::xpath::XXPathAPI> xpathApi = getXPathAPI();
346
0
        const OUString sExprPairs(
347
0
            sPrefix + sListTagName + "/" + sPrefix + sPairTagName);
348
0
        const Reference<css::xml::dom::XNodeList> listPairs =
349
0
            xpathApi->selectNodeList(parent, sExprPairs);
350
351
0
        std::vector< std::pair< OUString, OUString > > retVector;
352
0
        sal_Int32 length = listPairs->getLength();
353
0
        for (sal_Int32 i = 0; i < length; i++)
354
0
        {
355
0
            const Reference<css::xml::dom::XNode> aPair = listPairs->item(i);
356
0
            const OUString sExprFirst(sPrefix + sFirstTagName + "/text()");
357
0
            const Reference<css::xml::dom::XNode> first =
358
0
                xpathApi->selectSingleNode(aPair, sExprFirst);
359
360
0
            const OUString sExprSecond(sPrefix + sSecondTagName + "/text()");
361
0
            const Reference<css::xml::dom::XNode> second =
362
0
                xpathApi->selectSingleNode(aPair, sExprSecond);
363
0
            OSL_ASSERT(first.is() && second.is());
364
365
0
            retVector.emplace_back(
366
0
                                    first->getNodeValue(), second->getNodeValue());
367
0
        }
368
0
        return retVector;
369
0
    }
370
0
    catch(const css::uno::Exception &)
371
0
    {
372
0
        Any exc( ::cppu::getCaughtException() );
373
0
        throw css::deployment::DeploymentException(
374
0
            "Extension Manager: failed to read data entry in backend db: " +
375
0
            m_urlDb, nullptr, exc);
376
0
    }
377
0
}
378
379
//Only writes the data if there is at least one entry
380
void BackendDb::writeSimpleList(
381
    std::deque< OUString> const & list,
382
    std::u16string_view sListTagName,
383
    std::u16string_view sMemberTagName,
384
    Reference<css::xml::dom::XNode> const & xParent)
385
0
{
386
0
    try
387
0
    {
388
0
        if (list.empty())
389
0
            return;
390
0
        const OUString sNameSpace = getDbNSName();
391
0
        const OUString sPrefix(getNSPrefix() + ":");
392
0
        const Reference<css::xml::dom::XDocument> doc = getDocument();
393
394
0
        const Reference<css::xml::dom::XElement> listNode(
395
0
            doc->createElementNS(sNameSpace, sPrefix + sListTagName));
396
397
0
        xParent->appendChild(
398
0
            Reference<css::xml::dom::XNode>(
399
0
                listNode, css::uno::UNO_QUERY_THROW));
400
401
0
        for (auto const& elem : list)
402
0
        {
403
0
            const Reference<css::xml::dom::XNode> memberNode(
404
0
                doc->createElementNS(sNameSpace, sPrefix + sMemberTagName), css::uno::UNO_QUERY_THROW);
405
406
0
            listNode->appendChild(memberNode);
407
408
0
            const Reference<css::xml::dom::XNode> textNode(
409
0
                doc->createTextNode(elem), css::uno::UNO_QUERY_THROW);
410
411
0
            memberNode->appendChild(textNode);
412
0
        }
413
0
    }
414
0
    catch(const css::uno::Exception &)
415
0
    {
416
0
        Any exc( ::cppu::getCaughtException() );
417
0
        throw css::deployment::DeploymentException(
418
0
            "Extension Manager: failed to write data entry in backend db: " +
419
0
            m_urlDb, nullptr, exc);
420
0
    }
421
0
}
422
423
//Writes only the element if is has a value.
424
//The prefix is automatically added to the element name
425
void BackendDb::writeSimpleElement(
426
    std::u16string_view sElementName, OUString const & value,
427
    Reference<css::xml::dom::XNode> const & xParent)
428
0
{
429
0
    try
430
0
    {
431
0
        if (value.isEmpty())
432
0
            return;
433
0
        const OUString sPrefix = getNSPrefix();
434
0
        const Reference<css::xml::dom::XDocument> doc = getDocument();
435
0
        const OUString sNameSpace = getDbNSName();
436
0
        const Reference<css::xml::dom::XNode> dataNode(
437
0
            doc->createElementNS(sNameSpace, sPrefix + ":" + sElementName),
438
0
            UNO_QUERY_THROW);
439
0
        xParent->appendChild(dataNode);
440
441
0
        const Reference<css::xml::dom::XNode> dataValue(
442
0
            doc->createTextNode(value), UNO_QUERY_THROW);
443
0
        dataNode->appendChild(dataValue);
444
0
    }
445
0
    catch(const css::uno::Exception &)
446
0
    {
447
0
        Any exc( ::cppu::getCaughtException() );
448
0
        throw css::deployment::DeploymentException(
449
0
            "Extension Manager: failed to write data entry(writeSimpleElement) in backend db: " +
450
0
            m_urlDb, nullptr, exc);
451
0
    }
452
453
0
}
454
455
/// The key elements have a url attribute and are always children of the root element.
456
Reference<css::xml::dom::XNode> BackendDb::writeKeyElement(
457
    OUString const & url)
458
0
{
459
0
    try
460
0
    {
461
0
        const OUString sNameSpace = getDbNSName();
462
0
        const OUString sPrefix = getNSPrefix();
463
0
        const OUString sElementName = getKeyElementName();
464
0
        const Reference<css::xml::dom::XDocument> doc = getDocument();
465
0
        const Reference<css::xml::dom::XNode> root = doc->getFirstChild();
466
467
        //Check if there are an entry with the same url. This can be the case if the
468
        //status of an XPackage is ambiguous. In this case a call to activateExtension
469
        //(dp_extensionmanager.cxx), will register the package again. See also
470
        //Package::processPackage_impl in dp_backend.cxx.
471
        //A package can become
472
        //invalid after its successful registration, for example if a second extension with
473
        //the same service is installed.
474
0
        const OUString sExpression(
475
0
            sPrefix + ":" + sElementName + "[@url = \"" + url + "\"]");
476
0
        const Reference<css::xml::dom::XNode> existingNode =
477
0
            getXPathAPI()->selectSingleNode(root, sExpression);
478
0
        if (existingNode.is())
479
0
        {
480
0
            OSL_ASSERT(false);
481
            //replace the existing entry.
482
0
            removeEntry(url);
483
0
        }
484
485
0
        const Reference<css::xml::dom::XElement> keyElement(
486
0
            doc->createElementNS(sNameSpace, sPrefix +  ":" + sElementName));
487
488
0
        keyElement->setAttribute(u"url"_ustr, url);
489
490
0
        const Reference<css::xml::dom::XNode> keyNode(
491
0
            keyElement, UNO_QUERY_THROW);
492
0
        root->appendChild(keyNode);
493
0
        return keyNode;
494
0
    }
495
0
    catch(const css::uno::Exception &)
496
0
    {
497
0
        Any exc( ::cppu::getCaughtException() );
498
0
        throw css::deployment::DeploymentException(
499
0
            "Extension Manager: failed to write key element in backend db: " +
500
0
            m_urlDb, nullptr, exc);
501
0
    }
502
0
}
503
504
OUString BackendDb::readSimpleElement(
505
    std::u16string_view sElementName, Reference<css::xml::dom::XNode> const & xParent)
506
0
{
507
0
    try
508
0
    {
509
0
        const OUString sPrefix = getNSPrefix();
510
0
        const OUString sExpr(sPrefix + ":" + sElementName + "/text()");
511
0
        const Reference<css::xml::xpath::XXPathAPI> xpathApi = getXPathAPI();
512
0
        const Reference<css::xml::dom::XNode> val =
513
0
            xpathApi->selectSingleNode(xParent, sExpr);
514
0
        if (val.is())
515
0
            return val->getNodeValue();
516
0
        return OUString();
517
0
    }
518
0
    catch(const css::uno::Exception &)
519
0
    {
520
0
        Any exc( ::cppu::getCaughtException() );
521
0
        throw css::deployment::DeploymentException(
522
0
            "Extension Manager: failed to read data (readSimpleElement) in backend db: " +
523
0
            m_urlDb, nullptr, exc);
524
0
    }
525
0
}
526
527
528
std::deque< OUString> BackendDb::readList(
529
    Reference<css::xml::dom::XNode> const & parent,
530
    std::u16string_view sListTagName,
531
    std::u16string_view sMemberTagName)
532
0
{
533
0
    try
534
0
    {
535
0
        OSL_ASSERT(parent.is());
536
0
        const OUString sPrefix(getNSPrefix() + ":");
537
0
        const Reference<css::xml::xpath::XXPathAPI> xpathApi = getXPathAPI();
538
0
        const OUString sExprList(
539
0
            sPrefix + sListTagName + "/" + sPrefix + sMemberTagName + "/text()");
540
0
        const Reference<css::xml::dom::XNodeList> list =
541
0
            xpathApi->selectNodeList(parent, sExprList);
542
543
0
        std::deque<OUString > retList;
544
0
        sal_Int32 length = list->getLength();
545
0
        for (sal_Int32 i = 0; i < length; i++)
546
0
        {
547
0
            const Reference<css::xml::dom::XNode> member = list->item(i);
548
0
            retList.push_back(member->getNodeValue());
549
0
        }
550
0
        return retList;
551
0
    }
552
0
    catch(const css::uno::Exception &)
553
0
    {
554
0
        Any exc( ::cppu::getCaughtException() );
555
0
        throw css::deployment::DeploymentException(
556
0
            "Extension Manager: failed to read data entry in backend db: " +
557
0
            m_urlDb, nullptr, exc);
558
0
    }
559
0
}
560
561
std::vector<OUString> BackendDb::getOneChildFromAllEntries(
562
    std::u16string_view name)
563
0
{
564
0
    try
565
0
    {
566
0
        std::vector<OUString> listRet;
567
0
        Reference<css::xml::dom::XDocument> doc = getDocument();
568
0
        Reference<css::xml::dom::XNode> root = doc->getFirstChild();
569
570
0
        Reference<css::xml::xpath::XXPathAPI> xpathApi = getXPathAPI();
571
0
        const OUString sPrefix = getNSPrefix();
572
0
        const OUString sKeyElement = getKeyElementName();
573
0
        OUString sNodeSelectExpr =
574
0
            sPrefix +
575
0
            ":" +
576
0
            sKeyElement +
577
0
            "/" +
578
0
            sPrefix +
579
0
            ":" +
580
0
            name +
581
0
            "/text()";
582
583
0
        Reference<css::xml::dom::XNodeList> nodes =
584
0
            xpathApi->selectNodeList(root, sNodeSelectExpr);
585
0
        if (nodes.is())
586
0
        {
587
0
            sal_Int32 length = nodes->getLength();
588
0
            for (sal_Int32 i = 0; i < length; i++)
589
0
                listRet.push_back(nodes->item(i)->getNodeValue());
590
0
        }
591
0
        return listRet;
592
0
    }
593
0
    catch ( const css::deployment::DeploymentException& )
594
0
    {
595
0
        throw;
596
0
    }
597
0
    catch(const css::uno::Exception &)
598
0
    {
599
0
        Any exc( ::cppu::getCaughtException() );
600
0
        throw css::deployment::DeploymentException(
601
0
            "Extension Manager: failed to read data entry in backend db: " +
602
0
            m_urlDb, nullptr, exc);
603
0
    }
604
0
}
605
606
607
RegisteredDb::RegisteredDb(
608
    Reference<XComponentContext> const &  xContext,
609
0
    OUString const & url):BackendDb(xContext, url)
610
0
{
611
0
}
612
613
void RegisteredDb::addEntry(OUString const & url)
614
0
{
615
0
    try{
616
0
        if (!activateEntry(url))
617
0
        {
618
0
            const OUString sNameSpace = getDbNSName();
619
0
            const OUString sPrefix = getNSPrefix();
620
0
            const OUString sEntry = getKeyElementName();
621
622
0
            Reference<css::xml::dom::XDocument> doc = getDocument();
623
0
            Reference<css::xml::dom::XNode> root = doc->getFirstChild();
624
625
#if    OSL_DEBUG_LEVEL > 0
626
            //There must not be yet an entry with the same url
627
            OUString sExpression(
628
                sPrefix + ":" + sEntry + "[@url = \"" + url + "\"]");
629
            Reference<css::xml::dom::XNode> _extensionNode =
630
                getXPathAPI()->selectSingleNode(root, sExpression);
631
            OSL_ASSERT(! _extensionNode.is());
632
#endif
633
0
            Reference<css::xml::dom::XElement> helpElement(
634
0
                doc->createElementNS(sNameSpace, sPrefix +  ":" + sEntry));
635
636
0
            helpElement->setAttribute(u"url"_ustr, url);
637
638
0
            Reference<css::xml::dom::XNode> helpNode(
639
0
                helpElement, UNO_QUERY_THROW);
640
0
            root->appendChild(helpNode);
641
642
0
            save();
643
0
        }
644
0
    }
645
0
    catch(const css::uno::Exception &)
646
0
    {
647
0
        Any exc( ::cppu::getCaughtException() );
648
0
        throw css::deployment::DeploymentException(
649
0
            "Extension Manager: failed to write data entry in backend db: " +
650
0
            m_urlDb, nullptr, exc);
651
0
    }
652
0
}
653
654
} // namespace dp_registry
655
656
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */