LCOV - code coverage report
Current view: top level - unoxml/source/rdf - librdf_repository.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 683 821 83.2 %
Date: 2014-11-03 Functions: 102 111 91.9 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10