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

Generated by: LCOV version 1.10