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