Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(PW-1862) Added NarrativeFragment class for detailed line information in StructuredNarrative fragments #189

Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Prowide Core - CHANGELOG

#### 9.4.16 - SNAPSHOT
* (PW-1862) Added NarrativeFragment class for detailed line information in StructuredNarrative fragments
* Fixed SwiftMessage getPDE(): return empty value instead of null when codeword exists and has no value
* Added isPercentage() helper method to field 37K

#### 9.4.15 - March 2024
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1219,7 +1219,7 @@ public String getPDE() {
if (this.block5 != null) {
Optional<Tag> t = this.block5.getTag(SwiftBlock5Field.PDE);
if (t.isPresent()) {
return t.get().getValue();
return t.get().getValue() != null ? t.get().getValue() : "";
}
}
return null;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Copyright 2006-2023 Prowide
*
* Licensed 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.
*/
package com.prowidesoftware.swift.model.field;

/**
* Simple POJO for a fragment in a StructuredNarrative.
*
* <p>This model contains the narrative text, the line index (1 based) and the line length.
*
* <p>It is used by the {@link StructuredNarrative} class to get additional information of each line in the narrative.
*
* @since 9.4.16
*/
public class NarrativeFragment {
private String text;
private int lineIndex;
private int lineLength;

/**
* Creates a new fragment without line index or length.
*
* @param text narrative line text
*/
public NarrativeFragment(final String text) {
this(text, 0, 0);
}

/**
* Creates a new fragment.
*
* @param text narrative line text
* @param lineIndex complete narrative line index
* @param lineLength complete line length
*/
public NarrativeFragment(final String text, final int lineIndex, final int lineLength) {
this.text = text;
this.lineIndex = lineIndex;
this.lineLength = lineLength;
}

public String getText() {
return text;
}

public int getLineIndex() {
return lineIndex;
}

public int getLineLength() {
return lineLength;
}

public String toString() {

Check notice

Code scanning / CodeQL

Missing Override annotation Note

This method overrides
Object.toString
; it is advisable to add an Override annotation.
return text;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,11 @@ private static Narrative parseFormat(
StructuredNarrative structured = new StructuredNarrative();
boolean firstSupplementAdded = false;
List<String> valueLines = notEmptyLines(value);
int lineIndex = 0;
for (String valueLine : valueLines) {
lineIndex++;
final int lineLength = valueLine.length();

if (unstructuredSection) {
narrative.addUnstructuredFragment(valueLine);
continue;
Expand All @@ -123,9 +127,9 @@ private static Narrative parseFormat(
if (supportsSupplement) {
firstSupplementAdded = addNarrativeSupplement(firstSupplementAdded, valueLine, structured);
} else if (StringUtils.isNotEmpty(valueLine)) {
structured.addNarrativeFragment(valueLine);
structured.addNarrativeFragment(valueLine, lineIndex, lineLength);
}
} else structured.addNarrativeFragment(valueLine);
} else structured.addNarrativeFragment(valueLine, lineIndex, lineLength);
} else {
// new codeword
String codeword = StringUtils.substringBetween(valueLine, "/", "/");
Expand Down Expand Up @@ -172,21 +176,23 @@ private static Narrative parseFormat(
if (supportsCountry) {
if (!textWithoutBankCode.isEmpty()) {
structured.addNarrativeFragment(
textWithoutBankCode); // structured.addNarrativeFragment(null);
textWithoutBankCode,
lineIndex,
lineLength); // structured.addNarrativeFragment(null);
}
} else {
structured.addNarrativeFragment(textWithoutBankCode);
structured.addNarrativeFragment(textWithoutBankCode, lineIndex, lineLength);
}
}

narrative.add(structured);
} else if (!additionalNarrativesStartWithDoubleSlash && !structured.isEmpty()) {
structured.addNarrativeFragment(valueLine);
structured.addNarrativeFragment(valueLine, lineIndex, lineLength);
unstructuredSection = false;
}
}
} else if (!additionalNarrativesStartWithDoubleSlash && !structured.isEmpty()) {
structured.addNarrativeFragment(valueLine);
structured.addNarrativeFragment(valueLine, lineIndex, lineLength);
unstructuredSection = false;
}
if (unstructuredSection) narrative.addUnstructuredFragment(valueLine);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
*/
public class StructuredNarrative {
private final List<String> narrativeFragments = new ArrayList<>();
private final transient List<NarrativeFragment> narrativeFragmentsDetail = new ArrayList<>();
private final List<String> narrativeSupplementFragments = new ArrayList<>();
private String codeword;
private String currency;
Expand Down Expand Up @@ -136,10 +137,34 @@ public List<String> getNarrativeFragments() {
}

/**
* @see #getNarrativeFragments()
* Returns the list of text fragments in the narrative including the line index and line length,
* fragments are segments of the text that is wrapped in lines.
* If the narrative is a single string in a single line, the list will contain a single element.
* To get the narrative as a simple joined string use {@link #getNarrative(String)}
*
* @return the narrative fragments or an empty list if the narrative does not have any text
*/
public List<NarrativeFragment> getNarrativeFragmentsDetail() {
return narrativeFragmentsDetail;
}

/**
* @see #addNarrativeFragment(String, int, int)
*/
StructuredNarrative addNarrativeFragment(String narrativeFragment) {
return addNarrativeFragment(narrativeFragment, 0, 0);
}

/**
* Adds a fragment indicating the line index (1 based) and the line length.
*
* @param narrativeFragment text of the fragment
* @param lineIndex complete narrative line index
* @param lineLength complete line length
*/
StructuredNarrative addNarrativeFragment(String narrativeFragment, int lineIndex, int lineLength) {
this.narrativeFragments.add(narrativeFragment);
this.narrativeFragmentsDetail.add(new NarrativeFragment(narrativeFragment, lineIndex, lineLength));
return this;
}

Expand Down Expand Up @@ -183,7 +208,7 @@ public String getNarrative() {
public String getNarrative(String delimiter) {
if (!this.narrativeFragments.isEmpty()) {
String s = delimiter != null ? delimiter : "";
return String.join(s, this.narrativeFragments);
return String.join(s, this.getNarrativeFragments());
}
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,60 @@ public void testFormat2_12() {
n.getStructured("ACC").getNarrativeFragments().get(1));
}

/**
* valid input
*/
@Test
public void testFormat2_13() {
String v = "/BNF/RETN\n"
+ "//THE TRANSACTION IS REJECTED DUE T\n"
+ "//O INTERNAL POLICY\n"
+ "/MREF/XXX55444/220424\n"
+ "/TEXT/WE CONSIDER YR MT103 AS NULL\n"
+ "//AND VOID\n";
Narrative n = NarrativeResolver.parse(new Field72(v));

assertNull(n.getUnstructured());

assertEquals(3, n.getStructured().size()); // This count only the CodeWords

assertEquals(3, n.getStructured().get(0).getNarrativeFragmentsDetail().size());
assertEquals(1, n.getStructured().get(1).getNarrativeFragmentsDetail().size());
assertEquals(2, n.getStructured().get(2).getNarrativeFragmentsDetail().size());

assertEquals(
9, n.getStructured().get(0).getNarrativeFragmentsDetail().get(0).getLineLength());
assertEquals(
1, n.getStructured().get(0).getNarrativeFragmentsDetail().get(0).getLineIndex());
assertEquals(
35,
n.getStructured().get(0).getNarrativeFragmentsDetail().get(1).getLineLength());
assertEquals(
2, n.getStructured().get(0).getNarrativeFragmentsDetail().get(1).getLineIndex());
assertEquals(
19,
n.getStructured().get(0).getNarrativeFragmentsDetail().get(2).getLineLength());
assertEquals(
3, n.getStructured().get(0).getNarrativeFragmentsDetail().get(2).getLineIndex());

assertEquals(
21,
n.getStructured().get(1).getNarrativeFragmentsDetail().get(0).getLineLength());
assertEquals(
4, n.getStructured().get(1).getNarrativeFragmentsDetail().get(0).getLineIndex());

assertEquals(
34,
n.getStructured().get(2).getNarrativeFragmentsDetail().get(0).getLineLength());
assertEquals(
5, n.getStructured().get(2).getNarrativeFragmentsDetail().get(0).getLineIndex());
assertEquals(
10,
n.getStructured().get(2).getNarrativeFragmentsDetail().get(1).getLineLength());
assertEquals(
6, n.getStructured().get(2).getNarrativeFragmentsDetail().get(1).getLineIndex());
}

/*
* FORMAT 3
* Line 1: /8c/[3!a13d][additional information] (Code)(Currency)(Amount)(Narrative)
Expand Down
Loading