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