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