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

Generated by: LCOV version 1.10