[Libreoffice-commits] core.git: sw/source

Ashod Nakashian ashodnakashian at yahoo.com
Mon Nov 6 05:12:50 UTC 2017


 sw/source/core/edit/edfcol.cxx |  177 +++++++++++++++++++++++++++++------------
 sw/source/core/edit/edws.cxx   |    5 -
 2 files changed, 127 insertions(+), 55 deletions(-)

New commits:
commit e6b200524bd5f614ab5ece88e8187466e7c40096
Author: Ashod Nakashian <ashodnakashian at yahoo.com>
Date:   Thu Nov 2 21:20:50 2017 -0400

    TSCP: Store paragraph signature RDF in the paragraph
    
    Change-Id: Ic44e3238bd1c35445bc23d0cc1de07aa2bf4512c
    Reviewed-on: https://gerrit.libreoffice.org/44243
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>

diff --git a/sw/source/core/edit/edfcol.cxx b/sw/source/core/edit/edfcol.cxx
index 2b32ccfb9f0d..2486c3fb769e 100644
--- a/sw/source/core/edit/edfcol.cxx
+++ b/sw/source/core/edit/edfcol.cxx
@@ -95,9 +95,12 @@ namespace
 {
 static const OUString MetaFilename("tscp/bails.rdf");
 static const OUString MetaNS("urn:bails");
-static const OUString ParagraphSignatureRDFName = "urn:bails:loext:paragraph:signature";
-static const OUString ParagraphSignatureDateRDFName = "urn:bails:loext:paragraph:signature:date";
-static const OUString ParagraphSignatureUsageRDFName = "urn:bails:loext:paragraph:signature:usage";
+static const OUString ParagraphSignatureRDFNamespace = "urn:bails:loext:paragraph:signature:";
+static const OUString ParagraphSignatureIdRDFName = "urn:bails:loext:paragraph:signature:id";
+static const OUString ParagraphSignatureDigestRDFName = ":digest";
+static const OUString ParagraphSignatureDateRDFName = ":date";
+static const OUString ParagraphSignatureUsageRDFName = ":usage";
+static const OUString ParagraphSignatureLastIdRDFName = "urn:bails:loext:paragraph:signature:lastid";
 static const OUString ParagraphClassificationNameRDFName = "urn:bails:loext:paragraph:classification:name";
 static const OUString ParagraphClassificationValueRDFName = "urn:bails:loext:paragraph:classification:value";
 static const OUString MetadataFieldServiceName = "com.sun.star.text.textfield.MetadataField";
@@ -275,29 +278,68 @@ std::pair<OUString, OUString> lcl_getFieldRDF(const uno::Reference<frame::XModel
 bool lcl_IsParagraphSignatureField(const uno::Reference<frame::XModel>& xModel,
                                    const uno::Reference<css::text::XTextField>& xField)
 {
-    return lcl_getFieldRDF(xModel, xField, ParagraphSignatureRDFName).first == ParagraphSignatureRDFName;
+    return (lcl_getFieldRDF(xModel, xField, ParagraphSignatureIdRDFName).first == ParagraphSignatureIdRDFName);
+}
+
+struct SignatureDescr
+{
+    OUString msSignature;
+    OUString msUsage;
+    OUString msDate;
+    OUString msId;
+
+    bool isValid() const { return !msSignature.isEmpty(); }
+};
+
+SignatureDescr lcl_getSignatureDescr(const uno::Reference<frame::XModel>& xModel,
+                                     const uno::Reference<css::text::XTextContent>& xParagraph,
+                                     const OUString& sFieldId)
+{
+    SignatureDescr aDescr;
+    aDescr.msId = sFieldId;
+
+    const css::uno::Reference<css::rdf::XResource> xParaSubject(xParagraph, uno::UNO_QUERY);
+    const std::map<OUString, OUString> aStatements = SwRDFHelper::getStatements(xModel, MetaNS, xParaSubject);
+    const auto itSig = aStatements.find(ParagraphSignatureRDFNamespace + sFieldId + ParagraphSignatureDigestRDFName);
+    aDescr.msSignature = (itSig != aStatements.end() ? itSig->second : OUString());
+
+    const auto itDate = aStatements.find(ParagraphSignatureRDFNamespace + sFieldId + ParagraphSignatureDateRDFName);
+    aDescr.msDate = (itDate != aStatements.end() ? itDate->second : OUString());
+
+    const auto itUsage = aStatements.find(ParagraphSignatureRDFNamespace + sFieldId + ParagraphSignatureUsageRDFName);
+    aDescr.msUsage = (itUsage != aStatements.end() ? itUsage->second : OUString());
+
+    return aDescr;
+}
+
+SignatureDescr lcl_getSignatureDescr(const uno::Reference<frame::XModel>& xModel,
+                                     const uno::Reference<css::text::XTextContent>& xParagraph,
+                                     const uno::Reference<css::text::XTextField>& xField)
+{
+    const css::uno::Reference<css::rdf::XResource> xFieldSubject(xField, uno::UNO_QUERY);
+    std::map<OUString, OUString> aStatements = SwRDFHelper::getStatements(xModel, MetaNS, xFieldSubject);
+    const auto itId = aStatements.find(ParagraphSignatureIdRDFName);
+    return (itId != aStatements.end() ? lcl_getSignatureDescr(xModel, xParagraph, itId->second) : SignatureDescr());
 }
 
 /// Validate and return validation result and signature field display text.
 std::pair<bool, OUString>
 lcl_MakeParagraphSignatureFieldText(const uno::Reference<frame::XModel>& xModel,
+                                    const uno::Reference<css::text::XTextContent>& xParagraph,
                                     const uno::Reference<css::text::XTextField>& xField,
                                     const OString& utf8Text)
 {
     OUString msg = SwResId(STR_INVALID_SIGNATURE);
     bool valid = false;
 
-    const css::uno::Reference<css::rdf::XResource> xSubject(xField, uno::UNO_QUERY);
-    std::map<OUString, OUString> aStatements = SwRDFHelper::getStatements(xModel, MetaNS, xSubject);
-
-    const auto it = aStatements.find(ParagraphSignatureRDFName);
-    if (it != aStatements.end())
+    const SignatureDescr aDescr = lcl_getSignatureDescr(xModel, xParagraph, xField);
+    if (aDescr.isValid())
     {
         const sal_Char* pData = utf8Text.getStr();
         const std::vector<unsigned char> data(pData, pData + utf8Text.getLength());
 
         OString encSignature;
-        if (it->second.convertToString(&encSignature, RTL_TEXTENCODING_UTF8, 0))
+        if (aDescr.msSignature.convertToString(&encSignature, RTL_TEXTENCODING_UTF8, 0))
         {
             const std::vector<unsigned char> sig(svl::crypto::DecodeHexString(encSignature));
             SignatureInformation aInfo(0);
@@ -305,13 +347,8 @@ lcl_MakeParagraphSignatureFieldText(const uno::Reference<frame::XModel>& xModel,
             valid = valid && aInfo.nStatus == css::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED;
 
             msg = SwResId(STR_SIGNED_BY) + ": " + aInfo.ouSubject + ", ";
-
-            const auto itDate = aStatements.find(ParagraphSignatureDateRDFName);
-            msg += (itDate != aStatements.end() ? itDate->second : OUString());
-
-            const auto itUsage = aStatements.find(ParagraphSignatureUsageRDFName);
-            msg += (itUsage != aStatements.end() ? (" (" + itUsage->second + "): ") : OUString(": "));
-
+            msg += aDescr.msDate;
+            msg += (!aDescr.msUsage.isEmpty() ? (" (" + aDescr.msUsage + "): ") : OUString(": "));
             msg += (valid ? SwResId(STR_VALID) : SwResId(STR_INVALID));
         }
     }
@@ -319,9 +356,20 @@ lcl_MakeParagraphSignatureFieldText(const uno::Reference<frame::XModel>& xModel,
     return std::make_pair(valid, msg);
 }
 
+/// Generate the next valid ID for the a new signature on this paragraph.
+OUString lcl_getNextSignatureId(const uno::Reference<frame::XModel>& xModel,
+                                const uno::Reference<text::XTextContent>& xParagraph)
+{
+    const css::uno::Reference<css::rdf::XResource> xParaSubject(xParagraph, uno::UNO_QUERY);
+    std::map<OUString, OUString> aStatements = SwRDFHelper::getStatements(xModel, MetaNS, xParaSubject);
+    const auto it = aStatements.find(ParagraphSignatureLastIdRDFName);
+    return OUString::number(it != aStatements.end() ? it->second.toInt32() + 1 : 1);
+}
+
+
 /// Creates and inserts Paragraph Signature Metadata field and creates the RDF entry
 uno::Reference<text::XTextField> lcl_InsertParagraphSignature(const uno::Reference<frame::XModel>& xModel,
-                                                              const uno::Reference<text::XTextContent>& xParent,
+                                                              const uno::Reference<text::XTextContent>& xParagraph,
                                                               const OUString& signature,
                                                               const OUString& usage)
 {
@@ -329,16 +377,15 @@ uno::Reference<text::XTextField> lcl_InsertParagraphSignature(const uno::Referen
     auto xField = uno::Reference<text::XTextField>(xMultiServiceFactory->createInstance(MetadataFieldServiceName), uno::UNO_QUERY);
 
     // Add the signature at the end.
-    xField->attach(xParent->getAnchor()->getEnd());
+    xField->attach(xParagraph->getAnchor()->getEnd());
+
+    const OUString sId = lcl_getNextSignatureId(xModel, xParagraph);
 
     const css::uno::Reference<css::rdf::XResource> xSubject(xField, uno::UNO_QUERY);
-    SwRDFHelper::addStatement(xModel, MetaNS, MetaFilename, xSubject, ParagraphSignatureRDFName, signature);
-    SwRDFHelper::addStatement(xModel, MetaNS, MetaFilename, xSubject, ParagraphSignatureUsageRDFName, usage);
+    SwRDFHelper::addStatement(xModel, MetaNS, MetaFilename, xSubject, ParagraphSignatureIdRDFName, sId);
 
-    // First convert the UTC UNIX timestamp to a tools::DateTime.
+    // First convert the UTC UNIX timestamp to a tools::DateTime then to local time.
     DateTime aDateTime = DateTime::CreateFromUnixTime(time(nullptr));
-
-    // Then convert to a local UNO DateTime.
     aDateTime.ConvertToLocalTime();
     OUStringBuffer rBuffer;
     rBuffer.append((sal_Int32)aDateTime.GetYear());
@@ -351,7 +398,12 @@ uno::Reference<text::XTextField> lcl_InsertParagraphSignature(const uno::Referen
         rBuffer.append('0');
     rBuffer.append((sal_Int32)aDateTime.GetDay());
 
-    SwRDFHelper::addStatement(xModel, MetaNS, MetaFilename, xSubject, ParagraphSignatureDateRDFName, rBuffer.makeStringAndClear());
+    // Now set the RDF on the paragraph, since that's what is preserved in .doc(x).
+    const css::uno::Reference<css::rdf::XResource> xParaSubject(xParagraph, uno::UNO_QUERY);
+    SwRDFHelper::addStatement(xModel, MetaNS, MetaFilename, xParaSubject, ParagraphSignatureLastIdRDFName, sId);
+    SwRDFHelper::addStatement(xModel, MetaNS, MetaFilename, xParaSubject, ParagraphSignatureRDFNamespace + sId + ParagraphSignatureDigestRDFName, signature);
+    SwRDFHelper::addStatement(xModel, MetaNS, MetaFilename, xParaSubject, ParagraphSignatureRDFNamespace + sId + ParagraphSignatureUsageRDFName, usage);
+    SwRDFHelper::addStatement(xModel, MetaNS, MetaFilename, xParaSubject, ParagraphSignatureRDFNamespace + sId + ParagraphSignatureDateRDFName, rBuffer.makeStringAndClear());
 
     return xField;
 }
@@ -359,6 +411,7 @@ uno::Reference<text::XTextField> lcl_InsertParagraphSignature(const uno::Referen
 /// Updates the signature field text if changed and returns true only iff updated.
 bool lcl_UpdateParagraphSignatureField(SwDoc* pDoc,
                                        const uno::Reference<frame::XModel>& xModel,
+                                       const uno::Reference<css::text::XTextContent>& xParagraph,
                                        const uno::Reference<css::text::XTextField>& xField,
                                        const OString& utf8Text)
 {
@@ -369,7 +422,7 @@ bool lcl_UpdateParagraphSignatureField(SwDoc* pDoc,
             pDoc->GetIDocumentUndoRedo().DoUndo(isUndoEnabled);
         });
 
-    const std::pair<bool, OUString> res = lcl_MakeParagraphSignatureFieldText(xModel, xField, utf8Text);
+    const std::pair<bool, OUString> res = lcl_MakeParagraphSignatureFieldText(xModel, xParagraph, xField, utf8Text);
     uno::Reference<css::text::XTextRange> xText(xField, uno::UNO_QUERY);
     const OUString curText = xText->getString();
     if (curText != res.second)
@@ -463,13 +516,15 @@ bool lcl_UpdateParagraphClassificationField(SwDoc* pDoc,
         });
 
     uno::Reference<text::XTextField> xField = lcl_InsertParagraphClassification(xModel, xTextNode);
+
     css::uno::Reference<css::rdf::XResource> xFieldSubject(xField, uno::UNO_QUERY);
     SwRDFHelper::addStatement(xModel, MetaNS, MetaFilename, xFieldSubject, sKey, sValue);
-    css::uno::Reference<css::rdf::XResource> xNodeSubject(xTextNode, uno::UNO_QUERY);
-    SwRDFHelper::addStatement(xModel, MetaNS, MetaFilename, xNodeSubject, sKey, sValue);
     SwRDFHelper::addStatement(xModel, MetaNS, MetaFilename, xFieldSubject, ParagraphClassificationNameRDFName, sKey);
     SwRDFHelper::addStatement(xModel, MetaNS, MetaFilename, xFieldSubject, ParagraphClassificationValueRDFName, sValue);
 
+    css::uno::Reference<css::rdf::XResource> xNodeSubject(xTextNode, uno::UNO_QUERY);
+    SwRDFHelper::addStatement(xModel, MetaNS, MetaFilename, xNodeSubject, sKey, sValue);
+
     uno::Reference<css::text::XTextRange> xText(xField, uno::UNO_QUERY);
     const OUString curDisplayText = xText->getString();
     if (curDisplayText != sDisplayText)
@@ -488,6 +543,20 @@ void lcl_ValidateParagraphSignatures(SwDoc* pDoc, const uno::Reference<text::XTe
         return;
 
     uno::Reference<frame::XModel> xModel = pDocShell->GetBaseModel();
+
+    // Check if the paragraph is signed.
+    try
+    {
+        const css::uno::Reference<css::rdf::XResource> xParaSubject(xParagraph, uno::UNO_QUERY);
+        const std::map<OUString, OUString> aStatements = SwRDFHelper::getStatements(xModel, MetaNS, xParaSubject);
+        if (aStatements.find(ParagraphSignatureLastIdRDFName) == aStatements.end())
+            return;
+    }
+    catch (const ::css::uno::Exception&)
+    {
+        return;
+    }
+
     uno::Reference<container::XEnumerationAccess> xTextPortionEnumerationAccess(xParagraph, uno::UNO_QUERY);
     if (!xTextPortionEnumerationAccess.is())
         return;
@@ -522,9 +591,9 @@ void lcl_ValidateParagraphSignatures(SwDoc* pDoc, const uno::Reference<text::XTe
 
         if (updateDontRemove)
         {
-            lcl_UpdateParagraphSignatureField(pDoc, xModel, xField, utf8Text);
+            lcl_UpdateParagraphSignatureField(pDoc, xModel, xParagraph, xField, utf8Text);
         }
-        else if (!lcl_MakeParagraphSignatureFieldText(xModel, xField, utf8Text).first)
+        else if (!lcl_MakeParagraphSignatureFieldText(xModel, xParagraph, xField, utf8Text).first)
         {
             pDoc->GetIDocumentUndoRedo().StartUndo(SwUndoId::PARA_SIGN_ADD, nullptr);
             SwUndoParagraphSigning* pUndo = new SwUndoParagraphSigning(pDoc, xField, xParagraph, false);
@@ -1112,23 +1181,11 @@ void SwEditShell::ApplyParagraphClassification(std::vector<svx::ClassificationRe
     }
 }
 
-std::vector<svx::ClassificationResult> SwEditShell::CollectParagraphClassification()
+std::vector<svx::ClassificationResult> lcl_CollectParagraphClassification(const uno::Reference<frame::XModel>& xModel, const uno::Reference<text::XTextContent>& xParagraph)
 {
     std::vector<svx::ClassificationResult> aResult;
 
-    SwDocShell* pDocShell = GetDoc()->GetDocShell();
-    if (!pDocShell)
-        return aResult;
-
-    SwTextNode* pNode = GetCursor()->Start()->nNode.GetNode().GetTextNode();
-    if (pNode == nullptr)
-        return aResult;
-
-    uno::Reference<text::XTextContent> xParent = SwXParagraph::CreateXParagraph(*pNode->GetDoc(), pNode);
-    uno::Reference<frame::XModel> xModel = pDocShell->GetBaseModel();
-    uno::Reference<lang::XMultiServiceFactory> xMultiServiceFactory(xModel, uno::UNO_QUERY);
-
-    uno::Reference<container::XEnumerationAccess> xTextPortionEnumerationAccess(xParent, uno::UNO_QUERY);
+    uno::Reference<container::XEnumerationAccess> xTextPortionEnumerationAccess(xParagraph, uno::UNO_QUERY);
     if (!xTextPortionEnumerationAccess.is())
         return aResult;
 
@@ -1178,6 +1235,23 @@ std::vector<svx::ClassificationResult> SwEditShell::CollectParagraphClassificati
     return aResult;
 }
 
+std::vector<svx::ClassificationResult> SwEditShell::CollectParagraphClassification()
+{
+    std::vector<svx::ClassificationResult> aResult;
+
+    SwDocShell* pDocShell = GetDoc()->GetDocShell();
+    if (!pDocShell)
+        return aResult;
+
+    SwTextNode* pNode = GetCursor()->Start()->nNode.GetNode().GetTextNode();
+    if (pNode == nullptr)
+        return aResult;
+
+    uno::Reference<text::XTextContent> xParent = SwXParagraph::CreateXParagraph(*pNode->GetDoc(), pNode);
+    uno::Reference<frame::XModel> xModel = pDocShell->GetBaseModel();
+    return lcl_CollectParagraphClassification(xModel, xParent);
+}
+
 sal_Int16 lcl_GetAngle(const drawing::HomogenMatrix3& rMatrix)
 {
     basegfx::B2DHomMatrix aTransformation;
@@ -1494,8 +1568,9 @@ SwUndoParagraphSigning::SwUndoParagraphSigning(SwDoc* pDoc,
     // Save the metadata and field content to undo/redo.
     uno::Reference<frame::XModel> xModel = m_pDoc->GetDocShell()->GetBaseModel();
     const css::uno::Reference<css::rdf::XResource> xSubject(m_xField, uno::UNO_QUERY);
+
     std::map<OUString, OUString> aStatements = SwRDFHelper::getStatements(xModel, MetaNS, xSubject);
-    const auto it = aStatements.find(ParagraphSignatureRDFName);
+    const auto it = aStatements.find(ParagraphSignatureIdRDFName);
     if (it != aStatements.end())
         m_signature = it->second;
 
@@ -1579,8 +1654,8 @@ void SwEditShell::SignParagraph()
         return;
 
     // 1. Get the text (without fields).
-    const uno::Reference<text::XTextContent> xParent = SwXParagraph::CreateXParagraph(*pNode->GetDoc(), pNode);
-    const OString utf8Text = lcl_getParagraphBodyText(xParent);
+    const uno::Reference<text::XTextContent> xParagraph = SwXParagraph::CreateXParagraph(*pNode->GetDoc(), pNode);
+    const OString utf8Text = lcl_getParagraphBodyText(xParagraph);
     if (utf8Text.isEmpty())
         return;
 
@@ -1624,11 +1699,11 @@ void SwEditShell::SignParagraph()
     GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::PARA_SIGN_ADD, nullptr);
 
     const uno::Reference<frame::XModel> xModel = pDocShell->GetBaseModel();
-    uno::Reference<css::text::XTextField> xField = lcl_InsertParagraphSignature(xModel, xParent, signature, aUsage);
+    uno::Reference<css::text::XTextField> xField = lcl_InsertParagraphSignature(xModel, xParagraph, signature, aUsage);
 
-    lcl_UpdateParagraphSignatureField(GetDoc(), xModel, xField, utf8Text);
+    lcl_UpdateParagraphSignatureField(GetDoc(), xModel, xParagraph, xField, utf8Text);
 
-    SwUndoParagraphSigning* pUndo = new SwUndoParagraphSigning(GetDoc(), xField, xParent, true);
+    SwUndoParagraphSigning* pUndo = new SwUndoParagraphSigning(GetDoc(), xField, xParagraph, true);
     GetDoc()->GetIDocumentUndoRedo().AppendUndo(pUndo);
 
     GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::PARA_SIGN_ADD, nullptr);
@@ -1698,7 +1773,7 @@ uno::Reference<text::XTextField> lcl_GetParagraphMetadataFieldAtIndex(const SwDo
                 const css::uno::Reference<css::rdf::XResource> xSubject(pMeta->MakeUnoObject(), uno::UNO_QUERY);
                 uno::Reference<frame::XModel> xModel = pDocSh->GetBaseModel();
                 const std::map<OUString, OUString> aStatements = SwRDFHelper::getStatements(xModel, MetaNS, xSubject);
-                if (aStatements.find(ParagraphSignatureRDFName) != aStatements.end() ||
+                if (aStatements.find(ParagraphSignatureIdRDFName) != aStatements.end() ||
                     aStatements.find(ParagraphClassificationNameRDFName) != aStatements.end())
                 {
                     xTextField = uno::Reference<text::XTextField>(xSubject, uno::UNO_QUERY);
diff --git a/sw/source/core/edit/edws.cxx b/sw/source/core/edit/edws.cxx
index 01dc694ab450..73f8c6aba112 100644
--- a/sw/source/core/edit/edws.cxx
+++ b/sw/source/core/edit/edws.cxx
@@ -53,10 +53,7 @@ SwEditShell::SwEditShell( SwDoc& rDoc, vcl::Window *pWindow, const SwViewOption
 
     // Update the paragraph signatures.
     // Since this ctor is called only on creating/loading the doc, we validate once only.
-    //FIXME: This is taking too long for the scheduler's taste.
-    // Need to do a quick check to see if a paragraph is signed or not,
-    // but for that need paragraph RDF, which is in a later patch.
-    // ValidateAllParagraphSignatures(true);
+    ValidateAllParagraphSignatures(true);
 }
 
 SwEditShell::~SwEditShell() // USED


More information about the Libreoffice-commits mailing list