Version 5.2.6.1, tag libreoffice-5.2.6.1
[LibreOffice.git] / unoxml / source / rdf / librdf_repository.cxx
blobadab630400ef81b30548d877d764aab2cdf1caf8
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();
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()
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( static_cast<librdf_node *>
514 #if LIBRDF_VERSION >= 10012
515 (librdf_stream_get_context2(m_pStream.get())) );
516 #else
517 (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()
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() {}
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 static const char s_cell[] = "com.sun.star.table.Cell";
1495 static const char s_cellprops[] = "com.sun.star.text.CellProperties"; // for writer
1496 static const char s_paragraph[] = "com.sun.star.text.Paragraph";
1497 static const char s_bookmark[] = "com.sun.star.text.Bookmark";
1498 static const char s_meta[] = "com.sun.star.text.InContentMetadata";
1500 if (!i_xSubject.is()) {
1501 throw lang::IllegalArgumentException(
1502 "librdf_Repository::setStatementRDFa: Subject is null", *this, 0);
1504 if (!i_rPredicates.getLength()) {
1505 throw lang::IllegalArgumentException(
1506 "librdf_Repository::setStatementRDFa: no Predicates",
1507 *this, 1);
1509 for (sal_Int32 i = 0; i < i_rPredicates.getLength(); ++i) {
1510 if (!i_rPredicates[i].is()) {
1511 throw lang::IllegalArgumentException(
1512 "librdf_Repository::setStatementRDFa: Predicate is null",
1513 *this, 1);
1516 if (!i_xObject.is()) {
1517 throw lang::IllegalArgumentException(
1518 "librdf_Repository::setStatementRDFa: Object is null", *this, 2);
1520 const uno::Reference<lang::XServiceInfo> xService(i_xObject,
1521 uno::UNO_QUERY_THROW);
1522 uno::Reference<text::XTextRange> xTextRange;
1523 if (xService->supportsService(s_cell) ||
1524 xService->supportsService(s_cellprops) ||
1525 xService->supportsService(s_paragraph))
1527 xTextRange.set(i_xObject, uno::UNO_QUERY_THROW);
1529 else if (xService->supportsService(s_bookmark) ||
1530 xService->supportsService(s_meta))
1532 const uno::Reference<text::XTextContent> xTextContent(i_xObject,
1533 uno::UNO_QUERY_THROW);
1534 xTextRange = xTextContent->getAnchor();
1536 if (!xTextRange.is()) {
1537 throw lang::IllegalArgumentException(
1538 "librdf_Repository::setStatementRDFa: "
1539 "Object does not support RDFa", *this, 2);
1541 // ensure that the metadatable has an XML ID
1542 i_xObject->ensureMetadataReference();
1543 const beans::StringPair mdref( i_xObject->getMetadataReference() );
1544 if ((mdref.First.isEmpty()) || (mdref.Second.isEmpty())) {
1545 throw uno::RuntimeException(
1546 "librdf_Repository::setStatementRDFa: "
1547 "ensureMetadataReference did not", *this);
1549 OUString const sXmlId(mdref.First + "#" + mdref.Second);
1550 OUString const sContext(s_nsOOo + sXmlId);
1551 OUString const content( (i_rRDFaContent.isEmpty())
1552 ? xTextRange->getString()
1553 : i_rRDFaContent );
1554 uno::Reference<rdf::XNode> xContent;
1555 try {
1556 if (i_xRDFaDatatype.is()) {
1557 xContent.set(rdf::Literal::createWithType(m_xContext,
1558 content, i_xRDFaDatatype),
1559 uno::UNO_QUERY_THROW);
1560 } else {
1561 xContent.set(rdf::Literal::create(m_xContext, content),
1562 uno::UNO_QUERY_THROW);
1564 } catch (const lang::IllegalArgumentException & iae) {
1565 throw lang::WrappedTargetRuntimeException(
1566 "librdf_Repository::setStatementRDFa: "
1567 "cannot create literal", *this, uno::makeAny(iae));
1570 std::shared_ptr<librdf_TypeConverter::Resource> const pSubject(
1571 librdf_TypeConverter::extractResource_NoLock(i_xSubject));
1572 std::shared_ptr<librdf_TypeConverter::Node> const pContent(
1573 librdf_TypeConverter::extractNode_NoLock(xContent));
1574 ::std::vector< std::shared_ptr<librdf_TypeConverter::Resource> >
1575 predicates;
1576 ::std::transform(i_rPredicates.begin(), i_rPredicates.end(),
1577 ::std::back_inserter(predicates),
1578 [](uno::Reference<rdf::XURI> const& xURI)
1579 { return librdf_TypeConverter::extractResource_NoLock(xURI); });
1581 removeStatementRDFa(i_xObject); // not atomic with insertion?
1583 ::osl::MutexGuard g(m_aMutex); // don't call i_x* with mutex locked
1585 if (i_rRDFaContent.isEmpty()) {
1586 m_RDFaXHTMLContentSet.erase(sXmlId);
1587 } else {
1588 m_RDFaXHTMLContentSet.insert(sXmlId);
1592 for (::std::vector< std::shared_ptr<librdf_TypeConverter::Resource> >
1593 ::iterator iter = predicates.begin(); iter != predicates.end();
1594 ++iter)
1596 addStatementGraph_Lock(
1597 librdf_TypeConverter::Statement(pSubject,
1598 std::dynamic_pointer_cast<librdf_TypeConverter::URI>(*iter),
1599 pContent),
1600 sContext, true);
1603 catch (const container::NoSuchElementException& e)
1605 throw lang::WrappedTargetRuntimeException(
1606 "librdf_Repository::setStatementRDFa: "
1607 "cannot addStatementGraph", *this, uno::makeAny(e));
1611 void SAL_CALL librdf_Repository::removeStatementRDFa(
1612 const uno::Reference< rdf::XMetadatable > & i_xElement)
1613 throw (uno::RuntimeException, lang::IllegalArgumentException,
1614 rdf::RepositoryException, std::exception)
1616 if (!i_xElement.is()) {
1617 throw lang::IllegalArgumentException(
1618 "librdf_Repository::removeStatementRDFa: Element is null",
1619 *this, 0);
1622 const beans::StringPair mdref( i_xElement->getMetadataReference() );
1623 if ((mdref.First.isEmpty()) || (mdref.Second.isEmpty())) {
1624 return; // nothing to do...
1627 OUString const sXmlId(s_nsOOo + mdref.First + "#" + mdref.Second);
1629 clearGraph_NoLock(sXmlId, true);
1632 beans::Pair< uno::Sequence<rdf::Statement>, sal_Bool > SAL_CALL
1633 librdf_Repository::getStatementRDFa(
1634 const uno::Reference< rdf::XMetadatable > & i_xElement)
1635 throw (uno::RuntimeException, lang::IllegalArgumentException,
1636 rdf::RepositoryException, std::exception)
1638 if (!i_xElement.is()) {
1639 throw lang::IllegalArgumentException(
1640 "librdf_Repository::getStatementRDFa: Element is null", *this, 0);
1642 const beans::StringPair mdref( i_xElement->getMetadataReference() );
1643 if ((mdref.First.isEmpty()) || (mdref.Second.isEmpty())) {
1644 return beans::Pair< uno::Sequence<rdf::Statement>, sal_Bool >();
1646 OUString const sXmlId(mdref.First + "#" + mdref.Second);
1647 uno::Reference<rdf::XURI> xXmlId;
1648 try {
1649 xXmlId.set( rdf::URI::create(m_xContext, s_nsOOo + sXmlId),
1650 uno::UNO_QUERY_THROW);
1651 } catch (const lang::IllegalArgumentException & iae) {
1652 throw lang::WrappedTargetRuntimeException(
1653 "librdf_Repository::getStatementRDFa: "
1654 "cannot create URI for XML ID", *this, uno::makeAny(iae));
1657 ::std::vector< rdf::Statement > ret;
1660 const uno::Reference<container::XEnumeration> xIter(
1661 getStatementsGraph_NoLock(nullptr, nullptr, nullptr, xXmlId, true) );
1662 OSL_ENSURE(xIter.is(), "getStatementRDFa: no result?");
1663 if (!xIter.is()) throw uno::RuntimeException();
1664 while (xIter->hasMoreElements()) {
1665 rdf::Statement stmt;
1666 if (!(xIter->nextElement() >>= stmt)) {
1667 OSL_FAIL("getStatementRDFa: result of wrong type?");
1668 } else {
1669 ret.push_back(stmt);
1673 catch (const container::NoSuchElementException& e)
1675 throw lang::WrappedTargetRuntimeException(
1676 "librdf_Repository::getStatementRDFa: "
1677 "cannot getStatementsGraph", *this, uno::makeAny(e));
1680 ::osl::MutexGuard g(m_aMutex); // don't call i_x* with mutex locked
1682 return beans::Pair< uno::Sequence<rdf::Statement>, sal_Bool >(
1683 comphelper::containerToSequence(ret), 0 != m_RDFaXHTMLContentSet.count(sXmlId));
1686 extern "C"
1687 librdf_statement *rdfa_context_stream_map_handler(
1688 librdf_stream *i_pStream, void *, librdf_statement *i_pStatement)
1690 OSL_ENSURE(i_pStream, "rdfa_context_stream_map_handler: stream null");
1691 if (i_pStream) {
1692 librdf_node *pCtxt( static_cast<librdf_node *>
1693 #if LIBRDF_VERSION >= 10012
1694 (librdf_stream_get_context2(i_pStream)) );
1695 #else
1696 (librdf_stream_get_context(i_pStream)) );
1697 #endif
1698 OSL_ENSURE(pCtxt, "rdfa_context_stream_map_handler: context null");
1699 if (pCtxt && isInternalContext(pCtxt)) {
1700 return i_pStatement;
1703 return nullptr;
1706 uno::Reference< container::XEnumeration > SAL_CALL
1707 librdf_Repository::getStatementsRDFa(
1708 const uno::Reference< rdf::XResource > & i_xSubject,
1709 const uno::Reference< rdf::XURI > & i_xPredicate,
1710 const uno::Reference< rdf::XNode > & i_xObject)
1711 throw (uno::RuntimeException, rdf::RepositoryException, std::exception)
1713 if (isMetadatableWithoutMetadata(i_xSubject) ||
1714 isMetadatableWithoutMetadata(i_xPredicate) ||
1715 isMetadatableWithoutMetadata(i_xObject))
1717 return new librdf_GraphResult(this, m_aMutex,
1718 std::shared_ptr<librdf_stream>(),
1719 std::shared_ptr<librdf_node>());
1722 librdf_TypeConverter::Statement const stmt(
1723 librdf_TypeConverter::extractStatement_NoLock(
1724 i_xSubject, i_xPredicate, i_xObject));
1726 ::osl::MutexGuard g(m_aMutex); // don't call i_x* with mutex locked
1728 const std::shared_ptr<librdf_statement> pStatement(
1729 librdf_TypeConverter::mkStatement_Lock(m_pWorld.get(), stmt),
1730 safe_librdf_free_statement);
1731 OSL_ENSURE(pStatement, "mkStatement failed");
1733 const std::shared_ptr<librdf_stream> pStream(
1734 librdf_model_find_statements(m_pModel.get(), pStatement.get()),
1735 safe_librdf_free_stream);
1736 if (!pStream) {
1737 throw rdf::RepositoryException(
1738 "librdf_Repository::getStatementsRDFa: "
1739 "librdf_model_find_statements failed", *this);
1742 if (librdf_stream_add_map(pStream.get(), rdfa_context_stream_map_handler,
1743 nullptr, nullptr)) {
1744 throw rdf::RepositoryException(
1745 "librdf_Repository::getStatementsRDFa: "
1746 "librdf_stream_add_map failed", *this);
1749 return new librdf_GraphResult(this, m_aMutex, pStream,
1750 std::shared_ptr<librdf_node>());
1753 // css::lang::XInitialization:
1754 void SAL_CALL librdf_Repository::initialize(
1755 const uno::Sequence< css::uno::Any > & i_rArguments)
1756 throw (uno::RuntimeException, uno::Exception, std::exception)
1758 (void) i_rArguments;
1760 ::osl::MutexGuard g(m_aMutex);
1762 // m_pWorld.reset(m_TypeConverter.createWorld(), safe_librdf_free_world);
1763 m_pStorage.reset(m_TypeConverter.createStorage_Lock(m_pWorld.get()),
1764 safe_librdf_free_storage);
1765 m_pModel.reset(m_TypeConverter.createModel_Lock(
1766 m_pWorld.get(), m_pStorage.get()), safe_librdf_free_model);
1769 const NamedGraphMap_t::iterator librdf_Repository::clearGraph_NoLock(
1770 OUString const& i_rGraphName, bool i_Internal)
1771 // throw (uno::RuntimeException, container::NoSuchElementException,
1772 // rdf::RepositoryException)
1774 ::osl::MutexGuard g(m_aMutex);
1776 return clearGraph_Lock(i_rGraphName, i_Internal);
1779 const NamedGraphMap_t::iterator librdf_Repository::clearGraph_Lock(
1780 OUString const& i_rGraphName, bool i_Internal)
1782 // internal: must be called with mutex locked!
1783 const NamedGraphMap_t::iterator iter( m_NamedGraphs.find(i_rGraphName) );
1784 if (!i_Internal && iter == m_NamedGraphs.end()) {
1785 throw container::NoSuchElementException(
1786 "librdf_Repository::clearGraph: "
1787 "no graph with given URI exists", *this);
1789 const OString context(
1790 OUStringToOString(i_rGraphName, RTL_TEXTENCODING_UTF8) );
1792 const std::shared_ptr<librdf_node> pContext(
1793 librdf_new_node_from_uri_string(m_pWorld.get(),
1794 reinterpret_cast<const unsigned char*> (context.getStr())),
1795 safe_librdf_free_node);
1796 if (!pContext) {
1797 throw uno::RuntimeException(
1798 "librdf_Repository::clearGraph: "
1799 "librdf_new_node_from_uri_string failed", *this);
1801 if (librdf_model_context_remove_statements(m_pModel.get(), pContext.get()))
1803 throw rdf::RepositoryException(
1804 "librdf_Repository::clearGraph: "
1805 "librdf_model_context_remove_statements failed", *this);
1807 return iter;
1810 void librdf_Repository::addStatementGraph_NoLock(
1811 const uno::Reference< rdf::XResource > & i_xSubject,
1812 const uno::Reference< rdf::XURI > & i_xPredicate,
1813 const uno::Reference< rdf::XNode > & i_xObject,
1814 const uno::Reference< rdf::XURI > & i_xGraphName)
1815 //throw (uno::RuntimeException, lang::IllegalArgumentException,
1816 // container::NoSuchElementException, rdf::RepositoryException)
1818 if (!i_xSubject.is()) {
1819 throw lang::IllegalArgumentException(
1820 "librdf_Repository::addStatement: Subject is null", *this, 0);
1822 if (!i_xPredicate.is()) {
1823 throw lang::IllegalArgumentException(
1824 "librdf_Repository::addStatement: Predicate is null",
1825 *this, 1);
1827 if (!i_xObject.is()) {
1828 throw lang::IllegalArgumentException(
1829 "librdf_Repository::addStatement: Object is null", *this, 2);
1832 librdf_TypeConverter::Statement const stmt(
1833 librdf_TypeConverter::extractStatement_NoLock(
1834 i_xSubject, i_xPredicate, i_xObject));
1836 const OUString contextU( i_xGraphName->getStringValue() );
1838 ::osl::MutexGuard g(m_aMutex); // don't call i_x* with mutex locked
1840 addStatementGraph_Lock(stmt, contextU, false/*i_Internal*/);
1843 void librdf_Repository::addStatementGraph_Lock(
1844 librdf_TypeConverter::Statement const& i_rStatement,
1845 OUString const& i_rGraphName,
1846 bool i_Internal)
1848 if (!i_Internal
1849 && (m_NamedGraphs.find(i_rGraphName) == m_NamedGraphs.end()))
1851 throw container::NoSuchElementException(
1852 "librdf_Repository::addStatement: "
1853 "no graph with given URI exists", *this);
1855 const OString context(
1856 OUStringToOString(i_rGraphName, RTL_TEXTENCODING_UTF8) );
1858 const std::shared_ptr<librdf_node> pContext(
1859 librdf_new_node_from_uri_string(m_pWorld.get(),
1860 reinterpret_cast<const unsigned char*> (context.getStr())),
1861 safe_librdf_free_node);
1862 if (!pContext) {
1863 throw uno::RuntimeException(
1864 "librdf_Repository::addStatement: "
1865 "librdf_new_node_from_uri_string failed", *this);
1867 const std::shared_ptr<librdf_statement> pStatement(
1868 librdf_TypeConverter::mkStatement_Lock(m_pWorld.get(), i_rStatement),
1869 safe_librdf_free_statement);
1870 OSL_ENSURE(pStatement, "mkStatement failed");
1872 // Test for duplicate statement
1873 // librdf_model_add_statement disallows duplicates while
1874 // librdf_model_context_add_statement allows duplicates
1876 const std::shared_ptr<librdf_stream> pStream(
1877 librdf_model_find_statements_in_context(m_pModel.get(),
1878 pStatement.get(), pContext.get()),
1879 safe_librdf_free_stream);
1880 if (pStream && !librdf_stream_end(pStream.get()))
1881 return;
1884 if (librdf_model_context_add_statement(m_pModel.get(),
1885 pContext.get(), pStatement.get())) {
1886 throw rdf::RepositoryException(
1887 "librdf_Repository::addStatement: "
1888 "librdf_model_context_add_statement failed", *this);
1892 void librdf_Repository::removeStatementsGraph_NoLock(
1893 const uno::Reference< rdf::XResource > & i_xSubject,
1894 const uno::Reference< rdf::XURI > & i_xPredicate,
1895 const uno::Reference< rdf::XNode > & i_xObject,
1896 const uno::Reference< rdf::XURI > & i_xGraphName)
1897 //throw (uno::RuntimeException, lang::IllegalArgumentException,
1898 // container::NoSuchElementException, rdf::RepositoryException)
1900 if (isMetadatableWithoutMetadata(i_xSubject) ||
1901 isMetadatableWithoutMetadata(i_xPredicate) ||
1902 isMetadatableWithoutMetadata(i_xObject))
1904 return;
1907 librdf_TypeConverter::Statement const stmt(
1908 librdf_TypeConverter::extractStatement_NoLock(
1909 i_xSubject, i_xPredicate, i_xObject));
1910 const OUString contextU( i_xGraphName->getStringValue() );
1912 ::osl::MutexGuard g(m_aMutex); // don't call i_x* with mutex locked
1914 if (m_NamedGraphs.find(contextU) == m_NamedGraphs.end()) {
1915 throw container::NoSuchElementException(
1916 "librdf_Repository::removeStatements: "
1917 "no graph with given URI exists", *this);
1919 const OString context(
1920 OUStringToOString(contextU, RTL_TEXTENCODING_UTF8) );
1922 const std::shared_ptr<librdf_node> pContext(
1923 librdf_new_node_from_uri_string(m_pWorld.get(),
1924 reinterpret_cast<const unsigned char*> (context.getStr())),
1925 safe_librdf_free_node);
1926 if (!pContext) {
1927 throw uno::RuntimeException(
1928 "librdf_Repository::removeStatements: "
1929 "librdf_new_node_from_uri_string failed", *this);
1931 const std::shared_ptr<librdf_statement> pStatement(
1932 librdf_TypeConverter::mkStatement_Lock(m_pWorld.get(), stmt),
1933 safe_librdf_free_statement);
1934 OSL_ENSURE(pStatement, "mkStatement failed");
1936 const std::shared_ptr<librdf_stream> pStream(
1937 librdf_model_find_statements_in_context(m_pModel.get(),
1938 pStatement.get(), pContext.get()),
1939 safe_librdf_free_stream);
1940 if (!pStream) {
1941 throw rdf::RepositoryException(
1942 "librdf_Repository::removeStatements: "
1943 "librdf_model_find_statements_in_context failed", *this);
1946 if (!librdf_stream_end(pStream.get())) {
1947 do {
1948 librdf_statement *pStmt( librdf_stream_get_object(pStream.get()) );
1949 if (!pStmt) {
1950 throw rdf::RepositoryException(
1951 "librdf_Repository::removeStatements: "
1952 "librdf_stream_get_object failed", *this);
1954 if (librdf_model_context_remove_statement(m_pModel.get(),
1955 pContext.get(), pStmt)) {
1956 throw rdf::RepositoryException(
1957 "librdf_Repository::removeStatements: "
1958 "librdf_model_context_remove_statement failed", *this);
1960 } while (!librdf_stream_next(pStream.get()));
1964 uno::Reference< container::XEnumeration >
1965 librdf_Repository::getStatementsGraph_NoLock(
1966 const uno::Reference< rdf::XResource > & i_xSubject,
1967 const uno::Reference< rdf::XURI > & i_xPredicate,
1968 const uno::Reference< rdf::XNode > & i_xObject,
1969 const uno::Reference< rdf::XURI > & i_xGraphName,
1970 bool i_Internal)
1971 //throw (uno::RuntimeException, lang::IllegalArgumentException,
1972 // container::NoSuchElementException, rdf::RepositoryException)
1974 // N.B.: if any of subject, predicate, object is an XMetadatable, and
1975 // has no metadata reference, then there cannot be any node in the graph
1976 // representing it; in order to prevent side effect
1977 // (ensureMetadataReference), check for this condition and return
1978 if (isMetadatableWithoutMetadata(i_xSubject) ||
1979 isMetadatableWithoutMetadata(i_xPredicate) ||
1980 isMetadatableWithoutMetadata(i_xObject))
1982 return new librdf_GraphResult(this, m_aMutex,
1983 std::shared_ptr<librdf_stream>(),
1984 std::shared_ptr<librdf_node>());
1987 librdf_TypeConverter::Statement const stmt(
1988 librdf_TypeConverter::extractStatement_NoLock(
1989 i_xSubject, i_xPredicate, i_xObject));
1990 const OUString contextU( i_xGraphName->getStringValue() );
1992 ::osl::MutexGuard g(m_aMutex); // don't call i_x* with mutex locked
1994 if (!i_Internal && (m_NamedGraphs.find(contextU) == m_NamedGraphs.end())) {
1995 throw container::NoSuchElementException(
1996 "librdf_Repository::getStatements: "
1997 "no graph with given URI exists", *this);
1999 const OString context(
2000 OUStringToOString(contextU, RTL_TEXTENCODING_UTF8) );
2002 const std::shared_ptr<librdf_node> pContext(
2003 librdf_new_node_from_uri_string(m_pWorld.get(),
2004 reinterpret_cast<const unsigned char*> (context.getStr())),
2005 safe_librdf_free_node);
2006 if (!pContext) {
2007 throw uno::RuntimeException(
2008 "librdf_Repository::getStatements: "
2009 "librdf_new_node_from_uri_string failed", *this);
2011 const std::shared_ptr<librdf_statement> pStatement(
2012 librdf_TypeConverter::mkStatement_Lock(m_pWorld.get(), stmt),
2013 safe_librdf_free_statement);
2014 OSL_ENSURE(pStatement, "mkStatement failed");
2016 const std::shared_ptr<librdf_stream> pStream(
2017 librdf_model_find_statements_in_context(m_pModel.get(),
2018 pStatement.get(), pContext.get()),
2019 safe_librdf_free_stream);
2020 if (!pStream) {
2021 throw rdf::RepositoryException(
2022 "librdf_Repository::getStatements: "
2023 "librdf_model_find_statements_in_context failed", *this);
2026 // librdf_model_find_statements_in_context is buggy and does not put
2027 // the context into result statements; pass it to librdf_GraphResult here
2028 return new librdf_GraphResult(this, m_aMutex, pStream, pContext);
2031 extern "C"
2032 void librdf_raptor_init(void* /*user_data*/, raptor_world* pRaptorWorld)
2034 // fdo#64672 prevent raptor from setting global libxml2 error handlers
2035 raptor_world_set_flag(pRaptorWorld,
2036 RAPTOR_WORLD_FLAG_LIBXML_STRUCTURED_ERROR_SAVE, 0);
2037 raptor_world_set_flag(pRaptorWorld,
2038 RAPTOR_WORLD_FLAG_LIBXML_GENERIC_ERROR_SAVE, 0);
2041 librdf_world *librdf_TypeConverter::createWorld_Lock() const
2043 // create and initialize world
2044 librdf_world *pWorld( librdf_new_world() );
2045 if (!pWorld) {
2046 throw uno::RuntimeException(
2047 "librdf_TypeConverter::createWorld: librdf_new_world failed",
2048 m_rRep);
2050 librdf_world_set_raptor_init_handler(pWorld, nullptr, &librdf_raptor_init);
2051 //FIXME logger, digest, features?
2052 xsltSecurityPrefsPtr origprefs = xsltGetDefaultSecurityPrefs();
2053 librdf_world_open(pWorld);
2054 xsltSecurityPrefsPtr newprefs = xsltGetDefaultSecurityPrefs();
2055 if (newprefs != origprefs) {
2056 // #i110523# restore libxslt global configuration
2057 // (gratuitously overwritten by raptor_init_parser_grddl_common)
2058 // (this is the only reason unordf is linked against libxslt)
2059 xsltSetDefaultSecurityPrefs(origprefs);
2061 return pWorld;
2064 librdf_storage *
2065 librdf_TypeConverter::createStorage_Lock(librdf_world *i_pWorld) const
2067 librdf_storage *pStorage(
2068 // librdf_new_storage(i_pWorld, "memory", NULL, "contexts='yes'") );
2069 librdf_new_storage(i_pWorld, "hashes", nullptr,
2070 "contexts='yes',hash-type='memory'") );
2071 if (!pStorage) {
2072 throw uno::RuntimeException(
2073 "librdf_TypeConverter::createStorage: librdf_new_storage failed",
2074 m_rRep);
2076 return pStorage;
2079 librdf_model *librdf_TypeConverter::createModel_Lock(
2080 librdf_world *i_pWorld, librdf_storage * i_pStorage) const
2082 librdf_model *pRepository( librdf_new_model(i_pWorld, i_pStorage, nullptr) );
2083 if (!pRepository) {
2084 throw uno::RuntimeException(
2085 "librdf_TypeConverter::createModel: librdf_new_model failed",
2086 m_rRep);
2088 //FIXME
2089 #if 0
2091 librdf_uri * ctxt = librdf_new_uri(i_pWorld, reinterpret_cast<const unsigned char *>(LIBRDF_MODEL_FEATURE_CONTEXTS));
2092 librdf_node * contexts = librdf_model_get_feature(repository, ctxt);
2093 if (!contexts)
2094 throw;
2095 std::cout << "value of contexts feature: ";
2096 prtNode(contexts);
2097 std::cout << std::endl;
2098 // librdf_model_set_feature(repository, LIBRDF_FEATURE_CONTEXTS, ...);
2099 safe_librdf_free_node(contexts);
2100 safe_librdf_free_uri(ctxt);
2102 #endif
2103 return pRepository;
2106 // this does NOT create a node, only URI
2107 librdf_uri* librdf_TypeConverter::mkURI_Lock( librdf_world* i_pWorld,
2108 OString const& i_rURI)
2110 librdf_uri *pURI( librdf_new_uri(i_pWorld,
2111 reinterpret_cast<const unsigned char *>(i_rURI.getStr())));
2112 if (!pURI) {
2113 throw uno::RuntimeException(
2114 "librdf_TypeConverter::mkURI: librdf_new_uri failed", nullptr);
2116 return pURI;
2119 // extract blank or URI node - call without Mutex locked
2120 std::shared_ptr<librdf_TypeConverter::Resource>
2121 librdf_TypeConverter::extractResource_NoLock(
2122 const uno::Reference< rdf::XResource > & i_xResource)
2124 if (!i_xResource.is()) {
2125 return std::shared_ptr<Resource>();
2127 uno::Reference< rdf::XBlankNode > xBlankNode(i_xResource, uno::UNO_QUERY);
2128 if (xBlankNode.is()) {
2129 const OString label(
2130 OUStringToOString(xBlankNode->getStringValue(),
2131 RTL_TEXTENCODING_UTF8) );
2132 return std::shared_ptr<Resource>(new BlankNode(label));
2133 } else { // assumption: everything else is URI
2134 const OString uri(
2135 OUStringToOString(i_xResource->getStringValue(),
2136 RTL_TEXTENCODING_UTF8) );
2137 return std::shared_ptr<Resource>(new URI(uri));
2141 // create blank or URI node
2142 librdf_node* librdf_TypeConverter::mkResource_Lock( librdf_world* i_pWorld,
2143 Resource const*const i_pResource)
2145 if (!i_pResource) return nullptr;
2146 BlankNode const*const pBlankNode(
2147 dynamic_cast<BlankNode const*>(i_pResource));
2148 if (pBlankNode) {
2149 librdf_node *pNode(
2150 librdf_new_node_from_blank_identifier(i_pWorld,
2151 reinterpret_cast<const unsigned char*>(
2152 pBlankNode->value.getStr())));
2153 if (!pNode) {
2154 throw uno::RuntimeException(
2155 "librdf_TypeConverter::mkResource: "
2156 "librdf_new_node_from_blank_identifier failed", nullptr);
2158 return pNode;
2159 } else { // assumption: everything else is URI
2160 URI const*const pURI(dynamic_cast<URI const*>(i_pResource));
2161 assert(pURI);
2162 librdf_node *pNode(
2163 librdf_new_node_from_uri_string(i_pWorld,
2164 reinterpret_cast<const unsigned char*>(pURI->value.getStr())));
2165 if (!pNode) {
2166 throw uno::RuntimeException(
2167 "librdf_TypeConverter::mkResource: "
2168 "librdf_new_node_from_uri_string failed", nullptr);
2170 return pNode;
2174 // extract blank or URI or literal node - call without Mutex locked
2175 std::shared_ptr<librdf_TypeConverter::Node>
2176 librdf_TypeConverter::extractNode_NoLock(
2177 const uno::Reference< rdf::XNode > & i_xNode)
2179 if (!i_xNode.is()) {
2180 return std::shared_ptr<Node>();
2182 uno::Reference< rdf::XResource > xResource(i_xNode, uno::UNO_QUERY);
2183 if (xResource.is()) {
2184 return extractResource_NoLock(xResource);
2186 uno::Reference< rdf::XLiteral> xLiteral(i_xNode, uno::UNO_QUERY);
2187 OSL_ENSURE(xLiteral.is(),
2188 "mkNode: someone invented a new rdf.XNode and did not tell me");
2189 if (!xLiteral.is()) {
2190 return std::shared_ptr<Node>();
2192 const OString val(
2193 OUStringToOString(xLiteral->getValue(),
2194 RTL_TEXTENCODING_UTF8) );
2195 const OString lang(
2196 OUStringToOString(xLiteral->getLanguage(),
2197 RTL_TEXTENCODING_UTF8) );
2198 const uno::Reference< rdf::XURI > xType(xLiteral->getDatatype());
2199 boost::optional<OString> type;
2200 if (xType.is())
2202 type =
2203 OUStringToOString(xType->getStringValue(), RTL_TEXTENCODING_UTF8);
2205 return std::shared_ptr<Node>(new Literal(val, lang, type));
2208 // create blank or URI or literal node
2209 librdf_node* librdf_TypeConverter::mkNode_Lock( librdf_world* i_pWorld,
2210 Node const*const i_pNode)
2212 if (!i_pNode) return nullptr;
2213 Resource const*const pResource(dynamic_cast<Resource const*>(i_pNode));
2214 if (pResource) {
2215 return mkResource_Lock(i_pWorld, pResource);
2218 Literal const*const pLiteral(dynamic_cast<Literal const*>(i_pNode));
2219 assert(pLiteral);
2220 librdf_node * ret(nullptr);
2221 if (pLiteral->language.isEmpty()) {
2222 if (!pLiteral->type) {
2223 ret = librdf_new_node_from_literal(i_pWorld,
2224 reinterpret_cast<const unsigned char*>(pLiteral->value.getStr())
2225 , nullptr, 0);
2226 } else {
2227 const std::shared_ptr<librdf_uri> pDatatype(
2228 mkURI_Lock(i_pWorld, *pLiteral->type),
2229 safe_librdf_free_uri);
2230 ret = librdf_new_node_from_typed_literal(i_pWorld,
2231 reinterpret_cast<const unsigned char*>(pLiteral->value.getStr())
2232 , nullptr, pDatatype.get());
2234 } else {
2235 if (!pLiteral->type) {
2236 ret = librdf_new_node_from_literal(i_pWorld,
2237 reinterpret_cast<const unsigned char*>(pLiteral->value.getStr())
2238 , pLiteral->language.getStr(), 0);
2239 } else {
2240 OSL_FAIL("mkNode: invalid literal");
2241 return nullptr;
2244 if (!ret) {
2245 throw uno::RuntimeException(
2246 "librdf_TypeConverter::mkNode: librdf_new_node_from_literal failed", nullptr);
2248 return ret;
2251 // extract statement - call without Mutex locked
2252 librdf_TypeConverter::Statement librdf_TypeConverter::extractStatement_NoLock(
2253 const uno::Reference< rdf::XResource > & i_xSubject,
2254 const uno::Reference< rdf::XURI > & i_xPredicate,
2255 const uno::Reference< rdf::XNode > & i_xObject)
2257 std::shared_ptr<Resource> const pSubject(
2258 extractResource_NoLock(i_xSubject));
2259 const uno::Reference<rdf::XResource> xPredicate(i_xPredicate,
2260 uno::UNO_QUERY);
2261 std::shared_ptr<URI> const pPredicate(
2262 std::dynamic_pointer_cast<URI>(extractResource_NoLock(xPredicate)));
2263 std::shared_ptr<Node> const pObject(extractNode_NoLock(i_xObject));
2264 return Statement(pSubject, pPredicate, pObject);
2267 librdf_statement* librdf_TypeConverter::mkStatement_Lock(librdf_world* i_pWorld,
2268 Statement const& i_rStatement)
2270 librdf_node *const pSubject(
2271 mkResource_Lock(i_pWorld, i_rStatement.pSubject.get()) );
2272 librdf_node* pPredicate(nullptr);
2273 librdf_node* pObject(nullptr);
2274 try {
2275 pPredicate = mkResource_Lock(i_pWorld, i_rStatement.pPredicate.get());
2276 try {
2277 pObject = mkNode_Lock(i_pWorld, i_rStatement.pObject.get());
2278 } catch (...) {
2279 safe_librdf_free_node(pPredicate);
2280 throw;
2282 } catch (...) {
2283 safe_librdf_free_node(pSubject);
2284 throw;
2286 // NB: this takes ownership of the nodes! (which is really ugly)
2287 librdf_statement* pStatement( librdf_new_statement_from_nodes(i_pWorld,
2288 pSubject, pPredicate, pObject) );
2289 if (!pStatement) {
2290 throw uno::RuntimeException(
2291 "librdf_TypeConverter::mkStatement: "
2292 "librdf_new_statement_from_nodes failed", nullptr);
2294 return pStatement;
2297 uno::Reference<rdf::XURI>
2298 librdf_TypeConverter::convertToXURI(librdf_uri* i_pURI) const
2300 if (!i_pURI) return nullptr;
2301 const unsigned char* uri( librdf_uri_as_string(i_pURI) );
2302 if (!uri) {
2303 throw uno::RuntimeException(
2304 "librdf_TypeConverter::convertToXURI: "
2305 "librdf_uri_as_string failed", m_rRep);
2307 OUString uriU( OStringToOUString(
2308 OString(reinterpret_cast<const sal_Char*>(uri)),
2309 RTL_TEXTENCODING_UTF8) );
2310 try {
2311 return rdf::URI::create(m_xContext, uriU);
2312 } catch (const lang::IllegalArgumentException & iae) {
2313 throw lang::WrappedTargetRuntimeException(
2314 "librdf_TypeConverter::convertToXURI: "
2315 "illegal uri", m_rRep, uno::makeAny(iae));
2319 uno::Reference<rdf::XURI>
2320 librdf_TypeConverter::convertToXURI(librdf_node* i_pNode) const
2322 if (!i_pNode) return nullptr;
2323 if (librdf_node_is_resource(i_pNode)) {
2324 librdf_uri* pURI( librdf_node_get_uri(i_pNode) );
2325 if (!pURI) {
2326 throw uno::RuntimeException(
2327 "librdf_TypeConverter::convertToXURI: "
2328 "resource has no uri", m_rRep);
2330 return convertToXURI(pURI);
2331 } else {
2332 OSL_FAIL("convertToXURI: unknown librdf_node");
2333 return nullptr;
2337 uno::Reference<rdf::XResource>
2338 librdf_TypeConverter::convertToXResource(librdf_node* i_pNode) const
2340 if (!i_pNode) return nullptr;
2341 if (librdf_node_is_blank(i_pNode)) {
2342 const unsigned char* label( librdf_node_get_blank_identifier(i_pNode) );
2343 if (!label) {
2344 throw uno::RuntimeException(
2345 "librdf_TypeConverter::convertToXResource: "
2346 "blank node has no label", m_rRep);
2348 OUString labelU( OStringToOUString(
2349 OString(reinterpret_cast<const sal_Char*>(label)),
2350 RTL_TEXTENCODING_UTF8) );
2351 try {
2352 return uno::Reference<rdf::XResource>(
2353 rdf::BlankNode::create(m_xContext, labelU), uno::UNO_QUERY);
2354 } catch (const lang::IllegalArgumentException & iae) {
2355 throw lang::WrappedTargetRuntimeException(
2356 "librdf_TypeConverter::convertToXResource: "
2357 "illegal blank node label", m_rRep, uno::makeAny(iae));
2359 } else {
2360 return uno::Reference<rdf::XResource>(convertToXURI(i_pNode),
2361 uno::UNO_QUERY);
2365 uno::Reference<rdf::XNode>
2366 librdf_TypeConverter::convertToXNode(librdf_node* i_pNode) const
2368 if (!i_pNode) return nullptr;
2369 if (!librdf_node_is_literal(i_pNode)) {
2370 return uno::Reference<rdf::XNode>(convertToXResource(i_pNode),
2371 uno::UNO_QUERY);
2373 const unsigned char* value( librdf_node_get_literal_value(i_pNode) );
2374 if (!value) {
2375 throw uno::RuntimeException(
2376 "librdf_TypeConverter::convertToXNode: "
2377 "literal has no value", m_rRep);
2379 const char * lang( librdf_node_get_literal_value_language(i_pNode) );
2380 librdf_uri* pType(
2381 librdf_node_get_literal_value_datatype_uri(i_pNode) );
2382 OSL_ENSURE(!lang || !pType, "convertToXNode: invalid literal");
2383 const OUString valueU( OStringToOUString(
2384 OString(reinterpret_cast<const sal_Char*>(value)),
2385 RTL_TEXTENCODING_UTF8) );
2386 if (lang) {
2387 const OUString langU( OStringToOUString(
2388 OString(reinterpret_cast<const sal_Char*>(lang)),
2389 RTL_TEXTENCODING_UTF8) );
2390 return uno::Reference<rdf::XNode>(
2391 rdf::Literal::createWithLanguage(m_xContext, valueU, langU),
2392 uno::UNO_QUERY);
2393 } else if (pType) {
2394 uno::Reference<rdf::XURI> xType(convertToXURI(pType));
2395 OSL_ENSURE(xType.is(), "convertToXNode: null uri");
2396 return uno::Reference<rdf::XNode>(
2397 rdf::Literal::createWithType(m_xContext, valueU, xType),
2398 uno::UNO_QUERY);
2399 } else {
2400 return uno::Reference<rdf::XNode>(
2401 rdf::Literal::create(m_xContext, valueU),
2402 uno::UNO_QUERY);
2406 rdf::Statement
2407 librdf_TypeConverter::convertToStatement(librdf_statement* i_pStmt,
2408 librdf_node* i_pContext) const
2410 if (!i_pStmt) {
2411 throw uno::RuntimeException();
2413 return rdf::Statement(
2414 convertToXResource(librdf_statement_get_subject(i_pStmt)),
2415 convertToXURI(librdf_statement_get_predicate(i_pStmt)),
2416 convertToXNode(librdf_statement_get_object(i_pStmt)),
2417 convertToXURI(i_pContext));
2420 } // closing anonymous implementation namespace
2423 // component helper namespace
2424 namespace comp_librdf_Repository {
2426 OUString SAL_CALL _getImplementationName() {
2427 return OUString("librdf_Repository");
2430 uno::Sequence< OUString > SAL_CALL _getSupportedServiceNames()
2432 uno::Sequence< OUString > s { "com.sun.star.rdf.Repository" };
2433 return s;
2436 uno::Reference< uno::XInterface > SAL_CALL _create(
2437 const uno::Reference< uno::XComponentContext > & context)
2439 return static_cast< ::cppu::OWeakObject * >(new librdf_Repository(context));
2442 } // closing component helper namespace
2444 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */