1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "RDFaExportHelper.hxx"
22 #include <xmloff/xmlnmspe.hxx>
24 #include <xmloff/xmlexp.hxx>
25 #include <xmloff/xmltoken.hxx>
27 #include <comphelper/stl_types.hxx>
28 #include <comphelper/processfactory.hxx>
30 #include <com/sun/star/uri/XUriReference.hpp>
31 #include <com/sun/star/uri/UriReferenceFactory.hpp>
32 #include <com/sun/star/rdf/Statement.hpp>
33 #include <com/sun/star/rdf/URIs.hpp>
34 #include <com/sun/star/rdf/URI.hpp>
35 #include <com/sun/star/rdf/XLiteral.hpp>
36 #include <com/sun/star/rdf/XRepositorySupplier.hpp>
37 #include <com/sun/star/rdf/XDocumentRepository.hpp>
39 #include <rtl/ustrbuf.hxx>
41 #include <boost/bind.hpp>
42 #include <boost/iterator_adaptors.hpp>
43 #ifndef BOOST_ITERATOR_ADAPTOR_DWA053000_HPP_ // from iterator_adaptors.hpp
44 // N.B.: the check for the header guard _of a specific version of boost_
45 // is here so this may work on different versions of boost,
46 // which sadly put the goods in different header files
47 #include <boost/iterator/transform_iterator.hpp>
53 using namespace ::com::sun::star
;
58 makeCURIE(SvXMLExport
* i_pExport
,
59 uno::Reference
<rdf::XURI
> const & i_xURI
)
61 OSL_ENSURE(i_xURI
.is(), "makeCURIE: null URI");
62 if (!i_xURI
.is()) throw uno::RuntimeException();
64 const OUString
Namespace( i_xURI
->getNamespace() );
65 OSL_ENSURE(!Namespace
.isEmpty(), "makeCURIE: no namespace");
66 if (Namespace
.isEmpty()) throw uno::RuntimeException();
68 // N.B.: empty LocalName is valid!
69 return i_pExport
->EnsureNamespace(Namespace
) + ":" + i_xURI
->getLocalName();
72 // #i112473# SvXMLExport::GetRelativeReference() not right for RDF on SaveAs
73 // because the URIs in the repository are not rewritten on SaveAs, the
74 // URI of the loaded document has to be used, not the URI of the target doc.
76 getRelativeReference(SvXMLExport
const& rExport
, OUString
const& rURI
)
78 uno::Reference
< rdf::XURI
> const xModelURI(
79 rExport
.GetModel(), uno::UNO_QUERY_THROW
);
80 OUString
const baseURI( xModelURI
->getStringValue() );
82 uno::Reference
<uno::XComponentContext
> xContext( comphelper::getProcessComponentContext() );
83 uno::Reference
<uri::XUriReferenceFactory
> const xUriFactory
=
84 uri::UriReferenceFactory::create( xContext
);
86 uno::Reference
< uri::XUriReference
> const xBaseURI(
87 xUriFactory
->parse(baseURI
), uno::UNO_SET_THROW
);
88 uno::Reference
< uri::XUriReference
> const xAbsoluteURI(
89 xUriFactory
->parse(rURI
), uno::UNO_SET_THROW
);
90 uno::Reference
< uri::XUriReference
> const xRelativeURI(
91 xUriFactory
->makeRelative(xBaseURI
, xAbsoluteURI
, true, true, false),
93 OUString
const relativeURI(xRelativeURI
->getUriReference());
98 RDFaExportHelper::RDFaExportHelper(SvXMLExport
& i_rExport
)
99 : m_rExport(i_rExport
), m_xRepository(0), m_Counter(0)
101 const uno::Reference
<rdf::XRepositorySupplier
> xRS( m_rExport
.GetModel(),
103 OSL_ENSURE(xRS
.is(), "AddRDFa: model is no rdf::XRepositorySupplier");
104 if (!xRS
.is()) throw uno::RuntimeException();
105 m_xRepository
.set(xRS
->getRDFRepository(), uno::UNO_QUERY_THROW
);
109 RDFaExportHelper::LookupBlankNode(
110 uno::Reference
<rdf::XBlankNode
> const & i_xBlankNode
)
112 OSL_ENSURE(i_xBlankNode
.is(), "null BlankNode?");
113 if (!i_xBlankNode
.is()) throw uno::RuntimeException();
115 m_BlankNodeMap
[ i_xBlankNode
->getStringValue() ] );
116 if (rEntry
.isEmpty())
118 rEntry
= "_:b" + OUString::number(++m_Counter
);
124 RDFaExportHelper::AddRDFa(
125 uno::Reference
<rdf::XMetadatable
> const & i_xMetadatable
)
129 beans::Pair
< uno::Sequence
<rdf::Statement
>, sal_Bool
> const
130 RDFaResult( m_xRepository
->getStatementRDFa(i_xMetadatable
) );
132 uno::Sequence
<rdf::Statement
> const & rStatements( RDFaResult
.First
);
134 if (0 == rStatements
.getLength())
139 // all stmts have the same subject, so we only handle first one
140 const uno::Reference
<rdf::XURI
> xSubjectURI(rStatements
[0].Subject
,
142 const uno::Reference
<rdf::XBlankNode
> xSubjectBNode(
143 rStatements
[0].Subject
, uno::UNO_QUERY
);
144 if (!xSubjectURI
.is() && !xSubjectBNode
.is())
146 throw uno::RuntimeException();
148 const OUString
about( xSubjectURI
.is()
149 ? getRelativeReference(m_rExport
, xSubjectURI
->getStringValue())
150 : "[" + LookupBlankNode(xSubjectBNode
) + "]"
153 const uno::Reference
<rdf::XLiteral
> xContent(
154 rStatements
[0].Object
, uno::UNO_QUERY_THROW
);
155 const uno::Reference
<rdf::XURI
> xDatatype(xContent
->getDatatype());
158 const OUString
datatype(
159 makeCURIE(&m_rExport
, xDatatype
) );
160 m_rExport
.AddAttribute(XML_NAMESPACE_XHTML
,
161 token::XML_DATATYPE
, datatype
);
163 if (RDFaResult
.Second
) // there is xhtml:content
165 m_rExport
.AddAttribute(XML_NAMESPACE_XHTML
, token::XML_CONTENT
,
166 xContent
->getValue());
169 OUStringBuffer property
;
170 ::comphelper::intersperse(
171 ::boost::make_transform_iterator(rStatements
.begin(),
172 ::boost::bind(&makeCURIE
, &m_rExport
,
173 ::boost::bind(&rdf::Statement::Predicate
, _1
))),
174 // argh, this must be the same type :(
175 ::boost::make_transform_iterator(
177 ::boost::bind(&makeCURIE
, &m_rExport
,
178 ::boost::bind(&rdf::Statement::Predicate
, _1
))),
179 ::comphelper::OUStringBufferAppender(property
),
182 m_rExport
.AddAttribute(XML_NAMESPACE_XHTML
, token::XML_PROPERTY
,
183 property
.makeStringAndClear());
185 m_rExport
.AddAttribute(XML_NAMESPACE_XHTML
, token::XML_ABOUT
, about
);
187 catch (uno::Exception
&)
189 OSL_FAIL("AddRDFa: exception");
193 } // namespace xmloff
195 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */