diff options
author | Ashod Nakashian <ashod.nakashian@collabora.co.uk> | 2017-08-02 22:19:00 -0400 |
---|---|---|
committer | Ashod Nakashian <ashnakash@gmail.com> | 2017-08-04 04:33:01 +0200 |
commit | 57446e0b60b9edbe1d72b13d664857f8d09c5048 (patch) | |
tree | 3984e8ec8f61bea3542ac6083f4a4ff6a6f540be | |
parent | 80095665bfcb8dd22b7cfe4fcc7d7a3023712385 (diff) |
sw: store paragraph signature as rdf metadata
Change-Id: I13e6079e2aa3bee3dac10b11b0a23e9b798e02a3
Reviewed-on: https://gerrit.libreoffice.org/40722
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Ashod Nakashian <ashnakash@gmail.com>
-rw-r--r-- | sw/inc/rdfhelper.hxx | 11 | ||||
-rw-r--r-- | sw/source/core/doc/rdfhelper.cxx | 50 | ||||
-rw-r--r-- | sw/source/core/edit/edfcol.cxx | 24 |
3 files changed, 79 insertions, 6 deletions
diff --git a/sw/inc/rdfhelper.hxx b/sw/inc/rdfhelper.hxx index f89d470300ed..d7c03279cd7d 100644 --- a/sw/inc/rdfhelper.hxx +++ b/sw/inc/rdfhelper.hxx @@ -22,10 +22,17 @@ class SwTextNode; class SW_DLLPUBLIC SwRDFHelper { public: - /// Gets all (rNode, key, value) statements in RDF graphs of type rType. - static std::map<OUString, OUString> getTextNodeStatements(const OUString& rType, const SwTextNode& rNode); + /// Gets all (rTextNode, key, value) statements in RDF graphs of type rType. + static std::map<OUString, OUString> getTextNodeStatements(const OUString& rType, const SwTextNode& rTextNode); + /// Add an (rTextNode, key, value) statement in the graph of type rType -- or if it does not exist, create a graph at rPath first. static void addTextNodeStatement(const OUString& rType, const OUString& rPath, SwTextNode& rTextNode, const OUString& rKey, const OUString& rValue); + + /// Remove an (rTextNode, key, value) statement in the graph of type rType. + static void removeTextNodeStatement(const OUString& rType, SwTextNode& rTextNode, const OUString& rKey, const OUString& rValue); + + /// Update an (rTextNode, key, value) statement in the graph of type rType from old value to new. Creates the graph at rPath if doesn't exist. + static void updateTextNodeStatement(const OUString& rType, const OUString& rPath, SwTextNode& rTextNode, const OUString& rKey, const OUString& rOldValue, const OUString& rNewValue); }; #endif // INCLUDED_SW_INC_RDFHELPER_HXX diff --git a/sw/source/core/doc/rdfhelper.cxx b/sw/source/core/doc/rdfhelper.cxx index a139dfc0ba57..d43660dd258e 100644 --- a/sw/source/core/doc/rdfhelper.cxx +++ b/sw/source/core/doc/rdfhelper.cxx @@ -73,4 +73,54 @@ void SwRDFHelper::addTextNodeStatement(const OUString& rType, const OUString& rP xGraph->addStatement(xSubject, xKey, xValue); } +void SwRDFHelper::removeTextNodeStatement(const OUString& rType, SwTextNode& rTextNode, const OUString& rKey, const OUString& rValue) +{ + uno::Reference<uno::XComponentContext> xComponentContext(comphelper::getProcessComponentContext()); + uno::Reference<rdf::XURI> xType = rdf::URI::create(xComponentContext, rType); + uno::Reference<rdf::XDocumentMetadataAccess> xDocumentMetadataAccess(rTextNode.GetDoc()->GetDocShell()->GetBaseModel(), uno::UNO_QUERY); + uno::Sequence< uno::Reference<rdf::XURI> > aGraphNames = xDocumentMetadataAccess->getMetadataGraphsWithType(xType); + if (!aGraphNames.hasElements()) + return; + + uno::Reference<rdf::XURI> xGraphName = aGraphNames[0]; + uno::Reference<rdf::XNamedGraph> xGraph = xDocumentMetadataAccess->getRDFRepository()->getGraph(xGraphName); + uno::Reference<rdf::XResource> xSubject(SwXParagraph::CreateXParagraph(*rTextNode.GetDoc(), &rTextNode), uno::UNO_QUERY); + uno::Reference<rdf::XURI> xKey = rdf::URI::create(xComponentContext, rKey); + uno::Reference<rdf::XLiteral> xValue = rdf::Literal::create(xComponentContext, rValue); + xGraph->removeStatements(xSubject, xKey, xValue); +} + +void SwRDFHelper::updateTextNodeStatement(const OUString& rType, const OUString& rPath, SwTextNode& rTextNode, const OUString& rKey, const OUString& rOldValue, const OUString& rNewValue) +{ + uno::Reference<uno::XComponentContext> xComponentContext(comphelper::getProcessComponentContext()); + uno::Reference<rdf::XURI> xType = rdf::URI::create(xComponentContext, rType); + uno::Reference<rdf::XDocumentMetadataAccess> xDocumentMetadataAccess(rTextNode.GetDoc()->GetDocShell()->GetBaseModel(), uno::UNO_QUERY); + uno::Sequence< uno::Reference<rdf::XURI> > aGraphNames = xDocumentMetadataAccess->getMetadataGraphsWithType(xType); + uno::Reference<rdf::XURI> xGraphName; + if (aGraphNames.hasElements()) + { + xGraphName = aGraphNames[0]; + } + else + { + uno::Sequence< uno::Reference<rdf::XURI> > xTypes = { xType }; + xGraphName = xDocumentMetadataAccess->addMetadataFile(rPath, xTypes); + } + + uno::Reference<rdf::XNamedGraph> xGraph = xDocumentMetadataAccess->getRDFRepository()->getGraph(xGraphName); + uno::Reference<rdf::XResource> xSubject(SwXParagraph::CreateXParagraph(*rTextNode.GetDoc(), &rTextNode), uno::UNO_QUERY); + uno::Reference<rdf::XURI> xKey = rdf::URI::create(xComponentContext, rKey); + + if (aGraphNames.hasElements()) + { + // Remove the old value. + uno::Reference<rdf::XLiteral> xOldValue = rdf::Literal::create(xComponentContext, rOldValue); + xGraph->removeStatements(xSubject, xKey, xOldValue); + } + + // Now add it with new value. + uno::Reference<rdf::XLiteral> xNewValue = rdf::Literal::create(xComponentContext, rNewValue); + xGraph->addStatement(xSubject, xKey, xNewValue); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/edit/edfcol.cxx b/sw/source/core/edit/edfcol.cxx index 28d2907c939b..6dfbded172ff 100644 --- a/sw/source/core/edit/edfcol.cxx +++ b/sw/source/core/edit/edfcol.cxx @@ -60,6 +60,7 @@ #include <unoprnms.hxx> #include <rootfrm.hxx> #include <pagefrm.hxx> +#include <rdfhelper.hxx> #include <sfx2/watermarkitem.hxx> #include <cppuhelper/bootstrap.hxx> @@ -579,17 +580,32 @@ void SwEditShell::SignParagraph(SwPaM* pPaM) // 3. Sign it. svl::crypto::Signing signing(xCert); signing.AddDataRange(text.getStr(), text.getLength()); - OStringBuffer signature; - if (!signing.Sign(signature)) + OStringBuffer sigBuf; + if (!signing.Sign(sigBuf)) return; + const OString signature = sigBuf.makeStringAndClear(); const auto pData = reinterpret_cast<const unsigned char*>(text.getStr()); const std::vector<unsigned char> data(pData, pData + text.getLength()); - const std::vector<unsigned char> sig(svl::crypto::DecodeHexString(signature.makeStringAndClear())); + const std::vector<unsigned char> sig(svl::crypto::DecodeHexString(signature)); if (!svl::crypto::Signing::Verify(data, true, sig, aInfo)) return; - // 4. Add metadata. + // 4. Add metadata + static const OUString metaNS("urn:bails"); + static const OUString metaFile("bails.rdf"); + + std::map<OUString, OUString> aStatements = SwRDFHelper::getTextNodeStatements(metaNS, *pNode); + OUString name = "loext:signature:index"; + const OUString indexOld = aStatements[name]; + + // Update the index + const OUString index = OUString::number(indexOld.isEmpty() ? 1 : (indexOld.toInt32() + 1)); + SwRDFHelper::updateTextNodeStatement(metaNS, metaFile, *pNode, name, indexOld, index); + + // Add the signature + name = "loext:signature:signature" + index; + SwRDFHelper::addTextNodeStatement(metaNS, metaFile, *pNode, name, OStringToOUString(signature, RTL_TEXTENCODING_UTF8, 0)); } } |