| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| #include "librdf_repository.hxx" |
| |
| #include <string.h> |
| |
| #include <set> |
| #include <map> |
| #include <functional> |
| #include <algorithm> |
| |
| #include <boost/utility.hpp> |
| #include <boost/shared_ptr.hpp> |
| #include <boost/shared_array.hpp> |
| #include <boost/bind.hpp> |
| |
| #include <libxslt/security.h> |
| #include <libxml/parser.h> |
| |
| // #i114999# do not include librdf.h, it is broken in redland 1.0.11 |
| #include <redland.h> |
| |
| #include <com/sun/star/lang/XServiceInfo.hpp> |
| #include <com/sun/star/lang/XInitialization.hpp> |
| #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp> |
| #include <com/sun/star/lang/IllegalArgumentException.hpp> |
| #include <com/sun/star/io/XSeekableInputStream.hpp> |
| #include <com/sun/star/text/XTextRange.hpp> |
| #include <com/sun/star/rdf/XDocumentRepository.hpp> |
| #include <com/sun/star/rdf/XLiteral.hpp> |
| #include <com/sun/star/rdf/FileFormat.hpp> |
| #include <com/sun/star/rdf/URIs.hpp> |
| #include <com/sun/star/rdf/BlankNode.hpp> |
| #include <com/sun/star/rdf/URI.hpp> |
| #include <com/sun/star/rdf/Literal.hpp> |
| |
| #include <rtl/ref.hxx> |
| #include <rtl/ustring.hxx> |
| #include <cppuhelper/implbase1.hxx> |
| #include <cppuhelper/implbase3.hxx> |
| #include <cppuhelper/basemutex.hxx> |
| |
| #include <comphelper/stlunosequence.hxx> |
| #include <comphelper/sequenceasvector.hxx> |
| #include <comphelper/makesequence.hxx> |
| |
| |
| /** |
| Implementation of the service com.sun.star.rdf.Repository. |
| |
| This implementation uses the Redland RDF library (librdf). |
| |
| There are several classes involved: |
| librdf_TypeConverter: helper class to convert data types redland <-> uno |
| librdf_Repository: the main repository, does almost all the work |
| librdf_NamedGraph: the XNamedGraph, forwards everything to repository |
| librdf_GraphResult: an XEnumeration<Statement> |
| librdf_QuerySelectResult: an XEnumeration<sequence<XNode>> |
| |
| @author mst |
| */ |
| |
| /// anonymous implementation namespace |
| namespace { |
| |
| class librdf_NamedGraph; |
| class librdf_Repository; |
| |
| using namespace ::com::sun::star; |
| |
| typedef std::map< ::rtl::OUString, ::rtl::Reference<librdf_NamedGraph> > |
| NamedGraphMap_t; |
| |
| const char s_sparql [] = "sparql"; |
| const char s_nsRDFs [] = "http://www.w3.org/2000/01/rdf-schema#"; |
| const char s_label [] = "label"; |
| const char s_nsOOo [] = "http://openoffice.org/2004/office/rdfa/"; |
| |
| //////////////////////////////////////////////////////////////////////////// |
| |
| //FIXME: this approach is not ideal. can we use blind nodes instead? |
| bool isInternalContext(librdf_node *i_pNode) throw () |
| { |
| OSL_ENSURE(i_pNode, "isInternalContext: context null"); |
| OSL_ENSURE(librdf_node_is_resource(i_pNode), |
| "isInternalContext: context not resource"); |
| if (i_pNode) { |
| librdf_uri *pURI(librdf_node_get_uri(i_pNode)); |
| OSL_ENSURE(pURI, "isInternalContext: URI null"); |
| if (pURI) { |
| unsigned char *pContextURI(librdf_uri_as_string(pURI)); |
| OSL_ENSURE(pContextURI, |
| "isInternalContext: URI string null"); |
| // if prefix matches reserved uri, it is RDFa context |
| if (!strncmp(reinterpret_cast<char *>(pContextURI), |
| s_nsOOo, sizeof(s_nsOOo)-1)) { |
| return true; |
| } |
| } |
| return false; |
| } |
| return true; |
| } |
| |
| |
| //////////////////////////////////////////////////////////////////////////// |
| |
| // n.b.: librdf destructor functions dereference null pointers! |
| // so they need to be wrapped to be usable with boost::shared_ptr. |
| static void safe_librdf_free_world(librdf_world *const world) |
| { |
| if (world) { librdf_free_world(world); } |
| } |
| static void safe_librdf_free_model(librdf_model *const model) |
| { |
| if (model) { librdf_free_model(model); } |
| } |
| static void safe_librdf_free_node(librdf_node* node) |
| { |
| if (node) { librdf_free_node(node); } |
| } |
| static void safe_librdf_free_parser(librdf_parser *const parser) |
| { |
| if (parser) { librdf_free_parser(parser); } |
| } |
| static void safe_librdf_free_query(librdf_query *const query) |
| { |
| if (query) { librdf_free_query(query); } |
| } |
| static void |
| safe_librdf_free_query_results(librdf_query_results *const query_results) |
| { |
| if (query_results) { librdf_free_query_results(query_results); } |
| } |
| static void safe_librdf_free_serializer(librdf_serializer *const serializer) |
| { |
| if (serializer) { librdf_free_serializer(serializer); } |
| } |
| static void safe_librdf_free_statement(librdf_statement *const statement) |
| { |
| if (statement) { librdf_free_statement(statement); } |
| } |
| static void safe_librdf_free_storage(librdf_storage *const storage) |
| { |
| if (storage) { librdf_free_storage(storage); } |
| } |
| static void safe_librdf_free_stream(librdf_stream *const stream) |
| { |
| if (stream) { librdf_free_stream(stream); } |
| } |
| static void safe_librdf_free_uri(librdf_uri *const uri) |
| { |
| if (uri) { librdf_free_uri(uri); } |
| } |
| |
| |
| //////////////////////////////////////////////////////////////////////////// |
| |
| /** converts between librdf types and UNO API types. |
| */ |
| class librdf_TypeConverter |
| { |
| public: |
| librdf_TypeConverter( |
| uno::Reference< uno::XComponentContext > const & i_xContext, |
| librdf_Repository &i_rRep) |
| : m_xContext(i_xContext) |
| , m_rRep(i_rRep) |
| { }; |
| |
| librdf_world *createWorld() const; |
| librdf_storage *createStorage(librdf_world *i_pWorld) const; |
| librdf_model *createModel(librdf_world *i_pWorld, |
| librdf_storage * i_pStorage) const; |
| librdf_uri* mkURI( librdf_world* i_pWorld, |
| const uno::Reference< rdf::XURI > & i_xURI) const; |
| librdf_node* mkResource( librdf_world* i_pWorld, |
| const uno::Reference< rdf::XResource > & i_xResource) const; |
| librdf_node* mkNode( librdf_world* i_pWorld, |
| const uno::Reference< rdf::XNode > & i_xNode) const; |
| librdf_statement* mkStatement( librdf_world* i_pWorld, |
| const uno::Reference< rdf::XResource > & i_xSubject, |
| const uno::Reference< rdf::XURI > & i_xPredicate, |
| const uno::Reference< rdf::XNode > & i_xObject) const; |
| uno::Reference<rdf::XURI> convertToXURI(librdf_uri* i_pURI) const; |
| uno::Reference<rdf::XURI> convertToXURI(librdf_node* i_pURI) const; |
| uno::Reference<rdf::XResource> |
| convertToXResource(librdf_node* i_pNode) const; |
| uno::Reference<rdf::XNode> convertToXNode(librdf_node* i_pNode) const; |
| rdf::Statement |
| convertToStatement(librdf_statement* i_pStmt, librdf_node* i_pContext) |
| const; |
| |
| private: |
| uno::Reference< uno::XComponentContext > m_xContext; |
| librdf_Repository & m_rRep; |
| }; |
| |
| |
| //////////////////////////////////////////////////////////////////////////// |
| |
| /** implements the repository service. |
| */ |
| class librdf_Repository: |
| private boost::noncopyable, |
| // private ::cppu::BaseMutex, |
| public ::cppu::WeakImplHelper3< |
| lang::XServiceInfo, |
| rdf::XDocumentRepository, |
| lang::XInitialization> |
| { |
| public: |
| |
| explicit librdf_Repository( |
| uno::Reference< uno::XComponentContext > const & i_xContext); |
| virtual ~librdf_Repository(); |
| |
| // ::com::sun::star::lang::XServiceInfo: |
| virtual ::rtl::OUString SAL_CALL getImplementationName() |
| throw (uno::RuntimeException); |
| virtual ::sal_Bool SAL_CALL supportsService( |
| const ::rtl::OUString & ServiceName) throw (uno::RuntimeException); |
| virtual uno::Sequence< ::rtl::OUString > SAL_CALL |
| getSupportedServiceNames() throw (uno::RuntimeException); |
| |
| // ::com::sun::star::rdf::XRepository: |
| virtual uno::Reference< rdf::XBlankNode > SAL_CALL createBlankNode() |
| throw (uno::RuntimeException); |
| virtual uno::Reference<rdf::XNamedGraph> SAL_CALL importGraph( |
| ::sal_Int16 i_Format, |
| const uno::Reference< io::XInputStream > & i_xInStream, |
| const uno::Reference< rdf::XURI > & i_xGraphName, |
| const uno::Reference< rdf::XURI > & i_xBaseURI) |
| throw (uno::RuntimeException, lang::IllegalArgumentException, |
| datatransfer::UnsupportedFlavorException, |
| container::ElementExistException, rdf::ParseException, |
| rdf::RepositoryException, io::IOException); |
| virtual void SAL_CALL exportGraph(::sal_Int16 i_Format, |
| const uno::Reference< io::XOutputStream > & i_xOutStream, |
| const uno::Reference< rdf::XURI > & i_xGraphName, |
| const uno::Reference< rdf::XURI > & i_xBaseURI) |
| throw (uno::RuntimeException, lang::IllegalArgumentException, |
| datatransfer::UnsupportedFlavorException, |
| container::NoSuchElementException, rdf::RepositoryException, |
| io::IOException); |
| virtual uno::Sequence< uno::Reference< rdf::XURI > > SAL_CALL |
| getGraphNames() throw (uno::RuntimeException, rdf::RepositoryException); |
| virtual uno::Reference< rdf::XNamedGraph > SAL_CALL getGraph( |
| const uno::Reference< rdf::XURI > & i_xGraphName) |
| throw (uno::RuntimeException, lang::IllegalArgumentException, |
| rdf::RepositoryException); |
| virtual uno::Reference< rdf::XNamedGraph > SAL_CALL createGraph( |
| const uno::Reference< rdf::XURI > & i_xGraphName) |
| throw (uno::RuntimeException, lang::IllegalArgumentException, |
| container::ElementExistException, rdf::RepositoryException); |
| virtual void SAL_CALL destroyGraph( |
| const uno::Reference< rdf::XURI > & i_xGraphName) |
| throw (uno::RuntimeException, lang::IllegalArgumentException, |
| container::NoSuchElementException, rdf::RepositoryException); |
| virtual uno::Reference< container::XEnumeration > SAL_CALL getStatements( |
| const uno::Reference< rdf::XResource > & i_xSubject, |
| const uno::Reference< rdf::XURI > & i_xPredicate, |
| const uno::Reference< rdf::XNode > & i_xObject) |
| throw (uno::RuntimeException, |
| rdf::RepositoryException); |
| virtual uno::Reference< rdf::XQuerySelectResult > SAL_CALL |
| querySelect(const ::rtl::OUString & i_rQuery) |
| throw (uno::RuntimeException, rdf::QueryException, |
| rdf::RepositoryException); |
| virtual uno::Reference< container::XEnumeration > SAL_CALL |
| queryConstruct(const ::rtl::OUString & i_rQuery) |
| throw (uno::RuntimeException, rdf::QueryException, |
| rdf::RepositoryException); |
| virtual ::sal_Bool SAL_CALL queryAsk(const ::rtl::OUString & i_rQuery) |
| throw (uno::RuntimeException, rdf::QueryException, |
| rdf::RepositoryException); |
| |
| // ::com::sun::star::rdf::XDocumentRepository: |
| virtual void SAL_CALL setStatementRDFa( |
| const uno::Reference< rdf::XResource > & i_xSubject, |
| const uno::Sequence< uno::Reference< rdf::XURI > > & i_rPredicates, |
| const uno::Reference< rdf::XMetadatable > & i_xObject, |
| const ::rtl::OUString & i_rRDFaContent, |
| const uno::Reference< rdf::XURI > & i_xRDFaDatatype) |
| throw (uno::RuntimeException, lang::IllegalArgumentException, |
| rdf::RepositoryException); |
| virtual void SAL_CALL removeStatementRDFa( |
| const uno::Reference< rdf::XMetadatable > & i_xElement) |
| throw (uno::RuntimeException, lang::IllegalArgumentException, |
| rdf::RepositoryException); |
| virtual beans::Pair< uno::Sequence<rdf::Statement>, sal_Bool > SAL_CALL |
| getStatementRDFa(uno::Reference< rdf::XMetadatable > const& i_xElement) |
| throw (uno::RuntimeException, lang::IllegalArgumentException, |
| rdf::RepositoryException); |
| virtual uno::Reference< container::XEnumeration > SAL_CALL |
| getStatementsRDFa( |
| const uno::Reference< rdf::XResource > & i_xSubject, |
| const uno::Reference< rdf::XURI > & i_xPredicate, |
| const uno::Reference< rdf::XNode > & i_xObject) |
| throw (uno::RuntimeException, |
| rdf::RepositoryException); |
| |
| // ::com::sun::star::lang::XInitialization: |
| virtual void SAL_CALL initialize( |
| const uno::Sequence< ::com::sun::star::uno::Any > & i_rArguments) |
| throw (uno::RuntimeException, uno::Exception); |
| |
| // XNamedGraph forwards --------------------------------------------- |
| const NamedGraphMap_t::iterator SAL_CALL clearGraph( |
| const uno::Reference< rdf::XURI > & i_xName, |
| bool i_Internal = false ); |
| void SAL_CALL addStatementGraph( |
| const uno::Reference< rdf::XResource > & i_xSubject, |
| const uno::Reference< rdf::XURI > & i_xPredicate, |
| const uno::Reference< rdf::XNode > & i_xObject, |
| const uno::Reference< rdf::XURI > & i_xName, |
| bool i_Internal = false ); |
| // throw (uno::RuntimeException, lang::IllegalArgumentException, |
| // container::NoSuchElementException, rdf::RepositoryException); |
| void SAL_CALL removeStatementsGraph( |
| const uno::Reference< rdf::XResource > & i_xSubject, |
| const uno::Reference< rdf::XURI > & i_xPredicate, |
| const uno::Reference< rdf::XNode > & i_xObject, |
| const uno::Reference< rdf::XURI > & i_xName ); |
| // throw (uno::RuntimeException, lang::IllegalArgumentException, |
| // container::NoSuchElementException, rdf::RepositoryException); |
| uno::Reference< container::XEnumeration > SAL_CALL getStatementsGraph( |
| const uno::Reference< rdf::XResource > & i_xSubject, |
| const uno::Reference< rdf::XURI > & i_xPredicate, |
| const uno::Reference< rdf::XNode > & i_xObject, |
| const uno::Reference< rdf::XURI > & i_xName, |
| bool i_Internal = false ); |
| // throw (uno::RuntimeException, lang::IllegalArgumentException, |
| // container::NoSuchElementException, rdf::RepositoryException); |
| |
| const librdf_TypeConverter& getTypeConverter() { return m_TypeConverter; }; |
| |
| private: |
| |
| uno::Reference< uno::XComponentContext > m_xContext; |
| |
| /// librdf global data |
| /** N.B.: The redland documentation gives the impression that you can have |
| as many librdf_worlds as you like. This is true in the same sense |
| that you can physically be in as many places as you like. |
| Well, you can, just not at the same time. |
| The ugly truth is that destroying a librdf_world kills a bunch |
| of static variables; other librdf_worlds become very unhappy |
| when they access these. |
| And of course this is not documented anywhere that I could find. |
| So we allocate a single world, and refcount that. |
| */ |
| static boost::shared_ptr<librdf_world> m_pWorld; |
| /// refcount |
| static sal_uInt32 m_NumInstances; |
| /// mutex for m_pWorld - redland is not as threadsafe as is often claimed |
| static osl::Mutex m_aMutex; |
| |
| // NB: sequence of the shared pointers is important! |
| /// librdf repository storage |
| boost::shared_ptr<librdf_storage> m_pStorage; |
| /// librdf repository model |
| boost::shared_ptr<librdf_model> m_pModel; |
| |
| /// all named graphs |
| NamedGraphMap_t m_NamedGraphs; |
| |
| /// type conversion helper |
| librdf_TypeConverter m_TypeConverter; |
| |
| /// set of xml:ids of elements with xhtml:content |
| ::std::set< ::rtl::OUString > m_RDFaXHTMLContentSet; |
| }; |
| |
| |
| //////////////////////////////////////////////////////////////////////////// |
| |
| /** result of operations that return a graph, i.e., |
| an XEnumeration of statements. |
| */ |
| class librdf_GraphResult: |
| private boost::noncopyable, |
| public ::cppu::WeakImplHelper1< |
| container::XEnumeration> |
| { |
| public: |
| |
| librdf_GraphResult(librdf_Repository *i_pRepository, |
| ::osl::Mutex & i_rMutex, |
| boost::shared_ptr<librdf_stream> const& i_pStream, |
| boost::shared_ptr<librdf_node> const& i_pContext, |
| boost::shared_ptr<librdf_query> const& i_pQuery = |
| boost::shared_ptr<librdf_query>() ) |
| : m_xRep(i_pRepository) |
| , m_rMutex(i_rMutex) |
| , m_pQuery(i_pQuery) |
| , m_pContext(i_pContext) |
| , m_pStream(i_pStream) |
| { }; |
| |
| virtual ~librdf_GraphResult() {} |
| |
| // ::com::sun::star::container::XEnumeration: |
| virtual ::sal_Bool SAL_CALL hasMoreElements() |
| throw (uno::RuntimeException); |
| virtual uno::Any SAL_CALL nextElement() |
| throw (uno::RuntimeException, container::NoSuchElementException, |
| lang::WrappedTargetException); |
| |
| private: |
| // NB: this is not a weak pointer: streams _must_ be deleted before the |
| // storage they point into, so we keep the repository alive here |
| // also, sequence is important: the stream must be destroyed first. |
| ::rtl::Reference< librdf_Repository > m_xRep; |
| // needed for synchronizing access to librdf (it doesnt do win32 threading) |
| ::osl::Mutex & m_rMutex; |
| // the query (in case this is a result of a graph query) |
| // not that the redland documentation spells this out explicity, but |
| // queries must be freed only after all the results are completely read |
| boost::shared_ptr<librdf_query> const m_pQuery; |
| boost::shared_ptr<librdf_node> const m_pContext; |
| boost::shared_ptr<librdf_stream> const m_pStream; |
| |
| librdf_node* getContext() const; |
| }; |
| |
| |
| // ::com::sun::star::container::XEnumeration: |
| ::sal_Bool SAL_CALL |
| librdf_GraphResult::hasMoreElements() throw (uno::RuntimeException) |
| { |
| ::osl::MutexGuard g(m_rMutex); |
| return m_pStream.get() && !librdf_stream_end(m_pStream.get()); |
| } |
| |
| librdf_node* librdf_GraphResult::getContext() const |
| { |
| if (!m_pStream.get() || librdf_stream_end(m_pStream.get())) |
| return NULL; |
| librdf_node *pCtxt( static_cast<librdf_node *> |
| (librdf_stream_get_context(m_pStream.get())) ); |
| if (pCtxt) |
| return pCtxt; |
| return m_pContext.get(); |
| } |
| |
| ::com::sun::star::uno::Any SAL_CALL |
| librdf_GraphResult::nextElement() |
| throw (uno::RuntimeException, container::NoSuchElementException, |
| lang::WrappedTargetException) |
| { |
| ::osl::MutexGuard g(m_rMutex); |
| if (!m_pStream.get() || !librdf_stream_end(m_pStream.get())) { |
| librdf_node * pCtxt = getContext(); |
| |
| librdf_statement *pStmt( librdf_stream_get_object(m_pStream.get()) ); |
| if (!pStmt) { |
| rdf::QueryException e(::rtl::OUString::createFromAscii( |
| "librdf_GraphResult::nextElement: " |
| "librdf_stream_get_object failed"), *this); |
| throw lang::WrappedTargetException(::rtl::OUString::createFromAscii( |
| "librdf_GraphResult::nextElement: " |
| "librdf_stream_get_object failed"), *this, |
| uno::makeAny(e)); |
| } |
| // NB: pCtxt may be null here if this is result of a graph query |
| if (pCtxt && isInternalContext(pCtxt)) { |
| pCtxt = 0; // XML ID context is implementation detail! |
| } |
| rdf::Statement Stmt( |
| m_xRep->getTypeConverter().convertToStatement(pStmt, pCtxt) ); |
| // NB: this will invalidate current item. |
| librdf_stream_next(m_pStream.get()); |
| return uno::makeAny(Stmt); |
| } else { |
| throw container::NoSuchElementException(); |
| } |
| } |
| |
| |
| //////////////////////////////////////////////////////////////////////////// |
| |
| /** result of tuple queries ("SELECT"). |
| */ |
| class librdf_QuerySelectResult: |
| private boost::noncopyable, |
| public ::cppu::WeakImplHelper1< |
| rdf::XQuerySelectResult> |
| { |
| public: |
| |
| librdf_QuerySelectResult(librdf_Repository *i_pRepository, |
| ::osl::Mutex & i_rMutex, |
| boost::shared_ptr<librdf_query> const& i_pQuery, |
| boost::shared_ptr<librdf_query_results> const& i_pQueryResult, |
| uno::Sequence< ::rtl::OUString > const& i_rBindingNames ) |
| : m_xRep(i_pRepository) |
| , m_rMutex(i_rMutex) |
| , m_pQuery(i_pQuery) |
| , m_pQueryResult(i_pQueryResult) |
| , m_BindingNames(i_rBindingNames) |
| { }; |
| |
| virtual ~librdf_QuerySelectResult() {} |
| |
| // ::com::sun::star::container::XEnumeration: |
| virtual ::sal_Bool SAL_CALL hasMoreElements() |
| throw (uno::RuntimeException); |
| virtual uno::Any SAL_CALL nextElement() |
| throw (uno::RuntimeException, container::NoSuchElementException, |
| lang::WrappedTargetException); |
| |
| // ::com::sun::star::rdf::XQuerySelectResult: |
| virtual uno::Sequence< ::rtl::OUString > SAL_CALL getBindingNames() |
| throw (uno::RuntimeException); |
| |
| private: |
| |
| // NB: this is not a weak pointer: streams _must_ be deleted before the |
| // storage they point into, so we keep the repository alive here |
| // also, sequence is important: the stream must be destroyed first. |
| ::rtl::Reference< librdf_Repository > m_xRep; |
| // needed for synchronizing access to librdf (it doesnt do win32 threading) |
| ::osl::Mutex & m_rMutex; |
| // not that the redland documentation spells this out explicity, but |
| // queries must be freed only after all the results are completely read |
| boost::shared_ptr<librdf_query> m_pQuery; |
| boost::shared_ptr<librdf_query_results> m_pQueryResult; |
| uno::Sequence< ::rtl::OUString > m_BindingNames; |
| }; |
| |
| |
| // ::com::sun::star::container::XEnumeration: |
| ::sal_Bool SAL_CALL |
| librdf_QuerySelectResult::hasMoreElements() throw (uno::RuntimeException) |
| { |
| ::osl::MutexGuard g(m_rMutex); |
| return !librdf_query_results_finished(m_pQueryResult.get()); |
| } |
| |
| class NodeArrayDeleter : public std::unary_function<librdf_node**, void> |
| { |
| const int m_Count; |
| |
| public: |
| NodeArrayDeleter(int i_Count) : m_Count(i_Count) { } |
| |
| void operator() (librdf_node** io_pArray) const throw () |
| { |
| std::for_each(io_pArray, io_pArray + m_Count, safe_librdf_free_node); |
| delete[] io_pArray; |
| } |
| }; |
| |
| ::com::sun::star::uno::Any SAL_CALL |
| librdf_QuerySelectResult::nextElement() |
| throw (uno::RuntimeException, container::NoSuchElementException, |
| lang::WrappedTargetException) |
| { |
| ::osl::MutexGuard g(m_rMutex); |
| if (!librdf_query_results_finished(m_pQueryResult.get())) { |
| sal_Int32 count(m_BindingNames.getLength()); |
| OSL_ENSURE(count >= 0, "negative length?"); |
| boost::shared_array<librdf_node*> pNodes( new librdf_node*[count], |
| NodeArrayDeleter(count)); |
| for (int i = 0; i < count; ++i) { |
| pNodes[i] = 0; |
| } |
| if (librdf_query_results_get_bindings(m_pQueryResult.get(), NULL, |
| pNodes.get())) |
| { |
| rdf::QueryException e(::rtl::OUString::createFromAscii( |
| "librdf_QuerySelectResult::nextElement: " |
| "librdf_query_results_get_bindings failed"), *this); |
| throw lang::WrappedTargetException(::rtl::OUString::createFromAscii( |
| "librdf_QuerySelectResult::nextElement: " |
| "librdf_query_results_get_bindings failed"), *this, |
| uno::makeAny(e)); |
| } |
| uno::Sequence< uno::Reference< rdf::XNode > > ret(count); |
| for (int i = 0; i < count; ++i) { |
| ret[i] = m_xRep->getTypeConverter().convertToXNode(pNodes[i]); |
| } |
| // NB: this will invalidate current item. |
| librdf_query_results_next(m_pQueryResult.get()); |
| return uno::makeAny(ret); |
| } else { |
| throw container::NoSuchElementException(); |
| } |
| } |
| |
| // ::com::sun::star::rdf::XQuerySelectResult: |
| uno::Sequence< ::rtl::OUString > SAL_CALL |
| librdf_QuerySelectResult::getBindingNames() throw (uno::RuntimeException) |
| { |
| return m_BindingNames; |
| } |
| |
| |
| //////////////////////////////////////////////////////////////////////////// |
| |
| /** represents a named graph, and forwards all the work to repository. |
| */ |
| class librdf_NamedGraph: |
| private boost::noncopyable, |
| public ::cppu::WeakImplHelper1< |
| rdf::XNamedGraph> |
| { |
| public: |
| librdf_NamedGraph(librdf_Repository * i_pRep, |
| uno::Reference<rdf::XURI> const & i_xName) |
| : m_wRep(i_pRep) |
| , m_pRep(i_pRep) |
| , m_xName(i_xName) |
| { }; |
| |
| virtual ~librdf_NamedGraph() {} |
| |
| // ::com::sun::star::rdf::XNode: |
| virtual ::rtl::OUString SAL_CALL getStringValue() |
| throw (uno::RuntimeException); |
| |
| // ::com::sun::star::rdf::XURI: |
| virtual ::rtl::OUString SAL_CALL getNamespace() |
| throw (uno::RuntimeException); |
| virtual ::rtl::OUString SAL_CALL getLocalName() |
| throw (uno::RuntimeException); |
| |
| // ::com::sun::star::rdf::XNamedGraph: |
| virtual uno::Reference<rdf::XURI> SAL_CALL getName() |
| throw (uno::RuntimeException); |
| virtual void SAL_CALL clear() |
| throw (uno::RuntimeException, |
| container::NoSuchElementException, rdf::RepositoryException); |
| virtual void SAL_CALL addStatement( |
| const uno::Reference< rdf::XResource > & i_xSubject, |
| const uno::Reference< rdf::XURI > & i_xPredicate, |
| const uno::Reference< rdf::XNode > & i_xObject) |
| throw (uno::RuntimeException, lang::IllegalArgumentException, |
| container::NoSuchElementException, rdf::RepositoryException); |
| virtual void SAL_CALL removeStatements( |
| const uno::Reference< rdf::XResource > & i_xSubject, |
| const uno::Reference< rdf::XURI > & i_xPredicate, |
| const uno::Reference< rdf::XNode > & i_xObject) |
| throw (uno::RuntimeException, |
| container::NoSuchElementException, rdf::RepositoryException); |
| virtual uno::Reference< container::XEnumeration > SAL_CALL getStatements( |
| const uno::Reference< rdf::XResource > & i_xSubject, |
| const uno::Reference< rdf::XURI > & i_xPredicate, |
| const uno::Reference< rdf::XNode > & i_xObject) |
| throw (uno::RuntimeException, |
| container::NoSuchElementException, rdf::RepositoryException); |
| |
| private: |
| |
| /// weak reference: this is needed to check if m_pRep is valid |
| uno::WeakReference< rdf::XRepository > m_wRep; |
| librdf_Repository *m_pRep; |
| uno::Reference< rdf::XURI > m_xName; |
| }; |
| |
| |
| // ::com::sun::star::rdf::XNode: |
| ::rtl::OUString SAL_CALL librdf_NamedGraph::getStringValue() |
| throw (uno::RuntimeException) |
| { |
| return m_xName->getStringValue(); |
| } |
| |
| // ::com::sun::star::rdf::XURI: |
| ::rtl::OUString SAL_CALL librdf_NamedGraph::getNamespace() |
| throw (uno::RuntimeException) |
| { |
| return m_xName->getNamespace(); |
| } |
| |
| ::rtl::OUString SAL_CALL librdf_NamedGraph::getLocalName() |
| throw (uno::RuntimeException) |
| { |
| return m_xName->getLocalName(); |
| } |
| |
| // ::com::sun::star::rdf::XNamedGraph: |
| uno::Reference< rdf::XURI > SAL_CALL librdf_NamedGraph::getName() |
| throw (uno::RuntimeException) |
| { |
| return m_xName; |
| } |
| |
| void SAL_CALL librdf_NamedGraph::clear() |
| throw (uno::RuntimeException, |
| container::NoSuchElementException, rdf::RepositoryException) |
| { |
| uno::Reference< rdf::XRepository > xRep( m_wRep ); |
| if (!xRep.is()) { |
| throw rdf::RepositoryException(::rtl::OUString::createFromAscii( |
| "librdf_NamedGraph::clear: repository is gone"), *this); |
| } |
| try { |
| m_pRep->clearGraph(m_xName); |
| } catch (lang::IllegalArgumentException &) { |
| throw uno::RuntimeException(); |
| } |
| } |
| |
| void SAL_CALL librdf_NamedGraph::addStatement( |
| const uno::Reference< rdf::XResource > & i_xSubject, |
| const uno::Reference< rdf::XURI > & i_xPredicate, |
| const uno::Reference< rdf::XNode > & i_xObject) |
| throw (uno::RuntimeException, lang::IllegalArgumentException, |
| container::NoSuchElementException, rdf::RepositoryException) |
| { |
| uno::Reference< rdf::XRepository > xRep( m_wRep ); |
| if (!xRep.is()) { |
| throw rdf::RepositoryException(::rtl::OUString::createFromAscii( |
| "librdf_NamedGraph::addStatement: repository is gone"), *this); |
| } |
| m_pRep->addStatementGraph(i_xSubject, i_xPredicate, i_xObject, m_xName); |
| } |
| |
| void SAL_CALL librdf_NamedGraph::removeStatements( |
| const uno::Reference< rdf::XResource > & i_xSubject, |
| const uno::Reference< rdf::XURI > & i_xPredicate, |
| const uno::Reference< rdf::XNode > & i_xObject) |
| throw (uno::RuntimeException, |
| container::NoSuchElementException, rdf::RepositoryException) |
| { |
| uno::Reference< rdf::XRepository > xRep( m_wRep ); |
| if (!xRep.is()) { |
| throw rdf::RepositoryException(::rtl::OUString::createFromAscii( |
| "librdf_NamedGraph::removeStatements: repository is gone"), *this); |
| } |
| m_pRep->removeStatementsGraph(i_xSubject, i_xPredicate, i_xObject, m_xName); |
| } |
| |
| uno::Reference< container::XEnumeration > SAL_CALL |
| librdf_NamedGraph::getStatements( |
| const uno::Reference< rdf::XResource > & i_xSubject, |
| const uno::Reference< rdf::XURI > & i_xPredicate, |
| const uno::Reference< rdf::XNode > & i_xObject) |
| throw (uno::RuntimeException, |
| container::NoSuchElementException, rdf::RepositoryException) |
| { |
| uno::Reference< rdf::XRepository > xRep( m_wRep ); |
| if (!xRep.is()) { |
| throw rdf::RepositoryException(::rtl::OUString::createFromAscii( |
| "librdf_NamedGraph::getStatements: repository is gone"), *this); |
| } |
| return m_pRep->getStatementsGraph( |
| i_xSubject, i_xPredicate, i_xObject, m_xName); |
| } |
| |
| |
| //////////////////////////////////////////////////////////////////////////// |
| |
| boost::shared_ptr<librdf_world> librdf_Repository::m_pWorld; |
| sal_uInt32 librdf_Repository::m_NumInstances = 0; |
| osl::Mutex librdf_Repository::m_aMutex; |
| |
| librdf_Repository::librdf_Repository( |
| uno::Reference< uno::XComponentContext > const & i_xContext) |
| : /*BaseMutex(),*/ m_xContext(i_xContext) |
| // m_pWorld (static_cast<librdf_world *>(0), safe_librdf_free_world ), |
| , m_pStorage(static_cast<librdf_storage*>(0), safe_librdf_free_storage) |
| , m_pModel (static_cast<librdf_model *>(0), safe_librdf_free_model ) |
| , m_NamedGraphs() |
| , m_TypeConverter(i_xContext, *this) |
| { |
| OSL_ENSURE(i_xContext.is(), "librdf_Repository: null context"); |
| |
| ::osl::MutexGuard g(m_aMutex); |
| if (!m_NumInstances++) { |
| m_pWorld.reset(m_TypeConverter.createWorld(), safe_librdf_free_world); |
| } |
| } |
| |
| librdf_Repository::~librdf_Repository() |
| { |
| // must destroy these before world! |
| m_pModel.reset(); |
| m_pStorage.reset(); |
| |
| // FIXME: so it turns out that calling librdf_free_world will |
| // (via raptor_sax2_finish) call xmlCleanupParser, which will |
| // free libxml2's globals! ARRRGH!!! => never call librdf_free_world |
| #if 0 |
| ::osl::MutexGuard g(m_aMutex); |
| if (!--m_NumInstances) { |
| m_pWorld.reset(); |
| } |
| #endif |
| } |
| |
| // com.sun.star.uno.XServiceInfo: |
| ::rtl::OUString SAL_CALL librdf_Repository::getImplementationName() |
| throw (uno::RuntimeException) |
| { |
| return comp_librdf_Repository::_getImplementationName(); |
| } |
| |
| ::sal_Bool SAL_CALL librdf_Repository::supportsService( |
| ::rtl::OUString const & serviceName) throw (uno::RuntimeException) |
| { |
| uno::Sequence< ::rtl::OUString > serviceNames |
| = comp_librdf_Repository::_getSupportedServiceNames(); |
| for (::sal_Int32 i = 0; i < serviceNames.getLength(); ++i) { |
| if (serviceNames[i] == serviceName) |
| return sal_True; |
| } |
| return sal_False; |
| } |
| |
| uno::Sequence< ::rtl::OUString > SAL_CALL |
| librdf_Repository::getSupportedServiceNames() throw (uno::RuntimeException) |
| { |
| return comp_librdf_Repository::_getSupportedServiceNames(); |
| } |
| |
| // ::com::sun::star::rdf::XRepository: |
| uno::Reference< rdf::XBlankNode > SAL_CALL librdf_Repository::createBlankNode() |
| throw (uno::RuntimeException) |
| { |
| ::osl::MutexGuard g(m_aMutex); |
| const boost::shared_ptr<librdf_node> pNode( |
| librdf_new_node_from_blank_identifier(m_pWorld.get(), NULL), |
| safe_librdf_free_node); |
| if (!pNode) { |
| throw uno::RuntimeException(::rtl::OUString::createFromAscii( |
| "librdf_Repository::createBlankNode: " |
| "librdf_new_node_from_blank_identifier failed"), *this); |
| } |
| const unsigned char * id (librdf_node_get_blank_identifier(pNode.get())); |
| if (!id) { |
| throw uno::RuntimeException(::rtl::OUString::createFromAscii( |
| "librdf_Repository::createBlankNode: " |
| "librdf_node_get_blank_identifier failed"), *this); |
| } |
| const ::rtl::OUString nodeID(::rtl::OUString::createFromAscii( |
| reinterpret_cast<const char *>(id))); |
| try { |
| return rdf::BlankNode::create(m_xContext, nodeID); |
| } catch (lang::IllegalArgumentException & iae) { |
| throw lang::WrappedTargetRuntimeException( |
| ::rtl::OUString::createFromAscii( |
| "librdf_Repository::createBlankNode: " |
| "illegal blank node label"), *this, uno::makeAny(iae)); |
| } |
| } |
| |
| bool formatNeedsBaseURI(::sal_Int16 i_Format) |
| { |
| (void) i_Format; //FIXME any which dont? |
| return true; |
| } |
| |
| xmlParserInputPtr myExtEntityLoader( const char* /*URL*/, const char* /*ID*/, xmlParserCtxtPtr /*context*/) |
| { |
| return NULL; |
| } |
| |
| //void SAL_CALL |
| uno::Reference<rdf::XNamedGraph> SAL_CALL |
| librdf_Repository::importGraph(::sal_Int16 i_Format, |
| const uno::Reference< io::XInputStream > & i_xInStream, |
| const uno::Reference< rdf::XURI > & i_xGraphName, |
| const uno::Reference< rdf::XURI > & i_xBaseURI) |
| throw (uno::RuntimeException, lang::IllegalArgumentException, |
| datatransfer::UnsupportedFlavorException, |
| container::ElementExistException, rdf::ParseException, |
| rdf::RepositoryException, io::IOException) |
| { |
| ::osl::MutexGuard g(m_aMutex); |
| if (!i_xInStream.is()) { |
| throw lang::IllegalArgumentException( |
| ::rtl::OUString::createFromAscii("librdf_Repository::importGraph: " |
| "stream is null"), *this, 1); |
| } |
| //FIXME: other formats |
| if (i_Format != rdf::FileFormat::RDF_XML) { |
| throw datatransfer::UnsupportedFlavorException( |
| ::rtl::OUString::createFromAscii("librdf_Repository::importGraph: " |
| "file format not supported"), *this); |
| } |
| if (!i_xGraphName.is()) { |
| throw lang::IllegalArgumentException( |
| ::rtl::OUString::createFromAscii("librdf_Repository::importGraph: " |
| "graph name is null"), *this, 2); |
| } |
| if (i_xGraphName->getStringValue().matchAsciiL(s_nsOOo, sizeof(s_nsOOo)-1)) |
| { |
| throw lang::IllegalArgumentException( |
| ::rtl::OUString::createFromAscii("librdf_Repository::importGraph: " |
| "URI is reserved"), *this, 0); |
| } |
| if (formatNeedsBaseURI(i_Format) && !i_xBaseURI.is()) { |
| throw lang::IllegalArgumentException( |
| ::rtl::OUString::createFromAscii("librdf_Repository::importGraph: " |
| "base URI is null"), *this, 3); |
| } |
| OSL_ENSURE(i_xBaseURI.is(), "no base uri"); |
| const ::rtl::OUString baseURIU( i_xBaseURI->getStringValue() ); |
| if (baseURIU.indexOf('#') >= 0) { |
| throw lang::IllegalArgumentException( |
| ::rtl::OUString::createFromAscii("librdf_Repository::importGraph: " |
| "base URI is not absolute"), *this, 3); |
| } |
| |
| const ::rtl::OUString contextU( i_xGraphName->getStringValue() ); |
| if (m_NamedGraphs.find(contextU) != m_NamedGraphs.end()) { |
| throw container::ElementExistException( |
| ::rtl::OUString::createFromAscii("librdf_Repository::importGraph: " |
| "graph with given URI exists"), *this); |
| } |
| const ::rtl::OString context( |
| ::rtl::OUStringToOString(contextU, RTL_TEXTENCODING_UTF8) ); |
| |
| const boost::shared_ptr<librdf_node> pContext( |
| librdf_new_node_from_uri_string(m_pWorld.get(), |
| reinterpret_cast<const unsigned char*> (context.getStr())), |
| safe_librdf_free_node); |
| if (!pContext) { |
| throw uno::RuntimeException(::rtl::OUString::createFromAscii( |
| "librdf_Repository::importGraph: " |
| "librdf_new_node_from_uri_string failed"), *this); |
| } |
| |
| const ::rtl::OString baseURI( |
| ::rtl::OUStringToOString(baseURIU, RTL_TEXTENCODING_UTF8) ); |
| const boost::shared_ptr<librdf_uri> pBaseURI( |
| librdf_new_uri(m_pWorld.get(), |
| reinterpret_cast<const unsigned char*> (baseURI.getStr())), |
| safe_librdf_free_uri); |
| if (!pBaseURI) { |
| throw uno::RuntimeException(::rtl::OUString::createFromAscii( |
| "librdf_Repository::importGraph: " |
| "librdf_new_uri failed"), *this); |
| } |
| |
| const boost::shared_ptr<librdf_parser> pParser( |
| librdf_new_parser(m_pWorld.get(), "rdfxml", NULL, NULL), |
| safe_librdf_free_parser); |
| if (!pParser) { |
| throw uno::RuntimeException(::rtl::OUString::createFromAscii( |
| "librdf_Repository::importGraph: " |
| "librdf_new_parser failed"), *this); |
| } |
| |
| xmlExternalEntityLoader oldExtEntityLoader = xmlGetExternalEntityLoader(); |
| xmlSetExternalEntityLoader( myExtEntityLoader); |
| |
| uno::Sequence<sal_Int8> buf; |
| uno::Reference<io::XSeekable> xSeekable(i_xInStream, uno::UNO_QUERY); |
| // UGLY: if only that redland junk could read streams... |
| const sal_Int64 sz( xSeekable.is() ? xSeekable->getLength() : 1 << 20 ); |
| // exceptions are propagated |
| i_xInStream->readBytes( buf, static_cast<sal_Int32>( sz ) ); |
| const boost::shared_ptr<librdf_stream> pStream( |
| librdf_parser_parse_counted_string_as_stream(pParser.get(), |
| reinterpret_cast<const unsigned char*>(buf.getConstArray()), |
| buf.getLength(), pBaseURI.get()), |
| safe_librdf_free_stream); |
| if (!pStream) { |
| throw rdf::ParseException(::rtl::OUString::createFromAscii( |
| "librdf_Repository::importGraph: " |
| "librdf_parser_parse_counted_string_as_stream failed"), *this); |
| } |
| m_NamedGraphs.insert(std::make_pair(contextU, |
| new librdf_NamedGraph(this, i_xGraphName))); |
| if (librdf_model_context_add_statements(m_pModel.get(), |
| pContext.get(), pStream.get())) { |
| throw rdf::RepositoryException(::rtl::OUString::createFromAscii( |
| "librdf_Repository::importGraph: " |
| "librdf_model_context_add_statements failed"), *this); |
| } |
| |
| xmlSetExternalEntityLoader( oldExtEntityLoader); |
| return getGraph(i_xGraphName); |
| } |
| |
| void SAL_CALL |
| librdf_Repository::exportGraph(::sal_Int16 i_Format, |
| const uno::Reference< io::XOutputStream > & i_xOutStream, |
| const uno::Reference< rdf::XURI > & i_xGraphName, |
| const uno::Reference< rdf::XURI > & i_xBaseURI) |
| throw (uno::RuntimeException, lang::IllegalArgumentException, |
| datatransfer::UnsupportedFlavorException, |
| container::NoSuchElementException, rdf::RepositoryException, |
| io::IOException) |
| { |
| ::osl::MutexGuard g(m_aMutex); |
| if (!i_xOutStream.is()) { |
| throw lang::IllegalArgumentException( |
| ::rtl::OUString::createFromAscii("librdf_Repository::exportGraph: " |
| "stream is null"), *this, 1); |
| } |
| // FIXME: other formats |
| if (i_Format != rdf::FileFormat::RDF_XML) { |
| throw datatransfer::UnsupportedFlavorException( |
| ::rtl::OUString::createFromAscii("librdf_Repository::exportGraph: " |
| "file format not supported"), *this); |
| } |
| if (!i_xGraphName.is()) { |
| throw lang::IllegalArgumentException( |
| ::rtl::OUString::createFromAscii("librdf_Repository::exportGraph: " |
| "graph name is null"), *this, 2); |
| } |
| if (formatNeedsBaseURI(i_Format) && !i_xBaseURI.is()) { |
| throw lang::IllegalArgumentException( |
| ::rtl::OUString::createFromAscii("librdf_Repository::exportGraph: " |
| "base URI is null"), *this, 3); |
| } |
| OSL_ENSURE(i_xBaseURI.is(), "no base uri"); |
| const ::rtl::OUString baseURIU( i_xBaseURI->getStringValue() ); |
| if (baseURIU.indexOf('#') >= 0) { |
| throw lang::IllegalArgumentException( |
| ::rtl::OUString::createFromAscii("librdf_Repository::exportGraph: " |
| "base URI is not absolute"), *this, 3); |
| } |
| |
| const ::rtl::OUString contextU( i_xGraphName->getStringValue() ); |
| if (m_NamedGraphs.find(contextU) == m_NamedGraphs.end()) { |
| throw container::NoSuchElementException( |
| ::rtl::OUString::createFromAscii("librdf_Repository::exportGraph: " |
| "no graph with given URI exists"), *this); |
| } |
| const ::rtl::OString context( |
| ::rtl::OUStringToOString(contextU, RTL_TEXTENCODING_UTF8) ); |
| |
| const boost::shared_ptr<librdf_node> pContext( |
| librdf_new_node_from_uri_string(m_pWorld.get(), |
| reinterpret_cast<const unsigned char*> (context.getStr())), |
| safe_librdf_free_node); |
| if (!pContext) { |
| throw uno::RuntimeException(::rtl::OUString::createFromAscii( |
| "librdf_Repository::exportGraph: " |
| "librdf_new_node_from_uri_string failed"), *this); |
| } |
| const ::rtl::OString baseURI( |
| ::rtl::OUStringToOString(baseURIU, RTL_TEXTENCODING_UTF8) ); |
| const boost::shared_ptr<librdf_uri> pBaseURI( |
| librdf_new_uri(m_pWorld.get(), |
| reinterpret_cast<const unsigned char*> (baseURI.getStr())), |
| safe_librdf_free_uri); |
| if (!pBaseURI) { |
| throw uno::RuntimeException(::rtl::OUString::createFromAscii( |
| "librdf_Repository::exportGraph: " |
| "librdf_new_uri failed"), *this); |
| } |
| |
| const boost::shared_ptr<librdf_stream> pStream( |
| librdf_model_context_as_stream(m_pModel.get(), pContext.get()), |
| safe_librdf_free_stream); |
| if (!pStream) { |
| throw rdf::RepositoryException(::rtl::OUString::createFromAscii( |
| "librdf_Repository::exportGraph: " |
| "librdf_model_context_as_stream failed"), *this); |
| } |
| const char *format("rdfxml"); |
| // #i116443#: abbrev breaks when certain URIs are used as data types |
| // const char *format("rdfxml-abbrev"); |
| const boost::shared_ptr<librdf_serializer> pSerializer( |
| librdf_new_serializer(m_pWorld.get(), format, NULL, NULL), |
| safe_librdf_free_serializer); |
| if (!pSerializer) { |
| throw uno::RuntimeException(::rtl::OUString::createFromAscii( |
| "librdf_Repository::exportGraph: " |
| "librdf_new_serializer failed"), *this); |
| } |
| |
| const boost::shared_ptr<librdf_uri> pRelativeURI( |
| librdf_new_uri(m_pWorld.get(), reinterpret_cast<const unsigned char*> |
| ("http://feature.librdf.org/raptor-relativeURIs")), |
| safe_librdf_free_uri); |
| const boost::shared_ptr<librdf_uri> pWriteBaseURI( |
| librdf_new_uri(m_pWorld.get(), reinterpret_cast<const unsigned char*> |
| ("http://feature.librdf.org/raptor-writeBaseURI")), |
| safe_librdf_free_uri); |
| const boost::shared_ptr<librdf_node> p0( |
| librdf_new_node_from_literal(m_pWorld.get(), |
| reinterpret_cast<const unsigned char*> ("0"), NULL, 0), |
| safe_librdf_free_node); |
| const boost::shared_ptr<librdf_node> p1( |
| librdf_new_node_from_literal(m_pWorld.get(), |
| reinterpret_cast<const unsigned char*> ("1"), NULL, 0), |
| safe_librdf_free_node); |
| if (!pWriteBaseURI || !pRelativeURI || !p0 || !p1) { |
| throw uno::RuntimeException(::rtl::OUString::createFromAscii( |
| "librdf_Repository::exportGraph: " |
| "librdf_new_uri or librdf_new_node_from_literal failed"), *this); |
| } |
| |
| // make URIs relative to base URI |
| if (librdf_serializer_set_feature(pSerializer.get(), |
| pRelativeURI.get(), p1.get())) |
| { |
| throw uno::RuntimeException(::rtl::OUString::createFromAscii( |
| "librdf_Repository::exportGraph: " |
| "librdf_serializer_set_feature relativeURIs failed"), *this); |
| } |
| // but do not write the base URI to the file! |
| if (librdf_serializer_set_feature(pSerializer.get(), |
| pWriteBaseURI.get(), p0.get())) |
| { |
| throw uno::RuntimeException(::rtl::OUString::createFromAscii( |
| "librdf_Repository::exportGraph: " |
| "librdf_serializer_set_feature writeBaseURI failed"), *this); |
| } |
| |
| size_t length; |
| const boost::shared_ptr<unsigned char> pBuf( |
| librdf_serializer_serialize_stream_to_counted_string( |
| pSerializer.get(), pBaseURI.get(), pStream.get(), &length), free); |
| if (!pBuf) { |
| throw rdf::RepositoryException(::rtl::OUString::createFromAscii( |
| "librdf_Repository::exportGraph: " |
| "librdf_serializer_serialize_stream_to_counted_string failed"), |
| *this); |
| } |
| const uno::Sequence<sal_Int8> buf( |
| reinterpret_cast<sal_Int8*>(pBuf.get()), length); |
| // exceptions are propagated |
| i_xOutStream->writeBytes(buf); |
| } |
| |
| uno::Sequence< uno::Reference< rdf::XURI > > SAL_CALL |
| librdf_Repository::getGraphNames() |
| throw (uno::RuntimeException, rdf::RepositoryException) |
| { |
| ::osl::MutexGuard g(m_aMutex); |
| ::comphelper::SequenceAsVector< uno::Reference<rdf::XURI> > ret; |
| std::transform(m_NamedGraphs.begin(), m_NamedGraphs.end(), |
| std::back_inserter(ret), |
| boost::bind(&rdf::XNamedGraph::getName, |
| boost::bind(&NamedGraphMap_t::value_type::second, _1))); |
| return ret.getAsConstList(); |
| } |
| |
| uno::Reference< rdf::XNamedGraph > SAL_CALL |
| librdf_Repository::getGraph(const uno::Reference< rdf::XURI > & i_xGraphName) |
| throw (uno::RuntimeException, lang::IllegalArgumentException, |
| rdf::RepositoryException) |
| { |
| ::osl::MutexGuard g(m_aMutex); |
| if (!i_xGraphName.is()) { |
| throw lang::IllegalArgumentException( |
| ::rtl::OUString::createFromAscii("librdf_Repository::getGraph: " |
| "URI is null"), *this, 0); |
| } |
| const NamedGraphMap_t::iterator iter( |
| m_NamedGraphs.find(i_xGraphName->getStringValue()) ); |
| if (iter != m_NamedGraphs.end()) { |
| return uno::Reference<rdf::XNamedGraph>(iter->second.get()); |
| } else { |
| return 0; |
| } |
| } |
| |
| uno::Reference< rdf::XNamedGraph > SAL_CALL |
| librdf_Repository::createGraph(const uno::Reference< rdf::XURI > & i_xGraphName) |
| throw (uno::RuntimeException, lang::IllegalArgumentException, |
| container::ElementExistException, rdf::RepositoryException) |
| { |
| ::osl::MutexGuard g(m_aMutex); |
| if (!i_xGraphName.is()) { |
| throw lang::IllegalArgumentException( |
| ::rtl::OUString::createFromAscii("librdf_Repository::createGraph: " |
| "URI is null"), *this, 0); |
| } |
| if (i_xGraphName->getStringValue().matchAsciiL(s_nsOOo, sizeof(s_nsOOo)-1)) |
| { |
| throw lang::IllegalArgumentException( |
| ::rtl::OUString::createFromAscii("librdf_Repository::createGraph: " |
| "URI is reserved"), *this, 0); |
| } |
| |
| // NB: librdf does not have a concept of graphs as such; |
| // a librdf named graph exists iff the model contains a statement with |
| // the graph name as context |
| const ::rtl::OUString contextU( i_xGraphName->getStringValue() ); |
| if (m_NamedGraphs.find(contextU) != m_NamedGraphs.end()) { |
| throw container::ElementExistException( |
| ::rtl::OUString::createFromAscii("librdf_Repository::createGraph: " |
| "graph with given URI exists"), *this); |
| } |
| m_NamedGraphs.insert(std::make_pair(contextU, |
| new librdf_NamedGraph(this, i_xGraphName))); |
| return uno::Reference<rdf::XNamedGraph>( |
| m_NamedGraphs.find(contextU)->second.get()); |
| } |
| |
| void SAL_CALL |
| librdf_Repository::destroyGraph( |
| const uno::Reference< rdf::XURI > & i_xGraphName) |
| throw (uno::RuntimeException, lang::IllegalArgumentException, |
| container::NoSuchElementException, rdf::RepositoryException) |
| { |
| ::osl::MutexGuard g(m_aMutex); |
| const NamedGraphMap_t::iterator iter( clearGraph(i_xGraphName) ); |
| m_NamedGraphs.erase(iter); |
| } |
| |
| static bool isMetadatableWithoutMetadata( |
| uno::Reference<uno::XInterface> const & i_xNode) |
| { |
| const uno::Reference<rdf::XMetadatable> xMeta( i_xNode, uno::UNO_QUERY ); |
| return (xMeta.is() && !xMeta->getMetadataReference().Second.getLength()); |
| } |
| |
| uno::Reference< container::XEnumeration > SAL_CALL |
| librdf_Repository::getStatements( |
| const uno::Reference< rdf::XResource > & i_xSubject, |
| const uno::Reference< rdf::XURI > & i_xPredicate, |
| const uno::Reference< rdf::XNode > & i_xObject) |
| throw (uno::RuntimeException, rdf::RepositoryException) |
| { |
| if (isMetadatableWithoutMetadata(i_xSubject) || |
| isMetadatableWithoutMetadata(i_xPredicate) || |
| isMetadatableWithoutMetadata(i_xObject)) |
| { |
| return new librdf_GraphResult(this, m_aMutex, |
| ::boost::shared_ptr<librdf_stream>(), |
| ::boost::shared_ptr<librdf_node>()); |
| } |
| |
| ::osl::MutexGuard g(m_aMutex); |
| const boost::shared_ptr<librdf_statement> pStatement( |
| m_TypeConverter.mkStatement(m_pWorld.get(), |
| i_xSubject, i_xPredicate, i_xObject), |
| safe_librdf_free_statement); |
| OSL_ENSURE(pStatement, "mkStatement failed"); |
| |
| const boost::shared_ptr<librdf_stream> pStream( |
| librdf_model_find_statements(m_pModel.get(), pStatement.get()), |
| safe_librdf_free_stream); |
| if (!pStream) { |
| throw rdf::RepositoryException(::rtl::OUString::createFromAscii( |
| "librdf_Repository::getStatements: " |
| "librdf_model_find_statements failed"), *this); |
| } |
| |
| return new librdf_GraphResult(this, m_aMutex, pStream, |
| ::boost::shared_ptr<librdf_node>()); |
| } |
| |
| |
| uno::Reference< rdf::XQuerySelectResult > SAL_CALL |
| librdf_Repository::querySelect(const ::rtl::OUString & i_rQuery) |
| throw (uno::RuntimeException, rdf::QueryException, rdf::RepositoryException) |
| { |
| ::osl::MutexGuard g(m_aMutex); |
| const ::rtl::OString query( |
| ::rtl::OUStringToOString(i_rQuery, RTL_TEXTENCODING_UTF8) ); |
| const boost::shared_ptr<librdf_query> pQuery( |
| librdf_new_query(m_pWorld.get(), s_sparql, NULL, |
| reinterpret_cast<const unsigned char*> (query.getStr()), NULL), |
| safe_librdf_free_query); |
| if (!pQuery) { |
| throw rdf::QueryException(::rtl::OUString::createFromAscii( |
| "librdf_Repository::querySelect: " |
| "librdf_new_query failed"), *this); |
| } |
| const boost::shared_ptr<librdf_query_results> pResults( |
| librdf_model_query_execute(m_pModel.get(), pQuery.get()), |
| safe_librdf_free_query_results); |
| if (!pResults || !librdf_query_results_is_bindings(pResults.get())) { |
| throw rdf::QueryException(::rtl::OUString::createFromAscii( |
| "librdf_Repository::querySelect: " |
| "query result is null or not bindings"), *this); |
| } |
| |
| const int count( librdf_query_results_get_bindings_count(pResults.get()) ); |
| if (count >= 0) { |
| uno::Sequence< ::rtl::OUString > names(count); |
| for (int i = 0; i < count; ++i) { |
| const char* name( librdf_query_results_get_binding_name( |
| pResults.get(), i) ); |
| if (!name) { |
| throw rdf::QueryException(::rtl::OUString::createFromAscii( |
| "librdf_Repository::querySelect: " |
| "binding is null"), *this); |
| } |
| |
| names[i] = ::rtl::OUString::createFromAscii(name); |
| } |
| |
| return new librdf_QuerySelectResult(this, m_aMutex, |
| pQuery, pResults, names); |
| |
| } else { |
| throw rdf::QueryException(::rtl::OUString::createFromAscii( |
| "librdf_Repository::querySelect: " |
| "librdf_query_results_get_bindings_count failed"), *this); |
| } |
| } |
| |
| uno::Reference< container::XEnumeration > SAL_CALL |
| librdf_Repository::queryConstruct(const ::rtl::OUString & i_rQuery) |
| throw (uno::RuntimeException, rdf::QueryException, rdf::RepositoryException) |
| { |
| ::osl::MutexGuard g(m_aMutex); |
| const ::rtl::OString query( |
| ::rtl::OUStringToOString(i_rQuery, RTL_TEXTENCODING_UTF8) ); |
| const boost::shared_ptr<librdf_query> pQuery( |
| librdf_new_query(m_pWorld.get(), s_sparql, NULL, |
| reinterpret_cast<const unsigned char*> (query.getStr()), NULL), |
| safe_librdf_free_query); |
| if (!pQuery) { |
| throw rdf::QueryException(::rtl::OUString::createFromAscii( |
| "librdf_Repository::queryConstruct: " |
| "librdf_new_query failed"), *this); |
| } |
| const boost::shared_ptr<librdf_query_results> pResults( |
| librdf_model_query_execute(m_pModel.get(), pQuery.get()), |
| safe_librdf_free_query_results); |
| if (!pResults || !librdf_query_results_is_graph(pResults.get())) { |
| throw rdf::QueryException(::rtl::OUString::createFromAscii( |
| "librdf_Repository::queryConstruct: " |
| "query result is null or not graph"), *this); |
| } |
| const boost::shared_ptr<librdf_stream> pStream( |
| librdf_query_results_as_stream(pResults.get()), |
| safe_librdf_free_stream); |
| if (!pStream) { |
| throw rdf::QueryException(::rtl::OUString::createFromAscii( |
| "librdf_Repository::queryConstruct: " |
| "librdf_query_results_as_stream failed"), *this); |
| } |
| |
| return new librdf_GraphResult(this, m_aMutex, pStream, |
| ::boost::shared_ptr<librdf_node>(), pQuery); |
| } |
| |
| ::sal_Bool SAL_CALL |
| librdf_Repository::queryAsk(const ::rtl::OUString & i_rQuery) |
| throw (uno::RuntimeException, rdf::QueryException, rdf::RepositoryException) |
| { |
| ::osl::MutexGuard g(m_aMutex); |
| |
| const ::rtl::OString query( |
| ::rtl::OUStringToOString(i_rQuery, RTL_TEXTENCODING_UTF8) ); |
| const boost::shared_ptr<librdf_query> pQuery( |
| librdf_new_query(m_pWorld.get(), s_sparql, NULL, |
| reinterpret_cast<const unsigned char*> (query.getStr()), NULL), |
| safe_librdf_free_query); |
| if (!pQuery) { |
| throw rdf::QueryException(::rtl::OUString::createFromAscii( |
| "librdf_Repository::queryAsk: " |
| "librdf_new_query failed"), *this); |
| } |
| const boost::shared_ptr<librdf_query_results> pResults( |
| librdf_model_query_execute(m_pModel.get(), pQuery.get()), |
| safe_librdf_free_query_results); |
| if (!pResults || !librdf_query_results_is_boolean(pResults.get())) { |
| throw rdf::QueryException(::rtl::OUString::createFromAscii( |
| "librdf_Repository::queryAsk: " |
| "query result is null or not boolean"), *this); |
| } |
| return librdf_query_results_get_boolean(pResults.get()) |
| ? sal_True : sal_False; |
| } |
| |
| // ::com::sun::star::rdf::XDocumentRepository: |
| void SAL_CALL librdf_Repository::setStatementRDFa( |
| const uno::Reference< rdf::XResource > & i_xSubject, |
| const uno::Sequence< uno::Reference< rdf::XURI > > & i_rPredicates, |
| const uno::Reference< rdf::XMetadatable > & i_xObject, |
| const ::rtl::OUString & i_rRDFaContent, |
| const uno::Reference< rdf::XURI > & i_xRDFaDatatype) |
| throw (uno::RuntimeException, lang::IllegalArgumentException, |
| rdf::RepositoryException) |
| { |
| static const ::rtl::OUString s_cell( |
| ::rtl::OUString::createFromAscii("com.sun.star.table.Cell")); |
| static const ::rtl::OUString s_cellprops( // for writer |
| ::rtl::OUString::createFromAscii("com.sun.star.text.CellProperties")); |
| static const ::rtl::OUString s_paragraph( |
| ::rtl::OUString::createFromAscii("com.sun.star.text.Paragraph")); |
| static const ::rtl::OUString s_bookmark( |
| ::rtl::OUString::createFromAscii("com.sun.star.text.Bookmark")); |
| static const ::rtl::OUString s_meta( ::rtl::OUString::createFromAscii( |
| "com.sun.star.text.InContentMetadata")); |
| |
| if (!i_xSubject.is()) { |
| throw lang::IllegalArgumentException(::rtl::OUString::createFromAscii( |
| "librdf_Repository::setStatementRDFa: Subject is null"), *this, 0); |
| } |
| if (!i_rPredicates.getLength()) { |
| throw lang::IllegalArgumentException(::rtl::OUString::createFromAscii( |
| "librdf_Repository::setStatementRDFa: no Predicates"), |
| *this, 1); |
| } |
| for (sal_Int32 i = 0; i < i_rPredicates.getLength(); ++i) { |
| if (!i_rPredicates[i].is()) { |
| throw lang::IllegalArgumentException( |
| ::rtl::OUString::createFromAscii( |
| "librdf_Repository::setStatementRDFa: Predicate is null"), |
| *this, 1); |
| } |
| } |
| if (!i_xObject.is()) { |
| throw lang::IllegalArgumentException(::rtl::OUString::createFromAscii( |
| "librdf_Repository::setStatementRDFa: Object is null"), *this, 2); |
| } |
| const uno::Reference<lang::XServiceInfo> xService(i_xObject, |
| uno::UNO_QUERY_THROW); |
| uno::Reference<text::XTextRange> xTextRange; |
| if (xService->supportsService(s_cell) || |
| xService->supportsService(s_cellprops) || |
| xService->supportsService(s_paragraph)) |
| { |
| xTextRange.set(i_xObject, uno::UNO_QUERY_THROW); |
| } |
| else if (xService->supportsService(s_bookmark) || |
| xService->supportsService(s_meta)) |
| { |
| const uno::Reference<text::XTextContent> xTextContent(i_xObject, |
| uno::UNO_QUERY_THROW); |
| xTextRange = xTextContent->getAnchor(); |
| } |
| if (!xTextRange.is()) { |
| throw lang::IllegalArgumentException(::rtl::OUString::createFromAscii( |
| "librdf_Repository::setStatementRDFa: " |
| "Object does not support RDFa"), *this, 2); |
| } |
| // ensure that the metadatable has an XML ID |
| i_xObject->ensureMetadataReference(); |
| const beans::StringPair mdref( i_xObject->getMetadataReference() ); |
| if (mdref.First.equalsAscii("") || mdref.Second.equalsAscii("")) { |
| throw uno::RuntimeException( ::rtl::OUString::createFromAscii( |
| "librdf_Repository::setStatementRDFa: " |
| "ensureMetadataReference did not"), *this); |
| } |
| ::rtl::OUString const sXmlId(mdref.First + |
| ::rtl::OUString::createFromAscii("#") + mdref.Second); |
| uno::Reference<rdf::XURI> xXmlId; |
| try { |
| xXmlId.set( rdf::URI::create(m_xContext, |
| ::rtl::OUString::createFromAscii(s_nsOOo) + sXmlId), |
| uno::UNO_QUERY_THROW); |
| } catch (lang::IllegalArgumentException & iae) { |
| throw lang::WrappedTargetRuntimeException( |
| ::rtl::OUString::createFromAscii( |
| "librdf_Repository::setStatementRDFa: " |
| "cannot create URI for XML ID"), *this, uno::makeAny(iae)); |
| } |
| |
| ::osl::MutexGuard g(m_aMutex); |
| ::rtl::OUString const content( (i_rRDFaContent.getLength() == 0) |
| ? xTextRange->getString() |
| : i_rRDFaContent ); |
| uno::Reference<rdf::XNode> xContent; |
| try { |
| if (i_xRDFaDatatype.is()) { |
| xContent.set(rdf::Literal::createWithType(m_xContext, |
| content, i_xRDFaDatatype), |
| uno::UNO_QUERY_THROW); |
| } else { |
| xContent.set(rdf::Literal::create(m_xContext, content), |
| uno::UNO_QUERY_THROW); |
| } |
| } catch (lang::IllegalArgumentException & iae) { |
| throw lang::WrappedTargetRuntimeException( |
| ::rtl::OUString::createFromAscii( |
| "librdf_Repository::setStatementRDFa: " |
| "cannot create literal"), *this, uno::makeAny(iae)); |
| } |
| removeStatementRDFa(i_xObject); |
| if (i_rRDFaContent.getLength() == 0) { |
| m_RDFaXHTMLContentSet.erase(sXmlId); |
| } else { |
| m_RDFaXHTMLContentSet.insert(sXmlId); |
| } |
| ::std::for_each(::comphelper::stl_begin(i_rPredicates), |
| ::comphelper::stl_end(i_rPredicates), |
| ::boost::bind( &librdf_Repository::addStatementGraph, |
| this, i_xSubject, _1, xContent, xXmlId, true)); |
| } |
| |
| void SAL_CALL librdf_Repository::removeStatementRDFa( |
| const uno::Reference< rdf::XMetadatable > & i_xElement) |
| throw (uno::RuntimeException, lang::IllegalArgumentException, |
| rdf::RepositoryException) |
| { |
| if (!i_xElement.is()) { |
| throw lang::IllegalArgumentException(::rtl::OUString::createFromAscii( |
| "librdf_Repository::removeStatementRDFa: Element is null"), |
| *this, 0); |
| } |
| |
| const beans::StringPair mdref( i_xElement->getMetadataReference() ); |
| if (mdref.First.equalsAscii("") || mdref.Second.equalsAscii("")) { |
| return; // nothing to do... |
| } |
| uno::Reference<rdf::XURI> xXmlId; |
| try { |
| xXmlId.set( rdf::URI::create(m_xContext, |
| ::rtl::OUString::createFromAscii(s_nsOOo) |
| + mdref.First + ::rtl::OUString::createFromAscii("#") |
| + mdref.Second), |
| uno::UNO_QUERY_THROW); |
| } catch (lang::IllegalArgumentException & iae) { |
| throw lang::WrappedTargetRuntimeException( |
| ::rtl::OUString::createFromAscii( |
| "librdf_Repository::removeStatementRDFa: " |
| "cannot create URI for XML ID"), *this, uno::makeAny(iae)); |
| } |
| // clearGraph does locking, not needed here |
| clearGraph(xXmlId, true); |
| } |
| |
| beans::Pair< uno::Sequence<rdf::Statement>, sal_Bool > SAL_CALL |
| librdf_Repository::getStatementRDFa( |
| const uno::Reference< rdf::XMetadatable > & i_xElement) |
| throw (uno::RuntimeException, lang::IllegalArgumentException, |
| rdf::RepositoryException) |
| { |
| if (!i_xElement.is()) { |
| throw lang::IllegalArgumentException(::rtl::OUString::createFromAscii( |
| "librdf_Repository::getStatementRDFa: Element is null"), *this, 0); |
| } |
| const beans::StringPair mdref( i_xElement->getMetadataReference() ); |
| if (mdref.First.equalsAscii("") || mdref.Second.equalsAscii("")) { |
| return beans::Pair< uno::Sequence<rdf::Statement>, sal_Bool >(); |
| } |
| ::rtl::OUString const sXmlId(mdref.First + |
| ::rtl::OUString::createFromAscii("#") + mdref.Second); |
| uno::Reference<rdf::XURI> xXmlId; |
| try { |
| xXmlId.set( rdf::URI::create(m_xContext, |
| ::rtl::OUString::createFromAscii(s_nsOOo) + sXmlId), |
| uno::UNO_QUERY_THROW); |
| } catch (lang::IllegalArgumentException & iae) { |
| throw lang::WrappedTargetRuntimeException( |
| ::rtl::OUString::createFromAscii( |
| "librdf_Repository::getStatementRDFa: " |
| "cannot create URI for XML ID"), *this, uno::makeAny(iae)); |
| } |
| |
| ::osl::MutexGuard g(m_aMutex); |
| ::comphelper::SequenceAsVector< rdf::Statement > ret; |
| const uno::Reference<container::XEnumeration> xIter( |
| getStatementsGraph(0, 0, 0, xXmlId, true) ); |
| OSL_ENSURE(xIter.is(), "getStatementRDFa: no result?"); |
| if (!xIter.is()) throw uno::RuntimeException(); |
| while (xIter->hasMoreElements()) { |
| rdf::Statement stmt; |
| if (!(xIter->nextElement() >>= stmt)) { |
| OSL_ENSURE(false, "getStatementRDFa: result of wrong type?"); |
| } else { |
| ret.push_back(stmt); |
| } |
| } |
| return beans::Pair< uno::Sequence<rdf::Statement>, sal_Bool >( |
| ret.getAsConstList(), 0 != m_RDFaXHTMLContentSet.count(sXmlId)); |
| } |
| |
| extern "C" |
| librdf_statement *rdfa_context_stream_map_handler( |
| librdf_stream *i_pStream, void *, librdf_statement *i_pStatement) |
| { |
| OSL_ENSURE(i_pStream, "rdfa_context_stream_map_handler: stream null"); |
| if (i_pStream) { |
| librdf_node *pCtxt( static_cast<librdf_node *> |
| (librdf_stream_get_context(i_pStream)) ); |
| OSL_ENSURE(pCtxt, "rdfa_context_stream_map_handler: context null"); |
| if (pCtxt && isInternalContext(pCtxt)) { |
| return i_pStatement; |
| } |
| } |
| return 0; |
| }; |
| |
| uno::Reference< container::XEnumeration > SAL_CALL |
| librdf_Repository::getStatementsRDFa( |
| const uno::Reference< rdf::XResource > & i_xSubject, |
| const uno::Reference< rdf::XURI > & i_xPredicate, |
| const uno::Reference< rdf::XNode > & i_xObject) |
| throw (uno::RuntimeException, rdf::RepositoryException) |
| { |
| if (isMetadatableWithoutMetadata(i_xSubject) || |
| isMetadatableWithoutMetadata(i_xPredicate) || |
| isMetadatableWithoutMetadata(i_xObject)) |
| { |
| return new librdf_GraphResult(this, m_aMutex, |
| ::boost::shared_ptr<librdf_stream>(), |
| ::boost::shared_ptr<librdf_node>()); |
| } |
| |
| ::osl::MutexGuard g(m_aMutex); |
| const boost::shared_ptr<librdf_statement> pStatement( |
| m_TypeConverter.mkStatement(m_pWorld.get(), |
| i_xSubject, i_xPredicate, i_xObject), |
| safe_librdf_free_statement); |
| OSL_ENSURE(pStatement, "mkStatement failed"); |
| |
| const boost::shared_ptr<librdf_stream> pStream( |
| librdf_model_find_statements(m_pModel.get(), pStatement.get()), |
| safe_librdf_free_stream); |
| if (!pStream) { |
| throw rdf::RepositoryException(::rtl::OUString::createFromAscii( |
| "librdf_Repository::getStatementsRDFa: " |
| "librdf_model_find_statements failed"), *this); |
| } |
| |
| if (librdf_stream_add_map(pStream.get(), rdfa_context_stream_map_handler, |
| 0, 0)) { |
| throw rdf::RepositoryException(::rtl::OUString::createFromAscii( |
| "librdf_Repository::getStatementsRDFa: " |
| "librdf_stream_add_map failed"), *this); |
| } |
| |
| return new librdf_GraphResult(this, m_aMutex, pStream, |
| ::boost::shared_ptr<librdf_node>()); |
| } |
| |
| // ::com::sun::star::lang::XInitialization: |
| void SAL_CALL librdf_Repository::initialize( |
| const uno::Sequence< ::com::sun::star::uno::Any > & i_rArguments) |
| throw (uno::RuntimeException, uno::Exception) |
| { |
| (void) i_rArguments; |
| |
| ::osl::MutexGuard g(m_aMutex); |
| |
| // m_pWorld.reset(m_TypeConverter.createWorld(), safe_librdf_free_world); |
| m_pStorage.reset(m_TypeConverter.createStorage(m_pWorld.get()), |
| safe_librdf_free_storage); |
| m_pModel.reset(m_TypeConverter.createModel( |
| m_pWorld.get(), m_pStorage.get()), safe_librdf_free_model); |
| } |
| |
| const NamedGraphMap_t::iterator SAL_CALL librdf_Repository::clearGraph( |
| const uno::Reference< rdf::XURI > & i_xGraphName, bool i_Internal) |
| // throw (uno::RuntimeException, container::NoSuchElementException, |
| // rdf::RepositoryException) |
| { |
| if (!i_xGraphName.is()) { |
| throw lang::IllegalArgumentException( |
| ::rtl::OUString::createFromAscii("librdf_Repository::clearGraph: " |
| "URI is null"), *this, 0); |
| } |
| ::osl::MutexGuard g(m_aMutex); |
| const ::rtl::OUString contextU( i_xGraphName->getStringValue() ); |
| const NamedGraphMap_t::iterator iter( m_NamedGraphs.find(contextU) ); |
| if (!i_Internal && iter == m_NamedGraphs.end()) { |
| throw container::NoSuchElementException( |
| ::rtl::OUString::createFromAscii("librdf_Repository::clearGraph: " |
| "no graph with given URI exists"), *this); |
| } |
| const ::rtl::OString context( |
| ::rtl::OUStringToOString(contextU, RTL_TEXTENCODING_UTF8) ); |
| |
| const boost::shared_ptr<librdf_node> pContext( |
| librdf_new_node_from_uri_string(m_pWorld.get(), |
| reinterpret_cast<const unsigned char*> (context.getStr())), |
| safe_librdf_free_node); |
| if (!pContext) { |
| throw uno::RuntimeException(::rtl::OUString::createFromAscii( |
| "librdf_Repository::clearGraph: " |
| "librdf_new_node_from_uri_string failed"), *this); |
| } |
| if (librdf_model_context_remove_statements(m_pModel.get(), pContext.get())) |
| { |
| throw rdf::RepositoryException(::rtl::OUString::createFromAscii( |
| "librdf_Repository::clearGraph: " |
| "librdf_model_context_remove_statements failed"), *this); |
| } |
| return iter; |
| } |
| |
| void SAL_CALL librdf_Repository::addStatementGraph( |
| const uno::Reference< rdf::XResource > & i_xSubject, |
| const uno::Reference< rdf::XURI > & i_xPredicate, |
| const uno::Reference< rdf::XNode > & i_xObject, |
| const uno::Reference< rdf::XURI > & i_xGraphName, |
| bool i_Internal) |
| //throw (uno::RuntimeException, lang::IllegalArgumentException, |
| // container::NoSuchElementException, rdf::RepositoryException) |
| { |
| if (!i_xSubject.is()) { |
| throw lang::IllegalArgumentException(::rtl::OUString::createFromAscii( |
| "librdf_Repository::addStatement: Subject is null"), *this, 0); |
| } |
| if (!i_xPredicate.is()) { |
| throw lang::IllegalArgumentException(::rtl::OUString::createFromAscii( |
| "librdf_Repository::addStatement: Predicate is null"), |
| *this, 1); |
| } |
| if (!i_xObject.is()) { |
| throw lang::IllegalArgumentException(::rtl::OUString::createFromAscii( |
| "librdf_Repository::addStatement: Object is null"), *this, 2); |
| } |
| |
| ::osl::MutexGuard g(m_aMutex); |
| const ::rtl::OUString contextU( i_xGraphName->getStringValue() ); |
| if (!i_Internal && (m_NamedGraphs.find(contextU) == m_NamedGraphs.end())) { |
| throw container::NoSuchElementException( |
| ::rtl::OUString::createFromAscii("librdf_Repository::addStatement: " |
| "no graph with given URI exists"), *this); |
| } |
| const ::rtl::OString context( |
| ::rtl::OUStringToOString(contextU, RTL_TEXTENCODING_UTF8) ); |
| |
| const boost::shared_ptr<librdf_node> pContext( |
| librdf_new_node_from_uri_string(m_pWorld.get(), |
| reinterpret_cast<const unsigned char*> (context.getStr())), |
| safe_librdf_free_node); |
| if (!pContext) { |
| throw uno::RuntimeException(::rtl::OUString::createFromAscii( |
| "librdf_Repository::addStatement: " |
| "librdf_new_node_from_uri_string failed"), *this); |
| } |
| const boost::shared_ptr<librdf_statement> pStatement( |
| m_TypeConverter.mkStatement(m_pWorld.get(), |
| i_xSubject, i_xPredicate, i_xObject), |
| safe_librdf_free_statement); |
| OSL_ENSURE(pStatement, "mkStatement failed"); |
| |
| // Test for duplicate statement |
| // librdf_model_add_statement disallows duplicates while |
| // librdf_model_context_add_statement allows duplicates |
| { |
| const boost::shared_ptr<librdf_stream> pStream( |
| librdf_model_find_statements_in_context(m_pModel.get(), |
| pStatement.get(), pContext.get()), |
| safe_librdf_free_stream); |
| if (pStream && !librdf_stream_end(pStream.get())) |
| return; |
| } |
| |
| if (librdf_model_context_add_statement(m_pModel.get(), |
| pContext.get(), pStatement.get())) { |
| throw rdf::RepositoryException(::rtl::OUString::createFromAscii( |
| "librdf_Repository::addStatement: " |
| "librdf_model_context_add_statement failed"), *this); |
| } |
| } |
| |
| void SAL_CALL librdf_Repository::removeStatementsGraph( |
| const uno::Reference< rdf::XResource > & i_xSubject, |
| const uno::Reference< rdf::XURI > & i_xPredicate, |
| const uno::Reference< rdf::XNode > & i_xObject, |
| const uno::Reference< rdf::XURI > & i_xGraphName) |
| //throw (uno::RuntimeException, lang::IllegalArgumentException, |
| // container::NoSuchElementException, rdf::RepositoryException) |
| { |
| if (isMetadatableWithoutMetadata(i_xSubject) || |
| isMetadatableWithoutMetadata(i_xPredicate) || |
| isMetadatableWithoutMetadata(i_xObject)) |
| { |
| return; |
| } |
| |
| ::osl::MutexGuard g(m_aMutex); |
| const ::rtl::OUString contextU( i_xGraphName->getStringValue() ); |
| if (m_NamedGraphs.find(contextU) == m_NamedGraphs.end()) { |
| throw container::NoSuchElementException( |
| ::rtl::OUString::createFromAscii( |
| "librdf_Repository::removeStatements: " |
| "no graph with given URI exists"), *this); |
| } |
| const ::rtl::OString context( |
| ::rtl::OUStringToOString(contextU, RTL_TEXTENCODING_UTF8) ); |
| |
| const boost::shared_ptr<librdf_node> pContext( |
| librdf_new_node_from_uri_string(m_pWorld.get(), |
| reinterpret_cast<const unsigned char*> (context.getStr())), |
| safe_librdf_free_node); |
| if (!pContext) { |
| throw uno::RuntimeException(::rtl::OUString::createFromAscii( |
| "librdf_Repository::removeStatements: " |
| "librdf_new_node_from_uri_string failed"), *this); |
| } |
| const boost::shared_ptr<librdf_statement> pStatement( |
| m_TypeConverter.mkStatement(m_pWorld.get(), |
| i_xSubject, i_xPredicate, i_xObject), |
| safe_librdf_free_statement); |
| OSL_ENSURE(pStatement, "mkStatement failed"); |
| |
| const boost::shared_ptr<librdf_stream> pStream( |
| librdf_model_find_statements_in_context(m_pModel.get(), |
| pStatement.get(), pContext.get()), |
| safe_librdf_free_stream); |
| if (!pStream) { |
| throw rdf::RepositoryException(::rtl::OUString::createFromAscii( |
| "librdf_Repository::removeStatements: " |
| "librdf_model_find_statements_in_context failed"), *this); |
| } |
| |
| if (!librdf_stream_end(pStream.get())) { |
| do { |
| librdf_statement *pStmt( librdf_stream_get_object(pStream.get()) ); |
| if (!pStmt) { |
| throw rdf::RepositoryException(::rtl::OUString::createFromAscii( |
| "librdf_Repository::removeStatements: " |
| "librdf_stream_get_object failed"), *this); |
| } |
| if (librdf_model_context_remove_statement(m_pModel.get(), |
| pContext.get(), pStmt)) { |
| throw rdf::RepositoryException(::rtl::OUString::createFromAscii( |
| "librdf_Repository::removeStatements: " |
| "librdf_model_context_remove_statement failed"), *this); |
| } |
| } while (!librdf_stream_next(pStream.get())); |
| } |
| } |
| |
| uno::Reference< container::XEnumeration > SAL_CALL |
| librdf_Repository::getStatementsGraph( |
| const uno::Reference< rdf::XResource > & i_xSubject, |
| const uno::Reference< rdf::XURI > & i_xPredicate, |
| const uno::Reference< rdf::XNode > & i_xObject, |
| const uno::Reference< rdf::XURI > & i_xGraphName, |
| bool i_Internal) |
| //throw (uno::RuntimeException, lang::IllegalArgumentException, |
| // container::NoSuchElementException, rdf::RepositoryException) |
| { |
| // N.B.: if any of subject, predicate, object is an XMetadatable, and |
| // has no metadata reference, then there cannot be any node in the graph |
| // representing it; in order to prevent side effect |
| // (ensureMetadataReference), check for this condition and return |
| if (isMetadatableWithoutMetadata(i_xSubject) || |
| isMetadatableWithoutMetadata(i_xPredicate) || |
| isMetadatableWithoutMetadata(i_xObject)) |
| { |
| return new librdf_GraphResult(this, m_aMutex, |
| ::boost::shared_ptr<librdf_stream>(), |
| ::boost::shared_ptr<librdf_node>()); |
| } |
| |
| ::osl::MutexGuard g(m_aMutex); |
| const ::rtl::OUString contextU( i_xGraphName->getStringValue() ); |
| if (!i_Internal && (m_NamedGraphs.find(contextU) == m_NamedGraphs.end())) { |
| throw container::NoSuchElementException( |
| ::rtl::OUString::createFromAscii( |
| "librdf_Repository::getStatements: " |
| "no graph with given URI exists"), *this); |
| } |
| const ::rtl::OString context( |
| ::rtl::OUStringToOString(contextU, RTL_TEXTENCODING_UTF8) ); |
| |
| const boost::shared_ptr<librdf_node> pContext( |
| librdf_new_node_from_uri_string(m_pWorld.get(), |
| reinterpret_cast<const unsigned char*> (context.getStr())), |
| safe_librdf_free_node); |
| if (!pContext) { |
| throw uno::RuntimeException(::rtl::OUString::createFromAscii( |
| "librdf_Repository::getStatements: " |
| "librdf_new_node_from_uri_string failed"), *this); |
| } |
| const boost::shared_ptr<librdf_statement> pStatement( |
| m_TypeConverter.mkStatement(m_pWorld.get(), |
| i_xSubject, i_xPredicate, i_xObject), |
| safe_librdf_free_statement); |
| OSL_ENSURE(pStatement, "mkStatement failed"); |
| |
| const boost::shared_ptr<librdf_stream> pStream( |
| librdf_model_find_statements_in_context(m_pModel.get(), |
| pStatement.get(), pContext.get()), |
| safe_librdf_free_stream); |
| if (!pStream) { |
| throw rdf::RepositoryException(::rtl::OUString::createFromAscii( |
| "librdf_Repository::getStatements: " |
| "librdf_model_find_statements_in_context failed"), *this); |
| } |
| |
| // librdf_model_find_statements_in_context is buggy and does not put |
| // the context into result statements; pass it to librdf_GraphResult here |
| return new librdf_GraphResult(this, m_aMutex, pStream, pContext); |
| } |
| |
| librdf_world *librdf_TypeConverter::createWorld() const |
| { |
| // create and initialize world |
| librdf_world *pWorld( librdf_new_world() ); |
| if (!pWorld) { |
| throw uno::RuntimeException(::rtl::OUString::createFromAscii( |
| "librdf_TypeConverter::createWorld: librdf_new_world failed"), |
| m_rRep); |
| } |
| //FIXME logger, digest, features? |
| xsltSecurityPrefsPtr origprefs = xsltGetDefaultSecurityPrefs(); |
| librdf_world_open(pWorld); |
| xsltSecurityPrefsPtr newprefs = xsltGetDefaultSecurityPrefs(); |
| if (newprefs != origprefs) { |
| // #i110523# restore libxslt global configuration |
| // (gratuitously overwritten by raptor_init_parser_grddl_common) |
| // (this is the only reason unordf is linked against libxslt) |
| xsltSetDefaultSecurityPrefs(origprefs); |
| } |
| return pWorld; |
| } |
| |
| librdf_storage * |
| librdf_TypeConverter::createStorage(librdf_world *i_pWorld) const |
| { |
| librdf_storage *pStorage( |
| // librdf_new_storage(i_pWorld, "memory", NULL, "contexts='yes'") ); |
| librdf_new_storage(i_pWorld, "hashes", NULL, |
| "contexts='yes',hash-type='memory'") ); |
| if (!pStorage) { |
| throw uno::RuntimeException(::rtl::OUString::createFromAscii( |
| "librdf_TypeConverter::createStorage: librdf_new_storage failed"), |
| m_rRep); |
| } |
| return pStorage; |
| } |
| |
| librdf_model *librdf_TypeConverter::createModel( |
| librdf_world *i_pWorld, librdf_storage * i_pStorage) const |
| { |
| librdf_model *pRepository( librdf_new_model(i_pWorld, i_pStorage, NULL) ); |
| if (!pRepository) { |
| throw uno::RuntimeException(::rtl::OUString::createFromAscii( |
| "librdf_TypeConverter::createModel: librdf_new_model failed"), |
| m_rRep); |
| } |
| //FIXME |
| #if 0 |
| { |
| librdf_uri * ctxt = librdf_new_uri(i_pWorld, reinterpret_cast<const unsigned char *>(LIBRDF_MODEL_FEATURE_CONTEXTS)); |
| librdf_node * contexts = librdf_model_get_feature(repository, ctxt); |
| if (!contexts) |
| throw; |
| std::cout << "value of contexts feature: "; |
| prtNode(contexts); |
| std::cout << std::endl; |
| // librdf_model_set_feature(repository, LIBRDF_FEATURE_CONTEXTS, ...); |
| safe_librdf_free_node(contexts); |
| safe_librdf_free_uri(ctxt); |
| } |
| #endif |
| return pRepository; |
| } |
| |
| // this does NOT create a node, only URI |
| librdf_uri* librdf_TypeConverter::mkURI( librdf_world* i_pWorld, |
| const uno::Reference< rdf::XURI > & i_xURI) const |
| { |
| const ::rtl::OString uri( |
| ::rtl::OUStringToOString(i_xURI->getStringValue(), |
| RTL_TEXTENCODING_UTF8) ); |
| librdf_uri *pURI( librdf_new_uri(i_pWorld, |
| reinterpret_cast<const unsigned char *>(uri.getStr()))); |
| if (!pURI) { |
| throw uno::RuntimeException(::rtl::OUString::createFromAscii( |
| "librdf_TypeConverter::mkURI: librdf_new_uri failed"), 0); |
| } |
| return pURI; |
| } |
| |
| // create blank or URI node |
| librdf_node* librdf_TypeConverter::mkResource( librdf_world* i_pWorld, |
| const uno::Reference< rdf::XResource > & i_xResource) const |
| { |
| if (!i_xResource.is()) return 0; |
| uno::Reference< rdf::XBlankNode > xBlankNode(i_xResource, uno::UNO_QUERY); |
| if (xBlankNode.is()) { |
| const ::rtl::OString label( |
| ::rtl::OUStringToOString(xBlankNode->getStringValue(), |
| RTL_TEXTENCODING_UTF8) ); |
| librdf_node *pNode( |
| librdf_new_node_from_blank_identifier(i_pWorld, |
| reinterpret_cast<const unsigned char*> (label.getStr()))); |
| if (!pNode) { |
| throw uno::RuntimeException(::rtl::OUString::createFromAscii( |
| "librdf_TypeConverter::mkResource: " |
| "librdf_new_node_from_blank_identifier failed"), 0); |
| } |
| return pNode; |
| } else { // assumption: everything else is URI |
| const ::rtl::OString uri( |
| ::rtl::OUStringToOString(i_xResource->getStringValue(), |
| RTL_TEXTENCODING_UTF8) ); |
| librdf_node *pNode( |
| librdf_new_node_from_uri_string(i_pWorld, |
| reinterpret_cast<const unsigned char*> (uri.getStr()))); |
| if (!pNode) { |
| throw uno::RuntimeException(::rtl::OUString::createFromAscii( |
| "librdf_TypeConverter::mkResource: " |
| "librdf_new_node_from_uri_string failed"), 0); |
| } |
| return pNode; |
| } |
| } |
| |
| // create blank or URI or literal node |
| librdf_node* librdf_TypeConverter::mkNode( librdf_world* i_pWorld, |
| const uno::Reference< rdf::XNode > & i_xNode) const |
| { |
| if (!i_xNode.is()) return 0; |
| uno::Reference< rdf::XResource > xResource(i_xNode, uno::UNO_QUERY); |
| if (xResource.is()) { |
| return mkResource(i_pWorld, xResource); |
| } |
| uno::Reference< rdf::XLiteral> xLiteral(i_xNode, uno::UNO_QUERY); |
| OSL_ENSURE(xLiteral.is(), |
| "mkNode: someone invented a new rdf.XNode and did not tell me"); |
| if (!xLiteral.is()) return 0; |
| const ::rtl::OString val( |
| ::rtl::OUStringToOString(xLiteral->getValue(), |
| RTL_TEXTENCODING_UTF8) ); |
| const ::rtl::OString lang( |
| ::rtl::OUStringToOString(xLiteral->getLanguage(), |
| RTL_TEXTENCODING_UTF8) ); |
| const uno::Reference< rdf::XURI > xType(xLiteral->getDatatype()); |
| librdf_node * ret(0); |
| if (lang.getLength() == 0) { |
| if (!xType.is()) { |
| ret = librdf_new_node_from_literal(i_pWorld, |
| reinterpret_cast<const unsigned char*> (val.getStr()), |
| NULL, 0); |
| } else { |
| const boost::shared_ptr<librdf_uri> pDatatype( |
| mkURI(i_pWorld, xType), safe_librdf_free_uri); |
| ret = librdf_new_node_from_typed_literal(i_pWorld, |
| reinterpret_cast<const unsigned char*> (val.getStr()), |
| NULL, pDatatype.get()); |
| } |
| } else { |
| if (!xType.is()) { |
| ret = librdf_new_node_from_literal(i_pWorld, |
| reinterpret_cast<const unsigned char*> (val.getStr()), |
| (lang.getStr()), 0); |
| |
| } else { |
| OSL_ENSURE(false, "mkNode: invalid literal"); |
| return 0; |
| } |
| } |
| if (!ret) { |
| throw uno::RuntimeException(::rtl::OUString::createFromAscii( |
| "librdf_TypeConverter::mkNode: " |
| "librdf_new_node_from_literal failed"), 0); |
| } |
| return ret; |
| } |
| |
| librdf_statement* librdf_TypeConverter::mkStatement( librdf_world* i_pWorld, |
| const uno::Reference< rdf::XResource > & i_xSubject, |
| const uno::Reference< rdf::XURI > & i_xPredicate, |
| const uno::Reference< rdf::XNode > & i_xObject) const |
| { |
| librdf_node* pSubject( mkResource(i_pWorld, i_xSubject) ); |
| librdf_node* pPredicate(0); |
| librdf_node* pObject(0); |
| try { |
| const uno::Reference<rdf::XResource> xPredicate(i_xPredicate, |
| uno::UNO_QUERY); |
| pPredicate = mkResource(i_pWorld, xPredicate); |
| try { |
| pObject = mkNode(i_pWorld, i_xObject); |
| } catch (...) { |
| safe_librdf_free_node(pPredicate); |
| throw; |
| } |
| } catch (...) { |
| safe_librdf_free_node(pSubject); |
| throw; |
| } |
| // NB: this takes ownership of the nodes! (which is really ugly) |
| librdf_statement* pStatement( librdf_new_statement_from_nodes(i_pWorld, |
| pSubject, pPredicate, pObject) ); |
| if (!pStatement) { |
| throw uno::RuntimeException(::rtl::OUString::createFromAscii( |
| "librdf_TypeConverter::mkStatement: " |
| "librdf_new_statement_from_nodes failed"), 0); |
| } |
| return pStatement; |
| } |
| |
| uno::Reference<rdf::XURI> |
| librdf_TypeConverter::convertToXURI(librdf_uri* i_pURI) const |
| { |
| if (!i_pURI) return 0; |
| const unsigned char* uri( librdf_uri_as_string(i_pURI) ); |
| if (!uri) { |
| throw uno::RuntimeException(::rtl::OUString::createFromAscii( |
| "librdf_TypeConverter::convertToXURI: " |
| "librdf_uri_as_string failed"), m_rRep); |
| } |
| ::rtl::OUString uriU( ::rtl::OStringToOUString( |
| ::rtl::OString(reinterpret_cast<const sal_Char*>(uri)), |
| RTL_TEXTENCODING_UTF8) ); |
| try { |
| return rdf::URI::create(m_xContext, uriU); |
| } catch (lang::IllegalArgumentException & iae) { |
| throw lang::WrappedTargetRuntimeException( |
| ::rtl::OUString::createFromAscii( |
| "librdf_TypeConverter::convertToXURI: " |
| "illegal uri"), m_rRep, uno::makeAny(iae)); |
| } |
| } |
| |
| uno::Reference<rdf::XURI> |
| librdf_TypeConverter::convertToXURI(librdf_node* i_pNode) const |
| { |
| if (!i_pNode) return 0; |
| if (librdf_node_is_resource(i_pNode)) { |
| librdf_uri* pURI( librdf_node_get_uri(i_pNode) ); |
| if (!pURI) { |
| throw uno::RuntimeException(::rtl::OUString::createFromAscii( |
| "librdf_TypeConverter::convertToXURI: " |
| "resource has no uri"), m_rRep); |
| } |
| return convertToXURI(pURI); |
| } else { |
| OSL_ENSURE(false, "convertToXURI: unknown librdf_node"); |
| return 0; |
| } |
| } |
| |
| uno::Reference<rdf::XResource> |
| librdf_TypeConverter::convertToXResource(librdf_node* i_pNode) const |
| { |
| if (!i_pNode) return 0; |
| if (librdf_node_is_blank(i_pNode)) { |
| const unsigned char* label( librdf_node_get_blank_identifier(i_pNode) ); |
| if (!label) { |
| throw uno::RuntimeException(::rtl::OUString::createFromAscii( |
| "librdf_TypeConverter::convertToXResource: " |
| "blank node has no label"), m_rRep); |
| } |
| ::rtl::OUString labelU( ::rtl::OStringToOUString( |
| ::rtl::OString(reinterpret_cast<const sal_Char*>(label)), |
| RTL_TEXTENCODING_UTF8) ); |
| try { |
| return uno::Reference<rdf::XResource>( |
| rdf::BlankNode::create(m_xContext, labelU), uno::UNO_QUERY); |
| } catch (lang::IllegalArgumentException & iae) { |
| throw lang::WrappedTargetRuntimeException( |
| ::rtl::OUString::createFromAscii( |
| "librdf_TypeConverter::convertToXResource: " |
| "illegal blank node label"), m_rRep, uno::makeAny(iae)); |
| } |
| } else { |
| return uno::Reference<rdf::XResource>(convertToXURI(i_pNode), |
| uno::UNO_QUERY); |
| } |
| } |
| |
| uno::Reference<rdf::XNode> |
| librdf_TypeConverter::convertToXNode(librdf_node* i_pNode) const |
| { |
| if (!i_pNode) return 0; |
| if (!librdf_node_is_literal(i_pNode)) { |
| return uno::Reference<rdf::XNode>(convertToXResource(i_pNode), |
| uno::UNO_QUERY); |
| } |
| const unsigned char* value( librdf_node_get_literal_value(i_pNode) ); |
| if (!value) { |
| throw uno::RuntimeException(::rtl::OUString::createFromAscii( |
| "librdf_TypeConverter::convertToXNode: " |
| "literal has no value"), m_rRep); |
| } |
| const char * lang( librdf_node_get_literal_value_language(i_pNode) ); |
| librdf_uri* pType( |
| librdf_node_get_literal_value_datatype_uri(i_pNode) ); |
| OSL_ENSURE(!lang || !pType, "convertToXNode: invalid literal"); |
| const ::rtl::OUString valueU( ::rtl::OStringToOUString( |
| ::rtl::OString(reinterpret_cast<const sal_Char*>(value)), |
| RTL_TEXTENCODING_UTF8) ); |
| if (lang) { |
| const ::rtl::OUString langU( ::rtl::OStringToOUString( |
| ::rtl::OString(reinterpret_cast<const sal_Char*>(lang)), |
| RTL_TEXTENCODING_UTF8) ); |
| return uno::Reference<rdf::XNode>( |
| rdf::Literal::createWithLanguage(m_xContext, valueU, langU), |
| uno::UNO_QUERY); |
| } else if (pType) { |
| uno::Reference<rdf::XURI> xType(convertToXURI(pType)); |
| OSL_ENSURE(xType.is(), "convertToXNode: null uri"); |
| return uno::Reference<rdf::XNode>( |
| rdf::Literal::createWithType(m_xContext, valueU, xType), |
| uno::UNO_QUERY); |
| } else { |
| return uno::Reference<rdf::XNode>( |
| rdf::Literal::create(m_xContext, valueU), |
| uno::UNO_QUERY); |
| } |
| } |
| |
| rdf::Statement |
| librdf_TypeConverter::convertToStatement(librdf_statement* i_pStmt, |
| librdf_node* i_pContext) const |
| { |
| if (!i_pStmt) { |
| throw uno::RuntimeException(); |
| } |
| return rdf::Statement( |
| convertToXResource(librdf_statement_get_subject(i_pStmt)), |
| convertToXURI(librdf_statement_get_predicate(i_pStmt)), |
| convertToXNode(librdf_statement_get_object(i_pStmt)), |
| convertToXURI(i_pContext)); |
| } |
| |
| } // closing anonymous implementation namespace |
| |
| |
| |
| // component helper namespace |
| namespace comp_librdf_Repository { |
| |
| ::rtl::OUString SAL_CALL _getImplementationName() { |
| return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( |
| "librdf_Repository")); |
| } |
| |
| uno::Sequence< ::rtl::OUString > SAL_CALL _getSupportedServiceNames() |
| { |
| uno::Sequence< ::rtl::OUString > s(1); |
| s[0] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( |
| "com.sun.star.rdf.Repository")); |
| return s; |
| } |
| |
| uno::Reference< uno::XInterface > SAL_CALL _create( |
| const uno::Reference< uno::XComponentContext > & context) |
| SAL_THROW((uno::Exception)) |
| { |
| return static_cast< ::cppu::OWeakObject * >(new librdf_Repository(context)); |
| } |
| |
| } // closing component helper namespace |
| |