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

Generated by: LCOV version 1.10