/************************************************************** * * 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 "precompiled_xmloff.hxx" #include "RDFaExportHelper.hxx" #include "xmloff/xmlnmspe.hxx" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef BOOST_ITERATOR_ADAPTOR_DWA053000_HPP_ // from iterator_adaptors.hpp // N.B.: the check for the header guard _of a specific version of boost_ // is here so this may work on different versions of boost, // which sadly put the goods in different header files #include #endif #include #include using namespace ::com::sun::star; namespace xmloff { static const char s_prefix [] = "_:b"; static ::rtl::OUString makeCURIE(SvXMLExport * i_pExport, uno::Reference const & i_xURI) { OSL_ENSURE(i_xURI.is(), "makeCURIE: null URI"); if (!i_xURI.is()) throw uno::RuntimeException(); const ::rtl::OUString Namespace( i_xURI->getNamespace() ); OSL_ENSURE(Namespace.getLength(), "makeCURIE: no namespace"); if (!Namespace.getLength()) throw uno::RuntimeException(); ::rtl::OUStringBuffer buf; buf.append( i_pExport->EnsureNamespace(Namespace) ); buf.append( static_cast(':') ); // N.B.: empty LocalName is valid! buf.append( i_xURI->getLocalName() ); return buf.makeStringAndClear(); } // #i112473# SvXMLExport::GetRelativeReference() not right for RDF on SaveAs // because the URIs in the repository are not rewritten on SaveAs, the // URI of the loaded document has to be used, not the URI of the target doc. static ::rtl::OUString getRelativeReference(SvXMLExport const& rExport, ::rtl::OUString const& rURI) { uno::Reference< rdf::XURI > const xModelURI( rExport.GetModel(), uno::UNO_QUERY_THROW ); ::rtl::OUString const baseURI( xModelURI->getStringValue() ); uno::Reference const xContext( rExport.GetComponentContext()); uno::Reference const xServiceFactory( xContext->getServiceManager(), uno::UNO_SET_THROW); uno::Reference const xUriFactory( xServiceFactory->createInstanceWithContext( ::rtl::OUString::createFromAscii( "com.sun.star.uri.UriReferenceFactory"), xContext), uno::UNO_QUERY_THROW); uno::Reference< uri::XUriReference > const xBaseURI( xUriFactory->parse(baseURI), uno::UNO_SET_THROW ); uno::Reference< uri::XUriReference > const xAbsoluteURI( xUriFactory->parse(rURI), uno::UNO_SET_THROW ); uno::Reference< uri::XUriReference > const xRelativeURI( xUriFactory->makeRelative(xBaseURI, xAbsoluteURI, true, true, false), uno::UNO_SET_THROW ); ::rtl::OUString const relativeURI(xRelativeURI->getUriReference()); return relativeURI; } //////////////////////////////////////////////////////////////////////////// RDFaExportHelper::RDFaExportHelper(SvXMLExport & i_rExport) : m_rExport(i_rExport), m_xRepository(0), m_Counter(0) { const uno::Reference xRS( m_rExport.GetModel(), uno::UNO_QUERY); OSL_ENSURE(xRS.is(), "AddRDFa: model is no rdf::XRepositorySupplier"); if (!xRS.is()) throw uno::RuntimeException(); m_xRepository.set(xRS->getRDFRepository(), uno::UNO_QUERY_THROW); } ::rtl::OUString RDFaExportHelper::LookupBlankNode( uno::Reference const & i_xBlankNode) { OSL_ENSURE(i_xBlankNode.is(), "null BlankNode?"); if (!i_xBlankNode.is()) throw uno::RuntimeException(); ::rtl::OUString & rEntry( m_BlankNodeMap[ i_xBlankNode->getStringValue() ] ); if (!rEntry.getLength()) { ::rtl::OUStringBuffer buf; buf.appendAscii(s_prefix); buf.append(++m_Counter); rEntry = buf.makeStringAndClear(); } return rEntry; } //////////////////////////////////////////////////////////////////////////// void RDFaExportHelper::AddRDFa( uno::Reference const & i_xMetadatable) { try { beans::Pair< uno::Sequence, sal_Bool > const RDFaResult( m_xRepository->getStatementRDFa(i_xMetadatable) ); uno::Sequence const & rStatements( RDFaResult.First ); if (0 == rStatements.getLength()) { return; // no RDFa } // all stmts have the same subject, so we only handle first one const uno::Reference xSubjectURI(rStatements[0].Subject, uno::UNO_QUERY); const uno::Reference xSubjectBNode( rStatements[0].Subject, uno::UNO_QUERY); if (!xSubjectURI.is() && !xSubjectBNode.is()) { throw uno::RuntimeException(); } static const sal_Unicode s_OpenBracket ('['); static const sal_Unicode s_CloseBracket(']'); const ::rtl::OUString about( xSubjectURI.is() ? getRelativeReference(m_rExport, xSubjectURI->getStringValue()) : ::rtl::OUStringBuffer().append(s_OpenBracket).append( LookupBlankNode(xSubjectBNode)).append(s_CloseBracket) .makeStringAndClear() ); const uno::Reference xContent( rStatements[0].Object, uno::UNO_QUERY_THROW ); const uno::Reference xDatatype(xContent->getDatatype()); if (xDatatype.is()) { const ::rtl::OUString datatype( makeCURIE(&m_rExport, xDatatype) ); m_rExport.AddAttribute(XML_NAMESPACE_XHTML, token::XML_DATATYPE, datatype); } if (RDFaResult.Second) // there is xhtml:content { m_rExport.AddAttribute(XML_NAMESPACE_XHTML, token::XML_CONTENT, xContent->getValue()); } ::rtl::OUStringBuffer property; ::comphelper::intersperse( ::boost::make_transform_iterator( ::comphelper::stl_begin(rStatements), ::boost::bind(&makeCURIE, &m_rExport, ::boost::bind(&rdf::Statement::Predicate, _1))), // argh, this must be the same type :( ::boost::make_transform_iterator( ::comphelper::stl_end(rStatements), ::boost::bind(&makeCURIE, &m_rExport, ::boost::bind(&rdf::Statement::Predicate, _1))), ::comphelper::OUStringBufferAppender(property), ::rtl::OUString::createFromAscii(" ")); m_rExport.AddAttribute(XML_NAMESPACE_XHTML, token::XML_PROPERTY, property.makeStringAndClear()); m_rExport.AddAttribute(XML_NAMESPACE_XHTML, token::XML_ABOUT, about); } catch (uno::Exception &) { OSL_ENSURE(false, "AddRDFa: exception"); } } } // namespace xmloff