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