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

Generated by: LCOV version 1.11