Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include "RDFaExportHelper.hxx"
31 : :
32 : : #include "xmloff/xmlnmspe.hxx"
33 : :
34 : : #include <xmloff/xmlexp.hxx>
35 : : #include <xmloff/xmltoken.hxx>
36 : :
37 : : #include <comphelper/stlunosequence.hxx>
38 : : #include <comphelper/stl_types.hxx>
39 : :
40 : : #include <com/sun/star/uri/XUriReference.hpp>
41 : : #include <com/sun/star/uri/XUriReferenceFactory.hpp>
42 : : #include <com/sun/star/rdf/Statement.hpp>
43 : : #include <com/sun/star/rdf/URIs.hpp>
44 : : #include <com/sun/star/rdf/URI.hpp>
45 : : #include <com/sun/star/rdf/XLiteral.hpp>
46 : : #include <com/sun/star/rdf/XRepositorySupplier.hpp>
47 : : #include <com/sun/star/rdf/XDocumentRepository.hpp>
48 : :
49 : : #include <rtl/ustrbuf.hxx>
50 : :
51 : : #include <boost/bind.hpp>
52 : : #include <boost/iterator_adaptors.hpp>
53 : : #ifndef BOOST_ITERATOR_ADAPTOR_DWA053000_HPP_ // from iterator_adaptors.hpp
54 : : // N.B.: the check for the header guard _of a specific version of boost_
55 : : // is here so this may work on different versions of boost,
56 : : // which sadly put the goods in different header files
57 : : #include <boost/iterator/transform_iterator.hpp>
58 : : #endif
59 : :
60 : : #include <functional>
61 : : #include <algorithm>
62 : :
63 : :
64 : : using namespace ::com::sun::star;
65 : :
66 : : namespace xmloff {
67 : :
68 : : static const char s_prefix [] = "_:b";
69 : :
70 : : static ::rtl::OUString
71 : 50 : makeCURIE(SvXMLExport * i_pExport,
72 : : uno::Reference<rdf::XURI> const & i_xURI)
73 : : {
74 : : OSL_ENSURE(i_xURI.is(), "makeCURIE: null URI");
75 [ - + ][ # # ]: 50 : if (!i_xURI.is()) throw uno::RuntimeException();
76 : :
77 [ + - ][ + - ]: 50 : const ::rtl::OUString Namespace( i_xURI->getNamespace() );
78 : : OSL_ENSURE(!Namespace.isEmpty(), "makeCURIE: no namespace");
79 [ - + ][ # # ]: 50 : if (Namespace.isEmpty()) throw uno::RuntimeException();
80 : :
81 : 50 : ::rtl::OUStringBuffer buf;
82 [ + - ][ + - ]: 50 : buf.append( i_pExport->EnsureNamespace(Namespace) );
[ + - ]
83 [ + - ]: 50 : buf.append( static_cast<sal_Unicode>(':') );
84 : : // N.B.: empty LocalName is valid!
85 [ + - ][ + - ]: 50 : buf.append( i_xURI->getLocalName() );
[ + - ]
86 : :
87 [ + - ]: 50 : return buf.makeStringAndClear();
88 : : }
89 : :
90 : : // #i112473# SvXMLExport::GetRelativeReference() not right for RDF on SaveAs
91 : : // because the URIs in the repository are not rewritten on SaveAs, the
92 : : // URI of the loaded document has to be used, not the URI of the target doc.
93 : : static ::rtl::OUString
94 : 28 : getRelativeReference(SvXMLExport const& rExport, ::rtl::OUString const& rURI)
95 : : {
96 : : uno::Reference< rdf::XURI > const xModelURI(
97 [ + - ]: 28 : rExport.GetModel(), uno::UNO_QUERY_THROW );
98 [ + - ][ + - ]: 28 : ::rtl::OUString const baseURI( xModelURI->getStringValue() );
99 : :
100 : : uno::Reference<uno::XComponentContext> const xContext(
101 [ + - ]: 28 : rExport.GetComponentContext());
102 : : uno::Reference<lang::XMultiComponentFactory> const xServiceFactory(
103 [ + - ][ + - ]: 28 : xContext->getServiceManager(), uno::UNO_SET_THROW);
[ + - ]
104 : : uno::Reference<uri::XUriReferenceFactory> const xUriFactory(
105 [ + - ]: 28 : xServiceFactory->createInstanceWithContext(
106 : 28 : ::rtl::OUString( "com.sun.star.uri.UriReferenceFactory"), xContext),
107 [ + - ][ + - ]: 28 : uno::UNO_QUERY_THROW);
108 : :
109 : : uno::Reference< uri::XUriReference > const xBaseURI(
110 [ + - ][ + - ]: 28 : xUriFactory->parse(baseURI), uno::UNO_SET_THROW );
[ + - ]
111 : : uno::Reference< uri::XUriReference > const xAbsoluteURI(
112 [ + - ][ + - ]: 28 : xUriFactory->parse(rURI), uno::UNO_SET_THROW );
[ + - ]
113 : : uno::Reference< uri::XUriReference > const xRelativeURI(
114 [ + - ]: 28 : xUriFactory->makeRelative(xBaseURI, xAbsoluteURI, true, true, false),
115 [ + - ][ + - ]: 28 : uno::UNO_SET_THROW );
116 [ + - ][ + - ]: 28 : ::rtl::OUString const relativeURI(xRelativeURI->getUriReference());
117 : :
118 : 28 : return relativeURI;
119 : : }
120 : :
121 : :
122 : : ////////////////////////////////////////////////////////////////////////////
123 : :
124 : 8 : RDFaExportHelper::RDFaExportHelper(SvXMLExport & i_rExport)
125 [ + - ]: 8 : : m_rExport(i_rExport), m_xRepository(0), m_Counter(0)
126 : : {
127 : 8 : const uno::Reference<rdf::XRepositorySupplier> xRS( m_rExport.GetModel(),
128 [ + - ]: 8 : uno::UNO_QUERY);
129 : : OSL_ENSURE(xRS.is(), "AddRDFa: model is no rdf::XRepositorySupplier");
130 [ - + ][ # # ]: 8 : if (!xRS.is()) throw uno::RuntimeException();
131 [ + - ][ + - ]: 8 : m_xRepository.set(xRS->getRDFRepository(), uno::UNO_QUERY_THROW);
[ + - ]
132 : 8 : }
133 : :
134 : : ::rtl::OUString
135 : 6 : RDFaExportHelper::LookupBlankNode(
136 : : uno::Reference<rdf::XBlankNode> const & i_xBlankNode)
137 : : {
138 : : OSL_ENSURE(i_xBlankNode.is(), "null BlankNode?");
139 [ - + ][ # # ]: 6 : if (!i_xBlankNode.is()) throw uno::RuntimeException();
140 : : ::rtl::OUString & rEntry(
141 [ + - ]: 6 : m_BlankNodeMap[ i_xBlankNode->getStringValue() ] );
142 [ + + ]: 6 : if (rEntry.isEmpty())
143 : : {
144 : 4 : ::rtl::OUStringBuffer buf;
145 [ + - ]: 4 : buf.appendAscii(s_prefix);
146 [ + - ]: 4 : buf.append(++m_Counter);
147 [ + - ]: 4 : rEntry = buf.makeStringAndClear();
148 : : }
149 : 6 : return rEntry;
150 : : }
151 : :
152 : : ////////////////////////////////////////////////////////////////////////////
153 : :
154 : : void
155 : 60 : RDFaExportHelper::AddRDFa(
156 : : uno::Reference<rdf::XMetadatable> const & i_xMetadatable)
157 : : {
158 : : try
159 : : {
160 : : beans::Pair< uno::Sequence<rdf::Statement>, sal_Bool > const
161 [ + - ][ + - ]: 60 : RDFaResult( m_xRepository->getStatementRDFa(i_xMetadatable) );
162 : :
163 : 60 : uno::Sequence<rdf::Statement> const & rStatements( RDFaResult.First );
164 : :
165 [ + + ]: 60 : if (0 == rStatements.getLength())
166 : : {
167 : 60 : return; // no RDFa
168 : : }
169 : :
170 : : // all stmts have the same subject, so we only handle first one
171 : 34 : const uno::Reference<rdf::XURI> xSubjectURI(rStatements[0].Subject,
172 [ + - ]: 34 : uno::UNO_QUERY);
173 : : const uno::Reference<rdf::XBlankNode> xSubjectBNode(
174 [ + - ]: 34 : rStatements[0].Subject, uno::UNO_QUERY);
175 [ + + ][ - + ]: 34 : if (!xSubjectURI.is() && !xSubjectBNode.is())
[ - + ]
176 : : {
177 [ # # ]: 0 : throw uno::RuntimeException();
178 : : }
179 : : static const sal_Unicode s_OpenBracket ('[');
180 : : static const sal_Unicode s_CloseBracket(']');
181 : 34 : const ::rtl::OUString about( xSubjectURI.is()
182 [ + - ]: 28 : ? getRelativeReference(m_rExport, xSubjectURI->getStringValue())
183 [ + - ][ + + ]: 40 : : ::rtl::OUStringBuffer().append(s_OpenBracket).append(
[ # # ]
184 [ + - ][ + - ]: 46 : LookupBlankNode(xSubjectBNode)).append(s_CloseBracket)
[ + - ][ + + ]
[ # # ]
185 : : .makeStringAndClear()
186 [ + - ][ + - ]: 102 : );
[ + - ][ + + ]
[ # # ][ + + ]
187 : :
188 : : const uno::Reference<rdf::XLiteral> xContent(
189 [ + - ]: 34 : rStatements[0].Object, uno::UNO_QUERY_THROW );
190 [ + - ][ + - ]: 34 : const uno::Reference<rdf::XURI> xDatatype(xContent->getDatatype());
191 [ + + ]: 34 : if (xDatatype.is())
192 : : {
193 : : const ::rtl::OUString datatype(
194 [ + - ]: 10 : makeCURIE(&m_rExport, xDatatype) );
195 : : m_rExport.AddAttribute(XML_NAMESPACE_XHTML,
196 [ + - ]: 10 : token::XML_DATATYPE, datatype);
197 : : }
198 [ + + ]: 34 : if (RDFaResult.Second) // there is xhtml:content
199 : : {
200 : : m_rExport.AddAttribute(XML_NAMESPACE_XHTML, token::XML_CONTENT,
201 [ + - ][ + - ]: 16 : xContent->getValue());
[ + - ]
202 : : }
203 : :
204 : 34 : ::rtl::OUStringBuffer property;
205 : : ::comphelper::intersperse(
206 : : ::boost::make_transform_iterator(
207 : : ::comphelper::stl_begin(rStatements),
208 : : ::boost::bind(&makeCURIE, &m_rExport,
209 : : ::boost::bind(&rdf::Statement::Predicate, _1))),
210 : : // argh, this must be the same type :(
211 : : ::boost::make_transform_iterator(
212 : : ::comphelper::stl_end(rStatements),
213 : : ::boost::bind(&makeCURIE, &m_rExport,
214 : : ::boost::bind(&rdf::Statement::Predicate, _1))),
215 : : ::comphelper::OUStringBufferAppender(property),
216 [ + - ][ + - ]: 34 : ::rtl::OUString(" "));
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
217 : :
218 : : m_rExport.AddAttribute(XML_NAMESPACE_XHTML, token::XML_PROPERTY,
219 [ + - ][ + - ]: 34 : property.makeStringAndClear());
220 : :
221 [ + - ][ + + ]: 60 : m_rExport.AddAttribute(XML_NAMESPACE_XHTML, token::XML_ABOUT, about);
[ # # ][ + - ]
222 : : }
223 : 0 : catch (uno::Exception &)
224 : : {
225 : : OSL_FAIL("AddRDFa: exception");
226 : : }
227 : : }
228 : :
229 [ + - ][ + - ]: 489 : } // namespace xmloff
230 : :
231 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|