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