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