build fix: no comphelper/profilezone.hxx in this branch
[LibreOffice.git] / unoxml / source / rdf / librdf_repository.cxx
blob1cb823070b70ddd54b749f0ada5c741e301b6b88
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "librdf_repository.hxx"
22 #include <string.h>
24 #include <map>
25 #include <memory>
26 #include <set>
27 #include <iterator>
28 #include <functional>
29 #include <algorithm>
31 #include <boost/optional.hpp>
33 #include <libxslt/security.h>
35 #include <redland.h>
37 #include <com/sun/star/lang/XServiceInfo.hpp>
38 #include <com/sun/star/lang/XInitialization.hpp>
39 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
40 #include <com/sun/star/lang/IllegalArgumentException.hpp>
41 #include <com/sun/star/io/XSeekableInputStream.hpp>
42 #include <com/sun/star/text/XTextRange.hpp>
43 #include <com/sun/star/rdf/XDocumentRepository.hpp>
44 #include <com/sun/star/rdf/XLiteral.hpp>
45 #include <com/sun/star/rdf/FileFormat.hpp>
46 #include <com/sun/star/rdf/URIs.hpp>
47 #include <com/sun/star/rdf/BlankNode.hpp>
48 #include <com/sun/star/rdf/URI.hpp>
49 #include <com/sun/star/rdf/Literal.hpp>
51 #include <rtl/ref.hxx>
52 #include <rtl/ustring.hxx>
53 #include <osl/diagnose.h>
54 #include <cppuhelper/implbase.hxx>
55 #include <cppuhelper/basemutex.hxx>
56 #include <cppuhelper/supportsservice.hxx>
58 #include <comphelper/sequence.hxx>
59 #include <comphelper/xmltools.hxx>
61 #include <com/sun/star/embed/XEncryptionProtectedSource2.hpp>
63 /**
64 Implementation of the service com.sun.star.rdf.Repository.
66 This implementation uses the Redland RDF library (librdf).
68 There are several classes involved:
69 librdf_TypeConverter: helper class to convert data types redland <-> uno
70 librdf_Repository: the main repository, does almost all the work
71 librdf_NamedGraph: the XNamedGraph, forwards everything to repository
72 librdf_GraphResult: an XEnumeration<Statement>
73 librdf_QuerySelectResult: an XEnumeration<sequence<XNode>>
77 /// anonymous implementation namespace
78 namespace {
80 class librdf_NamedGraph;
81 class librdf_Repository;
83 using namespace ::com::sun::star;
85 typedef std::map< OUString, ::rtl::Reference<librdf_NamedGraph> >
86 NamedGraphMap_t;
88 const char s_sparql [] = "sparql";
89 const char s_nsOOo [] = "http://openoffice.org/2004/office/rdfa/";
92 //FIXME: this approach is not ideal. can we use blank nodes instead?
93 bool isInternalContext(librdf_node *i_pNode) throw ()
95 OSL_ENSURE(i_pNode, "isInternalContext: context null");
96 OSL_ENSURE(librdf_node_is_resource(i_pNode),
97 "isInternalContext: context not resource");
98 if (i_pNode) {
99 librdf_uri *pURI(librdf_node_get_uri(i_pNode));
100 OSL_ENSURE(pURI, "isInternalContext: URI null");
101 if (pURI) {
102 unsigned char *pContextURI(librdf_uri_as_string(pURI));
103 assert(pContextURI && "isInternalContext: URI string null");
104 // if prefix matches reserved uri, it is RDFa context
105 if (!strncmp(reinterpret_cast<char *>(pContextURI),
106 s_nsOOo, sizeof(s_nsOOo)-1)) {
107 return true;
110 return false;
112 return true;
116 // n.b.: librdf destructor functions dereference null pointers!
117 // so they need to be wrapped to be usable with std::shared_ptr.
118 void safe_librdf_free_world(librdf_world *const world)
120 if (world) { librdf_free_world(world); }
122 void safe_librdf_free_model(librdf_model *const model)
124 if (model) { librdf_free_model(model); }
126 void safe_librdf_free_node(librdf_node* node)
128 if (node) { librdf_free_node(node); }
130 void safe_librdf_free_parser(librdf_parser *const parser)
132 if (parser) { librdf_free_parser(parser); }
134 void safe_librdf_free_query(librdf_query *const query)
136 if (query) { librdf_free_query(query); }
138 void
139 safe_librdf_free_query_results(librdf_query_results *const query_results)
141 if (query_results) { librdf_free_query_results(query_results); }
143 void safe_librdf_free_serializer(librdf_serializer *const serializer)
145 if (serializer) { librdf_free_serializer(serializer); }
147 void safe_librdf_free_statement(librdf_statement *const statement)
149 if (statement) { librdf_free_statement(statement); }
151 void safe_librdf_free_storage(librdf_storage *const storage)
153 if (storage) { librdf_free_storage(storage); }
155 void safe_librdf_free_stream(librdf_stream *const stream)
157 if (stream) { librdf_free_stream(stream); }
159 void safe_librdf_free_uri(librdf_uri *const uri)
161 if (uri) { librdf_free_uri(uri); }
165 /** converts between librdf types and UNO API types.
167 class librdf_TypeConverter
169 public:
171 // some wrapper classes to temporarily hold values of UNO XNodes
172 struct Node
174 virtual ~Node() {}
176 struct Resource : public Node { };
177 struct URI : public Resource
179 OString const value;
180 explicit URI(OString const& i_rValue)
181 : value(i_rValue)
184 struct BlankNode : public Resource
186 OString const value;
187 explicit BlankNode(OString const& i_rValue)
188 : value(i_rValue)
191 struct Literal : public Node
193 OString const value;
194 OString const language;
195 ::boost::optional<OString> const type;
196 Literal(OString const& i_rValue, OString const& i_rLanguage,
197 ::boost::optional<OString> const& i_rType)
198 : value(i_rValue)
199 , language(i_rLanguage)
200 , type(i_rType)
203 struct Statement
205 std::shared_ptr<Resource> const pSubject;
206 std::shared_ptr<URI> const pPredicate;
207 std::shared_ptr<Node> const pObject;
208 Statement(std::shared_ptr<Resource> const& i_pSubject,
209 std::shared_ptr<URI> const& i_pPredicate,
210 std::shared_ptr<Node> const& i_pObject)
211 : pSubject(i_pSubject)
212 , pPredicate(i_pPredicate)
213 , pObject(i_pObject)
217 librdf_TypeConverter(
218 uno::Reference< uno::XComponentContext > const & i_xContext,
219 librdf_Repository &i_rRep)
220 : m_xContext(i_xContext)
221 , m_rRep(i_rRep)
222 { };
224 librdf_world *createWorld_Lock() const;
225 librdf_storage *createStorage_Lock(librdf_world *i_pWorld) const;
226 librdf_model *createModel_Lock(librdf_world *i_pWorld,
227 librdf_storage * i_pStorage) const;
228 static librdf_uri* mkURI_Lock(librdf_world* i_pWorld,
229 const OString & i_rURI);
230 static librdf_node* mkResource_Lock(librdf_world* i_pWorld,
231 const Resource * i_pResource);
232 static librdf_node* mkNode_Lock(librdf_world* i_pWorld,
233 const Node * i_pNode);
234 static librdf_statement* mkStatement_Lock(librdf_world* i_pWorld,
235 Statement const& i_rStatement);
236 static std::shared_ptr<Resource> extractResource_NoLock(
237 const uno::Reference< rdf::XResource > & i_xResource);
238 static std::shared_ptr<Node> extractNode_NoLock(
239 const uno::Reference< rdf::XNode > & i_xNode);
240 static Statement extractStatement_NoLock(
241 const uno::Reference< rdf::XResource > & i_xSubject,
242 const uno::Reference< rdf::XURI > & i_xPredicate,
243 const uno::Reference< rdf::XNode > & i_xObject);
244 uno::Reference<rdf::XURI> convertToXURI(librdf_uri* i_pURI) const;
245 uno::Reference<rdf::XURI> convertToXURI(librdf_node* i_pURI) const;
246 uno::Reference<rdf::XResource>
247 convertToXResource(librdf_node* i_pNode) const;
248 uno::Reference<rdf::XNode> convertToXNode(librdf_node* i_pNode) const;
249 rdf::Statement
250 convertToStatement(librdf_statement* i_pStmt, librdf_node* i_pContext)
251 const;
253 private:
254 uno::Reference< uno::XComponentContext > const m_xContext;
255 librdf_Repository & m_rRep;
259 /** implements the repository service.
261 class librdf_Repository:
262 // private ::cppu::BaseMutex,
263 public ::cppu::WeakImplHelper<
264 lang::XServiceInfo,
265 rdf::XDocumentRepository,
266 lang::XInitialization>
268 public:
270 explicit librdf_Repository(
271 uno::Reference< uno::XComponentContext > const & i_xContext);
272 virtual ~librdf_Repository() override;
274 // css::lang::XServiceInfo:
275 virtual OUString SAL_CALL getImplementationName()
276 throw (uno::RuntimeException, std::exception) override;
277 virtual sal_Bool SAL_CALL supportsService(
278 const OUString & ServiceName) throw (uno::RuntimeException, std::exception) override;
279 virtual uno::Sequence< OUString > SAL_CALL
280 getSupportedServiceNames() throw (uno::RuntimeException, std::exception) override;
282 // css::rdf::XRepository:
283 virtual uno::Reference< rdf::XBlankNode > SAL_CALL createBlankNode()
284 throw (uno::RuntimeException, std::exception) override;
285 virtual uno::Reference<rdf::XNamedGraph> SAL_CALL importGraph(
286 ::sal_Int16 i_Format,
287 const uno::Reference< io::XInputStream > & i_xInStream,
288 const uno::Reference< rdf::XURI > & i_xGraphName,
289 const uno::Reference< rdf::XURI > & i_xBaseURI)
290 throw (uno::RuntimeException, lang::IllegalArgumentException,
291 datatransfer::UnsupportedFlavorException,
292 container::ElementExistException, rdf::ParseException,
293 rdf::RepositoryException, io::IOException, std::exception) override;
294 virtual void SAL_CALL exportGraph(::sal_Int16 i_Format,
295 const uno::Reference< io::XOutputStream > & i_xOutStream,
296 const uno::Reference< rdf::XURI > & i_xGraphName,
297 const uno::Reference< rdf::XURI > & i_xBaseURI)
298 throw (uno::RuntimeException, lang::IllegalArgumentException,
299 datatransfer::UnsupportedFlavorException,
300 container::NoSuchElementException, rdf::RepositoryException,
301 io::IOException, std::exception) override;
302 virtual uno::Sequence< uno::Reference< rdf::XURI > > SAL_CALL
303 getGraphNames() throw (uno::RuntimeException, rdf::RepositoryException, std::exception) override;
304 virtual uno::Reference< rdf::XNamedGraph > SAL_CALL getGraph(
305 const uno::Reference< rdf::XURI > & i_xGraphName)
306 throw (uno::RuntimeException, lang::IllegalArgumentException,
307 rdf::RepositoryException, std::exception) override;
308 virtual uno::Reference< rdf::XNamedGraph > SAL_CALL createGraph(
309 const uno::Reference< rdf::XURI > & i_xGraphName)
310 throw (uno::RuntimeException, lang::IllegalArgumentException,
311 container::ElementExistException, rdf::RepositoryException, std::exception) override;
312 virtual void SAL_CALL destroyGraph(
313 const uno::Reference< rdf::XURI > & i_xGraphName)
314 throw (uno::RuntimeException, lang::IllegalArgumentException,
315 container::NoSuchElementException, rdf::RepositoryException, std::exception) override;
316 virtual uno::Reference< container::XEnumeration > SAL_CALL getStatements(
317 const uno::Reference< rdf::XResource > & i_xSubject,
318 const uno::Reference< rdf::XURI > & i_xPredicate,
319 const uno::Reference< rdf::XNode > & i_xObject)
320 throw (uno::RuntimeException,
321 rdf::RepositoryException, std::exception) override;
322 virtual uno::Reference< rdf::XQuerySelectResult > SAL_CALL
323 querySelect(const OUString & i_rQuery)
324 throw (uno::RuntimeException, rdf::QueryException,
325 rdf::RepositoryException, std::exception) override;
326 virtual uno::Reference< container::XEnumeration > SAL_CALL
327 queryConstruct(const OUString & i_rQuery)
328 throw (uno::RuntimeException, rdf::QueryException,
329 rdf::RepositoryException, std::exception) override;
330 virtual sal_Bool SAL_CALL queryAsk(const OUString & i_rQuery)
331 throw (uno::RuntimeException, rdf::QueryException,
332 rdf::RepositoryException, std::exception) override;
334 // css::rdf::XDocumentRepository:
335 virtual void SAL_CALL setStatementRDFa(
336 const uno::Reference< rdf::XResource > & i_xSubject,
337 const uno::Sequence< uno::Reference< rdf::XURI > > & i_rPredicates,
338 const uno::Reference< rdf::XMetadatable > & i_xObject,
339 const OUString & i_rRDFaContent,
340 const uno::Reference< rdf::XURI > & i_xRDFaDatatype)
341 throw (uno::RuntimeException, lang::IllegalArgumentException,
342 rdf::RepositoryException, std::exception) override;
343 virtual void SAL_CALL removeStatementRDFa(
344 const uno::Reference< rdf::XMetadatable > & i_xElement)
345 throw (uno::RuntimeException, lang::IllegalArgumentException,
346 rdf::RepositoryException, std::exception) override;
347 virtual beans::Pair< uno::Sequence<rdf::Statement>, sal_Bool > SAL_CALL
348 getStatementRDFa(uno::Reference< rdf::XMetadatable > const& i_xElement)
349 throw (uno::RuntimeException, lang::IllegalArgumentException,
350 rdf::RepositoryException, std::exception) override;
351 virtual uno::Reference< container::XEnumeration > SAL_CALL
352 getStatementsRDFa(
353 const uno::Reference< rdf::XResource > & i_xSubject,
354 const uno::Reference< rdf::XURI > & i_xPredicate,
355 const uno::Reference< rdf::XNode > & i_xObject)
356 throw (uno::RuntimeException,
357 rdf::RepositoryException, std::exception) override;
359 // css::lang::XInitialization:
360 virtual void SAL_CALL initialize(
361 const uno::Sequence< css::uno::Any > & i_rArguments)
362 throw (uno::RuntimeException, uno::Exception, std::exception) override;
364 // XNamedGraph forwards ---------------------------------------------
365 const NamedGraphMap_t::iterator clearGraph_NoLock(
366 const OUString & i_rGraphName,
367 bool i_Internal = false );
368 const NamedGraphMap_t::iterator clearGraph_Lock(
369 const OUString & i_rGraphName,
370 bool i_Internal);
371 void addStatementGraph_NoLock(
372 const uno::Reference< rdf::XResource > & i_xSubject,
373 const uno::Reference< rdf::XURI > & i_xPredicate,
374 const uno::Reference< rdf::XNode > & i_xObject,
375 const uno::Reference< rdf::XURI > & i_xName );
376 // throw (uno::RuntimeException, lang::IllegalArgumentException,
377 // container::NoSuchElementException, rdf::RepositoryException);
378 void addStatementGraph_Lock(
379 librdf_TypeConverter::Statement const& i_rStatement,
380 OUString const& i_rGraphName,
381 bool i_Internal);
382 void removeStatementsGraph_NoLock(
383 const uno::Reference< rdf::XResource > & i_xSubject,
384 const uno::Reference< rdf::XURI > & i_xPredicate,
385 const uno::Reference< rdf::XNode > & i_xObject,
386 const uno::Reference< rdf::XURI > & i_xName );
387 // throw (uno::RuntimeException, lang::IllegalArgumentException,
388 // container::NoSuchElementException, rdf::RepositoryException);
389 uno::Reference< container::XEnumeration > getStatementsGraph_NoLock(
390 const uno::Reference< rdf::XResource > & i_xSubject,
391 const uno::Reference< rdf::XURI > & i_xPredicate,
392 const uno::Reference< rdf::XNode > & i_xObject,
393 const uno::Reference< rdf::XURI > & i_xName,
394 bool i_Internal = false );
395 // throw (uno::RuntimeException, lang::IllegalArgumentException,
396 // container::NoSuchElementException, rdf::RepositoryException);
398 const librdf_TypeConverter& getTypeConverter() { return m_TypeConverter; };
400 private:
402 librdf_Repository(librdf_Repository const&) = delete;
403 librdf_Repository& operator=(librdf_Repository const&) = delete;
405 /// this is const, no need to lock m_aMutex to access it
406 uno::Reference< uno::XComponentContext > const m_xContext;
408 /// librdf global data
409 /** N.B.: The redland documentation gives the impression that you can have
410 as many librdf_worlds as you like. This is true in the same sense
411 that you can physically be in as many places as you like.
412 Well, you can, just not at the same time.
413 The ugly truth is that destroying a librdf_world kills a bunch
414 of static variables; other librdf_worlds become very unhappy
415 when they access these.
416 And of course this is not documented anywhere that I could find.
417 So we allocate a single world, and refcount that.
419 static std::shared_ptr<librdf_world> m_pWorld;
420 /// refcount
421 static sal_uInt32 m_NumInstances;
422 /// mutex for m_pWorld - redland is not as threadsafe as is often claimed
423 static osl::Mutex m_aMutex;
425 // NB: sequence of the shared pointers is important!
426 /// librdf repository storage
427 std::shared_ptr<librdf_storage> m_pStorage;
428 /// librdf repository model
429 std::shared_ptr<librdf_model> m_pModel;
431 /// all named graphs
432 NamedGraphMap_t m_NamedGraphs;
434 /// type conversion helper - stateless
435 librdf_TypeConverter m_TypeConverter;
437 /// set of xml:ids of elements with xhtml:content
438 ::std::set< OUString > m_RDFaXHTMLContentSet;
442 /** result of operations that return a graph, i.e.,
443 an XEnumeration of statements.
445 class librdf_GraphResult:
446 public ::cppu::WeakImplHelper<
447 container::XEnumeration>
449 public:
451 librdf_GraphResult(librdf_Repository *i_pRepository,
452 ::osl::Mutex & i_rMutex,
453 std::shared_ptr<librdf_stream> const& i_pStream,
454 std::shared_ptr<librdf_node> const& i_pContext,
455 std::shared_ptr<librdf_query> const& i_pQuery =
456 std::shared_ptr<librdf_query>() )
457 : m_xRep(i_pRepository)
458 , m_rMutex(i_rMutex)
459 , m_pQuery(i_pQuery)
460 , m_pContext(i_pContext)
461 , m_pStream(i_pStream)
462 { };
464 virtual ~librdf_GraphResult() override
466 ::osl::MutexGuard g(m_rMutex); // lock mutex when destroying members
467 const_cast<std::shared_ptr<librdf_stream>& >(m_pStream).reset();
468 const_cast<std::shared_ptr<librdf_node>& >(m_pContext).reset();
469 const_cast<std::shared_ptr<librdf_query>& >(m_pQuery).reset();
472 // css::container::XEnumeration:
473 virtual sal_Bool SAL_CALL hasMoreElements()
474 throw (uno::RuntimeException, std::exception) override;
475 virtual uno::Any SAL_CALL nextElement()
476 throw (uno::RuntimeException, container::NoSuchElementException,
477 lang::WrappedTargetException, std::exception) override;
479 private:
481 librdf_GraphResult(librdf_GraphResult const&) = delete;
482 librdf_GraphResult& operator=(librdf_GraphResult const&) = delete;
484 // NB: this is not a weak pointer: streams _must_ be deleted before the
485 // storage they point into, so we keep the repository alive here
486 // also, sequence is important: the stream must be destroyed first.
487 ::rtl::Reference< librdf_Repository > m_xRep;
488 // needed for synchronizing access to librdf (it doesn't do win32 threading)
489 ::osl::Mutex & m_rMutex;
490 // the query (in case this is a result of a graph query)
491 // not that the redland documentation spells this out explicity, but
492 // queries must be freed only after all the results are completely read
493 std::shared_ptr<librdf_query> const m_pQuery;
494 std::shared_ptr<librdf_node> const m_pContext;
495 std::shared_ptr<librdf_stream> const m_pStream;
497 librdf_node* getContext_Lock() const;
501 // css::container::XEnumeration:
502 sal_Bool SAL_CALL
503 librdf_GraphResult::hasMoreElements() throw (uno::RuntimeException, std::exception)
505 ::osl::MutexGuard g(m_rMutex);
506 return m_pStream.get() && !librdf_stream_end(m_pStream.get());
509 librdf_node* librdf_GraphResult::getContext_Lock() const
511 if (!m_pStream.get() || librdf_stream_end(m_pStream.get()))
512 return nullptr;
513 librdf_node *pCtxt(
514 #if LIBRDF_VERSION >= 10012
515 librdf_stream_get_context2(m_pStream.get()) );
516 #else
517 static_cast<librdf_node *>(librdf_stream_get_context(m_pStream.get())) );
518 #endif
519 if (pCtxt)
520 return pCtxt;
521 return m_pContext.get();
524 css::uno::Any SAL_CALL
525 librdf_GraphResult::nextElement()
526 throw (uno::RuntimeException, container::NoSuchElementException,
527 lang::WrappedTargetException, std::exception)
529 ::osl::MutexGuard g(m_rMutex);
530 if (!m_pStream.get() || !librdf_stream_end(m_pStream.get())) {
531 librdf_node * pCtxt = getContext_Lock();
533 librdf_statement *pStmt( librdf_stream_get_object(m_pStream.get()) );
534 if (!pStmt) {
535 rdf::QueryException e(
536 "librdf_GraphResult::nextElement: "
537 "librdf_stream_get_object failed", *this);
538 throw lang::WrappedTargetException(
539 "librdf_GraphResult::nextElement: "
540 "librdf_stream_get_object failed", *this,
541 uno::makeAny(e));
543 // NB: pCtxt may be null here if this is result of a graph query
544 if (pCtxt && isInternalContext(pCtxt)) {
545 pCtxt = nullptr; // XML ID context is implementation detail!
547 rdf::Statement Stmt(
548 m_xRep->getTypeConverter().convertToStatement(pStmt, pCtxt) );
549 // NB: this will invalidate current item.
550 librdf_stream_next(m_pStream.get());
551 return uno::makeAny(Stmt);
552 } else {
553 throw container::NoSuchElementException();
558 /** result of tuple queries ("SELECT").
560 class librdf_QuerySelectResult:
561 public ::cppu::WeakImplHelper<
562 rdf::XQuerySelectResult>
564 public:
566 librdf_QuerySelectResult(librdf_Repository *i_pRepository,
567 ::osl::Mutex & i_rMutex,
568 std::shared_ptr<librdf_query> const& i_pQuery,
569 std::shared_ptr<librdf_query_results> const& i_pQueryResult,
570 uno::Sequence< OUString > const& i_rBindingNames )
571 : m_xRep(i_pRepository)
572 , m_rMutex(i_rMutex)
573 , m_pQuery(i_pQuery)
574 , m_pQueryResult(i_pQueryResult)
575 , m_BindingNames(i_rBindingNames)
576 { };
578 virtual ~librdf_QuerySelectResult() override
580 ::osl::MutexGuard g(m_rMutex); // lock mutex when destroying members
581 const_cast<std::shared_ptr<librdf_query_results>& >(m_pQueryResult)
582 .reset();
583 const_cast<std::shared_ptr<librdf_query>& >(m_pQuery).reset();
586 // css::container::XEnumeration:
587 virtual sal_Bool SAL_CALL hasMoreElements()
588 throw (uno::RuntimeException, std::exception) override;
589 virtual uno::Any SAL_CALL nextElement()
590 throw (uno::RuntimeException, container::NoSuchElementException,
591 lang::WrappedTargetException, std::exception) override;
593 // css::rdf::XQuerySelectResult:
594 virtual uno::Sequence< OUString > SAL_CALL getBindingNames()
595 throw (uno::RuntimeException, std::exception) override;
597 private:
599 librdf_QuerySelectResult(librdf_QuerySelectResult const&) = delete;
600 librdf_QuerySelectResult& operator=(librdf_QuerySelectResult const&) = delete;
602 // NB: this is not a weak pointer: streams _must_ be deleted before the
603 // storage they point into, so we keep the repository alive here
604 // also, sequence is important: the stream must be destroyed first.
605 ::rtl::Reference< librdf_Repository > m_xRep;
606 // needed for synchronizing access to librdf (it doesn't do win32 threading)
607 ::osl::Mutex & m_rMutex;
608 // not that the redland documentation spells this out explicity, but
609 // queries must be freed only after all the results are completely read
610 std::shared_ptr<librdf_query> const m_pQuery;
611 std::shared_ptr<librdf_query_results> const m_pQueryResult;
612 uno::Sequence< OUString > const m_BindingNames;
616 // css::container::XEnumeration:
617 sal_Bool SAL_CALL
618 librdf_QuerySelectResult::hasMoreElements() throw (uno::RuntimeException, std::exception)
620 ::osl::MutexGuard g(m_rMutex);
621 return !librdf_query_results_finished(m_pQueryResult.get());
624 class NodeArrayDeleter : public std::unary_function<librdf_node**, void>
626 const int m_Count;
628 public:
629 explicit NodeArrayDeleter(int i_Count) : m_Count(i_Count) { }
631 void operator() (librdf_node** io_pArray) const throw ()
633 std::for_each(io_pArray, io_pArray + m_Count, safe_librdf_free_node);
634 delete[] io_pArray;
638 css::uno::Any SAL_CALL
639 librdf_QuerySelectResult::nextElement()
640 throw (uno::RuntimeException, container::NoSuchElementException,
641 lang::WrappedTargetException, std::exception)
643 ::osl::MutexGuard g(m_rMutex);
644 if (!librdf_query_results_finished(m_pQueryResult.get())) {
645 sal_Int32 count(m_BindingNames.getLength());
646 OSL_ENSURE(count >= 0, "negative length?");
647 std::shared_ptr<librdf_node*> const pNodes(new librdf_node*[count],
648 NodeArrayDeleter(count));
649 for (int i = 0; i < count; ++i) {
650 pNodes.get()[i] = nullptr;
652 if (librdf_query_results_get_bindings(m_pQueryResult.get(), nullptr,
653 pNodes.get()))
655 rdf::QueryException e(
656 "librdf_QuerySelectResult::nextElement: "
657 "librdf_query_results_get_bindings failed", *this);
658 throw lang::WrappedTargetException(
659 "librdf_QuerySelectResult::nextElement: "
660 "librdf_query_results_get_bindings failed", *this,
661 uno::makeAny(e));
663 uno::Sequence< uno::Reference< rdf::XNode > > ret(count);
664 for (int i = 0; i < count; ++i) {
665 ret[i] = m_xRep->getTypeConverter().convertToXNode(pNodes.get()[i]);
667 // NB: this will invalidate current item.
668 librdf_query_results_next(m_pQueryResult.get());
669 return uno::makeAny(ret);
670 } else {
671 throw container::NoSuchElementException();
675 // css::rdf::XQuerySelectResult:
676 uno::Sequence< OUString > SAL_CALL
677 librdf_QuerySelectResult::getBindingNames() throw (uno::RuntimeException, std::exception)
679 // const - no lock needed
680 return m_BindingNames;
684 /** represents a named graph, and forwards all the work to repository.
686 class librdf_NamedGraph:
687 public ::cppu::WeakImplHelper<
688 rdf::XNamedGraph>
690 public:
691 librdf_NamedGraph(librdf_Repository * i_pRep,
692 uno::Reference<rdf::XURI> const & i_xName)
693 : m_wRep(i_pRep)
694 , m_pRep(i_pRep)
695 , m_xName(i_xName)
696 { };
698 virtual ~librdf_NamedGraph() override {}
700 // css::rdf::XNode:
701 virtual OUString SAL_CALL getStringValue()
702 throw (uno::RuntimeException, std::exception) override;
704 // css::rdf::XURI:
705 virtual OUString SAL_CALL getNamespace()
706 throw (uno::RuntimeException, std::exception) override;
707 virtual OUString SAL_CALL getLocalName()
708 throw (uno::RuntimeException, std::exception) override;
710 // css::rdf::XNamedGraph:
711 virtual uno::Reference<rdf::XURI> SAL_CALL getName()
712 throw (uno::RuntimeException, std::exception) override;
713 virtual void SAL_CALL clear()
714 throw (uno::RuntimeException,
715 container::NoSuchElementException, rdf::RepositoryException, std::exception) override;
716 virtual void SAL_CALL addStatement(
717 const uno::Reference< rdf::XResource > & i_xSubject,
718 const uno::Reference< rdf::XURI > & i_xPredicate,
719 const uno::Reference< rdf::XNode > & i_xObject)
720 throw (uno::RuntimeException, lang::IllegalArgumentException,
721 container::NoSuchElementException, rdf::RepositoryException, std::exception) override;
722 virtual void SAL_CALL removeStatements(
723 const uno::Reference< rdf::XResource > & i_xSubject,
724 const uno::Reference< rdf::XURI > & i_xPredicate,
725 const uno::Reference< rdf::XNode > & i_xObject)
726 throw (uno::RuntimeException,
727 container::NoSuchElementException, rdf::RepositoryException, std::exception) override;
728 virtual uno::Reference< container::XEnumeration > SAL_CALL getStatements(
729 const uno::Reference< rdf::XResource > & i_xSubject,
730 const uno::Reference< rdf::XURI > & i_xPredicate,
731 const uno::Reference< rdf::XNode > & i_xObject)
732 throw (uno::RuntimeException,
733 container::NoSuchElementException, rdf::RepositoryException, std::exception) override;
735 private:
737 librdf_NamedGraph(librdf_NamedGraph const&) = delete;
738 librdf_NamedGraph& operator=(librdf_NamedGraph const&) = delete;
740 /// weak reference: this is needed to check if m_pRep is valid
741 uno::WeakReference< rdf::XRepository > const m_wRep;
742 librdf_Repository *const m_pRep;
743 uno::Reference< rdf::XURI > const m_xName;
747 // css::rdf::XNode:
748 OUString SAL_CALL librdf_NamedGraph::getStringValue()
749 throw (uno::RuntimeException, std::exception)
751 return m_xName->getStringValue();
754 // css::rdf::XURI:
755 OUString SAL_CALL librdf_NamedGraph::getNamespace()
756 throw (uno::RuntimeException, std::exception)
758 return m_xName->getNamespace();
761 OUString SAL_CALL librdf_NamedGraph::getLocalName()
762 throw (uno::RuntimeException, std::exception)
764 return m_xName->getLocalName();
767 // css::rdf::XNamedGraph:
768 uno::Reference< rdf::XURI > SAL_CALL librdf_NamedGraph::getName()
769 throw (uno::RuntimeException, std::exception)
771 return m_xName;
774 void SAL_CALL librdf_NamedGraph::clear()
775 throw (uno::RuntimeException,
776 container::NoSuchElementException, rdf::RepositoryException, std::exception)
778 uno::Reference< rdf::XRepository > xRep( m_wRep );
779 if (!xRep.is()) {
780 throw rdf::RepositoryException(
781 "librdf_NamedGraph::clear: repository is gone", *this);
783 const OUString contextU( m_xName->getStringValue() );
784 try {
785 m_pRep->clearGraph_NoLock(contextU);
786 } catch (lang::IllegalArgumentException &) {
787 throw uno::RuntimeException();
791 void SAL_CALL librdf_NamedGraph::addStatement(
792 const uno::Reference< rdf::XResource > & i_xSubject,
793 const uno::Reference< rdf::XURI > & i_xPredicate,
794 const uno::Reference< rdf::XNode > & i_xObject)
795 throw (uno::RuntimeException, lang::IllegalArgumentException,
796 container::NoSuchElementException, rdf::RepositoryException, std::exception)
798 uno::Reference< rdf::XRepository > xRep( m_wRep );
799 if (!xRep.is()) {
800 throw rdf::RepositoryException(
801 "librdf_NamedGraph::addStatement: repository is gone", *this);
803 m_pRep->addStatementGraph_NoLock(
804 i_xSubject, i_xPredicate, i_xObject, m_xName);
807 void SAL_CALL librdf_NamedGraph::removeStatements(
808 const uno::Reference< rdf::XResource > & i_xSubject,
809 const uno::Reference< rdf::XURI > & i_xPredicate,
810 const uno::Reference< rdf::XNode > & i_xObject)
811 throw (uno::RuntimeException,
812 container::NoSuchElementException, rdf::RepositoryException, std::exception)
814 uno::Reference< rdf::XRepository > xRep( m_wRep );
815 if (!xRep.is()) {
816 throw rdf::RepositoryException(
817 "librdf_NamedGraph::removeStatements: repository is gone", *this);
819 m_pRep->removeStatementsGraph_NoLock(
820 i_xSubject, i_xPredicate, i_xObject, m_xName);
823 uno::Reference< container::XEnumeration > SAL_CALL
824 librdf_NamedGraph::getStatements(
825 const uno::Reference< rdf::XResource > & i_xSubject,
826 const uno::Reference< rdf::XURI > & i_xPredicate,
827 const uno::Reference< rdf::XNode > & i_xObject)
828 throw (uno::RuntimeException,
829 container::NoSuchElementException, rdf::RepositoryException, std::exception)
831 uno::Reference< rdf::XRepository > xRep( m_wRep );
832 if (!xRep.is()) {
833 throw rdf::RepositoryException(
834 "librdf_NamedGraph::getStatements: repository is gone", *this);
836 return m_pRep->getStatementsGraph_NoLock(
837 i_xSubject, i_xPredicate, i_xObject, m_xName);
841 std::shared_ptr<librdf_world> librdf_Repository::m_pWorld;
842 sal_uInt32 librdf_Repository::m_NumInstances = 0;
843 osl::Mutex librdf_Repository::m_aMutex;
845 librdf_Repository::librdf_Repository(
846 uno::Reference< uno::XComponentContext > const & i_xContext)
847 : /*BaseMutex(),*/ m_xContext(i_xContext)
848 // m_pWorld (static_cast<librdf_world *>(0), safe_librdf_free_world ),
849 , m_pStorage(static_cast<librdf_storage*>(nullptr), safe_librdf_free_storage)
850 , m_pModel (static_cast<librdf_model *>(nullptr), safe_librdf_free_model )
851 , m_NamedGraphs()
852 , m_TypeConverter(i_xContext, *this)
854 OSL_ENSURE(i_xContext.is(), "librdf_Repository: null context");
856 ::osl::MutexGuard g(m_aMutex);
857 if (!m_NumInstances++) {
858 m_pWorld.reset(m_TypeConverter.createWorld_Lock(),
859 safe_librdf_free_world);
863 librdf_Repository::~librdf_Repository()
865 ::osl::MutexGuard g(m_aMutex);
867 // must destroy these before world!
868 m_pModel.reset();
869 m_pStorage.reset();
871 // FIXME: so it turns out that calling librdf_free_world will
872 // (via raptor_sax2_finish) call xmlCleanupParser, which will
873 // free libxml2's globals! ARRRGH!!! => never call librdf_free_world
874 #if 0
875 if (!--m_NumInstances) {
876 m_pWorld.reset();
878 #endif
881 // com.sun.star.uno.XServiceInfo:
882 OUString SAL_CALL librdf_Repository::getImplementationName()
883 throw (uno::RuntimeException, std::exception)
885 return comp_librdf_Repository::_getImplementationName();
888 sal_Bool SAL_CALL librdf_Repository::supportsService(
889 OUString const & serviceName) throw (uno::RuntimeException, std::exception)
891 return cppu::supportsService(this, serviceName);
894 uno::Sequence< OUString > SAL_CALL
895 librdf_Repository::getSupportedServiceNames() throw (uno::RuntimeException, std::exception)
897 return comp_librdf_Repository::_getSupportedServiceNames();
900 // css::rdf::XRepository:
901 uno::Reference< rdf::XBlankNode > SAL_CALL librdf_Repository::createBlankNode()
902 throw (uno::RuntimeException, std::exception)
904 ::osl::MutexGuard g(m_aMutex);
905 const std::shared_ptr<librdf_node> pNode(
906 librdf_new_node_from_blank_identifier(m_pWorld.get(), nullptr),
907 safe_librdf_free_node);
908 if (!pNode) {
909 throw uno::RuntimeException(
910 "librdf_Repository::createBlankNode: "
911 "librdf_new_node_from_blank_identifier failed", *this);
913 const unsigned char * id (librdf_node_get_blank_identifier(pNode.get()));
914 if (!id) {
915 throw uno::RuntimeException(
916 "librdf_Repository::createBlankNode: "
917 "librdf_node_get_blank_identifier failed", *this);
919 const OUString nodeID(OUString::createFromAscii(
920 reinterpret_cast<const char *>(id)));
921 try {
922 return rdf::BlankNode::create(m_xContext, nodeID);
923 } catch (const lang::IllegalArgumentException & iae) {
924 throw lang::WrappedTargetRuntimeException(
925 "librdf_Repository::createBlankNode: "
926 "illegal blank node label", *this, uno::makeAny(iae));
930 bool formatNeedsBaseURI(::sal_Int16 i_Format)
932 (void) i_Format; //FIXME any which don't?
933 return true;
936 //void SAL_CALL
937 uno::Reference<rdf::XNamedGraph> SAL_CALL
938 librdf_Repository::importGraph(::sal_Int16 i_Format,
939 const uno::Reference< io::XInputStream > & i_xInStream,
940 const uno::Reference< rdf::XURI > & i_xGraphName,
941 const uno::Reference< rdf::XURI > & i_xBaseURI)
942 throw (uno::RuntimeException, lang::IllegalArgumentException,
943 datatransfer::UnsupportedFlavorException,
944 container::ElementExistException, rdf::ParseException,
945 rdf::RepositoryException, io::IOException, std::exception)
947 if (!i_xInStream.is()) {
948 throw lang::IllegalArgumentException(
949 "librdf_Repository::importGraph: stream is null", *this, 1);
951 //FIXME: other formats
952 if (i_Format != rdf::FileFormat::RDF_XML) {
953 throw datatransfer::UnsupportedFlavorException(
954 "librdf_Repository::importGraph: file format not supported", *this);
956 if (!i_xGraphName.is()) {
957 throw lang::IllegalArgumentException(
958 "librdf_Repository::importGraph: graph name is null", *this, 2);
960 if (i_xGraphName->getStringValue().startsWith(s_nsOOo))
962 throw lang::IllegalArgumentException(
963 "librdf_Repository::importGraph: URI is reserved", *this, 0);
965 if (formatNeedsBaseURI(i_Format) && !i_xBaseURI.is()) {
966 throw lang::IllegalArgumentException(
967 "librdf_Repository::importGraph: base URI is null", *this, 3);
969 OSL_ENSURE(i_xBaseURI.is(), "no base uri");
970 const OUString baseURIU( i_xBaseURI->getStringValue() );
971 if (baseURIU.indexOf('#') >= 0) {
972 throw lang::IllegalArgumentException(
973 "librdf_Repository::importGraph: base URI is not absolute", *this, 3);
976 const OUString contextU( i_xGraphName->getStringValue() );
978 uno::Sequence<sal_Int8> buf;
979 uno::Reference<io::XSeekable> xSeekable(i_xInStream, uno::UNO_QUERY);
980 // UGLY: if only redland could read streams...
981 const sal_Int64 sz( xSeekable.is() ? xSeekable->getLength() : 1 << 20 );
982 // exceptions are propagated
983 i_xInStream->readBytes( buf, static_cast<sal_Int32>( sz ) );
985 ::osl::MutexGuard g(m_aMutex); // don't call i_x* with mutex locked
987 if (m_NamedGraphs.find(contextU) != m_NamedGraphs.end()) {
988 throw container::ElementExistException(
989 "librdf_Repository::importGraph: graph with given URI exists", *this);
991 const OString context(
992 OUStringToOString(contextU, RTL_TEXTENCODING_UTF8) );
994 const std::shared_ptr<librdf_node> pContext(
995 librdf_new_node_from_uri_string(m_pWorld.get(),
996 reinterpret_cast<const unsigned char*> (context.getStr())),
997 safe_librdf_free_node);
998 if (!pContext) {
999 throw uno::RuntimeException(
1000 "librdf_Repository::importGraph: librdf_new_node_from_uri_string failed", *this);
1003 const OString baseURI(
1004 OUStringToOString(baseURIU, RTL_TEXTENCODING_UTF8) );
1005 const std::shared_ptr<librdf_uri> pBaseURI(
1006 librdf_new_uri(m_pWorld.get(),
1007 reinterpret_cast<const unsigned char*> (baseURI.getStr())),
1008 safe_librdf_free_uri);
1009 if (!pBaseURI) {
1010 throw uno::RuntimeException( "librdf_Repository::importGraph: librdf_new_uri failed", *this);
1013 const std::shared_ptr<librdf_parser> pParser(
1014 librdf_new_parser(m_pWorld.get(), "rdfxml", nullptr, nullptr),
1015 safe_librdf_free_parser);
1016 if (!pParser) {
1017 throw uno::RuntimeException(
1018 "librdf_Repository::importGraph: "
1019 "librdf_new_parser failed", *this);
1022 const std::shared_ptr<librdf_stream> pStream(
1023 librdf_parser_parse_counted_string_as_stream(pParser.get(),
1024 reinterpret_cast<const unsigned char*>(buf.getConstArray()),
1025 buf.getLength(), pBaseURI.get()),
1026 safe_librdf_free_stream);
1027 if (!pStream) {
1028 throw rdf::ParseException(
1029 "librdf_Repository::importGraph: "
1030 "librdf_parser_parse_counted_string_as_stream failed", *this);
1032 rtl::Reference<librdf_NamedGraph> const pGraph(
1033 new librdf_NamedGraph(this, i_xGraphName));
1034 m_NamedGraphs.insert(std::make_pair(contextU, pGraph));
1035 if (librdf_model_context_add_statements(m_pModel.get(),
1036 pContext.get(), pStream.get())) {
1037 throw rdf::RepositoryException(
1038 "librdf_Repository::importGraph: "
1039 "librdf_model_context_add_statements failed", *this);
1042 return uno::Reference<rdf::XNamedGraph>(pGraph.get());
1045 void addChaffWhenEncryptedStorage(const uno::Reference< io::XOutputStream > &rStream, unsigned char* pBuffer, size_t length)
1047 if (!length)
1048 return;
1050 uno::Reference< embed::XEncryptionProtectedSource2 > xEncr(rStream,
1051 uno::UNO_QUERY);
1053 bool bAddChaff = xEncr.is() && xEncr->hasEncryptionData();
1055 // exceptions are propagated
1056 if (!bAddChaff)
1058 const uno::Sequence<sal_Int8> buf(
1059 reinterpret_cast<sal_Int8*>(pBuffer), length);
1060 rStream->writeBytes(buf);
1062 else
1064 unsigned char *postcomment =
1065 reinterpret_cast<unsigned char*>(strchr(reinterpret_cast<char*>(pBuffer), '\n'));
1066 if (postcomment != nullptr)
1068 ++postcomment;
1070 size_t preamblelen = postcomment - pBuffer;
1072 uno::Sequence<sal_Int8> buf(
1073 reinterpret_cast<sal_Int8*>(pBuffer), preamblelen);
1074 rStream->writeBytes(buf);
1076 OStringBuffer aComment;
1077 aComment.append("<!--");
1078 aComment.append(comphelper::xml::makeXMLChaff());
1079 aComment.append("-->");
1081 buf = uno::Sequence<sal_Int8>(
1082 reinterpret_cast<const sal_Int8*>(aComment.getStr()), aComment.getLength());
1083 rStream->writeBytes(buf);
1085 buf = uno::Sequence<sal_Int8>(
1086 reinterpret_cast<sal_Int8*>(postcomment), length-preamblelen);
1087 rStream->writeBytes(buf);
1092 void SAL_CALL
1093 librdf_Repository::exportGraph(::sal_Int16 i_Format,
1094 const uno::Reference< io::XOutputStream > & i_xOutStream,
1095 const uno::Reference< rdf::XURI > & i_xGraphName,
1096 const uno::Reference< rdf::XURI > & i_xBaseURI)
1097 throw (uno::RuntimeException, lang::IllegalArgumentException,
1098 datatransfer::UnsupportedFlavorException,
1099 container::NoSuchElementException, rdf::RepositoryException,
1100 io::IOException, std::exception)
1102 if (!i_xOutStream.is()) {
1103 throw lang::IllegalArgumentException(
1104 "librdf_Repository::exportGraph: stream is null", *this, 1);
1106 // FIXME: other formats
1107 if (i_Format != rdf::FileFormat::RDF_XML) {
1108 throw datatransfer::UnsupportedFlavorException(
1109 "librdf_Repository::exportGraph: "
1110 "file format not supported", *this);
1112 if (!i_xGraphName.is()) {
1113 throw lang::IllegalArgumentException(
1114 "librdf_Repository::exportGraph: "
1115 "graph name is null", *this, 2);
1117 if (formatNeedsBaseURI(i_Format) && !i_xBaseURI.is()) {
1118 throw lang::IllegalArgumentException(
1119 "librdf_Repository::exportGraph: "
1120 "base URI is null", *this, 3);
1122 OSL_ENSURE(i_xBaseURI.is(), "no base uri");
1123 const OUString baseURIU( i_xBaseURI->getStringValue() );
1124 if (baseURIU.indexOf('#') >= 0) {
1125 throw lang::IllegalArgumentException(
1126 "librdf_Repository::exportGraph: "
1127 "base URI is not absolute", *this, 3);
1130 const OUString contextU( i_xGraphName->getStringValue() );
1132 ::osl::ClearableMutexGuard g(m_aMutex); // don't call i_x* with mutex locked
1134 if (m_NamedGraphs.find(contextU) == m_NamedGraphs.end()) {
1135 throw container::NoSuchElementException(
1136 "librdf_Repository::exportGraph: "
1137 "no graph with given URI exists", *this);
1139 const OString context(
1140 OUStringToOString(contextU, RTL_TEXTENCODING_UTF8) );
1142 const std::shared_ptr<librdf_node> pContext(
1143 librdf_new_node_from_uri_string(m_pWorld.get(),
1144 reinterpret_cast<const unsigned char*> (context.getStr())),
1145 safe_librdf_free_node);
1146 if (!pContext) {
1147 throw uno::RuntimeException(
1148 "librdf_Repository::exportGraph: "
1149 "librdf_new_node_from_uri_string failed", *this);
1151 const OString baseURI(
1152 OUStringToOString(baseURIU, RTL_TEXTENCODING_UTF8) );
1153 const std::shared_ptr<librdf_uri> pBaseURI(
1154 librdf_new_uri(m_pWorld.get(),
1155 reinterpret_cast<const unsigned char*> (baseURI.getStr())),
1156 safe_librdf_free_uri);
1157 if (!pBaseURI) {
1158 throw uno::RuntimeException(
1159 "librdf_Repository::exportGraph: "
1160 "librdf_new_uri failed", *this);
1163 const std::shared_ptr<librdf_stream> pStream(
1164 librdf_model_context_as_stream(m_pModel.get(), pContext.get()),
1165 safe_librdf_free_stream);
1166 if (!pStream) {
1167 throw rdf::RepositoryException(
1168 "librdf_Repository::exportGraph: "
1169 "librdf_model_context_as_stream failed", *this);
1171 const char *format("rdfxml");
1172 // #i116443#: abbrev breaks when certain URIs are used as data types
1173 // const char *format("rdfxml-abbrev");
1174 const std::shared_ptr<librdf_serializer> pSerializer(
1175 librdf_new_serializer(m_pWorld.get(), format, nullptr, nullptr),
1176 safe_librdf_free_serializer);
1177 if (!pSerializer) {
1178 throw uno::RuntimeException(
1179 "librdf_Repository::exportGraph: "
1180 "librdf_new_serializer failed", *this);
1183 const std::shared_ptr<librdf_uri> pRelativeURI(
1184 librdf_new_uri(m_pWorld.get(), reinterpret_cast<const unsigned char*>
1185 ("http://feature.librdf.org/raptor-relativeURIs")),
1186 safe_librdf_free_uri);
1187 const std::shared_ptr<librdf_uri> pWriteBaseURI(
1188 librdf_new_uri(m_pWorld.get(), reinterpret_cast<const unsigned char*>
1189 ("http://feature.librdf.org/raptor-writeBaseURI")),
1190 safe_librdf_free_uri);
1191 const std::shared_ptr<librdf_node> p0(
1192 librdf_new_node_from_literal(m_pWorld.get(),
1193 reinterpret_cast<const unsigned char*> ("0"), nullptr, 0),
1194 safe_librdf_free_node);
1195 const std::shared_ptr<librdf_node> p1(
1196 librdf_new_node_from_literal(m_pWorld.get(),
1197 reinterpret_cast<const unsigned char*> ("1"), nullptr, 0),
1198 safe_librdf_free_node);
1199 if (!pWriteBaseURI || !pRelativeURI || !p0 || !p1) {
1200 throw uno::RuntimeException(
1201 "librdf_Repository::exportGraph: "
1202 "librdf_new_uri or librdf_new_node_from_literal failed", *this);
1205 // make URIs relative to base URI
1206 if (librdf_serializer_set_feature(pSerializer.get(),
1207 pRelativeURI.get(), p1.get()))
1209 throw uno::RuntimeException(
1210 "librdf_Repository::exportGraph: "
1211 "librdf_serializer_set_feature relativeURIs failed", *this);
1213 // but do not write the base URI to the file!
1214 if (librdf_serializer_set_feature(pSerializer.get(),
1215 pWriteBaseURI.get(), p0.get()))
1217 throw uno::RuntimeException(
1218 "librdf_Repository::exportGraph: "
1219 "librdf_serializer_set_feature writeBaseURI failed", *this);
1222 size_t length;
1223 const std::shared_ptr<unsigned char> pBuf(
1224 librdf_serializer_serialize_stream_to_counted_string(
1225 pSerializer.get(), pBaseURI.get(), pStream.get(), &length), free);
1226 if (!pBuf) {
1227 throw rdf::RepositoryException(
1228 "librdf_Repository::exportGraph: "
1229 "librdf_serializer_serialize_stream_to_counted_string failed",
1230 *this);
1233 g.clear(); // release Mutex before calling i_xOutStream methods
1235 addChaffWhenEncryptedStorage(i_xOutStream, pBuf.get(), length);
1238 uno::Sequence< uno::Reference< rdf::XURI > > SAL_CALL
1239 librdf_Repository::getGraphNames()
1240 throw (uno::RuntimeException, rdf::RepositoryException, std::exception)
1242 ::osl::MutexGuard g(m_aMutex);
1243 ::std::vector< uno::Reference<rdf::XURI> > ret;
1244 std::transform(m_NamedGraphs.begin(), m_NamedGraphs.end(),
1245 std::back_inserter(ret),
1246 [](std::pair<OUString, ::rtl::Reference<librdf_NamedGraph>> const& it)
1247 { return it.second->getName(); });
1248 return comphelper::containerToSequence(ret);
1251 uno::Reference< rdf::XNamedGraph > SAL_CALL
1252 librdf_Repository::getGraph(const uno::Reference< rdf::XURI > & i_xGraphName)
1253 throw (uno::RuntimeException, lang::IllegalArgumentException,
1254 rdf::RepositoryException, std::exception)
1256 if (!i_xGraphName.is()) {
1257 throw lang::IllegalArgumentException(
1258 "librdf_Repository::getGraph: URI is null", *this, 0);
1260 const OUString contextU( i_xGraphName->getStringValue() );
1262 ::osl::MutexGuard g(m_aMutex);
1263 const NamedGraphMap_t::iterator iter( m_NamedGraphs.find(contextU) );
1264 if (iter != m_NamedGraphs.end()) {
1265 return uno::Reference<rdf::XNamedGraph>(iter->second.get());
1266 } else {
1267 return nullptr;
1271 uno::Reference< rdf::XNamedGraph > SAL_CALL
1272 librdf_Repository::createGraph(const uno::Reference< rdf::XURI > & i_xGraphName)
1273 throw (uno::RuntimeException, lang::IllegalArgumentException,
1274 container::ElementExistException, rdf::RepositoryException, std::exception)
1276 if (!i_xGraphName.is()) {
1277 throw lang::IllegalArgumentException(
1278 "librdf_Repository::createGraph: URI is null", *this, 0);
1281 const OUString contextU( i_xGraphName->getStringValue() );
1282 if (contextU.startsWith(s_nsOOo))
1284 throw lang::IllegalArgumentException(
1285 "librdf_Repository::createGraph: URI is reserved", *this, 0);
1288 ::osl::MutexGuard g(m_aMutex); // don't call i_x* with mutex locked
1290 // NB: librdf does not have a concept of graphs as such;
1291 // a librdf named graph exists iff the model contains a statement with
1292 // the graph name as context
1294 if (m_NamedGraphs.find(contextU) != m_NamedGraphs.end()) {
1295 throw container::ElementExistException(
1296 "librdf_Repository::createGraph: graph with given URI exists", *this);
1298 m_NamedGraphs.insert(std::make_pair(contextU,
1299 new librdf_NamedGraph(this, i_xGraphName)));
1300 return uno::Reference<rdf::XNamedGraph>(
1301 m_NamedGraphs.find(contextU)->second.get());
1304 void SAL_CALL
1305 librdf_Repository::destroyGraph(
1306 const uno::Reference< rdf::XURI > & i_xGraphName)
1307 throw (uno::RuntimeException, lang::IllegalArgumentException,
1308 container::NoSuchElementException, rdf::RepositoryException, std::exception)
1310 if (!i_xGraphName.is()) {
1311 throw lang::IllegalArgumentException(
1312 "librdf_Repository::destroyGraph: URI is null", *this, 0);
1314 const OUString contextU( i_xGraphName->getStringValue() );
1316 ::osl::MutexGuard g(m_aMutex); // don't call i_x* with mutex locked
1318 const NamedGraphMap_t::iterator iter( clearGraph_Lock(contextU, false) );
1319 m_NamedGraphs.erase(iter);
1322 bool isMetadatableWithoutMetadata(
1323 uno::Reference<uno::XInterface> const & i_xNode)
1325 const uno::Reference<rdf::XMetadatable> xMeta( i_xNode, uno::UNO_QUERY );
1326 return (xMeta.is() && xMeta->getMetadataReference().Second.isEmpty());
1329 uno::Reference< container::XEnumeration > SAL_CALL
1330 librdf_Repository::getStatements(
1331 const uno::Reference< rdf::XResource > & i_xSubject,
1332 const uno::Reference< rdf::XURI > & i_xPredicate,
1333 const uno::Reference< rdf::XNode > & i_xObject)
1334 throw (uno::RuntimeException, rdf::RepositoryException, std::exception)
1336 if (isMetadatableWithoutMetadata(i_xSubject) ||
1337 isMetadatableWithoutMetadata(i_xPredicate) ||
1338 isMetadatableWithoutMetadata(i_xObject))
1340 return new librdf_GraphResult(this, m_aMutex,
1341 std::shared_ptr<librdf_stream>(),
1342 std::shared_ptr<librdf_node>());
1345 librdf_TypeConverter::Statement const stmt(
1346 librdf_TypeConverter::extractStatement_NoLock(
1347 i_xSubject, i_xPredicate, i_xObject));
1349 ::osl::MutexGuard g(m_aMutex); // don't call i_x* with mutex locked
1351 const std::shared_ptr<librdf_statement> pStatement(
1352 librdf_TypeConverter::mkStatement_Lock(m_pWorld.get(), stmt),
1353 safe_librdf_free_statement);
1354 OSL_ENSURE(pStatement, "mkStatement failed");
1356 const std::shared_ptr<librdf_stream> pStream(
1357 librdf_model_find_statements(m_pModel.get(), pStatement.get()),
1358 safe_librdf_free_stream);
1359 if (!pStream) {
1360 throw rdf::RepositoryException(
1361 "librdf_Repository::getStatements: "
1362 "librdf_model_find_statements failed", *this);
1365 return new librdf_GraphResult(this, m_aMutex, pStream,
1366 std::shared_ptr<librdf_node>());
1370 uno::Reference< rdf::XQuerySelectResult > SAL_CALL
1371 librdf_Repository::querySelect(const OUString & i_rQuery)
1372 throw (uno::RuntimeException, rdf::QueryException, rdf::RepositoryException, std::exception)
1374 ::osl::MutexGuard g(m_aMutex);
1375 const OString query(
1376 OUStringToOString(i_rQuery, RTL_TEXTENCODING_UTF8) );
1377 const std::shared_ptr<librdf_query> pQuery(
1378 librdf_new_query(m_pWorld.get(), s_sparql, nullptr,
1379 reinterpret_cast<const unsigned char*> (query.getStr()), nullptr),
1380 safe_librdf_free_query);
1381 if (!pQuery) {
1382 throw rdf::QueryException(
1383 "librdf_Repository::querySelect: "
1384 "librdf_new_query failed", *this);
1386 const std::shared_ptr<librdf_query_results> pResults(
1387 librdf_model_query_execute(m_pModel.get(), pQuery.get()),
1388 safe_librdf_free_query_results);
1389 if (!pResults || !librdf_query_results_is_bindings(pResults.get())) {
1390 throw rdf::QueryException(
1391 "librdf_Repository::querySelect: "
1392 "query result is null or not bindings", *this);
1395 const int count( librdf_query_results_get_bindings_count(pResults.get()) );
1396 if (count >= 0) {
1397 uno::Sequence< OUString > names(count);
1398 for (int i = 0; i < count; ++i) {
1399 const char* name( librdf_query_results_get_binding_name(
1400 pResults.get(), i) );
1401 if (!name) {
1402 throw rdf::QueryException(
1403 "librdf_Repository::querySelect: binding is null", *this);
1406 names[i] = OUString::createFromAscii(name);
1409 return new librdf_QuerySelectResult(this, m_aMutex,
1410 pQuery, pResults, names);
1412 } else {
1413 throw rdf::QueryException(
1414 "librdf_Repository::querySelect: "
1415 "librdf_query_results_get_bindings_count failed", *this);
1419 uno::Reference< container::XEnumeration > SAL_CALL
1420 librdf_Repository::queryConstruct(const OUString & i_rQuery)
1421 throw (uno::RuntimeException, rdf::QueryException, rdf::RepositoryException, std::exception)
1423 ::osl::MutexGuard g(m_aMutex);
1424 const OString query(
1425 OUStringToOString(i_rQuery, RTL_TEXTENCODING_UTF8) );
1426 const std::shared_ptr<librdf_query> pQuery(
1427 librdf_new_query(m_pWorld.get(), s_sparql, nullptr,
1428 reinterpret_cast<const unsigned char*> (query.getStr()), nullptr),
1429 safe_librdf_free_query);
1430 if (!pQuery) {
1431 throw rdf::QueryException(
1432 "librdf_Repository::queryConstruct: "
1433 "librdf_new_query failed", *this);
1435 const std::shared_ptr<librdf_query_results> pResults(
1436 librdf_model_query_execute(m_pModel.get(), pQuery.get()),
1437 safe_librdf_free_query_results);
1438 if (!pResults || !librdf_query_results_is_graph(pResults.get())) {
1439 throw rdf::QueryException(
1440 "librdf_Repository::queryConstruct: "
1441 "query result is null or not graph", *this);
1443 const std::shared_ptr<librdf_stream> pStream(
1444 librdf_query_results_as_stream(pResults.get()),
1445 safe_librdf_free_stream);
1446 if (!pStream) {
1447 throw rdf::QueryException(
1448 "librdf_Repository::queryConstruct: "
1449 "librdf_query_results_as_stream failed", *this);
1452 return new librdf_GraphResult(this, m_aMutex, pStream,
1453 std::shared_ptr<librdf_node>(), pQuery);
1456 sal_Bool SAL_CALL
1457 librdf_Repository::queryAsk(const OUString & i_rQuery)
1458 throw (uno::RuntimeException, rdf::QueryException, rdf::RepositoryException, std::exception)
1460 ::osl::MutexGuard g(m_aMutex);
1462 const OString query(
1463 OUStringToOString(i_rQuery, RTL_TEXTENCODING_UTF8) );
1464 const std::shared_ptr<librdf_query> pQuery(
1465 librdf_new_query(m_pWorld.get(), s_sparql, nullptr,
1466 reinterpret_cast<const unsigned char*> (query.getStr()), nullptr),
1467 safe_librdf_free_query);
1468 if (!pQuery) {
1469 throw rdf::QueryException(
1470 "librdf_Repository::queryAsk: "
1471 "librdf_new_query failed", *this);
1473 const std::shared_ptr<librdf_query_results> pResults(
1474 librdf_model_query_execute(m_pModel.get(), pQuery.get()),
1475 safe_librdf_free_query_results);
1476 if (!pResults || !librdf_query_results_is_boolean(pResults.get())) {
1477 throw rdf::QueryException(
1478 "librdf_Repository::queryAsk: "
1479 "query result is null or not boolean", *this);
1481 return bool(librdf_query_results_get_boolean(pResults.get()));
1484 // css::rdf::XDocumentRepository:
1485 void SAL_CALL librdf_Repository::setStatementRDFa(
1486 const uno::Reference< rdf::XResource > & i_xSubject,
1487 const uno::Sequence< uno::Reference< rdf::XURI > > & i_rPredicates,
1488 const uno::Reference< rdf::XMetadatable > & i_xObject,
1489 const OUString & i_rRDFaContent,
1490 const uno::Reference< rdf::XURI > & i_xRDFaDatatype)
1491 throw (uno::RuntimeException, lang::IllegalArgumentException,
1492 rdf::RepositoryException, std::exception)
1494 if (!i_xSubject.is()) {
1495 throw lang::IllegalArgumentException(
1496 "librdf_Repository::setStatementRDFa: Subject is null", *this, 0);
1498 if (!i_rPredicates.getLength()) {
1499 throw lang::IllegalArgumentException(
1500 "librdf_Repository::setStatementRDFa: no Predicates",
1501 *this, 1);
1503 for (sal_Int32 i = 0; i < i_rPredicates.getLength(); ++i) {
1504 if (!i_rPredicates[i].is()) {
1505 throw lang::IllegalArgumentException(
1506 "librdf_Repository::setStatementRDFa: Predicate is null",
1507 *this, 1);
1510 if (!i_xObject.is()) {
1511 throw lang::IllegalArgumentException(
1512 "librdf_Repository::setStatementRDFa: Object is null", *this, 2);
1514 const uno::Reference<lang::XServiceInfo> xService(i_xObject,
1515 uno::UNO_QUERY_THROW);
1516 uno::Reference<text::XTextRange> xTextRange;
1517 if (xService->supportsService("com.sun.star.table.Cell") ||
1518 xService->supportsService("com.sun.star.text.CellProperties") || // for writer
1519 xService->supportsService("com.sun.star.text.Paragraph"))
1521 xTextRange.set(i_xObject, uno::UNO_QUERY_THROW);
1523 else if (xService->supportsService("com.sun.star.text.Bookmark") ||
1524 xService->supportsService("com.sun.star.text.InContentMetadata"))
1526 const uno::Reference<text::XTextContent> xTextContent(i_xObject,
1527 uno::UNO_QUERY_THROW);
1528 xTextRange = xTextContent->getAnchor();
1530 if (!xTextRange.is()) {
1531 throw lang::IllegalArgumentException(
1532 "librdf_Repository::setStatementRDFa: "
1533 "Object does not support RDFa", *this, 2);
1535 // ensure that the metadatable has an XML ID
1536 i_xObject->ensureMetadataReference();
1537 const beans::StringPair mdref( i_xObject->getMetadataReference() );
1538 if ((mdref.First.isEmpty()) || (mdref.Second.isEmpty())) {
1539 throw uno::RuntimeException(
1540 "librdf_Repository::setStatementRDFa: "
1541 "ensureMetadataReference did not", *this);
1543 OUString const sXmlId(mdref.First + "#" + mdref.Second);
1544 OUString const sContext(s_nsOOo + sXmlId);
1545 OUString const content( (i_rRDFaContent.isEmpty())
1546 ? xTextRange->getString()
1547 : i_rRDFaContent );
1548 uno::Reference<rdf::XNode> xContent;
1549 try {
1550 if (i_xRDFaDatatype.is()) {
1551 xContent.set(rdf::Literal::createWithType(m_xContext,
1552 content, i_xRDFaDatatype),
1553 uno::UNO_QUERY_THROW);
1554 } else {
1555 xContent.set(rdf::Literal::create(m_xContext, content),
1556 uno::UNO_QUERY_THROW);
1558 } catch (const lang::IllegalArgumentException & iae) {
1559 throw lang::WrappedTargetRuntimeException(
1560 "librdf_Repository::setStatementRDFa: "
1561 "cannot create literal", *this, uno::makeAny(iae));
1564 std::shared_ptr<librdf_TypeConverter::Resource> const pSubject(
1565 librdf_TypeConverter::extractResource_NoLock(i_xSubject));
1566 std::shared_ptr<librdf_TypeConverter::Node> const pContent(
1567 librdf_TypeConverter::extractNode_NoLock(xContent));
1568 ::std::vector< std::shared_ptr<librdf_TypeConverter::Resource> >
1569 predicates;
1570 ::std::transform(i_rPredicates.begin(), i_rPredicates.end(),
1571 ::std::back_inserter(predicates),
1572 [](uno::Reference<rdf::XURI> const& xURI)
1573 { return librdf_TypeConverter::extractResource_NoLock(xURI); });
1575 removeStatementRDFa(i_xObject); // not atomic with insertion?
1577 ::osl::MutexGuard g(m_aMutex); // don't call i_x* with mutex locked
1579 if (i_rRDFaContent.isEmpty()) {
1580 m_RDFaXHTMLContentSet.erase(sXmlId);
1581 } else {
1582 m_RDFaXHTMLContentSet.insert(sXmlId);
1586 for (::std::vector< std::shared_ptr<librdf_TypeConverter::Resource> >
1587 ::iterator iter = predicates.begin(); iter != predicates.end();
1588 ++iter)
1590 addStatementGraph_Lock(
1591 librdf_TypeConverter::Statement(pSubject,
1592 std::dynamic_pointer_cast<librdf_TypeConverter::URI>(*iter),
1593 pContent),
1594 sContext, true);
1597 catch (const container::NoSuchElementException& e)
1599 throw lang::WrappedTargetRuntimeException(
1600 "librdf_Repository::setStatementRDFa: "
1601 "cannot addStatementGraph", *this, uno::makeAny(e));
1605 void SAL_CALL librdf_Repository::removeStatementRDFa(
1606 const uno::Reference< rdf::XMetadatable > & i_xElement)
1607 throw (uno::RuntimeException, lang::IllegalArgumentException,
1608 rdf::RepositoryException, std::exception)
1610 if (!i_xElement.is()) {
1611 throw lang::IllegalArgumentException(
1612 "librdf_Repository::removeStatementRDFa: Element is null",
1613 *this, 0);
1616 const beans::StringPair mdref( i_xElement->getMetadataReference() );
1617 if ((mdref.First.isEmpty()) || (mdref.Second.isEmpty())) {
1618 return; // nothing to do...
1621 OUString const sXmlId(s_nsOOo + mdref.First + "#" + mdref.Second);
1623 clearGraph_NoLock(sXmlId, true);
1626 beans::Pair< uno::Sequence<rdf::Statement>, sal_Bool > SAL_CALL
1627 librdf_Repository::getStatementRDFa(
1628 const uno::Reference< rdf::XMetadatable > & i_xElement)
1629 throw (uno::RuntimeException, lang::IllegalArgumentException,
1630 rdf::RepositoryException, std::exception)
1632 if (!i_xElement.is()) {
1633 throw lang::IllegalArgumentException(
1634 "librdf_Repository::getStatementRDFa: Element is null", *this, 0);
1636 const beans::StringPair mdref( i_xElement->getMetadataReference() );
1637 if ((mdref.First.isEmpty()) || (mdref.Second.isEmpty())) {
1638 return beans::Pair< uno::Sequence<rdf::Statement>, sal_Bool >();
1640 OUString const sXmlId(mdref.First + "#" + mdref.Second);
1641 uno::Reference<rdf::XURI> xXmlId;
1642 try {
1643 xXmlId.set( rdf::URI::create(m_xContext, s_nsOOo + sXmlId),
1644 uno::UNO_QUERY_THROW);
1645 } catch (const lang::IllegalArgumentException & iae) {
1646 throw lang::WrappedTargetRuntimeException(
1647 "librdf_Repository::getStatementRDFa: "
1648 "cannot create URI for XML ID", *this, uno::makeAny(iae));
1651 ::std::vector< rdf::Statement > ret;
1654 const uno::Reference<container::XEnumeration> xIter(
1655 getStatementsGraph_NoLock(nullptr, nullptr, nullptr, xXmlId, true) );
1656 OSL_ENSURE(xIter.is(), "getStatementRDFa: no result?");
1657 if (!xIter.is()) throw uno::RuntimeException();
1658 while (xIter->hasMoreElements()) {
1659 rdf::Statement stmt;
1660 if (!(xIter->nextElement() >>= stmt)) {
1661 OSL_FAIL("getStatementRDFa: result of wrong type?");
1662 } else {
1663 ret.push_back(stmt);
1667 catch (const container::NoSuchElementException& e)
1669 throw lang::WrappedTargetRuntimeException(
1670 "librdf_Repository::getStatementRDFa: "
1671 "cannot getStatementsGraph", *this, uno::makeAny(e));
1674 ::osl::MutexGuard g(m_aMutex); // don't call i_x* with mutex locked
1676 return beans::Pair< uno::Sequence<rdf::Statement>, sal_Bool >(
1677 comphelper::containerToSequence(ret), 0 != m_RDFaXHTMLContentSet.count(sXmlId));
1680 extern "C"
1681 librdf_statement *rdfa_context_stream_map_handler(
1682 librdf_stream *i_pStream, void *, librdf_statement *i_pStatement)
1684 OSL_ENSURE(i_pStream, "rdfa_context_stream_map_handler: stream null");
1685 if (i_pStream) {
1686 librdf_node *pCtxt(
1687 #if LIBRDF_VERSION >= 10012
1688 librdf_stream_get_context2(i_pStream) );
1689 #else
1690 static_cast<librdf_node *>(librdf_stream_get_context(i_pStream)) );
1691 #endif
1692 OSL_ENSURE(pCtxt, "rdfa_context_stream_map_handler: context null");
1693 if (pCtxt && isInternalContext(pCtxt)) {
1694 return i_pStatement;
1697 return nullptr;
1700 uno::Reference< container::XEnumeration > SAL_CALL
1701 librdf_Repository::getStatementsRDFa(
1702 const uno::Reference< rdf::XResource > & i_xSubject,
1703 const uno::Reference< rdf::XURI > & i_xPredicate,
1704 const uno::Reference< rdf::XNode > & i_xObject)
1705 throw (uno::RuntimeException, rdf::RepositoryException, std::exception)
1707 if (isMetadatableWithoutMetadata(i_xSubject) ||
1708 isMetadatableWithoutMetadata(i_xPredicate) ||
1709 isMetadatableWithoutMetadata(i_xObject))
1711 return new librdf_GraphResult(this, m_aMutex,
1712 std::shared_ptr<librdf_stream>(),
1713 std::shared_ptr<librdf_node>());
1716 librdf_TypeConverter::Statement const stmt(
1717 librdf_TypeConverter::extractStatement_NoLock(
1718 i_xSubject, i_xPredicate, i_xObject));
1720 ::osl::MutexGuard g(m_aMutex); // don't call i_x* with mutex locked
1722 const std::shared_ptr<librdf_statement> pStatement(
1723 librdf_TypeConverter::mkStatement_Lock(m_pWorld.get(), stmt),
1724 safe_librdf_free_statement);
1725 OSL_ENSURE(pStatement, "mkStatement failed");
1727 const std::shared_ptr<librdf_stream> pStream(
1728 librdf_model_find_statements(m_pModel.get(), pStatement.get()),
1729 safe_librdf_free_stream);
1730 if (!pStream) {
1731 throw rdf::RepositoryException(
1732 "librdf_Repository::getStatementsRDFa: "
1733 "librdf_model_find_statements failed", *this);
1736 if (librdf_stream_add_map(pStream.get(), rdfa_context_stream_map_handler,
1737 nullptr, nullptr)) {
1738 throw rdf::RepositoryException(
1739 "librdf_Repository::getStatementsRDFa: "
1740 "librdf_stream_add_map failed", *this);
1743 return new librdf_GraphResult(this, m_aMutex, pStream,
1744 std::shared_ptr<librdf_node>());
1747 // css::lang::XInitialization:
1748 void SAL_CALL librdf_Repository::initialize(
1749 const uno::Sequence< css::uno::Any > & i_rArguments)
1750 throw (uno::RuntimeException, uno::Exception, std::exception)
1752 (void) i_rArguments;
1754 ::osl::MutexGuard g(m_aMutex);
1756 // m_pWorld.reset(m_TypeConverter.createWorld(), safe_librdf_free_world);
1757 m_pStorage.reset(m_TypeConverter.createStorage_Lock(m_pWorld.get()),
1758 safe_librdf_free_storage);
1759 m_pModel.reset(m_TypeConverter.createModel_Lock(
1760 m_pWorld.get(), m_pStorage.get()), safe_librdf_free_model);
1763 const NamedGraphMap_t::iterator librdf_Repository::clearGraph_NoLock(
1764 OUString const& i_rGraphName, bool i_Internal)
1765 // throw (uno::RuntimeException, container::NoSuchElementException,
1766 // rdf::RepositoryException)
1768 ::osl::MutexGuard g(m_aMutex);
1770 return clearGraph_Lock(i_rGraphName, i_Internal);
1773 const NamedGraphMap_t::iterator librdf_Repository::clearGraph_Lock(
1774 OUString const& i_rGraphName, bool i_Internal)
1776 // internal: must be called with mutex locked!
1777 const NamedGraphMap_t::iterator iter( m_NamedGraphs.find(i_rGraphName) );
1778 if (!i_Internal && iter == m_NamedGraphs.end()) {
1779 throw container::NoSuchElementException(
1780 "librdf_Repository::clearGraph: "
1781 "no graph with given URI exists", *this);
1783 const OString context(
1784 OUStringToOString(i_rGraphName, RTL_TEXTENCODING_UTF8) );
1786 const std::shared_ptr<librdf_node> pContext(
1787 librdf_new_node_from_uri_string(m_pWorld.get(),
1788 reinterpret_cast<const unsigned char*> (context.getStr())),
1789 safe_librdf_free_node);
1790 if (!pContext) {
1791 throw uno::RuntimeException(
1792 "librdf_Repository::clearGraph: "
1793 "librdf_new_node_from_uri_string failed", *this);
1795 if (librdf_model_context_remove_statements(m_pModel.get(), pContext.get()))
1797 throw rdf::RepositoryException(
1798 "librdf_Repository::clearGraph: "
1799 "librdf_model_context_remove_statements failed", *this);
1801 return iter;
1804 void librdf_Repository::addStatementGraph_NoLock(
1805 const uno::Reference< rdf::XResource > & i_xSubject,
1806 const uno::Reference< rdf::XURI > & i_xPredicate,
1807 const uno::Reference< rdf::XNode > & i_xObject,
1808 const uno::Reference< rdf::XURI > & i_xGraphName)
1809 //throw (uno::RuntimeException, lang::IllegalArgumentException,
1810 // container::NoSuchElementException, rdf::RepositoryException)
1812 if (!i_xSubject.is()) {
1813 throw lang::IllegalArgumentException(
1814 "librdf_Repository::addStatement: Subject is null", *this, 0);
1816 if (!i_xPredicate.is()) {
1817 throw lang::IllegalArgumentException(
1818 "librdf_Repository::addStatement: Predicate is null",
1819 *this, 1);
1821 if (!i_xObject.is()) {
1822 throw lang::IllegalArgumentException(
1823 "librdf_Repository::addStatement: Object is null", *this, 2);
1826 librdf_TypeConverter::Statement const stmt(
1827 librdf_TypeConverter::extractStatement_NoLock(
1828 i_xSubject, i_xPredicate, i_xObject));
1830 const OUString contextU( i_xGraphName->getStringValue() );
1832 ::osl::MutexGuard g(m_aMutex); // don't call i_x* with mutex locked
1834 addStatementGraph_Lock(stmt, contextU, false/*i_Internal*/);
1837 void librdf_Repository::addStatementGraph_Lock(
1838 librdf_TypeConverter::Statement const& i_rStatement,
1839 OUString const& i_rGraphName,
1840 bool i_Internal)
1842 if (!i_Internal
1843 && (m_NamedGraphs.find(i_rGraphName) == m_NamedGraphs.end()))
1845 throw container::NoSuchElementException(
1846 "librdf_Repository::addStatement: "
1847 "no graph with given URI exists", *this);
1849 const OString context(
1850 OUStringToOString(i_rGraphName, RTL_TEXTENCODING_UTF8) );
1852 const std::shared_ptr<librdf_node> pContext(
1853 librdf_new_node_from_uri_string(m_pWorld.get(),
1854 reinterpret_cast<const unsigned char*> (context.getStr())),
1855 safe_librdf_free_node);
1856 if (!pContext) {
1857 throw uno::RuntimeException(
1858 "librdf_Repository::addStatement: "
1859 "librdf_new_node_from_uri_string failed", *this);
1861 const std::shared_ptr<librdf_statement> pStatement(
1862 librdf_TypeConverter::mkStatement_Lock(m_pWorld.get(), i_rStatement),
1863 safe_librdf_free_statement);
1864 OSL_ENSURE(pStatement, "mkStatement failed");
1866 // Test for duplicate statement
1867 // librdf_model_add_statement disallows duplicates while
1868 // librdf_model_context_add_statement allows duplicates
1870 const std::shared_ptr<librdf_stream> pStream(
1871 librdf_model_find_statements_in_context(m_pModel.get(),
1872 pStatement.get(), pContext.get()),
1873 safe_librdf_free_stream);
1874 if (pStream && !librdf_stream_end(pStream.get()))
1875 return;
1878 if (librdf_model_context_add_statement(m_pModel.get(),
1879 pContext.get(), pStatement.get())) {
1880 throw rdf::RepositoryException(
1881 "librdf_Repository::addStatement: "
1882 "librdf_model_context_add_statement failed", *this);
1886 void librdf_Repository::removeStatementsGraph_NoLock(
1887 const uno::Reference< rdf::XResource > & i_xSubject,
1888 const uno::Reference< rdf::XURI > & i_xPredicate,
1889 const uno::Reference< rdf::XNode > & i_xObject,
1890 const uno::Reference< rdf::XURI > & i_xGraphName)
1891 //throw (uno::RuntimeException, lang::IllegalArgumentException,
1892 // container::NoSuchElementException, rdf::RepositoryException)
1894 if (isMetadatableWithoutMetadata(i_xSubject) ||
1895 isMetadatableWithoutMetadata(i_xPredicate) ||
1896 isMetadatableWithoutMetadata(i_xObject))
1898 return;
1901 librdf_TypeConverter::Statement const stmt(
1902 librdf_TypeConverter::extractStatement_NoLock(
1903 i_xSubject, i_xPredicate, i_xObject));
1904 const OUString contextU( i_xGraphName->getStringValue() );
1906 ::osl::MutexGuard g(m_aMutex); // don't call i_x* with mutex locked
1908 if (m_NamedGraphs.find(contextU) == m_NamedGraphs.end()) {
1909 throw container::NoSuchElementException(
1910 "librdf_Repository::removeStatements: "
1911 "no graph with given URI exists", *this);
1913 const OString context(
1914 OUStringToOString(contextU, RTL_TEXTENCODING_UTF8) );
1916 const std::shared_ptr<librdf_node> pContext(
1917 librdf_new_node_from_uri_string(m_pWorld.get(),
1918 reinterpret_cast<const unsigned char*> (context.getStr())),
1919 safe_librdf_free_node);
1920 if (!pContext) {
1921 throw uno::RuntimeException(
1922 "librdf_Repository::removeStatements: "
1923 "librdf_new_node_from_uri_string failed", *this);
1925 const std::shared_ptr<librdf_statement> pStatement(
1926 librdf_TypeConverter::mkStatement_Lock(m_pWorld.get(), stmt),
1927 safe_librdf_free_statement);
1928 OSL_ENSURE(pStatement, "mkStatement failed");
1930 const std::shared_ptr<librdf_stream> pStream(
1931 librdf_model_find_statements_in_context(m_pModel.get(),
1932 pStatement.get(), pContext.get()),
1933 safe_librdf_free_stream);
1934 if (!pStream) {
1935 throw rdf::RepositoryException(
1936 "librdf_Repository::removeStatements: "
1937 "librdf_model_find_statements_in_context failed", *this);
1940 if (!librdf_stream_end(pStream.get())) {
1941 do {
1942 librdf_statement *pStmt( librdf_stream_get_object(pStream.get()) );
1943 if (!pStmt) {
1944 throw rdf::RepositoryException(
1945 "librdf_Repository::removeStatements: "
1946 "librdf_stream_get_object failed", *this);
1948 if (librdf_model_context_remove_statement(m_pModel.get(),
1949 pContext.get(), pStmt)) {
1950 throw rdf::RepositoryException(
1951 "librdf_Repository::removeStatements: "
1952 "librdf_model_context_remove_statement failed", *this);
1954 } while (!librdf_stream_next(pStream.get()));
1958 uno::Reference< container::XEnumeration >
1959 librdf_Repository::getStatementsGraph_NoLock(
1960 const uno::Reference< rdf::XResource > & i_xSubject,
1961 const uno::Reference< rdf::XURI > & i_xPredicate,
1962 const uno::Reference< rdf::XNode > & i_xObject,
1963 const uno::Reference< rdf::XURI > & i_xGraphName,
1964 bool i_Internal)
1965 //throw (uno::RuntimeException, lang::IllegalArgumentException,
1966 // container::NoSuchElementException, rdf::RepositoryException)
1968 // N.B.: if any of subject, predicate, object is an XMetadatable, and
1969 // has no metadata reference, then there cannot be any node in the graph
1970 // representing it; in order to prevent side effect
1971 // (ensureMetadataReference), check for this condition and return
1972 if (isMetadatableWithoutMetadata(i_xSubject) ||
1973 isMetadatableWithoutMetadata(i_xPredicate) ||
1974 isMetadatableWithoutMetadata(i_xObject))
1976 return new librdf_GraphResult(this, m_aMutex,
1977 std::shared_ptr<librdf_stream>(),
1978 std::shared_ptr<librdf_node>());
1981 librdf_TypeConverter::Statement const stmt(
1982 librdf_TypeConverter::extractStatement_NoLock(
1983 i_xSubject, i_xPredicate, i_xObject));
1984 const OUString contextU( i_xGraphName->getStringValue() );
1986 ::osl::MutexGuard g(m_aMutex); // don't call i_x* with mutex locked
1988 if (!i_Internal && (m_NamedGraphs.find(contextU) == m_NamedGraphs.end())) {
1989 throw container::NoSuchElementException(
1990 "librdf_Repository::getStatements: "
1991 "no graph with given URI exists", *this);
1993 const OString context(
1994 OUStringToOString(contextU, RTL_TEXTENCODING_UTF8) );
1996 const std::shared_ptr<librdf_node> pContext(
1997 librdf_new_node_from_uri_string(m_pWorld.get(),
1998 reinterpret_cast<const unsigned char*> (context.getStr())),
1999 safe_librdf_free_node);
2000 if (!pContext) {
2001 throw uno::RuntimeException(
2002 "librdf_Repository::getStatements: "
2003 "librdf_new_node_from_uri_string failed", *this);
2005 const std::shared_ptr<librdf_statement> pStatement(
2006 librdf_TypeConverter::mkStatement_Lock(m_pWorld.get(), stmt),
2007 safe_librdf_free_statement);
2008 OSL_ENSURE(pStatement, "mkStatement failed");
2010 const std::shared_ptr<librdf_stream> pStream(
2011 librdf_model_find_statements_in_context(m_pModel.get(),
2012 pStatement.get(), pContext.get()),
2013 safe_librdf_free_stream);
2014 if (!pStream) {
2015 throw rdf::RepositoryException(
2016 "librdf_Repository::getStatements: "
2017 "librdf_model_find_statements_in_context failed", *this);
2020 // librdf_model_find_statements_in_context is buggy and does not put
2021 // the context into result statements; pass it to librdf_GraphResult here
2022 return new librdf_GraphResult(this, m_aMutex, pStream, pContext);
2025 extern "C"
2026 void librdf_raptor_init(void* /*user_data*/, raptor_world* pRaptorWorld)
2028 // fdo#64672 prevent raptor from setting global libxml2 error handlers
2029 raptor_world_set_flag(pRaptorWorld,
2030 RAPTOR_WORLD_FLAG_LIBXML_STRUCTURED_ERROR_SAVE, 0);
2031 raptor_world_set_flag(pRaptorWorld,
2032 RAPTOR_WORLD_FLAG_LIBXML_GENERIC_ERROR_SAVE, 0);
2035 librdf_world *librdf_TypeConverter::createWorld_Lock() const
2037 // create and initialize world
2038 librdf_world *pWorld( librdf_new_world() );
2039 if (!pWorld) {
2040 throw uno::RuntimeException(
2041 "librdf_TypeConverter::createWorld: librdf_new_world failed",
2042 m_rRep);
2044 librdf_world_set_raptor_init_handler(pWorld, nullptr, &librdf_raptor_init);
2045 //FIXME logger, digest, features?
2046 xsltSecurityPrefsPtr origprefs = xsltGetDefaultSecurityPrefs();
2047 librdf_world_open(pWorld);
2048 xsltSecurityPrefsPtr newprefs = xsltGetDefaultSecurityPrefs();
2049 if (newprefs != origprefs) {
2050 // #i110523# restore libxslt global configuration
2051 // (gratuitously overwritten by raptor_init_parser_grddl_common)
2052 // (this is the only reason unordf is linked against libxslt)
2053 xsltSetDefaultSecurityPrefs(origprefs);
2055 return pWorld;
2058 librdf_storage *
2059 librdf_TypeConverter::createStorage_Lock(librdf_world *i_pWorld) const
2061 librdf_storage *pStorage(
2062 // librdf_new_storage(i_pWorld, "memory", NULL, "contexts='yes'") );
2063 librdf_new_storage(i_pWorld, "hashes", nullptr,
2064 "contexts='yes',hash-type='memory'") );
2065 if (!pStorage) {
2066 throw uno::RuntimeException(
2067 "librdf_TypeConverter::createStorage: librdf_new_storage failed",
2068 m_rRep);
2070 return pStorage;
2073 librdf_model *librdf_TypeConverter::createModel_Lock(
2074 librdf_world *i_pWorld, librdf_storage * i_pStorage) const
2076 librdf_model *pRepository( librdf_new_model(i_pWorld, i_pStorage, nullptr) );
2077 if (!pRepository) {
2078 throw uno::RuntimeException(
2079 "librdf_TypeConverter::createModel: librdf_new_model failed",
2080 m_rRep);
2082 //FIXME
2083 #if 0
2085 librdf_uri * ctxt = librdf_new_uri(i_pWorld, reinterpret_cast<const unsigned char *>(LIBRDF_MODEL_FEATURE_CONTEXTS));
2086 librdf_node * contexts = librdf_model_get_feature(repository, ctxt);
2087 if (!contexts)
2088 throw;
2089 std::cout << "value of contexts feature: ";
2090 prtNode(contexts);
2091 std::cout << std::endl;
2092 // librdf_model_set_feature(repository, LIBRDF_FEATURE_CONTEXTS, ...);
2093 safe_librdf_free_node(contexts);
2094 safe_librdf_free_uri(ctxt);
2096 #endif
2097 return pRepository;
2100 // this does NOT create a node, only URI
2101 librdf_uri* librdf_TypeConverter::mkURI_Lock( librdf_world* i_pWorld,
2102 OString const& i_rURI)
2104 librdf_uri *pURI( librdf_new_uri(i_pWorld,
2105 reinterpret_cast<const unsigned char *>(i_rURI.getStr())));
2106 if (!pURI) {
2107 throw uno::RuntimeException(
2108 "librdf_TypeConverter::mkURI: librdf_new_uri failed", nullptr);
2110 return pURI;
2113 // extract blank or URI node - call without Mutex locked
2114 std::shared_ptr<librdf_TypeConverter::Resource>
2115 librdf_TypeConverter::extractResource_NoLock(
2116 const uno::Reference< rdf::XResource > & i_xResource)
2118 if (!i_xResource.is()) {
2119 return std::shared_ptr<Resource>();
2121 uno::Reference< rdf::XBlankNode > xBlankNode(i_xResource, uno::UNO_QUERY);
2122 if (xBlankNode.is()) {
2123 const OString label(
2124 OUStringToOString(xBlankNode->getStringValue(),
2125 RTL_TEXTENCODING_UTF8) );
2126 return std::shared_ptr<Resource>(new BlankNode(label));
2127 } else { // assumption: everything else is URI
2128 const OString uri(
2129 OUStringToOString(i_xResource->getStringValue(),
2130 RTL_TEXTENCODING_UTF8) );
2131 return std::shared_ptr<Resource>(new URI(uri));
2135 // create blank or URI node
2136 librdf_node* librdf_TypeConverter::mkResource_Lock( librdf_world* i_pWorld,
2137 Resource const*const i_pResource)
2139 if (!i_pResource) return nullptr;
2140 BlankNode const*const pBlankNode(
2141 dynamic_cast<BlankNode const*>(i_pResource));
2142 if (pBlankNode) {
2143 librdf_node *pNode(
2144 librdf_new_node_from_blank_identifier(i_pWorld,
2145 reinterpret_cast<const unsigned char*>(
2146 pBlankNode->value.getStr())));
2147 if (!pNode) {
2148 throw uno::RuntimeException(
2149 "librdf_TypeConverter::mkResource: "
2150 "librdf_new_node_from_blank_identifier failed", nullptr);
2152 return pNode;
2153 } else { // assumption: everything else is URI
2154 URI const*const pURI(dynamic_cast<URI const*>(i_pResource));
2155 assert(pURI);
2156 librdf_node *pNode(
2157 librdf_new_node_from_uri_string(i_pWorld,
2158 reinterpret_cast<const unsigned char*>(pURI->value.getStr())));
2159 if (!pNode) {
2160 throw uno::RuntimeException(
2161 "librdf_TypeConverter::mkResource: "
2162 "librdf_new_node_from_uri_string failed", nullptr);
2164 return pNode;
2168 // extract blank or URI or literal node - call without Mutex locked
2169 std::shared_ptr<librdf_TypeConverter::Node>
2170 librdf_TypeConverter::extractNode_NoLock(
2171 const uno::Reference< rdf::XNode > & i_xNode)
2173 if (!i_xNode.is()) {
2174 return std::shared_ptr<Node>();
2176 uno::Reference< rdf::XResource > xResource(i_xNode, uno::UNO_QUERY);
2177 if (xResource.is()) {
2178 return extractResource_NoLock(xResource);
2180 uno::Reference< rdf::XLiteral> xLiteral(i_xNode, uno::UNO_QUERY);
2181 OSL_ENSURE(xLiteral.is(),
2182 "mkNode: someone invented a new rdf.XNode and did not tell me");
2183 if (!xLiteral.is()) {
2184 return std::shared_ptr<Node>();
2186 const OString val(
2187 OUStringToOString(xLiteral->getValue(),
2188 RTL_TEXTENCODING_UTF8) );
2189 const OString lang(
2190 OUStringToOString(xLiteral->getLanguage(),
2191 RTL_TEXTENCODING_UTF8) );
2192 const uno::Reference< rdf::XURI > xType(xLiteral->getDatatype());
2193 boost::optional<OString> type;
2194 if (xType.is())
2196 type =
2197 OUStringToOString(xType->getStringValue(), RTL_TEXTENCODING_UTF8);
2199 return std::shared_ptr<Node>(new Literal(val, lang, type));
2202 // create blank or URI or literal node
2203 librdf_node* librdf_TypeConverter::mkNode_Lock( librdf_world* i_pWorld,
2204 Node const*const i_pNode)
2206 if (!i_pNode) return nullptr;
2207 Resource const*const pResource(dynamic_cast<Resource const*>(i_pNode));
2208 if (pResource) {
2209 return mkResource_Lock(i_pWorld, pResource);
2212 Literal const*const pLiteral(dynamic_cast<Literal const*>(i_pNode));
2213 assert(pLiteral);
2214 librdf_node * ret(nullptr);
2215 if (pLiteral->language.isEmpty()) {
2216 if (!pLiteral->type) {
2217 ret = librdf_new_node_from_literal(i_pWorld,
2218 reinterpret_cast<const unsigned char*>(pLiteral->value.getStr())
2219 , nullptr, 0);
2220 } else {
2221 const std::shared_ptr<librdf_uri> pDatatype(
2222 mkURI_Lock(i_pWorld, *pLiteral->type),
2223 safe_librdf_free_uri);
2224 ret = librdf_new_node_from_typed_literal(i_pWorld,
2225 reinterpret_cast<const unsigned char*>(pLiteral->value.getStr())
2226 , nullptr, pDatatype.get());
2228 } else {
2229 if (!pLiteral->type) {
2230 ret = librdf_new_node_from_literal(i_pWorld,
2231 reinterpret_cast<const unsigned char*>(pLiteral->value.getStr())
2232 , pLiteral->language.getStr(), 0);
2233 } else {
2234 OSL_FAIL("mkNode: invalid literal");
2235 return nullptr;
2238 if (!ret) {
2239 throw uno::RuntimeException(
2240 "librdf_TypeConverter::mkNode: librdf_new_node_from_literal failed", nullptr);
2242 return ret;
2245 // extract statement - call without Mutex locked
2246 librdf_TypeConverter::Statement librdf_TypeConverter::extractStatement_NoLock(
2247 const uno::Reference< rdf::XResource > & i_xSubject,
2248 const uno::Reference< rdf::XURI > & i_xPredicate,
2249 const uno::Reference< rdf::XNode > & i_xObject)
2251 std::shared_ptr<Resource> const pSubject(
2252 extractResource_NoLock(i_xSubject));
2253 const uno::Reference<rdf::XResource> xPredicate(i_xPredicate,
2254 uno::UNO_QUERY);
2255 std::shared_ptr<URI> const pPredicate(
2256 std::dynamic_pointer_cast<URI>(extractResource_NoLock(xPredicate)));
2257 std::shared_ptr<Node> const pObject(extractNode_NoLock(i_xObject));
2258 return Statement(pSubject, pPredicate, pObject);
2261 librdf_statement* librdf_TypeConverter::mkStatement_Lock(librdf_world* i_pWorld,
2262 Statement const& i_rStatement)
2264 librdf_node *const pSubject(
2265 mkResource_Lock(i_pWorld, i_rStatement.pSubject.get()) );
2266 librdf_node* pPredicate(nullptr);
2267 librdf_node* pObject(nullptr);
2268 try {
2269 pPredicate = mkResource_Lock(i_pWorld, i_rStatement.pPredicate.get());
2270 try {
2271 pObject = mkNode_Lock(i_pWorld, i_rStatement.pObject.get());
2272 } catch (...) {
2273 safe_librdf_free_node(pPredicate);
2274 throw;
2276 } catch (...) {
2277 safe_librdf_free_node(pSubject);
2278 throw;
2280 // NB: this takes ownership of the nodes! (which is really ugly)
2281 librdf_statement* pStatement( librdf_new_statement_from_nodes(i_pWorld,
2282 pSubject, pPredicate, pObject) );
2283 if (!pStatement) {
2284 throw uno::RuntimeException(
2285 "librdf_TypeConverter::mkStatement: "
2286 "librdf_new_statement_from_nodes failed", nullptr);
2288 return pStatement;
2291 uno::Reference<rdf::XURI>
2292 librdf_TypeConverter::convertToXURI(librdf_uri* i_pURI) const
2294 if (!i_pURI) return nullptr;
2295 const unsigned char* uri( librdf_uri_as_string(i_pURI) );
2296 if (!uri) {
2297 throw uno::RuntimeException(
2298 "librdf_TypeConverter::convertToXURI: "
2299 "librdf_uri_as_string failed", m_rRep);
2301 OUString uriU( OStringToOUString(
2302 OString(reinterpret_cast<const sal_Char*>(uri)),
2303 RTL_TEXTENCODING_UTF8) );
2304 try {
2305 return rdf::URI::create(m_xContext, uriU);
2306 } catch (const lang::IllegalArgumentException & iae) {
2307 throw lang::WrappedTargetRuntimeException(
2308 "librdf_TypeConverter::convertToXURI: "
2309 "illegal uri", m_rRep, uno::makeAny(iae));
2313 uno::Reference<rdf::XURI>
2314 librdf_TypeConverter::convertToXURI(librdf_node* i_pNode) const
2316 if (!i_pNode) return nullptr;
2317 if (librdf_node_is_resource(i_pNode)) {
2318 librdf_uri* pURI( librdf_node_get_uri(i_pNode) );
2319 if (!pURI) {
2320 throw uno::RuntimeException(
2321 "librdf_TypeConverter::convertToXURI: "
2322 "resource has no uri", m_rRep);
2324 return convertToXURI(pURI);
2325 } else {
2326 OSL_FAIL("convertToXURI: unknown librdf_node");
2327 return nullptr;
2331 uno::Reference<rdf::XResource>
2332 librdf_TypeConverter::convertToXResource(librdf_node* i_pNode) const
2334 if (!i_pNode) return nullptr;
2335 if (librdf_node_is_blank(i_pNode)) {
2336 const unsigned char* label( librdf_node_get_blank_identifier(i_pNode) );
2337 if (!label) {
2338 throw uno::RuntimeException(
2339 "librdf_TypeConverter::convertToXResource: "
2340 "blank node has no label", m_rRep);
2342 OUString labelU( OStringToOUString(
2343 OString(reinterpret_cast<const sal_Char*>(label)),
2344 RTL_TEXTENCODING_UTF8) );
2345 try {
2346 return uno::Reference<rdf::XResource>(
2347 rdf::BlankNode::create(m_xContext, labelU), uno::UNO_QUERY);
2348 } catch (const lang::IllegalArgumentException & iae) {
2349 throw lang::WrappedTargetRuntimeException(
2350 "librdf_TypeConverter::convertToXResource: "
2351 "illegal blank node label", m_rRep, uno::makeAny(iae));
2353 } else {
2354 return uno::Reference<rdf::XResource>(convertToXURI(i_pNode),
2355 uno::UNO_QUERY);
2359 uno::Reference<rdf::XNode>
2360 librdf_TypeConverter::convertToXNode(librdf_node* i_pNode) const
2362 if (!i_pNode) return nullptr;
2363 if (!librdf_node_is_literal(i_pNode)) {
2364 return uno::Reference<rdf::XNode>(convertToXResource(i_pNode),
2365 uno::UNO_QUERY);
2367 const unsigned char* value( librdf_node_get_literal_value(i_pNode) );
2368 if (!value) {
2369 throw uno::RuntimeException(
2370 "librdf_TypeConverter::convertToXNode: "
2371 "literal has no value", m_rRep);
2373 const char * lang( librdf_node_get_literal_value_language(i_pNode) );
2374 librdf_uri* pType(
2375 librdf_node_get_literal_value_datatype_uri(i_pNode) );
2376 OSL_ENSURE(!lang || !pType, "convertToXNode: invalid literal");
2377 const OUString valueU( OStringToOUString(
2378 OString(reinterpret_cast<const sal_Char*>(value)),
2379 RTL_TEXTENCODING_UTF8) );
2380 if (lang) {
2381 const OUString langU( OStringToOUString(
2382 OString(reinterpret_cast<const sal_Char*>(lang)),
2383 RTL_TEXTENCODING_UTF8) );
2384 return uno::Reference<rdf::XNode>(
2385 rdf::Literal::createWithLanguage(m_xContext, valueU, langU),
2386 uno::UNO_QUERY);
2387 } else if (pType) {
2388 uno::Reference<rdf::XURI> xType(convertToXURI(pType));
2389 OSL_ENSURE(xType.is(), "convertToXNode: null uri");
2390 return uno::Reference<rdf::XNode>(
2391 rdf::Literal::createWithType(m_xContext, valueU, xType),
2392 uno::UNO_QUERY);
2393 } else {
2394 return uno::Reference<rdf::XNode>(
2395 rdf::Literal::create(m_xContext, valueU),
2396 uno::UNO_QUERY);
2400 rdf::Statement
2401 librdf_TypeConverter::convertToStatement(librdf_statement* i_pStmt,
2402 librdf_node* i_pContext) const
2404 if (!i_pStmt) {
2405 throw uno::RuntimeException();
2407 return rdf::Statement(
2408 convertToXResource(librdf_statement_get_subject(i_pStmt)),
2409 convertToXURI(librdf_statement_get_predicate(i_pStmt)),
2410 convertToXNode(librdf_statement_get_object(i_pStmt)),
2411 convertToXURI(i_pContext));
2414 } // closing anonymous implementation namespace
2417 // component helper namespace
2418 namespace comp_librdf_Repository {
2420 OUString SAL_CALL _getImplementationName() {
2421 return OUString("librdf_Repository");
2424 uno::Sequence< OUString > SAL_CALL _getSupportedServiceNames()
2426 uno::Sequence< OUString > s { "com.sun.star.rdf.Repository" };
2427 return s;
2430 uno::Reference< uno::XInterface > SAL_CALL _create(
2431 const uno::Reference< uno::XComponentContext > & context)
2433 return static_cast< ::cppu::OWeakObject * >(new librdf_Repository(context));
2436 } // closing component helper namespace
2438 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */