Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "librdf_repository.hxx"
21 :
22 : #include <string.h>
23 :
24 : #include <set>
25 : #include <map>
26 : #include <functional>
27 : #include <algorithm>
28 :
29 : #include <boost/utility.hpp>
30 : #include <boost/shared_ptr.hpp>
31 : #include <boost/shared_array.hpp>
32 : #include <boost/bind.hpp>
33 :
34 : #include <libxslt/security.h>
35 :
36 : #include <redland.h>
37 :
38 : #include <com/sun/star/lang/XServiceInfo.hpp>
39 : #include <com/sun/star/lang/XInitialization.hpp>
40 : #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
41 : #include <com/sun/star/lang/IllegalArgumentException.hpp>
42 : #include <com/sun/star/io/XSeekableInputStream.hpp>
43 : #include <com/sun/star/text/XTextRange.hpp>
44 : #include <com/sun/star/rdf/XDocumentRepository.hpp>
45 : #include <com/sun/star/rdf/XLiteral.hpp>
46 : #include <com/sun/star/rdf/FileFormat.hpp>
47 : #include <com/sun/star/rdf/URIs.hpp>
48 : #include <com/sun/star/rdf/BlankNode.hpp>
49 : #include <com/sun/star/rdf/URI.hpp>
50 : #include <com/sun/star/rdf/Literal.hpp>
51 :
52 : #include <rtl/ref.hxx>
53 : #include <rtl/ustring.hxx>
54 : #include <cppuhelper/implbase1.hxx>
55 : #include <cppuhelper/implbase3.hxx>
56 : #include <cppuhelper/basemutex.hxx>
57 :
58 : #include <comphelper/stlunosequence.hxx>
59 : #include <comphelper/sequenceasvector.hxx>
60 : #include <comphelper/makesequence.hxx>
61 : #include <comphelper/xmltools.hxx>
62 :
63 : #include <com/sun/star/embed/XEncryptionProtectedSource2.hpp>
64 :
65 : /**
66 : Implementation of the service com.sun.star.rdf.Repository.
67 :
68 : This implementation uses the Redland RDF library (librdf).
69 :
70 : There are several classes involved:
71 : librdf_TypeConverter: helper class to convert data types redland <-> uno
72 : librdf_Repository: the main repository, does almost all the work
73 : librdf_NamedGraph: the XNamedGraph, forwards everything to repository
74 : librdf_GraphResult: an XEnumeration<Statement>
75 : librdf_QuerySelectResult: an XEnumeration<sequence<XNode>>
76 :
77 : @author mst
78 : */
79 :
80 : /// anonymous implementation namespace
81 : namespace {
82 :
83 : class librdf_NamedGraph;
84 : class librdf_Repository;
85 :
86 : using namespace ::com::sun::star;
87 :
88 : typedef std::map< OUString, ::rtl::Reference<librdf_NamedGraph> >
89 : NamedGraphMap_t;
90 :
91 : const char s_sparql [] = "sparql";
92 : const char s_nsRDFs [] = "http://www.w3.org/2000/01/rdf-schema#";
93 : const char s_label [] = "label";
94 : const char s_nsOOo [] = "http://openoffice.org/2004/office/rdfa/";
95 :
96 : ////////////////////////////////////////////////////////////////////////////
97 :
98 : //FIXME: this approach is not ideal. can we use blind nodes instead?
99 301 : bool isInternalContext(librdf_node *i_pNode) throw ()
100 : {
101 : OSL_ENSURE(i_pNode, "isInternalContext: context null");
102 : OSL_ENSURE(librdf_node_is_resource(i_pNode),
103 : "isInternalContext: context not resource");
104 301 : if (i_pNode) {
105 301 : librdf_uri *pURI(librdf_node_get_uri(i_pNode));
106 : OSL_ENSURE(pURI, "isInternalContext: URI null");
107 301 : if (pURI) {
108 301 : unsigned char *pContextURI(librdf_uri_as_string(pURI));
109 : OSL_ENSURE(pContextURI,
110 : "isInternalContext: URI string null");
111 : // if prefix matches reserved uri, it is RDFa context
112 301 : if (!strncmp(reinterpret_cast<char *>(pContextURI),
113 301 : s_nsOOo, sizeof(s_nsOOo)-1)) {
114 61 : return true;
115 : }
116 : }
117 240 : return false;
118 : }
119 0 : return true;
120 : }
121 :
122 :
123 : ////////////////////////////////////////////////////////////////////////////
124 :
125 : // n.b.: librdf destructor functions dereference null pointers!
126 : // so they need to be wrapped to be usable with boost::shared_ptr.
127 30 : static void safe_librdf_free_world(librdf_world *const world)
128 : {
129 30 : if (world) { librdf_free_world(world); }
130 30 : }
131 200 : static void safe_librdf_free_model(librdf_model *const model)
132 : {
133 200 : if (model) { librdf_free_model(model); }
134 200 : }
135 930 : static void safe_librdf_free_node(librdf_node* node)
136 : {
137 930 : if (node) { librdf_free_node(node); }
138 930 : }
139 35 : static void safe_librdf_free_parser(librdf_parser *const parser)
140 : {
141 35 : if (parser) { librdf_free_parser(parser); }
142 35 : }
143 8 : static void safe_librdf_free_query(librdf_query *const query)
144 : {
145 8 : if (query) { librdf_free_query(query); }
146 8 : }
147 : static void
148 8 : safe_librdf_free_query_results(librdf_query_results *const query_results)
149 : {
150 8 : if (query_results) { librdf_free_query_results(query_results); }
151 8 : }
152 20 : static void safe_librdf_free_serializer(librdf_serializer *const serializer)
153 : {
154 20 : if (serializer) { librdf_free_serializer(serializer); }
155 20 : }
156 885 : static void safe_librdf_free_statement(librdf_statement *const statement)
157 : {
158 885 : if (statement) { librdf_free_statement(statement); }
159 885 : }
160 200 : static void safe_librdf_free_storage(librdf_storage *const storage)
161 : {
162 200 : if (storage) { librdf_free_storage(storage); }
163 200 : }
164 941 : static void safe_librdf_free_stream(librdf_stream *const stream)
165 : {
166 941 : if (stream) { librdf_free_stream(stream); }
167 941 : }
168 107 : static void safe_librdf_free_uri(librdf_uri *const uri)
169 : {
170 107 : if (uri) { librdf_free_uri(uri); }
171 107 : }
172 :
173 :
174 : ////////////////////////////////////////////////////////////////////////////
175 :
176 : /** converts between librdf types and UNO API types.
177 : */
178 96 : class librdf_TypeConverter
179 : {
180 : public:
181 104 : librdf_TypeConverter(
182 : uno::Reference< uno::XComponentContext > const & i_xContext,
183 : librdf_Repository &i_rRep)
184 : : m_xContext(i_xContext)
185 104 : , m_rRep(i_rRep)
186 104 : { };
187 :
188 : librdf_world *createWorld() const;
189 : librdf_storage *createStorage(librdf_world *i_pWorld) const;
190 : librdf_model *createModel(librdf_world *i_pWorld,
191 : librdf_storage * i_pStorage) const;
192 : librdf_uri* mkURI( librdf_world* i_pWorld,
193 : const uno::Reference< rdf::XURI > & i_xURI) const;
194 : librdf_node* mkResource( librdf_world* i_pWorld,
195 : const uno::Reference< rdf::XResource > & i_xResource) const;
196 : librdf_node* mkNode( librdf_world* i_pWorld,
197 : const uno::Reference< rdf::XNode > & i_xNode) const;
198 : librdf_statement* mkStatement( librdf_world* i_pWorld,
199 : const uno::Reference< rdf::XResource > & i_xSubject,
200 : const uno::Reference< rdf::XURI > & i_xPredicate,
201 : const uno::Reference< rdf::XNode > & i_xObject) const;
202 : uno::Reference<rdf::XURI> convertToXURI(librdf_uri* i_pURI) const;
203 : uno::Reference<rdf::XURI> convertToXURI(librdf_node* i_pURI) const;
204 : uno::Reference<rdf::XResource>
205 : convertToXResource(librdf_node* i_pNode) const;
206 : uno::Reference<rdf::XNode> convertToXNode(librdf_node* i_pNode) const;
207 : rdf::Statement
208 : convertToStatement(librdf_statement* i_pStmt, librdf_node* i_pContext)
209 : const;
210 :
211 : private:
212 : uno::Reference< uno::XComponentContext > m_xContext;
213 : librdf_Repository & m_rRep;
214 : };
215 :
216 :
217 : ////////////////////////////////////////////////////////////////////////////
218 :
219 : /** implements the repository service.
220 : */
221 : class librdf_Repository:
222 : private boost::noncopyable,
223 : // private ::cppu::BaseMutex,
224 : public ::cppu::WeakImplHelper3<
225 : lang::XServiceInfo,
226 : rdf::XDocumentRepository,
227 : lang::XInitialization>
228 : {
229 : public:
230 :
231 : explicit librdf_Repository(
232 : uno::Reference< uno::XComponentContext > const & i_xContext);
233 : virtual ~librdf_Repository();
234 :
235 : // ::com::sun::star::lang::XServiceInfo:
236 : virtual OUString SAL_CALL getImplementationName()
237 : throw (uno::RuntimeException);
238 : virtual ::sal_Bool SAL_CALL supportsService(
239 : const OUString & ServiceName) throw (uno::RuntimeException);
240 : virtual uno::Sequence< OUString > SAL_CALL
241 : getSupportedServiceNames() throw (uno::RuntimeException);
242 :
243 : // ::com::sun::star::rdf::XRepository:
244 : virtual uno::Reference< rdf::XBlankNode > SAL_CALL createBlankNode()
245 : throw (uno::RuntimeException);
246 : virtual uno::Reference<rdf::XNamedGraph> SAL_CALL importGraph(
247 : ::sal_Int16 i_Format,
248 : const uno::Reference< io::XInputStream > & i_xInStream,
249 : const uno::Reference< rdf::XURI > & i_xGraphName,
250 : const uno::Reference< rdf::XURI > & i_xBaseURI)
251 : throw (uno::RuntimeException, lang::IllegalArgumentException,
252 : datatransfer::UnsupportedFlavorException,
253 : container::ElementExistException, rdf::ParseException,
254 : rdf::RepositoryException, io::IOException);
255 : virtual void SAL_CALL exportGraph(::sal_Int16 i_Format,
256 : const uno::Reference< io::XOutputStream > & i_xOutStream,
257 : const uno::Reference< rdf::XURI > & i_xGraphName,
258 : const uno::Reference< rdf::XURI > & i_xBaseURI)
259 : throw (uno::RuntimeException, lang::IllegalArgumentException,
260 : datatransfer::UnsupportedFlavorException,
261 : container::NoSuchElementException, rdf::RepositoryException,
262 : io::IOException);
263 : virtual uno::Sequence< uno::Reference< rdf::XURI > > SAL_CALL
264 : getGraphNames() throw (uno::RuntimeException, rdf::RepositoryException);
265 : virtual uno::Reference< rdf::XNamedGraph > SAL_CALL getGraph(
266 : const uno::Reference< rdf::XURI > & i_xGraphName)
267 : throw (uno::RuntimeException, lang::IllegalArgumentException,
268 : rdf::RepositoryException);
269 : virtual uno::Reference< rdf::XNamedGraph > SAL_CALL createGraph(
270 : const uno::Reference< rdf::XURI > & i_xGraphName)
271 : throw (uno::RuntimeException, lang::IllegalArgumentException,
272 : container::ElementExistException, rdf::RepositoryException);
273 : virtual void SAL_CALL destroyGraph(
274 : const uno::Reference< rdf::XURI > & i_xGraphName)
275 : throw (uno::RuntimeException, lang::IllegalArgumentException,
276 : container::NoSuchElementException, rdf::RepositoryException);
277 : virtual uno::Reference< container::XEnumeration > SAL_CALL getStatements(
278 : const uno::Reference< rdf::XResource > & i_xSubject,
279 : const uno::Reference< rdf::XURI > & i_xPredicate,
280 : const uno::Reference< rdf::XNode > & i_xObject)
281 : throw (uno::RuntimeException,
282 : rdf::RepositoryException);
283 : virtual uno::Reference< rdf::XQuerySelectResult > SAL_CALL
284 : querySelect(const OUString & i_rQuery)
285 : throw (uno::RuntimeException, rdf::QueryException,
286 : rdf::RepositoryException);
287 : virtual uno::Reference< container::XEnumeration > SAL_CALL
288 : queryConstruct(const OUString & i_rQuery)
289 : throw (uno::RuntimeException, rdf::QueryException,
290 : rdf::RepositoryException);
291 : virtual ::sal_Bool SAL_CALL queryAsk(const OUString & i_rQuery)
292 : throw (uno::RuntimeException, rdf::QueryException,
293 : rdf::RepositoryException);
294 :
295 : // ::com::sun::star::rdf::XDocumentRepository:
296 : virtual void SAL_CALL setStatementRDFa(
297 : const uno::Reference< rdf::XResource > & i_xSubject,
298 : const uno::Sequence< uno::Reference< rdf::XURI > > & i_rPredicates,
299 : const uno::Reference< rdf::XMetadatable > & i_xObject,
300 : const OUString & i_rRDFaContent,
301 : const uno::Reference< rdf::XURI > & i_xRDFaDatatype)
302 : throw (uno::RuntimeException, lang::IllegalArgumentException,
303 : rdf::RepositoryException);
304 : virtual void SAL_CALL removeStatementRDFa(
305 : const uno::Reference< rdf::XMetadatable > & i_xElement)
306 : throw (uno::RuntimeException, lang::IllegalArgumentException,
307 : rdf::RepositoryException);
308 : virtual beans::Pair< uno::Sequence<rdf::Statement>, sal_Bool > SAL_CALL
309 : getStatementRDFa(uno::Reference< rdf::XMetadatable > const& i_xElement)
310 : throw (uno::RuntimeException, lang::IllegalArgumentException,
311 : rdf::RepositoryException);
312 : virtual uno::Reference< container::XEnumeration > SAL_CALL
313 : getStatementsRDFa(
314 : const uno::Reference< rdf::XResource > & i_xSubject,
315 : const uno::Reference< rdf::XURI > & i_xPredicate,
316 : const uno::Reference< rdf::XNode > & i_xObject)
317 : throw (uno::RuntimeException,
318 : rdf::RepositoryException);
319 :
320 : // ::com::sun::star::lang::XInitialization:
321 : virtual void SAL_CALL initialize(
322 : const uno::Sequence< ::com::sun::star::uno::Any > & i_rArguments)
323 : throw (uno::RuntimeException, uno::Exception);
324 :
325 : // XNamedGraph forwards ---------------------------------------------
326 : const NamedGraphMap_t::iterator SAL_CALL clearGraph(
327 : const uno::Reference< rdf::XURI > & i_xName,
328 : bool i_Internal = false );
329 : void addStatementGraph(
330 : const uno::Reference< rdf::XResource > & i_xSubject,
331 : const uno::Reference< rdf::XURI > & i_xPredicate,
332 : const uno::Reference< rdf::XNode > & i_xObject,
333 : const uno::Reference< rdf::XURI > & i_xName,
334 : bool i_Internal = false );
335 : // throw (uno::RuntimeException, lang::IllegalArgumentException,
336 : // container::NoSuchElementException, rdf::RepositoryException);
337 : void removeStatementsGraph(
338 : const uno::Reference< rdf::XResource > & i_xSubject,
339 : const uno::Reference< rdf::XURI > & i_xPredicate,
340 : const uno::Reference< rdf::XNode > & i_xObject,
341 : const uno::Reference< rdf::XURI > & i_xName );
342 : // throw (uno::RuntimeException, lang::IllegalArgumentException,
343 : // container::NoSuchElementException, rdf::RepositoryException);
344 : uno::Reference< container::XEnumeration > getStatementsGraph(
345 : const uno::Reference< rdf::XResource > & i_xSubject,
346 : const uno::Reference< rdf::XURI > & i_xPredicate,
347 : const uno::Reference< rdf::XNode > & i_xObject,
348 : const uno::Reference< rdf::XURI > & i_xName,
349 : bool i_Internal = false );
350 : // throw (uno::RuntimeException, lang::IllegalArgumentException,
351 : // container::NoSuchElementException, rdf::RepositoryException);
352 :
353 311 : const librdf_TypeConverter& getTypeConverter() { return m_TypeConverter; };
354 :
355 : private:
356 :
357 : uno::Reference< uno::XComponentContext > m_xContext;
358 :
359 : /// librdf global data
360 : /** N.B.: The redland documentation gives the impression that you can have
361 : as many librdf_worlds as you like. This is true in the same sense
362 : that you can physically be in as many places as you like.
363 : Well, you can, just not at the same time.
364 : The ugly truth is that destroying a librdf_world kills a bunch
365 : of static variables; other librdf_worlds become very unhappy
366 : when they access these.
367 : And of course this is not documented anywhere that I could find.
368 : So we allocate a single world, and refcount that.
369 : */
370 : static boost::shared_ptr<librdf_world> m_pWorld;
371 : /// refcount
372 : static sal_uInt32 m_NumInstances;
373 : /// mutex for m_pWorld - redland is not as threadsafe as is often claimed
374 : static osl::Mutex m_aMutex;
375 :
376 : // NB: sequence of the shared pointers is important!
377 : /// librdf repository storage
378 : boost::shared_ptr<librdf_storage> m_pStorage;
379 : /// librdf repository model
380 : boost::shared_ptr<librdf_model> m_pModel;
381 :
382 : /// all named graphs
383 : NamedGraphMap_t m_NamedGraphs;
384 :
385 : /// type conversion helper
386 : librdf_TypeConverter m_TypeConverter;
387 :
388 : /// set of xml:ids of elements with xhtml:content
389 : ::std::set< OUString > m_RDFaXHTMLContentSet;
390 : };
391 :
392 :
393 : ////////////////////////////////////////////////////////////////////////////
394 :
395 : /** result of operations that return a graph, i.e.,
396 : an XEnumeration of statements.
397 : */
398 : class librdf_GraphResult:
399 : private boost::noncopyable,
400 : public ::cppu::WeakImplHelper1<
401 : container::XEnumeration>
402 : {
403 : public:
404 :
405 449 : librdf_GraphResult(librdf_Repository *i_pRepository,
406 : ::osl::Mutex & i_rMutex,
407 : boost::shared_ptr<librdf_stream> const& i_pStream,
408 : boost::shared_ptr<librdf_node> const& i_pContext,
409 : boost::shared_ptr<librdf_query> const& i_pQuery =
410 : boost::shared_ptr<librdf_query>() )
411 : : m_xRep(i_pRepository)
412 : , m_rMutex(i_rMutex)
413 : , m_pQuery(i_pQuery)
414 : , m_pContext(i_pContext)
415 449 : , m_pStream(i_pStream)
416 449 : { };
417 :
418 898 : virtual ~librdf_GraphResult() {}
419 :
420 : // ::com::sun::star::container::XEnumeration:
421 : virtual ::sal_Bool SAL_CALL hasMoreElements()
422 : throw (uno::RuntimeException);
423 : virtual uno::Any SAL_CALL nextElement()
424 : throw (uno::RuntimeException, container::NoSuchElementException,
425 : lang::WrappedTargetException);
426 :
427 : private:
428 : // NB: this is not a weak pointer: streams _must_ be deleted before the
429 : // storage they point into, so we keep the repository alive here
430 : // also, sequence is important: the stream must be destroyed first.
431 : ::rtl::Reference< librdf_Repository > m_xRep;
432 : // needed for synchronizing access to librdf (it doesnt do win32 threading)
433 : ::osl::Mutex & m_rMutex;
434 : // the query (in case this is a result of a graph query)
435 : // not that the redland documentation spells this out explicity, but
436 : // queries must be freed only after all the results are completely read
437 : boost::shared_ptr<librdf_query> const m_pQuery;
438 : boost::shared_ptr<librdf_node> const m_pContext;
439 : boost::shared_ptr<librdf_stream> const m_pStream;
440 :
441 : librdf_node* getContext() const;
442 : };
443 :
444 :
445 : // ::com::sun::star::container::XEnumeration:
446 : ::sal_Bool SAL_CALL
447 662 : librdf_GraphResult::hasMoreElements() throw (uno::RuntimeException)
448 : {
449 662 : ::osl::MutexGuard g(m_rMutex);
450 662 : return m_pStream.get() && !librdf_stream_end(m_pStream.get());
451 : }
452 :
453 302 : librdf_node* librdf_GraphResult::getContext() const
454 : {
455 302 : if (!m_pStream.get() || librdf_stream_end(m_pStream.get()))
456 0 : return NULL;
457 : librdf_node *pCtxt( static_cast<librdf_node *>
458 : #if LIBRDF_VERSION >= 10012
459 302 : (librdf_stream_get_context2(m_pStream.get())) );
460 : #else
461 : (librdf_stream_get_context(m_pStream.get())) );
462 : #endif
463 302 : if (pCtxt)
464 301 : return pCtxt;
465 1 : return m_pContext.get();
466 : }
467 :
468 : ::com::sun::star::uno::Any SAL_CALL
469 302 : librdf_GraphResult::nextElement()
470 : throw (uno::RuntimeException, container::NoSuchElementException,
471 : lang::WrappedTargetException)
472 : {
473 302 : ::osl::MutexGuard g(m_rMutex);
474 302 : if (!m_pStream.get() || !librdf_stream_end(m_pStream.get())) {
475 302 : librdf_node * pCtxt = getContext();
476 :
477 302 : librdf_statement *pStmt( librdf_stream_get_object(m_pStream.get()) );
478 302 : if (!pStmt) {
479 : rdf::QueryException e(
480 : "librdf_GraphResult::nextElement: "
481 0 : "librdf_stream_get_object failed", *this);
482 : throw lang::WrappedTargetException(
483 : "librdf_GraphResult::nextElement: "
484 : "librdf_stream_get_object failed", *this,
485 0 : uno::makeAny(e));
486 : }
487 : // NB: pCtxt may be null here if this is result of a graph query
488 302 : if (pCtxt && isInternalContext(pCtxt)) {
489 61 : pCtxt = 0; // XML ID context is implementation detail!
490 : }
491 : rdf::Statement Stmt(
492 302 : m_xRep->getTypeConverter().convertToStatement(pStmt, pCtxt) );
493 : // NB: this will invalidate current item.
494 302 : librdf_stream_next(m_pStream.get());
495 604 : return uno::makeAny(Stmt);
496 : } else {
497 0 : throw container::NoSuchElementException();
498 302 : }
499 : }
500 :
501 :
502 : ////////////////////////////////////////////////////////////////////////////
503 :
504 : /** result of tuple queries ("SELECT").
505 : */
506 : class librdf_QuerySelectResult:
507 : private boost::noncopyable,
508 : public ::cppu::WeakImplHelper1<
509 : rdf::XQuerySelectResult>
510 : {
511 : public:
512 :
513 6 : librdf_QuerySelectResult(librdf_Repository *i_pRepository,
514 : ::osl::Mutex & i_rMutex,
515 : boost::shared_ptr<librdf_query> const& i_pQuery,
516 : boost::shared_ptr<librdf_query_results> const& i_pQueryResult,
517 : uno::Sequence< OUString > const& i_rBindingNames )
518 : : m_xRep(i_pRepository)
519 : , m_rMutex(i_rMutex)
520 : , m_pQuery(i_pQuery)
521 : , m_pQueryResult(i_pQueryResult)
522 6 : , m_BindingNames(i_rBindingNames)
523 6 : { };
524 :
525 12 : virtual ~librdf_QuerySelectResult() {}
526 :
527 : // ::com::sun::star::container::XEnumeration:
528 : virtual ::sal_Bool SAL_CALL hasMoreElements()
529 : throw (uno::RuntimeException);
530 : virtual uno::Any SAL_CALL nextElement()
531 : throw (uno::RuntimeException, container::NoSuchElementException,
532 : lang::WrappedTargetException);
533 :
534 : // ::com::sun::star::rdf::XQuerySelectResult:
535 : virtual uno::Sequence< OUString > SAL_CALL getBindingNames()
536 : throw (uno::RuntimeException);
537 :
538 : private:
539 :
540 : // NB: this is not a weak pointer: streams _must_ be deleted before the
541 : // storage they point into, so we keep the repository alive here
542 : // also, sequence is important: the stream must be destroyed first.
543 : ::rtl::Reference< librdf_Repository > m_xRep;
544 : // needed for synchronizing access to librdf (it doesnt do win32 threading)
545 : ::osl::Mutex & m_rMutex;
546 : // not that the redland documentation spells this out explicity, but
547 : // queries must be freed only after all the results are completely read
548 : boost::shared_ptr<librdf_query> m_pQuery;
549 : boost::shared_ptr<librdf_query_results> m_pQueryResult;
550 : uno::Sequence< OUString > m_BindingNames;
551 : };
552 :
553 :
554 : // ::com::sun::star::container::XEnumeration:
555 : ::sal_Bool SAL_CALL
556 11 : librdf_QuerySelectResult::hasMoreElements() throw (uno::RuntimeException)
557 : {
558 11 : ::osl::MutexGuard g(m_rMutex);
559 11 : return !librdf_query_results_finished(m_pQueryResult.get());
560 : }
561 :
562 : class NodeArrayDeleter : public std::unary_function<librdf_node**, void>
563 : {
564 : const int m_Count;
565 :
566 : public:
567 5 : NodeArrayDeleter(int i_Count) : m_Count(i_Count) { }
568 :
569 5 : void operator() (librdf_node** io_pArray) const throw ()
570 : {
571 5 : std::for_each(io_pArray, io_pArray + m_Count, safe_librdf_free_node);
572 5 : delete[] io_pArray;
573 5 : }
574 : };
575 :
576 : ::com::sun::star::uno::Any SAL_CALL
577 5 : librdf_QuerySelectResult::nextElement()
578 : throw (uno::RuntimeException, container::NoSuchElementException,
579 : lang::WrappedTargetException)
580 : {
581 5 : ::osl::MutexGuard g(m_rMutex);
582 5 : if (!librdf_query_results_finished(m_pQueryResult.get())) {
583 5 : sal_Int32 count(m_BindingNames.getLength());
584 : OSL_ENSURE(count >= 0, "negative length?");
585 5 : boost::shared_array<librdf_node*> pNodes( new librdf_node*[count],
586 10 : NodeArrayDeleter(count));
587 14 : for (int i = 0; i < count; ++i) {
588 9 : pNodes[i] = 0;
589 : }
590 5 : if (librdf_query_results_get_bindings(m_pQueryResult.get(), NULL,
591 5 : pNodes.get()))
592 : {
593 : rdf::QueryException e(
594 : "librdf_QuerySelectResult::nextElement: "
595 0 : "librdf_query_results_get_bindings failed", *this);
596 : throw lang::WrappedTargetException(
597 : "librdf_QuerySelectResult::nextElement: "
598 : "librdf_query_results_get_bindings failed", *this,
599 0 : uno::makeAny(e));
600 : }
601 10 : uno::Sequence< uno::Reference< rdf::XNode > > ret(count);
602 14 : for (int i = 0; i < count; ++i) {
603 9 : ret[i] = m_xRep->getTypeConverter().convertToXNode(pNodes[i]);
604 : }
605 : // NB: this will invalidate current item.
606 5 : librdf_query_results_next(m_pQueryResult.get());
607 15 : return uno::makeAny(ret);
608 : } else {
609 0 : throw container::NoSuchElementException();
610 5 : }
611 : }
612 :
613 : // ::com::sun::star::rdf::XQuerySelectResult:
614 : uno::Sequence< OUString > SAL_CALL
615 6 : librdf_QuerySelectResult::getBindingNames() throw (uno::RuntimeException)
616 : {
617 6 : return m_BindingNames;
618 : }
619 :
620 :
621 : ////////////////////////////////////////////////////////////////////////////
622 :
623 : /** represents a named graph, and forwards all the work to repository.
624 : */
625 : class librdf_NamedGraph:
626 : private boost::noncopyable,
627 : public ::cppu::WeakImplHelper1<
628 : rdf::XNamedGraph>
629 : {
630 : public:
631 109 : librdf_NamedGraph(librdf_Repository * i_pRep,
632 : uno::Reference<rdf::XURI> const & i_xName)
633 : : m_wRep(i_pRep)
634 : , m_pRep(i_pRep)
635 109 : , m_xName(i_xName)
636 109 : { };
637 :
638 202 : virtual ~librdf_NamedGraph() {}
639 :
640 : // ::com::sun::star::rdf::XNode:
641 : virtual OUString SAL_CALL getStringValue()
642 : throw (uno::RuntimeException);
643 :
644 : // ::com::sun::star::rdf::XURI:
645 : virtual OUString SAL_CALL getNamespace()
646 : throw (uno::RuntimeException);
647 : virtual OUString SAL_CALL getLocalName()
648 : throw (uno::RuntimeException);
649 :
650 : // ::com::sun::star::rdf::XNamedGraph:
651 : virtual uno::Reference<rdf::XURI> SAL_CALL getName()
652 : throw (uno::RuntimeException);
653 : virtual void SAL_CALL clear()
654 : throw (uno::RuntimeException,
655 : container::NoSuchElementException, rdf::RepositoryException);
656 : virtual void SAL_CALL addStatement(
657 : const uno::Reference< rdf::XResource > & i_xSubject,
658 : const uno::Reference< rdf::XURI > & i_xPredicate,
659 : const uno::Reference< rdf::XNode > & i_xObject)
660 : throw (uno::RuntimeException, lang::IllegalArgumentException,
661 : container::NoSuchElementException, rdf::RepositoryException);
662 : virtual void SAL_CALL removeStatements(
663 : const uno::Reference< rdf::XResource > & i_xSubject,
664 : const uno::Reference< rdf::XURI > & i_xPredicate,
665 : const uno::Reference< rdf::XNode > & i_xObject)
666 : throw (uno::RuntimeException,
667 : container::NoSuchElementException, rdf::RepositoryException);
668 : virtual uno::Reference< container::XEnumeration > SAL_CALL getStatements(
669 : const uno::Reference< rdf::XResource > & i_xSubject,
670 : const uno::Reference< rdf::XURI > & i_xPredicate,
671 : const uno::Reference< rdf::XNode > & i_xObject)
672 : throw (uno::RuntimeException,
673 : container::NoSuchElementException, rdf::RepositoryException);
674 :
675 : private:
676 :
677 : /// weak reference: this is needed to check if m_pRep is valid
678 : uno::WeakReference< rdf::XRepository > m_wRep;
679 : librdf_Repository *m_pRep;
680 : uno::Reference< rdf::XURI > m_xName;
681 : };
682 :
683 :
684 : // ::com::sun::star::rdf::XNode:
685 1 : OUString SAL_CALL librdf_NamedGraph::getStringValue()
686 : throw (uno::RuntimeException)
687 : {
688 1 : return m_xName->getStringValue();
689 : }
690 :
691 : // ::com::sun::star::rdf::XURI:
692 0 : OUString SAL_CALL librdf_NamedGraph::getNamespace()
693 : throw (uno::RuntimeException)
694 : {
695 0 : return m_xName->getNamespace();
696 : }
697 :
698 0 : OUString SAL_CALL librdf_NamedGraph::getLocalName()
699 : throw (uno::RuntimeException)
700 : {
701 0 : return m_xName->getLocalName();
702 : }
703 :
704 : // ::com::sun::star::rdf::XNamedGraph:
705 25 : uno::Reference< rdf::XURI > SAL_CALL librdf_NamedGraph::getName()
706 : throw (uno::RuntimeException)
707 : {
708 25 : return m_xName;
709 : }
710 :
711 2 : void SAL_CALL librdf_NamedGraph::clear()
712 : throw (uno::RuntimeException,
713 : container::NoSuchElementException, rdf::RepositoryException)
714 : {
715 2 : uno::Reference< rdf::XRepository > xRep( m_wRep );
716 2 : if (!xRep.is()) {
717 : throw rdf::RepositoryException(
718 0 : "librdf_NamedGraph::clear: repository is gone", *this);
719 : }
720 : try {
721 2 : m_pRep->clearGraph(m_xName);
722 0 : } catch (lang::IllegalArgumentException &) {
723 0 : throw uno::RuntimeException();
724 2 : }
725 1 : }
726 :
727 401 : void SAL_CALL librdf_NamedGraph::addStatement(
728 : const uno::Reference< rdf::XResource > & i_xSubject,
729 : const uno::Reference< rdf::XURI > & i_xPredicate,
730 : const uno::Reference< rdf::XNode > & i_xObject)
731 : throw (uno::RuntimeException, lang::IllegalArgumentException,
732 : container::NoSuchElementException, rdf::RepositoryException)
733 : {
734 401 : uno::Reference< rdf::XRepository > xRep( m_wRep );
735 401 : if (!xRep.is()) {
736 : throw rdf::RepositoryException(
737 0 : "librdf_NamedGraph::addStatement: repository is gone", *this);
738 : }
739 402 : m_pRep->addStatementGraph(i_xSubject, i_xPredicate, i_xObject, m_xName);
740 400 : }
741 :
742 9 : void SAL_CALL librdf_NamedGraph::removeStatements(
743 : const uno::Reference< rdf::XResource > & i_xSubject,
744 : const uno::Reference< rdf::XURI > & i_xPredicate,
745 : const uno::Reference< rdf::XNode > & i_xObject)
746 : throw (uno::RuntimeException,
747 : container::NoSuchElementException, rdf::RepositoryException)
748 : {
749 9 : uno::Reference< rdf::XRepository > xRep( m_wRep );
750 9 : if (!xRep.is()) {
751 : throw rdf::RepositoryException(
752 0 : "librdf_NamedGraph::removeStatements: repository is gone", *this);
753 : }
754 10 : m_pRep->removeStatementsGraph(i_xSubject, i_xPredicate, i_xObject, m_xName);
755 8 : }
756 :
757 : uno::Reference< container::XEnumeration > SAL_CALL
758 263 : librdf_NamedGraph::getStatements(
759 : const uno::Reference< rdf::XResource > & i_xSubject,
760 : const uno::Reference< rdf::XURI > & i_xPredicate,
761 : const uno::Reference< rdf::XNode > & i_xObject)
762 : throw (uno::RuntimeException,
763 : container::NoSuchElementException, rdf::RepositoryException)
764 : {
765 263 : uno::Reference< rdf::XRepository > xRep( m_wRep );
766 263 : if (!xRep.is()) {
767 : throw rdf::RepositoryException(
768 0 : "librdf_NamedGraph::getStatements: repository is gone", *this);
769 : }
770 : return m_pRep->getStatementsGraph(
771 264 : i_xSubject, i_xPredicate, i_xObject, m_xName);
772 : }
773 :
774 :
775 : ////////////////////////////////////////////////////////////////////////////
776 :
777 30 : boost::shared_ptr<librdf_world> librdf_Repository::m_pWorld;
778 : sal_uInt32 librdf_Repository::m_NumInstances = 0;
779 30 : osl::Mutex librdf_Repository::m_aMutex;
780 :
781 104 : librdf_Repository::librdf_Repository(
782 : uno::Reference< uno::XComponentContext > const & i_xContext)
783 : : /*BaseMutex(),*/ m_xContext(i_xContext)
784 : // m_pWorld (static_cast<librdf_world *>(0), safe_librdf_free_world ),
785 : , m_pStorage(static_cast<librdf_storage*>(0), safe_librdf_free_storage)
786 : , m_pModel (static_cast<librdf_model *>(0), safe_librdf_free_model )
787 : , m_NamedGraphs()
788 104 : , m_TypeConverter(i_xContext, *this)
789 : {
790 : OSL_ENSURE(i_xContext.is(), "librdf_Repository: null context");
791 :
792 104 : ::osl::MutexGuard g(m_aMutex);
793 104 : if (!m_NumInstances++) {
794 30 : m_pWorld.reset(m_TypeConverter.createWorld(), safe_librdf_free_world);
795 104 : }
796 104 : }
797 :
798 288 : librdf_Repository::~librdf_Repository()
799 : {
800 : // must destroy these before world!
801 96 : m_pModel.reset();
802 96 : m_pStorage.reset();
803 :
804 : // FIXME: so it turns out that calling librdf_free_world will
805 : // (via raptor_sax2_finish) call xmlCleanupParser, which will
806 : // free libxml2's globals! ARRRGH!!! => never call librdf_free_world
807 : #if 0
808 : ::osl::MutexGuard g(m_aMutex);
809 : if (!--m_NumInstances) {
810 : m_pWorld.reset();
811 : }
812 : #endif
813 192 : }
814 :
815 : // com.sun.star.uno.XServiceInfo:
816 0 : OUString SAL_CALL librdf_Repository::getImplementationName()
817 : throw (uno::RuntimeException)
818 : {
819 0 : return comp_librdf_Repository::_getImplementationName();
820 : }
821 :
822 0 : ::sal_Bool SAL_CALL librdf_Repository::supportsService(
823 : OUString const & serviceName) throw (uno::RuntimeException)
824 : {
825 : uno::Sequence< OUString > serviceNames
826 0 : = comp_librdf_Repository::_getSupportedServiceNames();
827 0 : for (::sal_Int32 i = 0; i < serviceNames.getLength(); ++i) {
828 0 : if (serviceNames[i] == serviceName)
829 0 : return sal_True;
830 : }
831 0 : return sal_False;
832 : }
833 :
834 : uno::Sequence< OUString > SAL_CALL
835 0 : librdf_Repository::getSupportedServiceNames() throw (uno::RuntimeException)
836 : {
837 0 : return comp_librdf_Repository::_getSupportedServiceNames();
838 : }
839 :
840 : // ::com::sun::star::rdf::XRepository:
841 4 : uno::Reference< rdf::XBlankNode > SAL_CALL librdf_Repository::createBlankNode()
842 : throw (uno::RuntimeException)
843 : {
844 4 : ::osl::MutexGuard g(m_aMutex);
845 : const boost::shared_ptr<librdf_node> pNode(
846 : librdf_new_node_from_blank_identifier(m_pWorld.get(), NULL),
847 8 : safe_librdf_free_node);
848 4 : if (!pNode) {
849 : throw uno::RuntimeException(
850 : "librdf_Repository::createBlankNode: "
851 0 : "librdf_new_node_from_blank_identifier failed", *this);
852 : }
853 4 : const unsigned char * id (librdf_node_get_blank_identifier(pNode.get()));
854 4 : if (!id) {
855 : throw uno::RuntimeException(
856 : "librdf_Repository::createBlankNode: "
857 0 : "librdf_node_get_blank_identifier failed", *this);
858 : }
859 : const OUString nodeID(OUString::createFromAscii(
860 8 : reinterpret_cast<const char *>(id)));
861 : try {
862 8 : return rdf::BlankNode::create(m_xContext, nodeID);
863 0 : } catch (const lang::IllegalArgumentException & iae) {
864 : throw lang::WrappedTargetRuntimeException(
865 : "librdf_Repository::createBlankNode: "
866 0 : "illegal blank node label", *this, uno::makeAny(iae));
867 4 : }
868 : }
869 :
870 58 : bool formatNeedsBaseURI(::sal_Int16 i_Format)
871 : {
872 : (void) i_Format; //FIXME any which dont?
873 58 : return true;
874 : }
875 :
876 : //void SAL_CALL
877 : uno::Reference<rdf::XNamedGraph> SAL_CALL
878 39 : librdf_Repository::importGraph(::sal_Int16 i_Format,
879 : const uno::Reference< io::XInputStream > & i_xInStream,
880 : const uno::Reference< rdf::XURI > & i_xGraphName,
881 : const uno::Reference< rdf::XURI > & i_xBaseURI)
882 : throw (uno::RuntimeException, lang::IllegalArgumentException,
883 : datatransfer::UnsupportedFlavorException,
884 : container::ElementExistException, rdf::ParseException,
885 : rdf::RepositoryException, io::IOException)
886 : {
887 39 : ::osl::MutexGuard g(m_aMutex);
888 39 : if (!i_xInStream.is()) {
889 : throw lang::IllegalArgumentException(
890 1 : "librdf_Repository::importGraph: stream is null", *this, 1);
891 : }
892 : //FIXME: other formats
893 38 : if (i_Format != rdf::FileFormat::RDF_XML) {
894 : throw datatransfer::UnsupportedFlavorException(
895 0 : "librdf_Repository::importGraph: file format not supported", *this);
896 : }
897 38 : if (!i_xGraphName.is()) {
898 : throw lang::IllegalArgumentException(
899 0 : "librdf_Repository::importGraph: graph name is null", *this, 2);
900 : }
901 38 : if (i_xGraphName->getStringValue().matchAsciiL(s_nsOOo, sizeof(s_nsOOo)-1))
902 : {
903 : throw lang::IllegalArgumentException(
904 0 : "librdf_Repository::importGraph: URI is reserved", *this, 0);
905 : }
906 38 : if (formatNeedsBaseURI(i_Format) && !i_xBaseURI.is()) {
907 : throw lang::IllegalArgumentException(
908 1 : "librdf_Repository::importGraph: base URI is null", *this, 3);
909 : }
910 : OSL_ENSURE(i_xBaseURI.is(), "no base uri");
911 74 : const OUString baseURIU( i_xBaseURI->getStringValue() );
912 37 : if (baseURIU.indexOf('#') >= 0) {
913 : throw lang::IllegalArgumentException(
914 1 : "librdf_Repository::importGraph: base URI is not absolute", *this, 3);
915 : }
916 :
917 72 : const OUString contextU( i_xGraphName->getStringValue() );
918 36 : if (m_NamedGraphs.find(contextU) != m_NamedGraphs.end()) {
919 : throw container::ElementExistException(
920 1 : "librdf_Repository::importGraph: graph with given URI exists", *this);
921 : }
922 : const OString context(
923 70 : OUStringToOString(contextU, RTL_TEXTENCODING_UTF8) );
924 :
925 : const boost::shared_ptr<librdf_node> pContext(
926 : librdf_new_node_from_uri_string(m_pWorld.get(),
927 35 : reinterpret_cast<const unsigned char*> (context.getStr())),
928 70 : safe_librdf_free_node);
929 35 : if (!pContext) {
930 : throw uno::RuntimeException(
931 0 : "librdf_Repository::importGraph: librdf_new_node_from_uri_string failed", *this);
932 : }
933 :
934 : const OString baseURI(
935 70 : OUStringToOString(baseURIU, RTL_TEXTENCODING_UTF8) );
936 : const boost::shared_ptr<librdf_uri> pBaseURI(
937 : librdf_new_uri(m_pWorld.get(),
938 35 : reinterpret_cast<const unsigned char*> (baseURI.getStr())),
939 70 : safe_librdf_free_uri);
940 35 : if (!pBaseURI) {
941 0 : throw uno::RuntimeException( "librdf_Repository::importGraph: librdf_new_uri failed", *this);
942 : }
943 :
944 : const boost::shared_ptr<librdf_parser> pParser(
945 : librdf_new_parser(m_pWorld.get(), "rdfxml", NULL, NULL),
946 70 : safe_librdf_free_parser);
947 35 : if (!pParser) {
948 : throw uno::RuntimeException(
949 : "librdf_Repository::importGraph: "
950 0 : "librdf_new_parser failed", *this);
951 : }
952 :
953 70 : uno::Sequence<sal_Int8> buf;
954 70 : uno::Reference<io::XSeekable> xSeekable(i_xInStream, uno::UNO_QUERY);
955 : // UGLY: if only that redland junk could read streams...
956 35 : const sal_Int64 sz( xSeekable.is() ? xSeekable->getLength() : 1 << 20 );
957 : // exceptions are propagated
958 35 : i_xInStream->readBytes( buf, static_cast<sal_Int32>( sz ) );
959 : const boost::shared_ptr<librdf_stream> pStream(
960 : librdf_parser_parse_counted_string_as_stream(pParser.get(),
961 35 : reinterpret_cast<const unsigned char*>(buf.getConstArray()),
962 35 : buf.getLength(), pBaseURI.get()),
963 140 : safe_librdf_free_stream);
964 35 : if (!pStream) {
965 : throw rdf::ParseException(
966 : "librdf_Repository::importGraph: "
967 0 : "librdf_parser_parse_counted_string_as_stream failed", *this);
968 : }
969 : m_NamedGraphs.insert(std::make_pair(contextU,
970 35 : new librdf_NamedGraph(this, i_xGraphName)));
971 35 : if (librdf_model_context_add_statements(m_pModel.get(),
972 35 : pContext.get(), pStream.get())) {
973 : throw rdf::RepositoryException(
974 : "librdf_Repository::importGraph: "
975 0 : "librdf_model_context_add_statements failed", *this);
976 : }
977 :
978 74 : return getGraph(i_xGraphName);
979 : }
980 :
981 20 : void addChaffWhenEncryptedStorage(const uno::Reference< io::XOutputStream > &rStream, unsigned char* pBuffer, size_t length)
982 : {
983 20 : if (!length)
984 20 : return;
985 :
986 : uno::Reference< embed::XEncryptionProtectedSource2 > xEncr(rStream,
987 20 : uno::UNO_QUERY);
988 :
989 20 : bool bAddChaff = xEncr.is() && xEncr->hasEncryptionData();
990 :
991 : // exceptions are propagated
992 20 : if (!bAddChaff)
993 : {
994 : const uno::Sequence<sal_Int8> buf(
995 19 : reinterpret_cast<sal_Int8*>(pBuffer), length);
996 19 : rStream->writeBytes(buf);
997 : }
998 : else
999 : {
1000 : unsigned char *postcomment =
1001 1 : (unsigned char*)strchr((const char*)pBuffer, '\n');
1002 1 : if (postcomment != NULL)
1003 : {
1004 1 : ++postcomment;
1005 :
1006 1 : size_t preamblelen = postcomment - pBuffer;
1007 :
1008 : uno::Sequence<sal_Int8> buf(
1009 1 : reinterpret_cast<sal_Int8*>(pBuffer), preamblelen);
1010 1 : rStream->writeBytes(buf);
1011 :
1012 2 : OStringBuffer aComment;
1013 1 : aComment.append("<!--");
1014 1 : aComment.append(comphelper::xml::makeXMLChaff());
1015 1 : aComment.append("-->");
1016 :
1017 3 : buf = uno::Sequence<sal_Int8>(
1018 2 : reinterpret_cast<const sal_Int8*>(aComment.getStr()), aComment.getLength());
1019 1 : rStream->writeBytes(buf);
1020 :
1021 2 : buf = uno::Sequence<sal_Int8>(
1022 2 : reinterpret_cast<sal_Int8*>(postcomment), length-preamblelen);
1023 2 : rStream->writeBytes(buf);
1024 : }
1025 20 : }
1026 : }
1027 :
1028 : void SAL_CALL
1029 20 : librdf_Repository::exportGraph(::sal_Int16 i_Format,
1030 : const uno::Reference< io::XOutputStream > & i_xOutStream,
1031 : const uno::Reference< rdf::XURI > & i_xGraphName,
1032 : const uno::Reference< rdf::XURI > & i_xBaseURI)
1033 : throw (uno::RuntimeException, lang::IllegalArgumentException,
1034 : datatransfer::UnsupportedFlavorException,
1035 : container::NoSuchElementException, rdf::RepositoryException,
1036 : io::IOException)
1037 : {
1038 20 : ::osl::MutexGuard g(m_aMutex);
1039 20 : if (!i_xOutStream.is()) {
1040 : throw lang::IllegalArgumentException(
1041 0 : "librdf_Repository::exportGraph: stream is null", *this, 1);
1042 : }
1043 : // FIXME: other formats
1044 20 : if (i_Format != rdf::FileFormat::RDF_XML) {
1045 : throw datatransfer::UnsupportedFlavorException(
1046 : "librdf_Repository::exportGraph: "
1047 0 : "file format not supported", *this);
1048 : }
1049 20 : if (!i_xGraphName.is()) {
1050 : throw lang::IllegalArgumentException(
1051 : "librdf_Repository::exportGraph: "
1052 0 : "graph name is null", *this, 2);
1053 : }
1054 20 : if (formatNeedsBaseURI(i_Format) && !i_xBaseURI.is()) {
1055 : throw lang::IllegalArgumentException(
1056 : "librdf_Repository::exportGraph: "
1057 0 : "base URI is null", *this, 3);
1058 : }
1059 : OSL_ENSURE(i_xBaseURI.is(), "no base uri");
1060 40 : const OUString baseURIU( i_xBaseURI->getStringValue() );
1061 20 : if (baseURIU.indexOf('#') >= 0) {
1062 : throw lang::IllegalArgumentException(
1063 : "librdf_Repository::exportGraph: "
1064 0 : "base URI is not absolute", *this, 3);
1065 : }
1066 :
1067 40 : const OUString contextU( i_xGraphName->getStringValue() );
1068 20 : if (m_NamedGraphs.find(contextU) == m_NamedGraphs.end()) {
1069 : throw container::NoSuchElementException(
1070 : "librdf_Repository::exportGraph: "
1071 0 : "no graph with given URI exists", *this);
1072 : }
1073 : const OString context(
1074 40 : OUStringToOString(contextU, RTL_TEXTENCODING_UTF8) );
1075 :
1076 : const boost::shared_ptr<librdf_node> pContext(
1077 : librdf_new_node_from_uri_string(m_pWorld.get(),
1078 20 : reinterpret_cast<const unsigned char*> (context.getStr())),
1079 40 : safe_librdf_free_node);
1080 20 : if (!pContext) {
1081 : throw uno::RuntimeException(
1082 : "librdf_Repository::exportGraph: "
1083 0 : "librdf_new_node_from_uri_string failed", *this);
1084 : }
1085 : const OString baseURI(
1086 40 : OUStringToOString(baseURIU, RTL_TEXTENCODING_UTF8) );
1087 : const boost::shared_ptr<librdf_uri> pBaseURI(
1088 : librdf_new_uri(m_pWorld.get(),
1089 20 : reinterpret_cast<const unsigned char*> (baseURI.getStr())),
1090 40 : safe_librdf_free_uri);
1091 20 : if (!pBaseURI) {
1092 : throw uno::RuntimeException(
1093 : "librdf_Repository::exportGraph: "
1094 0 : "librdf_new_uri failed", *this);
1095 : }
1096 :
1097 : const boost::shared_ptr<librdf_stream> pStream(
1098 : librdf_model_context_as_stream(m_pModel.get(), pContext.get()),
1099 40 : safe_librdf_free_stream);
1100 20 : if (!pStream) {
1101 : throw rdf::RepositoryException(
1102 : "librdf_Repository::exportGraph: "
1103 0 : "librdf_model_context_as_stream failed", *this);
1104 : }
1105 20 : const char *format("rdfxml");
1106 : // #i116443#: abbrev breaks when certain URIs are used as data types
1107 : // const char *format("rdfxml-abbrev");
1108 : const boost::shared_ptr<librdf_serializer> pSerializer(
1109 : librdf_new_serializer(m_pWorld.get(), format, NULL, NULL),
1110 40 : safe_librdf_free_serializer);
1111 20 : if (!pSerializer) {
1112 : throw uno::RuntimeException(
1113 : "librdf_Repository::exportGraph: "
1114 0 : "librdf_new_serializer failed", *this);
1115 : }
1116 :
1117 : const boost::shared_ptr<librdf_uri> pRelativeURI(
1118 : librdf_new_uri(m_pWorld.get(), reinterpret_cast<const unsigned char*>
1119 : ("http://feature.librdf.org/raptor-relativeURIs")),
1120 40 : safe_librdf_free_uri);
1121 : const boost::shared_ptr<librdf_uri> pWriteBaseURI(
1122 : librdf_new_uri(m_pWorld.get(), reinterpret_cast<const unsigned char*>
1123 : ("http://feature.librdf.org/raptor-writeBaseURI")),
1124 40 : safe_librdf_free_uri);
1125 : const boost::shared_ptr<librdf_node> p0(
1126 : librdf_new_node_from_literal(m_pWorld.get(),
1127 : reinterpret_cast<const unsigned char*> ("0"), NULL, 0),
1128 40 : safe_librdf_free_node);
1129 : const boost::shared_ptr<librdf_node> p1(
1130 : librdf_new_node_from_literal(m_pWorld.get(),
1131 : reinterpret_cast<const unsigned char*> ("1"), NULL, 0),
1132 40 : safe_librdf_free_node);
1133 20 : if (!pWriteBaseURI || !pRelativeURI || !p0 || !p1) {
1134 : throw uno::RuntimeException(
1135 : "librdf_Repository::exportGraph: "
1136 0 : "librdf_new_uri or librdf_new_node_from_literal failed", *this);
1137 : }
1138 :
1139 : // make URIs relative to base URI
1140 20 : if (librdf_serializer_set_feature(pSerializer.get(),
1141 20 : pRelativeURI.get(), p1.get()))
1142 : {
1143 : throw uno::RuntimeException(
1144 : "librdf_Repository::exportGraph: "
1145 0 : "librdf_serializer_set_feature relativeURIs failed", *this);
1146 : }
1147 : // but do not write the base URI to the file!
1148 20 : if (librdf_serializer_set_feature(pSerializer.get(),
1149 20 : pWriteBaseURI.get(), p0.get()))
1150 : {
1151 : throw uno::RuntimeException(
1152 : "librdf_Repository::exportGraph: "
1153 0 : "librdf_serializer_set_feature writeBaseURI failed", *this);
1154 : }
1155 :
1156 : size_t length;
1157 : const boost::shared_ptr<unsigned char> pBuf(
1158 : librdf_serializer_serialize_stream_to_counted_string(
1159 40 : pSerializer.get(), pBaseURI.get(), pStream.get(), &length), free);
1160 20 : if (!pBuf) {
1161 : throw rdf::RepositoryException(
1162 : "librdf_Repository::exportGraph: "
1163 : "librdf_serializer_serialize_stream_to_counted_string failed",
1164 0 : *this);
1165 : }
1166 40 : addChaffWhenEncryptedStorage(i_xOutStream, pBuf.get(), length);
1167 20 : }
1168 :
1169 : uno::Sequence< uno::Reference< rdf::XURI > > SAL_CALL
1170 22 : librdf_Repository::getGraphNames()
1171 : throw (uno::RuntimeException, rdf::RepositoryException)
1172 : {
1173 22 : ::osl::MutexGuard g(m_aMutex);
1174 44 : ::comphelper::SequenceAsVector< uno::Reference<rdf::XURI> > ret;
1175 : std::transform(m_NamedGraphs.begin(), m_NamedGraphs.end(),
1176 : std::back_inserter(ret),
1177 : boost::bind(&rdf::XNamedGraph::getName,
1178 22 : boost::bind(&NamedGraphMap_t::value_type::second, _1)));
1179 44 : return ret.getAsConstList();
1180 : }
1181 :
1182 : uno::Reference< rdf::XNamedGraph > SAL_CALL
1183 130 : librdf_Repository::getGraph(const uno::Reference< rdf::XURI > & i_xGraphName)
1184 : throw (uno::RuntimeException, lang::IllegalArgumentException,
1185 : rdf::RepositoryException)
1186 : {
1187 130 : ::osl::MutexGuard g(m_aMutex);
1188 130 : if (!i_xGraphName.is()) {
1189 : throw lang::IllegalArgumentException(
1190 0 : "librdf_Repository::getGraph: URI is null", *this, 0);
1191 : }
1192 : const NamedGraphMap_t::iterator iter(
1193 130 : m_NamedGraphs.find(i_xGraphName->getStringValue()) );
1194 130 : if (iter != m_NamedGraphs.end()) {
1195 71 : return uno::Reference<rdf::XNamedGraph>(iter->second.get());
1196 : } else {
1197 59 : return 0;
1198 130 : }
1199 : }
1200 :
1201 : uno::Reference< rdf::XNamedGraph > SAL_CALL
1202 76 : librdf_Repository::createGraph(const uno::Reference< rdf::XURI > & i_xGraphName)
1203 : throw (uno::RuntimeException, lang::IllegalArgumentException,
1204 : container::ElementExistException, rdf::RepositoryException)
1205 : {
1206 76 : ::osl::MutexGuard g(m_aMutex);
1207 76 : if (!i_xGraphName.is()) {
1208 : throw lang::IllegalArgumentException(
1209 1 : "librdf_Repository::createGraph: URI is null", *this, 0);
1210 : }
1211 75 : if (i_xGraphName->getStringValue().matchAsciiL(s_nsOOo, sizeof(s_nsOOo)-1))
1212 : {
1213 : throw lang::IllegalArgumentException(
1214 0 : "librdf_Repository::createGraph: URI is reserved", *this, 0);
1215 : }
1216 :
1217 : // NB: librdf does not have a concept of graphs as such;
1218 : // a librdf named graph exists iff the model contains a statement with
1219 : // the graph name as context
1220 150 : const OUString contextU( i_xGraphName->getStringValue() );
1221 75 : if (m_NamedGraphs.find(contextU) != m_NamedGraphs.end()) {
1222 : throw container::ElementExistException(
1223 1 : "librdf_Repository::createGraph: graph with given URI exists", *this);
1224 : }
1225 : m_NamedGraphs.insert(std::make_pair(contextU,
1226 74 : new librdf_NamedGraph(this, i_xGraphName)));
1227 : return uno::Reference<rdf::XNamedGraph>(
1228 150 : m_NamedGraphs.find(contextU)->second.get());
1229 : }
1230 :
1231 : void SAL_CALL
1232 3 : librdf_Repository::destroyGraph(
1233 : const uno::Reference< rdf::XURI > & i_xGraphName)
1234 : throw (uno::RuntimeException, lang::IllegalArgumentException,
1235 : container::NoSuchElementException, rdf::RepositoryException)
1236 : {
1237 3 : ::osl::MutexGuard g(m_aMutex);
1238 3 : const NamedGraphMap_t::iterator iter( clearGraph(i_xGraphName) );
1239 3 : m_NamedGraphs.erase(iter);
1240 2 : }
1241 :
1242 1342 : static bool isMetadatableWithoutMetadata(
1243 : uno::Reference<uno::XInterface> const & i_xNode)
1244 : {
1245 1342 : const uno::Reference<rdf::XMetadatable> xMeta( i_xNode, uno::UNO_QUERY );
1246 1342 : return (xMeta.is() && xMeta->getMetadataReference().Second.isEmpty());
1247 : }
1248 :
1249 : uno::Reference< container::XEnumeration > SAL_CALL
1250 121 : librdf_Repository::getStatements(
1251 : const uno::Reference< rdf::XResource > & i_xSubject,
1252 : const uno::Reference< rdf::XURI > & i_xPredicate,
1253 : const uno::Reference< rdf::XNode > & i_xObject)
1254 : throw (uno::RuntimeException, rdf::RepositoryException)
1255 : {
1256 347 : if (isMetadatableWithoutMetadata(i_xSubject) ||
1257 226 : isMetadatableWithoutMetadata(i_xPredicate) ||
1258 105 : isMetadatableWithoutMetadata(i_xObject))
1259 : {
1260 : return new librdf_GraphResult(this, m_aMutex,
1261 : ::boost::shared_ptr<librdf_stream>(),
1262 16 : ::boost::shared_ptr<librdf_node>());
1263 : }
1264 :
1265 105 : ::osl::MutexGuard g(m_aMutex);
1266 : const boost::shared_ptr<librdf_statement> pStatement(
1267 : m_TypeConverter.mkStatement(m_pWorld.get(),
1268 : i_xSubject, i_xPredicate, i_xObject),
1269 210 : safe_librdf_free_statement);
1270 : OSL_ENSURE(pStatement, "mkStatement failed");
1271 :
1272 : const boost::shared_ptr<librdf_stream> pStream(
1273 : librdf_model_find_statements(m_pModel.get(), pStatement.get()),
1274 210 : safe_librdf_free_stream);
1275 105 : if (!pStream) {
1276 : throw rdf::RepositoryException(
1277 : "librdf_Repository::getStatements: "
1278 0 : "librdf_model_find_statements failed", *this);
1279 : }
1280 :
1281 : return new librdf_GraphResult(this, m_aMutex, pStream,
1282 210 : ::boost::shared_ptr<librdf_node>());
1283 : }
1284 :
1285 :
1286 : uno::Reference< rdf::XQuerySelectResult > SAL_CALL
1287 6 : librdf_Repository::querySelect(const OUString & i_rQuery)
1288 : throw (uno::RuntimeException, rdf::QueryException, rdf::RepositoryException)
1289 : {
1290 6 : ::osl::MutexGuard g(m_aMutex);
1291 : const OString query(
1292 12 : OUStringToOString(i_rQuery, RTL_TEXTENCODING_UTF8) );
1293 : const boost::shared_ptr<librdf_query> pQuery(
1294 : librdf_new_query(m_pWorld.get(), s_sparql, NULL,
1295 6 : reinterpret_cast<const unsigned char*> (query.getStr()), NULL),
1296 12 : safe_librdf_free_query);
1297 6 : if (!pQuery) {
1298 : throw rdf::QueryException(
1299 : "librdf_Repository::querySelect: "
1300 0 : "librdf_new_query failed", *this);
1301 : }
1302 : const boost::shared_ptr<librdf_query_results> pResults(
1303 : librdf_model_query_execute(m_pModel.get(), pQuery.get()),
1304 12 : safe_librdf_free_query_results);
1305 6 : if (!pResults || !librdf_query_results_is_bindings(pResults.get())) {
1306 : throw rdf::QueryException(
1307 : "librdf_Repository::querySelect: "
1308 0 : "query result is null or not bindings", *this);
1309 : }
1310 :
1311 6 : const int count( librdf_query_results_get_bindings_count(pResults.get()) );
1312 6 : if (count >= 0) {
1313 6 : uno::Sequence< OUString > names(count);
1314 15 : for (int i = 0; i < count; ++i) {
1315 : const char* name( librdf_query_results_get_binding_name(
1316 9 : pResults.get(), i) );
1317 9 : if (!name) {
1318 : throw rdf::QueryException(
1319 0 : "librdf_Repository::querySelect: binding is null", *this);
1320 : }
1321 :
1322 9 : names[i] = OUString::createFromAscii(name);
1323 : }
1324 :
1325 : return new librdf_QuerySelectResult(this, m_aMutex,
1326 12 : pQuery, pResults, names);
1327 :
1328 : } else {
1329 : throw rdf::QueryException(
1330 : "librdf_Repository::querySelect: "
1331 0 : "librdf_query_results_get_bindings_count failed", *this);
1332 6 : }
1333 : }
1334 :
1335 : uno::Reference< container::XEnumeration > SAL_CALL
1336 1 : librdf_Repository::queryConstruct(const OUString & i_rQuery)
1337 : throw (uno::RuntimeException, rdf::QueryException, rdf::RepositoryException)
1338 : {
1339 1 : ::osl::MutexGuard g(m_aMutex);
1340 : const OString query(
1341 2 : OUStringToOString(i_rQuery, RTL_TEXTENCODING_UTF8) );
1342 : const boost::shared_ptr<librdf_query> pQuery(
1343 : librdf_new_query(m_pWorld.get(), s_sparql, NULL,
1344 1 : reinterpret_cast<const unsigned char*> (query.getStr()), NULL),
1345 2 : safe_librdf_free_query);
1346 1 : if (!pQuery) {
1347 : throw rdf::QueryException(
1348 : "librdf_Repository::queryConstruct: "
1349 0 : "librdf_new_query failed", *this);
1350 : }
1351 : const boost::shared_ptr<librdf_query_results> pResults(
1352 : librdf_model_query_execute(m_pModel.get(), pQuery.get()),
1353 2 : safe_librdf_free_query_results);
1354 1 : if (!pResults || !librdf_query_results_is_graph(pResults.get())) {
1355 : throw rdf::QueryException(
1356 : "librdf_Repository::queryConstruct: "
1357 0 : "query result is null or not graph", *this);
1358 : }
1359 : const boost::shared_ptr<librdf_stream> pStream(
1360 : librdf_query_results_as_stream(pResults.get()),
1361 2 : safe_librdf_free_stream);
1362 1 : if (!pStream) {
1363 : throw rdf::QueryException(
1364 : "librdf_Repository::queryConstruct: "
1365 0 : "librdf_query_results_as_stream failed", *this);
1366 : }
1367 :
1368 : return new librdf_GraphResult(this, m_aMutex, pStream,
1369 2 : ::boost::shared_ptr<librdf_node>(), pQuery);
1370 : }
1371 :
1372 : ::sal_Bool SAL_CALL
1373 1 : librdf_Repository::queryAsk(const OUString & i_rQuery)
1374 : throw (uno::RuntimeException, rdf::QueryException, rdf::RepositoryException)
1375 : {
1376 1 : ::osl::MutexGuard g(m_aMutex);
1377 :
1378 : const OString query(
1379 2 : OUStringToOString(i_rQuery, RTL_TEXTENCODING_UTF8) );
1380 : const boost::shared_ptr<librdf_query> pQuery(
1381 : librdf_new_query(m_pWorld.get(), s_sparql, NULL,
1382 1 : reinterpret_cast<const unsigned char*> (query.getStr()), NULL),
1383 2 : safe_librdf_free_query);
1384 1 : if (!pQuery) {
1385 : throw rdf::QueryException(
1386 : "librdf_Repository::queryAsk: "
1387 0 : "librdf_new_query failed", *this);
1388 : }
1389 : const boost::shared_ptr<librdf_query_results> pResults(
1390 : librdf_model_query_execute(m_pModel.get(), pQuery.get()),
1391 2 : safe_librdf_free_query_results);
1392 1 : if (!pResults || !librdf_query_results_is_boolean(pResults.get())) {
1393 : throw rdf::QueryException(
1394 : "librdf_Repository::queryAsk: "
1395 0 : "query result is null or not boolean", *this);
1396 : }
1397 1 : return librdf_query_results_get_boolean(pResults.get())
1398 2 : ? sal_True : sal_False;
1399 : }
1400 :
1401 : // ::com::sun::star::rdf::XDocumentRepository:
1402 39 : void SAL_CALL librdf_Repository::setStatementRDFa(
1403 : const uno::Reference< rdf::XResource > & i_xSubject,
1404 : const uno::Sequence< uno::Reference< rdf::XURI > > & i_rPredicates,
1405 : const uno::Reference< rdf::XMetadatable > & i_xObject,
1406 : const OUString & i_rRDFaContent,
1407 : const uno::Reference< rdf::XURI > & i_xRDFaDatatype)
1408 : throw (uno::RuntimeException, lang::IllegalArgumentException,
1409 : rdf::RepositoryException)
1410 : {
1411 39 : static const OUString s_cell("com.sun.star.table.Cell");
1412 39 : static const OUString s_cellprops("com.sun.star.text.CellProperties"); // for writer
1413 39 : static const OUString s_paragraph("com.sun.star.text.Paragraph");
1414 39 : static const OUString s_bookmark("com.sun.star.text.Bookmark");
1415 39 : static const OUString s_meta("com.sun.star.text.InContentMetadata");
1416 :
1417 39 : if (!i_xSubject.is()) {
1418 : throw lang::IllegalArgumentException(
1419 0 : "librdf_Repository::setStatementRDFa: Subject is null", *this, 0);
1420 : }
1421 39 : if (!i_rPredicates.getLength()) {
1422 : throw lang::IllegalArgumentException(
1423 : "librdf_Repository::setStatementRDFa: no Predicates",
1424 1 : *this, 1);
1425 : }
1426 84 : for (sal_Int32 i = 0; i < i_rPredicates.getLength(); ++i) {
1427 46 : if (!i_rPredicates[i].is()) {
1428 : throw lang::IllegalArgumentException(
1429 : "librdf_Repository::setStatementRDFa: Predicate is null",
1430 0 : *this, 1);
1431 : }
1432 : }
1433 38 : if (!i_xObject.is()) {
1434 : throw lang::IllegalArgumentException(
1435 1 : "librdf_Repository::setStatementRDFa: Object is null", *this, 2);
1436 : }
1437 : const uno::Reference<lang::XServiceInfo> xService(i_xObject,
1438 37 : uno::UNO_QUERY_THROW);
1439 74 : uno::Reference<text::XTextRange> xTextRange;
1440 111 : if (xService->supportsService(s_cell) ||
1441 74 : xService->supportsService(s_cellprops) ||
1442 37 : xService->supportsService(s_paragraph))
1443 : {
1444 31 : xTextRange.set(i_xObject, uno::UNO_QUERY_THROW);
1445 : }
1446 8 : else if (xService->supportsService(s_bookmark) ||
1447 2 : xService->supportsService(s_meta))
1448 : {
1449 : const uno::Reference<text::XTextContent> xTextContent(i_xObject,
1450 6 : uno::UNO_QUERY_THROW);
1451 6 : xTextRange = xTextContent->getAnchor();
1452 : }
1453 37 : if (!xTextRange.is()) {
1454 : throw lang::IllegalArgumentException(
1455 : "librdf_Repository::setStatementRDFa: "
1456 0 : "Object does not support RDFa", *this, 2);
1457 : }
1458 : // ensure that the metadatable has an XML ID
1459 37 : i_xObject->ensureMetadataReference();
1460 74 : const beans::StringPair mdref( i_xObject->getMetadataReference() );
1461 37 : if ((mdref.First.isEmpty()) || (mdref.Second.isEmpty())) {
1462 : throw uno::RuntimeException(
1463 : "librdf_Repository::setStatementRDFa: "
1464 0 : "ensureMetadataReference did not", *this);
1465 : }
1466 74 : OUString const sXmlId(mdref.First + "#" + mdref.Second);
1467 74 : uno::Reference<rdf::XURI> xXmlId;
1468 : try {
1469 : xXmlId.set( rdf::URI::create(m_xContext,
1470 74 : OUString::createFromAscii(s_nsOOo) + sXmlId),
1471 37 : uno::UNO_QUERY_THROW);
1472 0 : } catch (const lang::IllegalArgumentException & iae) {
1473 : throw lang::WrappedTargetRuntimeException(
1474 : "librdf_Repository::setStatementRDFa: "
1475 0 : "cannot create URI for XML ID", *this, uno::makeAny(iae));
1476 : }
1477 :
1478 74 : ::osl::MutexGuard g(m_aMutex);
1479 37 : OUString const content( (i_rRDFaContent.isEmpty())
1480 20 : ? xTextRange->getString()
1481 94 : : i_rRDFaContent );
1482 74 : uno::Reference<rdf::XNode> xContent;
1483 : try {
1484 37 : if (i_xRDFaDatatype.is()) {
1485 : xContent.set(rdf::Literal::createWithType(m_xContext,
1486 : content, i_xRDFaDatatype),
1487 11 : uno::UNO_QUERY_THROW);
1488 : } else {
1489 : xContent.set(rdf::Literal::create(m_xContext, content),
1490 26 : uno::UNO_QUERY_THROW);
1491 : }
1492 0 : } catch (const lang::IllegalArgumentException & iae) {
1493 : throw lang::WrappedTargetRuntimeException(
1494 : "librdf_Repository::setStatementRDFa: "
1495 0 : "cannot create literal", *this, uno::makeAny(iae));
1496 : }
1497 37 : removeStatementRDFa(i_xObject);
1498 37 : if (i_rRDFaContent.isEmpty()) {
1499 20 : m_RDFaXHTMLContentSet.erase(sXmlId);
1500 : } else {
1501 17 : m_RDFaXHTMLContentSet.insert(sXmlId);
1502 : }
1503 : ::std::for_each(::comphelper::stl_begin(i_rPredicates),
1504 : ::comphelper::stl_end(i_rPredicates),
1505 : ::boost::bind( &librdf_Repository::addStatementGraph,
1506 74 : this, i_xSubject, _1, xContent, xXmlId, true));
1507 37 : }
1508 :
1509 39 : void SAL_CALL librdf_Repository::removeStatementRDFa(
1510 : const uno::Reference< rdf::XMetadatable > & i_xElement)
1511 : throw (uno::RuntimeException, lang::IllegalArgumentException,
1512 : rdf::RepositoryException)
1513 : {
1514 39 : if (!i_xElement.is()) {
1515 : throw lang::IllegalArgumentException(
1516 : "librdf_Repository::removeStatementRDFa: Element is null",
1517 0 : *this, 0);
1518 : }
1519 :
1520 39 : const beans::StringPair mdref( i_xElement->getMetadataReference() );
1521 39 : if ((mdref.First.isEmpty()) || (mdref.Second.isEmpty())) {
1522 39 : return; // nothing to do...
1523 : }
1524 78 : uno::Reference<rdf::XURI> xXmlId;
1525 : try {
1526 : xXmlId.set( rdf::URI::create(m_xContext,
1527 : OUString::createFromAscii(s_nsOOo)
1528 78 : + mdref.First + "#"
1529 78 : + mdref.Second),
1530 39 : uno::UNO_QUERY_THROW);
1531 0 : } catch (const lang::IllegalArgumentException & iae) {
1532 : throw lang::WrappedTargetRuntimeException(
1533 : "librdf_Repository::removeStatementRDFa: "
1534 0 : "cannot create URI for XML ID", *this, uno::makeAny(iae));
1535 : }
1536 : // clearGraph does locking, not needed here
1537 78 : clearGraph(xXmlId, true);
1538 : }
1539 :
1540 : beans::Pair< uno::Sequence<rdf::Statement>, sal_Bool > SAL_CALL
1541 80 : librdf_Repository::getStatementRDFa(
1542 : const uno::Reference< rdf::XMetadatable > & i_xElement)
1543 : throw (uno::RuntimeException, lang::IllegalArgumentException,
1544 : rdf::RepositoryException)
1545 : {
1546 80 : if (!i_xElement.is()) {
1547 : throw lang::IllegalArgumentException(
1548 0 : "librdf_Repository::getStatementRDFa: Element is null", *this, 0);
1549 : }
1550 80 : const beans::StringPair mdref( i_xElement->getMetadataReference() );
1551 80 : if ((mdref.First.isEmpty()) || (mdref.Second.isEmpty())) {
1552 15 : return beans::Pair< uno::Sequence<rdf::Statement>, sal_Bool >();
1553 : }
1554 130 : OUString const sXmlId(mdref.First + "#" + mdref.Second);
1555 130 : uno::Reference<rdf::XURI> xXmlId;
1556 : try {
1557 : xXmlId.set( rdf::URI::create(m_xContext,
1558 130 : OUString::createFromAscii(s_nsOOo) + sXmlId),
1559 65 : uno::UNO_QUERY_THROW);
1560 0 : } catch (const lang::IllegalArgumentException & iae) {
1561 : throw lang::WrappedTargetRuntimeException(
1562 : "librdf_Repository::getStatementRDFa: "
1563 0 : "cannot create URI for XML ID", *this, uno::makeAny(iae));
1564 : }
1565 :
1566 130 : ::osl::MutexGuard g(m_aMutex);
1567 130 : ::comphelper::SequenceAsVector< rdf::Statement > ret;
1568 : const uno::Reference<container::XEnumeration> xIter(
1569 130 : getStatementsGraph(0, 0, 0, xXmlId, true) );
1570 : OSL_ENSURE(xIter.is(), "getStatementRDFa: no result?");
1571 65 : if (!xIter.is()) throw uno::RuntimeException();
1572 191 : while (xIter->hasMoreElements()) {
1573 61 : rdf::Statement stmt;
1574 61 : if (!(xIter->nextElement() >>= stmt)) {
1575 : OSL_FAIL("getStatementRDFa: result of wrong type?");
1576 : } else {
1577 61 : ret.push_back(stmt);
1578 : }
1579 61 : }
1580 : return beans::Pair< uno::Sequence<rdf::Statement>, sal_Bool >(
1581 145 : ret.getAsConstList(), 0 != m_RDFaXHTMLContentSet.count(sXmlId));
1582 : }
1583 :
1584 : extern "C"
1585 0 : librdf_statement *rdfa_context_stream_map_handler(
1586 : librdf_stream *i_pStream, void *, librdf_statement *i_pStatement)
1587 : {
1588 : OSL_ENSURE(i_pStream, "rdfa_context_stream_map_handler: stream null");
1589 0 : if (i_pStream) {
1590 : librdf_node *pCtxt( static_cast<librdf_node *>
1591 : #if LIBRDF_VERSION >= 10012
1592 0 : (librdf_stream_get_context2(i_pStream)) );
1593 : #else
1594 : (librdf_stream_get_context(i_pStream)) );
1595 : #endif
1596 : OSL_ENSURE(pCtxt, "rdfa_context_stream_map_handler: context null");
1597 0 : if (pCtxt && isInternalContext(pCtxt)) {
1598 0 : return i_pStatement;
1599 : }
1600 : }
1601 0 : return 0;
1602 : };
1603 :
1604 : uno::Reference< container::XEnumeration > SAL_CALL
1605 0 : librdf_Repository::getStatementsRDFa(
1606 : const uno::Reference< rdf::XResource > & i_xSubject,
1607 : const uno::Reference< rdf::XURI > & i_xPredicate,
1608 : const uno::Reference< rdf::XNode > & i_xObject)
1609 : throw (uno::RuntimeException, rdf::RepositoryException)
1610 : {
1611 0 : if (isMetadatableWithoutMetadata(i_xSubject) ||
1612 0 : isMetadatableWithoutMetadata(i_xPredicate) ||
1613 0 : isMetadatableWithoutMetadata(i_xObject))
1614 : {
1615 : return new librdf_GraphResult(this, m_aMutex,
1616 : ::boost::shared_ptr<librdf_stream>(),
1617 0 : ::boost::shared_ptr<librdf_node>());
1618 : }
1619 :
1620 0 : ::osl::MutexGuard g(m_aMutex);
1621 : const boost::shared_ptr<librdf_statement> pStatement(
1622 : m_TypeConverter.mkStatement(m_pWorld.get(),
1623 : i_xSubject, i_xPredicate, i_xObject),
1624 0 : safe_librdf_free_statement);
1625 : OSL_ENSURE(pStatement, "mkStatement failed");
1626 :
1627 : const boost::shared_ptr<librdf_stream> pStream(
1628 : librdf_model_find_statements(m_pModel.get(), pStatement.get()),
1629 0 : safe_librdf_free_stream);
1630 0 : if (!pStream) {
1631 : throw rdf::RepositoryException(
1632 : "librdf_Repository::getStatementsRDFa: "
1633 0 : "librdf_model_find_statements failed", *this);
1634 : }
1635 :
1636 0 : if (librdf_stream_add_map(pStream.get(), rdfa_context_stream_map_handler,
1637 0 : 0, 0)) {
1638 : throw rdf::RepositoryException(
1639 : "librdf_Repository::getStatementsRDFa: "
1640 0 : "librdf_stream_add_map failed", *this);
1641 : }
1642 :
1643 : return new librdf_GraphResult(this, m_aMutex, pStream,
1644 0 : ::boost::shared_ptr<librdf_node>());
1645 : }
1646 :
1647 : // ::com::sun::star::lang::XInitialization:
1648 104 : void SAL_CALL librdf_Repository::initialize(
1649 : const uno::Sequence< ::com::sun::star::uno::Any > & i_rArguments)
1650 : throw (uno::RuntimeException, uno::Exception)
1651 : {
1652 : (void) i_rArguments;
1653 :
1654 104 : ::osl::MutexGuard g(m_aMutex);
1655 :
1656 : // m_pWorld.reset(m_TypeConverter.createWorld(), safe_librdf_free_world);
1657 : m_pStorage.reset(m_TypeConverter.createStorage(m_pWorld.get()),
1658 104 : safe_librdf_free_storage);
1659 : m_pModel.reset(m_TypeConverter.createModel(
1660 104 : m_pWorld.get(), m_pStorage.get()), safe_librdf_free_model);
1661 104 : }
1662 :
1663 44 : const NamedGraphMap_t::iterator SAL_CALL librdf_Repository::clearGraph(
1664 : const uno::Reference< rdf::XURI > & i_xGraphName, bool i_Internal)
1665 : // throw (uno::RuntimeException, container::NoSuchElementException,
1666 : // rdf::RepositoryException)
1667 : {
1668 44 : if (!i_xGraphName.is()) {
1669 : throw lang::IllegalArgumentException(
1670 1 : "librdf_Repository::clearGraph: URI is null", *this, 0);
1671 : }
1672 43 : ::osl::MutexGuard g(m_aMutex);
1673 86 : const OUString contextU( i_xGraphName->getStringValue() );
1674 43 : const NamedGraphMap_t::iterator iter( m_NamedGraphs.find(contextU) );
1675 43 : if (!i_Internal && iter == m_NamedGraphs.end()) {
1676 : throw container::NoSuchElementException(
1677 : "librdf_Repository::clearGraph: "
1678 1 : "no graph with given URI exists", *this);
1679 : }
1680 : const OString context(
1681 84 : OUStringToOString(contextU, RTL_TEXTENCODING_UTF8) );
1682 :
1683 : const boost::shared_ptr<librdf_node> pContext(
1684 : librdf_new_node_from_uri_string(m_pWorld.get(),
1685 42 : reinterpret_cast<const unsigned char*> (context.getStr())),
1686 84 : safe_librdf_free_node);
1687 42 : if (!pContext) {
1688 : throw uno::RuntimeException(
1689 : "librdf_Repository::clearGraph: "
1690 0 : "librdf_new_node_from_uri_string failed", *this);
1691 : }
1692 42 : if (librdf_model_context_remove_statements(m_pModel.get(), pContext.get()))
1693 : {
1694 : throw rdf::RepositoryException(
1695 : "librdf_Repository::clearGraph: "
1696 0 : "librdf_model_context_remove_statements failed", *this);
1697 : }
1698 85 : return iter;
1699 : }
1700 :
1701 446 : void librdf_Repository::addStatementGraph(
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 : const uno::Reference< rdf::XURI > & i_xGraphName,
1706 : bool i_Internal)
1707 : //throw (uno::RuntimeException, lang::IllegalArgumentException,
1708 : // container::NoSuchElementException, rdf::RepositoryException)
1709 : {
1710 446 : if (!i_xSubject.is()) {
1711 : throw lang::IllegalArgumentException(
1712 0 : "librdf_Repository::addStatement: Subject is null", *this, 0);
1713 : }
1714 446 : if (!i_xPredicate.is()) {
1715 : throw lang::IllegalArgumentException(
1716 : "librdf_Repository::addStatement: Predicate is null",
1717 0 : *this, 1);
1718 : }
1719 446 : if (!i_xObject.is()) {
1720 : throw lang::IllegalArgumentException(
1721 0 : "librdf_Repository::addStatement: Object is null", *this, 2);
1722 : }
1723 :
1724 446 : ::osl::MutexGuard g(m_aMutex);
1725 861 : const OUString contextU( i_xGraphName->getStringValue() );
1726 446 : if (!i_Internal && (m_NamedGraphs.find(contextU) == m_NamedGraphs.end())) {
1727 : throw container::NoSuchElementException(
1728 : "librdf_Repository::addStatement: "
1729 1 : "no graph with given URI exists", *this);
1730 : }
1731 : const OString context(
1732 859 : OUStringToOString(contextU, RTL_TEXTENCODING_UTF8) );
1733 :
1734 : const boost::shared_ptr<librdf_node> pContext(
1735 : librdf_new_node_from_uri_string(m_pWorld.get(),
1736 445 : reinterpret_cast<const unsigned char*> (context.getStr())),
1737 859 : safe_librdf_free_node);
1738 445 : if (!pContext) {
1739 : throw uno::RuntimeException(
1740 : "librdf_Repository::addStatement: "
1741 0 : "librdf_new_node_from_uri_string failed", *this);
1742 : }
1743 : const boost::shared_ptr<librdf_statement> pStatement(
1744 : m_TypeConverter.mkStatement(m_pWorld.get(),
1745 : i_xSubject, i_xPredicate, i_xObject),
1746 859 : safe_librdf_free_statement);
1747 : OSL_ENSURE(pStatement, "mkStatement failed");
1748 :
1749 : // Test for duplicate statement
1750 : // librdf_model_add_statement disallows duplicates while
1751 : // librdf_model_context_add_statement allows duplicates
1752 : {
1753 : const boost::shared_ptr<librdf_stream> pStream(
1754 : librdf_model_find_statements_in_context(m_pModel.get(),
1755 : pStatement.get(), pContext.get()),
1756 445 : safe_librdf_free_stream);
1757 445 : if (pStream && !librdf_stream_end(pStream.get()))
1758 476 : return;
1759 : }
1760 :
1761 414 : if (librdf_model_context_add_statement(m_pModel.get(),
1762 414 : pContext.get(), pStatement.get())) {
1763 : throw rdf::RepositoryException(
1764 : "librdf_Repository::addStatement: "
1765 0 : "librdf_model_context_add_statement failed", *this);
1766 415 : }
1767 : }
1768 :
1769 9 : void librdf_Repository::removeStatementsGraph(
1770 : const uno::Reference< rdf::XResource > & i_xSubject,
1771 : const uno::Reference< rdf::XURI > & i_xPredicate,
1772 : const uno::Reference< rdf::XNode > & i_xObject,
1773 : const uno::Reference< rdf::XURI > & i_xGraphName)
1774 : //throw (uno::RuntimeException, lang::IllegalArgumentException,
1775 : // container::NoSuchElementException, rdf::RepositoryException)
1776 : {
1777 27 : if (isMetadatableWithoutMetadata(i_xSubject) ||
1778 18 : isMetadatableWithoutMetadata(i_xPredicate) ||
1779 9 : isMetadatableWithoutMetadata(i_xObject))
1780 : {
1781 8 : return;
1782 : }
1783 :
1784 9 : ::osl::MutexGuard g(m_aMutex);
1785 18 : const OUString contextU( i_xGraphName->getStringValue() );
1786 9 : if (m_NamedGraphs.find(contextU) == m_NamedGraphs.end()) {
1787 : throw container::NoSuchElementException(
1788 : "librdf_Repository::removeStatements: "
1789 1 : "no graph with given URI exists", *this);
1790 : }
1791 : const OString context(
1792 16 : OUStringToOString(contextU, RTL_TEXTENCODING_UTF8) );
1793 :
1794 : const boost::shared_ptr<librdf_node> pContext(
1795 : librdf_new_node_from_uri_string(m_pWorld.get(),
1796 8 : reinterpret_cast<const unsigned char*> (context.getStr())),
1797 16 : safe_librdf_free_node);
1798 8 : if (!pContext) {
1799 : throw uno::RuntimeException(
1800 : "librdf_Repository::removeStatements: "
1801 0 : "librdf_new_node_from_uri_string failed", *this);
1802 : }
1803 : const boost::shared_ptr<librdf_statement> pStatement(
1804 : m_TypeConverter.mkStatement(m_pWorld.get(),
1805 : i_xSubject, i_xPredicate, i_xObject),
1806 16 : safe_librdf_free_statement);
1807 : OSL_ENSURE(pStatement, "mkStatement failed");
1808 :
1809 : const boost::shared_ptr<librdf_stream> pStream(
1810 : librdf_model_find_statements_in_context(m_pModel.get(),
1811 : pStatement.get(), pContext.get()),
1812 16 : safe_librdf_free_stream);
1813 8 : if (!pStream) {
1814 : throw rdf::RepositoryException(
1815 : "librdf_Repository::removeStatements: "
1816 0 : "librdf_model_find_statements_in_context failed", *this);
1817 : }
1818 :
1819 8 : if (!librdf_stream_end(pStream.get())) {
1820 10 : do {
1821 10 : librdf_statement *pStmt( librdf_stream_get_object(pStream.get()) );
1822 10 : if (!pStmt) {
1823 : throw rdf::RepositoryException(
1824 : "librdf_Repository::removeStatements: "
1825 0 : "librdf_stream_get_object failed", *this);
1826 : }
1827 10 : if (librdf_model_context_remove_statement(m_pModel.get(),
1828 10 : pContext.get(), pStmt)) {
1829 : throw rdf::RepositoryException(
1830 : "librdf_Repository::removeStatements: "
1831 0 : "librdf_model_context_remove_statement failed", *this);
1832 : }
1833 10 : } while (!librdf_stream_next(pStream.get()));
1834 9 : }
1835 : }
1836 :
1837 : uno::Reference< container::XEnumeration >
1838 328 : librdf_Repository::getStatementsGraph(
1839 : const uno::Reference< rdf::XResource > & i_xSubject,
1840 : const uno::Reference< rdf::XURI > & i_xPredicate,
1841 : const uno::Reference< rdf::XNode > & i_xObject,
1842 : const uno::Reference< rdf::XURI > & i_xGraphName,
1843 : bool i_Internal)
1844 : //throw (uno::RuntimeException, lang::IllegalArgumentException,
1845 : // container::NoSuchElementException, rdf::RepositoryException)
1846 : {
1847 : // N.B.: if any of subject, predicate, object is an XMetadatable, and
1848 : // has no metadata reference, then there cannot be any node in the graph
1849 : // representing it; in order to prevent side effect
1850 : // (ensureMetadataReference), check for this condition and return
1851 984 : if (isMetadatableWithoutMetadata(i_xSubject) ||
1852 656 : isMetadatableWithoutMetadata(i_xPredicate) ||
1853 328 : isMetadatableWithoutMetadata(i_xObject))
1854 : {
1855 : return new librdf_GraphResult(this, m_aMutex,
1856 : ::boost::shared_ptr<librdf_stream>(),
1857 0 : ::boost::shared_ptr<librdf_node>());
1858 : }
1859 :
1860 328 : ::osl::MutexGuard g(m_aMutex);
1861 656 : const OUString contextU( i_xGraphName->getStringValue() );
1862 328 : if (!i_Internal && (m_NamedGraphs.find(contextU) == m_NamedGraphs.end())) {
1863 : throw container::NoSuchElementException(
1864 : "librdf_Repository::getStatements: "
1865 1 : "no graph with given URI exists", *this);
1866 : }
1867 : const OString context(
1868 654 : OUStringToOString(contextU, RTL_TEXTENCODING_UTF8) );
1869 :
1870 : const boost::shared_ptr<librdf_node> pContext(
1871 : librdf_new_node_from_uri_string(m_pWorld.get(),
1872 327 : reinterpret_cast<const unsigned char*> (context.getStr())),
1873 654 : safe_librdf_free_node);
1874 327 : if (!pContext) {
1875 : throw uno::RuntimeException(
1876 : "librdf_Repository::getStatements: "
1877 0 : "librdf_new_node_from_uri_string failed", *this);
1878 : }
1879 : const boost::shared_ptr<librdf_statement> pStatement(
1880 : m_TypeConverter.mkStatement(m_pWorld.get(),
1881 : i_xSubject, i_xPredicate, i_xObject),
1882 654 : safe_librdf_free_statement);
1883 : OSL_ENSURE(pStatement, "mkStatement failed");
1884 :
1885 : const boost::shared_ptr<librdf_stream> pStream(
1886 : librdf_model_find_statements_in_context(m_pModel.get(),
1887 : pStatement.get(), pContext.get()),
1888 654 : safe_librdf_free_stream);
1889 327 : if (!pStream) {
1890 : throw rdf::RepositoryException(
1891 : "librdf_Repository::getStatements: "
1892 0 : "librdf_model_find_statements_in_context failed", *this);
1893 : }
1894 :
1895 : // librdf_model_find_statements_in_context is buggy and does not put
1896 : // the context into result statements; pass it to librdf_GraphResult here
1897 655 : return new librdf_GraphResult(this, m_aMutex, pStream, pContext);
1898 : }
1899 :
1900 : extern "C"
1901 30 : void librdf_raptor_init(void* /*user_data*/, raptor_world* pRaptorWorld)
1902 : {
1903 : // fdo#64672 prevent raptor from setting global libxml2 error handlers
1904 : raptor_world_set_flag(pRaptorWorld,
1905 30 : RAPTOR_WORLD_FLAG_LIBXML_STRUCTURED_ERROR_SAVE, 0);
1906 : raptor_world_set_flag(pRaptorWorld,
1907 30 : RAPTOR_WORLD_FLAG_LIBXML_GENERIC_ERROR_SAVE, 0);
1908 30 : }
1909 :
1910 30 : librdf_world *librdf_TypeConverter::createWorld() const
1911 : {
1912 : // create and initialize world
1913 30 : librdf_world *pWorld( librdf_new_world() );
1914 30 : if (!pWorld) {
1915 : throw uno::RuntimeException(
1916 : "librdf_TypeConverter::createWorld: librdf_new_world failed",
1917 0 : m_rRep);
1918 : }
1919 30 : librdf_world_set_raptor_init_handler(pWorld, 0, &librdf_raptor_init);
1920 : //FIXME logger, digest, features?
1921 30 : xsltSecurityPrefsPtr origprefs = xsltGetDefaultSecurityPrefs();
1922 30 : librdf_world_open(pWorld);
1923 30 : xsltSecurityPrefsPtr newprefs = xsltGetDefaultSecurityPrefs();
1924 30 : if (newprefs != origprefs) {
1925 : // #i110523# restore libxslt global configuration
1926 : // (gratuitously overwritten by raptor_init_parser_grddl_common)
1927 : // (this is the only reason unordf is linked against libxslt)
1928 0 : xsltSetDefaultSecurityPrefs(origprefs);
1929 : }
1930 30 : return pWorld;
1931 : }
1932 :
1933 : librdf_storage *
1934 104 : librdf_TypeConverter::createStorage(librdf_world *i_pWorld) const
1935 : {
1936 : librdf_storage *pStorage(
1937 : // librdf_new_storage(i_pWorld, "memory", NULL, "contexts='yes'") );
1938 : librdf_new_storage(i_pWorld, "hashes", NULL,
1939 104 : "contexts='yes',hash-type='memory'") );
1940 104 : if (!pStorage) {
1941 : throw uno::RuntimeException(
1942 : "librdf_TypeConverter::createStorage: librdf_new_storage failed",
1943 0 : m_rRep);
1944 : }
1945 104 : return pStorage;
1946 : }
1947 :
1948 104 : librdf_model *librdf_TypeConverter::createModel(
1949 : librdf_world *i_pWorld, librdf_storage * i_pStorage) const
1950 : {
1951 104 : librdf_model *pRepository( librdf_new_model(i_pWorld, i_pStorage, NULL) );
1952 104 : if (!pRepository) {
1953 : throw uno::RuntimeException(
1954 : "librdf_TypeConverter::createModel: librdf_new_model failed",
1955 0 : m_rRep);
1956 : }
1957 : //FIXME
1958 : #if 0
1959 : {
1960 : librdf_uri * ctxt = librdf_new_uri(i_pWorld, reinterpret_cast<const unsigned char *>(LIBRDF_MODEL_FEATURE_CONTEXTS));
1961 : librdf_node * contexts = librdf_model_get_feature(repository, ctxt);
1962 : if (!contexts)
1963 : throw;
1964 : std::cout << "value of contexts feature: ";
1965 : prtNode(contexts);
1966 : std::cout << std::endl;
1967 : // librdf_model_set_feature(repository, LIBRDF_FEATURE_CONTEXTS, ...);
1968 : safe_librdf_free_node(contexts);
1969 : safe_librdf_free_uri(ctxt);
1970 : }
1971 : #endif
1972 104 : return pRepository;
1973 : }
1974 :
1975 : // this does NOT create a node, only URI
1976 12 : librdf_uri* librdf_TypeConverter::mkURI( librdf_world* i_pWorld,
1977 : const uno::Reference< rdf::XURI > & i_xURI) const
1978 : {
1979 : const OString uri(
1980 24 : OUStringToOString(i_xURI->getStringValue(),
1981 24 : RTL_TEXTENCODING_UTF8) );
1982 : librdf_uri *pURI( librdf_new_uri(i_pWorld,
1983 12 : reinterpret_cast<const unsigned char *>(uri.getStr())));
1984 12 : if (!pURI) {
1985 : throw uno::RuntimeException(
1986 0 : "librdf_TypeConverter::mkURI: librdf_new_uri failed", 0);
1987 : }
1988 12 : return pURI;
1989 : }
1990 :
1991 : // create blank or URI node
1992 2321 : librdf_node* librdf_TypeConverter::mkResource( librdf_world* i_pWorld,
1993 : const uno::Reference< rdf::XResource > & i_xResource) const
1994 : {
1995 2321 : if (!i_xResource.is()) return 0;
1996 2042 : uno::Reference< rdf::XBlankNode > xBlankNode(i_xResource, uno::UNO_QUERY);
1997 2042 : if (xBlankNode.is()) {
1998 : const OString label(
1999 14 : OUStringToOString(xBlankNode->getStringValue(),
2000 14 : RTL_TEXTENCODING_UTF8) );
2001 : librdf_node *pNode(
2002 : librdf_new_node_from_blank_identifier(i_pWorld,
2003 7 : reinterpret_cast<const unsigned char*> (label.getStr())));
2004 7 : if (!pNode) {
2005 : throw uno::RuntimeException(
2006 : "librdf_TypeConverter::mkResource: "
2007 0 : "librdf_new_node_from_blank_identifier failed", 0);
2008 : }
2009 7 : return pNode;
2010 : } else { // assumption: everything else is URI
2011 : const OString uri(
2012 4070 : OUStringToOString(i_xResource->getStringValue(),
2013 4070 : RTL_TEXTENCODING_UTF8) );
2014 : librdf_node *pNode(
2015 : librdf_new_node_from_uri_string(i_pWorld,
2016 2035 : reinterpret_cast<const unsigned char*> (uri.getStr())));
2017 2035 : if (!pNode) {
2018 : throw uno::RuntimeException(
2019 : "librdf_TypeConverter::mkResource: "
2020 0 : "librdf_new_node_from_uri_string failed", 0);
2021 : }
2022 2035 : return pNode;
2023 2042 : }
2024 : }
2025 :
2026 : // create blank or URI or literal node
2027 885 : librdf_node* librdf_TypeConverter::mkNode( librdf_world* i_pWorld,
2028 : const uno::Reference< rdf::XNode > & i_xNode) const
2029 : {
2030 885 : if (!i_xNode.is()) return 0;
2031 602 : uno::Reference< rdf::XResource > xResource(i_xNode, uno::UNO_QUERY);
2032 602 : if (xResource.is()) {
2033 551 : return mkResource(i_pWorld, xResource);
2034 : }
2035 102 : uno::Reference< rdf::XLiteral> xLiteral(i_xNode, uno::UNO_QUERY);
2036 : OSL_ENSURE(xLiteral.is(),
2037 : "mkNode: someone invented a new rdf.XNode and did not tell me");
2038 51 : if (!xLiteral.is()) return 0;
2039 : const OString val(
2040 51 : OUStringToOString(xLiteral->getValue(),
2041 102 : RTL_TEXTENCODING_UTF8) );
2042 : const OString lang(
2043 51 : OUStringToOString(xLiteral->getLanguage(),
2044 102 : RTL_TEXTENCODING_UTF8) );
2045 102 : const uno::Reference< rdf::XURI > xType(xLiteral->getDatatype());
2046 51 : librdf_node * ret(0);
2047 51 : if (lang.isEmpty()) {
2048 49 : if (!xType.is()) {
2049 : ret = librdf_new_node_from_literal(i_pWorld,
2050 37 : reinterpret_cast<const unsigned char*> (val.getStr()),
2051 37 : NULL, 0);
2052 : } else {
2053 : const boost::shared_ptr<librdf_uri> pDatatype(
2054 12 : mkURI(i_pWorld, xType), safe_librdf_free_uri);
2055 : ret = librdf_new_node_from_typed_literal(i_pWorld,
2056 12 : reinterpret_cast<const unsigned char*> (val.getStr()),
2057 24 : NULL, pDatatype.get());
2058 : }
2059 : } else {
2060 2 : if (!xType.is()) {
2061 : ret = librdf_new_node_from_literal(i_pWorld,
2062 2 : reinterpret_cast<const unsigned char*> (val.getStr()),
2063 4 : (lang.getStr()), 0);
2064 :
2065 : } else {
2066 : OSL_FAIL("mkNode: invalid literal");
2067 0 : return 0;
2068 : }
2069 : }
2070 51 : if (!ret) {
2071 : throw uno::RuntimeException(
2072 0 : "librdf_TypeConverter::mkNode: librdf_new_node_from_literal failed", 0);
2073 : }
2074 653 : return ret;
2075 : }
2076 :
2077 885 : librdf_statement* librdf_TypeConverter::mkStatement( librdf_world* i_pWorld,
2078 : const uno::Reference< rdf::XResource > & i_xSubject,
2079 : const uno::Reference< rdf::XURI > & i_xPredicate,
2080 : const uno::Reference< rdf::XNode > & i_xObject) const
2081 : {
2082 885 : librdf_node* pSubject( mkResource(i_pWorld, i_xSubject) );
2083 885 : librdf_node* pPredicate(0);
2084 885 : librdf_node* pObject(0);
2085 : try {
2086 : const uno::Reference<rdf::XResource> xPredicate(i_xPredicate,
2087 885 : uno::UNO_QUERY);
2088 885 : pPredicate = mkResource(i_pWorld, xPredicate);
2089 : try {
2090 885 : pObject = mkNode(i_pWorld, i_xObject);
2091 0 : } catch (...) {
2092 0 : safe_librdf_free_node(pPredicate);
2093 0 : throw;
2094 885 : }
2095 0 : } catch (...) {
2096 0 : safe_librdf_free_node(pSubject);
2097 0 : throw;
2098 : }
2099 : // NB: this takes ownership of the nodes! (which is really ugly)
2100 : librdf_statement* pStatement( librdf_new_statement_from_nodes(i_pWorld,
2101 885 : pSubject, pPredicate, pObject) );
2102 885 : if (!pStatement) {
2103 : throw uno::RuntimeException(
2104 : "librdf_TypeConverter::mkStatement: "
2105 0 : "librdf_new_statement_from_nodes failed", 0);
2106 : }
2107 885 : return pStatement;
2108 : }
2109 :
2110 : uno::Reference<rdf::XURI>
2111 1003 : librdf_TypeConverter::convertToXURI(librdf_uri* i_pURI) const
2112 : {
2113 1003 : if (!i_pURI) return 0;
2114 1003 : const unsigned char* uri( librdf_uri_as_string(i_pURI) );
2115 1003 : if (!uri) {
2116 : throw uno::RuntimeException(
2117 : "librdf_TypeConverter::convertToXURI: "
2118 0 : "librdf_uri_as_string failed", m_rRep);
2119 : }
2120 : OUString uriU( OStringToOUString(
2121 : OString(reinterpret_cast<const sal_Char*>(uri)),
2122 1003 : RTL_TEXTENCODING_UTF8) );
2123 : try {
2124 1003 : return rdf::URI::create(m_xContext, uriU);
2125 0 : } catch (const lang::IllegalArgumentException & iae) {
2126 : throw lang::WrappedTargetRuntimeException(
2127 : "librdf_TypeConverter::convertToXURI: "
2128 0 : "illegal uri", m_rRep, uno::makeAny(iae));
2129 1003 : }
2130 : }
2131 :
2132 : uno::Reference<rdf::XURI>
2133 1046 : librdf_TypeConverter::convertToXURI(librdf_node* i_pNode) const
2134 : {
2135 1046 : if (!i_pNode) return 0;
2136 984 : if (librdf_node_is_resource(i_pNode)) {
2137 984 : librdf_uri* pURI( librdf_node_get_uri(i_pNode) );
2138 984 : if (!pURI) {
2139 : throw uno::RuntimeException(
2140 : "librdf_TypeConverter::convertToXURI: "
2141 0 : "resource has no uri", m_rRep);
2142 : }
2143 984 : return convertToXURI(pURI);
2144 : } else {
2145 : OSL_FAIL("convertToXURI: unknown librdf_node");
2146 0 : return 0;
2147 : }
2148 : }
2149 :
2150 : uno::Reference<rdf::XResource>
2151 458 : librdf_TypeConverter::convertToXResource(librdf_node* i_pNode) const
2152 : {
2153 458 : if (!i_pNode) return 0;
2154 458 : if (librdf_node_is_blank(i_pNode)) {
2155 16 : const unsigned char* label( librdf_node_get_blank_identifier(i_pNode) );
2156 16 : if (!label) {
2157 : throw uno::RuntimeException(
2158 : "librdf_TypeConverter::convertToXResource: "
2159 0 : "blank node has no label", m_rRep);
2160 : }
2161 : OUString labelU( OStringToOUString(
2162 : OString(reinterpret_cast<const sal_Char*>(label)),
2163 16 : RTL_TEXTENCODING_UTF8) );
2164 : try {
2165 : return uno::Reference<rdf::XResource>(
2166 16 : rdf::BlankNode::create(m_xContext, labelU), uno::UNO_QUERY);
2167 0 : } catch (const lang::IllegalArgumentException & iae) {
2168 : throw lang::WrappedTargetRuntimeException(
2169 : "librdf_TypeConverter::convertToXResource: "
2170 0 : "illegal blank node label", m_rRep, uno::makeAny(iae));
2171 16 : }
2172 : } else {
2173 : return uno::Reference<rdf::XResource>(convertToXURI(i_pNode),
2174 442 : uno::UNO_QUERY);
2175 : }
2176 : }
2177 :
2178 : uno::Reference<rdf::XNode>
2179 311 : librdf_TypeConverter::convertToXNode(librdf_node* i_pNode) const
2180 : {
2181 311 : if (!i_pNode) return 0;
2182 311 : if (!librdf_node_is_literal(i_pNode)) {
2183 : return uno::Reference<rdf::XNode>(convertToXResource(i_pNode),
2184 156 : uno::UNO_QUERY);
2185 : }
2186 155 : const unsigned char* value( librdf_node_get_literal_value(i_pNode) );
2187 155 : if (!value) {
2188 : throw uno::RuntimeException(
2189 : "librdf_TypeConverter::convertToXNode: "
2190 0 : "literal has no value", m_rRep);
2191 : }
2192 155 : const char * lang( librdf_node_get_literal_value_language(i_pNode) );
2193 : librdf_uri* pType(
2194 155 : librdf_node_get_literal_value_datatype_uri(i_pNode) );
2195 : OSL_ENSURE(!lang || !pType, "convertToXNode: invalid literal");
2196 : const OUString valueU( OStringToOUString(
2197 : OString(reinterpret_cast<const sal_Char*>(value)),
2198 155 : RTL_TEXTENCODING_UTF8) );
2199 155 : if (lang) {
2200 : const OUString langU( OStringToOUString(
2201 : OString(reinterpret_cast<const sal_Char*>(lang)),
2202 2 : RTL_TEXTENCODING_UTF8) );
2203 : return uno::Reference<rdf::XNode>(
2204 : rdf::Literal::createWithLanguage(m_xContext, valueU, langU),
2205 2 : uno::UNO_QUERY);
2206 153 : } else if (pType) {
2207 19 : uno::Reference<rdf::XURI> xType(convertToXURI(pType));
2208 : OSL_ENSURE(xType.is(), "convertToXNode: null uri");
2209 : return uno::Reference<rdf::XNode>(
2210 : rdf::Literal::createWithType(m_xContext, valueU, xType),
2211 19 : uno::UNO_QUERY);
2212 : } else {
2213 : return uno::Reference<rdf::XNode>(
2214 : rdf::Literal::create(m_xContext, valueU),
2215 134 : uno::UNO_QUERY);
2216 155 : }
2217 : }
2218 :
2219 : rdf::Statement
2220 302 : librdf_TypeConverter::convertToStatement(librdf_statement* i_pStmt,
2221 : librdf_node* i_pContext) const
2222 : {
2223 302 : if (!i_pStmt) {
2224 0 : throw uno::RuntimeException();
2225 : }
2226 : return rdf::Statement(
2227 : convertToXResource(librdf_statement_get_subject(i_pStmt)),
2228 : convertToXURI(librdf_statement_get_predicate(i_pStmt)),
2229 : convertToXNode(librdf_statement_get_object(i_pStmt)),
2230 302 : convertToXURI(i_pContext));
2231 : }
2232 :
2233 : } // closing anonymous implementation namespace
2234 :
2235 :
2236 :
2237 : // component helper namespace
2238 : namespace comp_librdf_Repository {
2239 :
2240 65 : OUString SAL_CALL _getImplementationName() {
2241 65 : return OUString("librdf_Repository");
2242 : }
2243 :
2244 30 : uno::Sequence< OUString > SAL_CALL _getSupportedServiceNames()
2245 : {
2246 30 : uno::Sequence< OUString > s(1);
2247 30 : s[0] = "com.sun.star.rdf.Repository";
2248 30 : return s;
2249 : }
2250 :
2251 104 : uno::Reference< uno::XInterface > SAL_CALL _create(
2252 : const uno::Reference< uno::XComponentContext > & context)
2253 : SAL_THROW((uno::Exception))
2254 : {
2255 104 : return static_cast< ::cppu::OWeakObject * >(new librdf_Repository(context));
2256 : }
2257 :
2258 90 : } // closing component helper namespace
2259 :
2260 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|