TableResolver.java

1
package pro.verron.officestamper.preset.processors.table;
2
3
import jakarta.xml.bind.JAXBElement;
4
import org.docx4j.XmlUtils;
5
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
6
import org.docx4j.wml.ContentAccessor;
7
import org.docx4j.wml.Tbl;
8
import org.docx4j.wml.Tc;
9
import org.docx4j.wml.Tr;
10
import org.springframework.lang.Nullable;
11
import pro.verron.officestamper.api.*;
12
import pro.verron.officestamper.core.PlaceholderReplacer;
13
import pro.verron.officestamper.preset.CommentProcessorFactory;
14
import pro.verron.officestamper.preset.StampTable;
15
import pro.verron.officestamper.utils.WmlFactory;
16
17
import java.util.Collections;
18
import java.util.HashMap;
19
import java.util.List;
20
import java.util.Map;
21
import java.util.function.Function;
22
23
import static pro.verron.officestamper.api.OfficeStamperException.throwing;
24
25
/// TableResolver class.
26
///
27
/// @author Joseph Verron
28
/// @version ${version}
29
/// @since 1.6.2
30
public class TableResolver
31
        extends AbstractCommentProcessor
32
        implements CommentProcessorFactory.ITableResolver {
33
    private final Map<Tbl, StampTable> cols = new HashMap<>();
34
    private final Function<Tbl, List<Object>> nullSupplier;
35
36
    private TableResolver(
37
            ParagraphPlaceholderReplacer placeholderReplacer, Function<Tbl, List<Object>> nullSupplier
38
    ) {
39
        super(placeholderReplacer);
40
        this.nullSupplier = nullSupplier;
41
    }
42
43
    /// Generate a new [TableResolver] instance where value is replaced by an empty list when <code>null</code>
44
    ///
45
    /// @param pr a [PlaceholderReplacer] instance
46
    ///
47
    /// @return a new [TableResolver] instance
48
    public static CommentProcessor newInstance(ParagraphPlaceholderReplacer pr) {
49 1 1. newInstance : replaced return value with null for pro/verron/officestamper/preset/processors/table/TableResolver::newInstance → KILLED
        return new TableResolver(pr, table -> Collections.emptyList());
50
    }
51
52
    /// {@inheritDoc}
53
    @Override public void resolveTable(@Nullable StampTable givenTable) {
54
        var tbl = this.getParagraph()
55
                      .parent(Tbl.class)
56
                      .orElseThrow(throwing("Paragraph is not within a table!"));
57
        cols.put(tbl, givenTable);
58
    }
59
60
    /// {@inheritDoc}
61
    @Override public void commitChanges(DocxPart document) {
62
        for (Map.Entry<Tbl, StampTable> entry : cols.entrySet()) {
63
            Tbl wordTable = entry.getKey();
64
65
            StampTable stampedTable = entry.getValue();
66
67 1 1. commitChanges : negated conditional → KILLED
            if (stampedTable != null) {
68 1 1. commitChanges : removed call to pro/verron/officestamper/preset/processors/table/TableResolver::replaceTableInplace → KILLED
                replaceTableInplace(wordTable, stampedTable);
69
            }
70
            else {
71
                List<Object> tableParentContent = ((ContentAccessor) wordTable.getParent()).getContent();
72
                int tablePosition = tableParentContent.indexOf(wordTable);
73
                List<Object> toInsert = nullSupplier.apply(wordTable);
74
                tableParentContent.set(tablePosition, toInsert);
75
            }
76
        }
77
    }
78
79
    @Override public void commitChanges(WordprocessingMLPackage document) {
80
        throw new OfficeStamperException("Should not be called, since deprecation");
81
    }
82
83
    /// {@inheritDoc}
84
    @Override public void reset() {
85 1 1. reset : removed call to java/util/Map::clear → SURVIVED
        cols.clear();
86
    }
87
88
    private void replaceTableInplace(Tbl wordTable, StampTable stampedTable) {
89
        var headers = stampedTable.headers();
90
91
        var rows = wordTable.getContent();
92
        var headerRow = (Tr) rows.get(0);
93
        var firstDataRow = (Tr) rows.get(1);
94
95 1 1. replaceTableInplace : removed call to pro/verron/officestamper/preset/processors/table/TableResolver::growAndFillRow → KILLED
        growAndFillRow(headerRow, headers);
96
97 1 1. replaceTableInplace : negated conditional → KILLED
        if (stampedTable.isEmpty()) rows.remove(firstDataRow);
98
        else {
99 1 1. replaceTableInplace : removed call to pro/verron/officestamper/preset/processors/table/TableResolver::growAndFillRow → KILLED
            growAndFillRow(firstDataRow, stampedTable.getFirst());
100
            for (var rowContent : stampedTable.subList(1, stampedTable.size()))
101
                rows.add(copyRowFromTemplate(firstDataRow, rowContent));
102
        }
103
    }
104
105
    private void growAndFillRow(Tr row, List<String> values) {
106
        List<Object> cellRowContent = row.getContent();
107
108
        //Replace text in first cell
109
        JAXBElement<Tc> cell0 = (JAXBElement<Tc>) cellRowContent.getFirst();
110
        Tc cell0tc = cell0.getValue();
111 2 1. growAndFillRow : removed call to pro/verron/officestamper/preset/processors/table/TableResolver::setCellText → KILLED
2. growAndFillRow : negated conditional → KILLED
        setCellText(cell0tc, values.isEmpty() ? "" : values.getFirst());
112
113 2 1. growAndFillRow : changed conditional boundary → SURVIVED
2. growAndFillRow : negated conditional → KILLED
        if (values.size() > 1) {
114
            //Copy the first cell and replace content for each remaining value
115
            for (String cellContent : values.subList(1, values.size())) {
116
                JAXBElement<Tc> xmlCell = XmlUtils.deepCopy(cell0);
117 1 1. growAndFillRow : removed call to pro/verron/officestamper/preset/processors/table/TableResolver::setCellText → KILLED
                setCellText(xmlCell.getValue(), cellContent);
118
                cellRowContent.add(xmlCell);
119
            }
120
        }
121
    }
122
123
    private Tr copyRowFromTemplate(Tr firstDataRow, List<String> rowContent) {
124
        Tr newXmlRow = XmlUtils.deepCopy(firstDataRow);
125
        List<Object> xmlRow = newXmlRow.getContent();
126 2 1. copyRowFromTemplate : negated conditional → KILLED
2. copyRowFromTemplate : changed conditional boundary → KILLED
        for (int i = 0; i < rowContent.size(); i++) {
127
            String cellContent = rowContent.get(i);
128
            Tc xmlCell = ((JAXBElement<Tc>) xmlRow.get(i)).getValue();
129 1 1. copyRowFromTemplate : removed call to pro/verron/officestamper/preset/processors/table/TableResolver::setCellText → KILLED
            setCellText(xmlCell, cellContent);
130
        }
131 1 1. copyRowFromTemplate : replaced return value with null for pro/verron/officestamper/preset/processors/table/TableResolver::copyRowFromTemplate → KILLED
        return newXmlRow;
132
    }
133
134
    private void setCellText(Tc tableCell, String content) {
135
        var tableCellContent = tableCell.getContent();
136 1 1. setCellText : removed call to java/util/List::clear → KILLED
        tableCellContent.clear();
137
        tableCellContent.add(WmlFactory.newParagraph(content));
138
    }
139
}

Mutations

49

1.1
Location : newInstance
Killed by : pro.verron.officestamper.test.ResolutionTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.ResolutionTest]/[test-template:testStaticResolution(java.lang.String, boolean, boolean, boolean, java.lang.String, java.lang.String)]/[test-template-invocation:#6]
replaced return value with null for pro/verron/officestamper/preset/processors/table/TableResolver::newInstance → KILLED

67

1.1
Location : commitChanges
Killed by : pro.verron.officestamper.test.StampTableTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.StampTableTest]/[test-template:stampTableTest(pro.verron.officestamper.test.ContextFactory)]/[test-template-invocation:#2]
negated conditional → KILLED

68

1.1
Location : commitChanges
Killed by : pro.verron.officestamper.test.StampTableTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.StampTableTest]/[test-template:stampTableTest(pro.verron.officestamper.test.ContextFactory)]/[test-template-invocation:#2]
removed call to pro/verron/officestamper/preset/processors/table/TableResolver::replaceTableInplace → KILLED

85

1.1
Location : reset
Killed by : none
removed call to java/util/Map::clear → SURVIVED
Covering tests

95

1.1
Location : replaceTableInplace
Killed by : pro.verron.officestamper.test.StampTableTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.StampTableTest]/[test-template:stampTableTest(pro.verron.officestamper.test.ContextFactory)]/[test-template-invocation:#2]
removed call to pro/verron/officestamper/preset/processors/table/TableResolver::growAndFillRow → KILLED

97

1.1
Location : replaceTableInplace
Killed by : pro.verron.officestamper.test.StampTableTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.StampTableTest]/[test-template:stampTableTest(pro.verron.officestamper.test.ContextFactory)]/[test-template-invocation:#2]
negated conditional → KILLED

99

1.1
Location : replaceTableInplace
Killed by : pro.verron.officestamper.test.StampTableTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.StampTableTest]/[test-template:stampTableTest(pro.verron.officestamper.test.ContextFactory)]/[test-template-invocation:#2]
removed call to pro/verron/officestamper/preset/processors/table/TableResolver::growAndFillRow → KILLED

111

1.1
Location : growAndFillRow
Killed by : pro.verron.officestamper.test.StampTableTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.StampTableTest]/[test-template:stampTableTest(pro.verron.officestamper.test.ContextFactory)]/[test-template-invocation:#2]
removed call to pro/verron/officestamper/preset/processors/table/TableResolver::setCellText → KILLED

2.2
Location : growAndFillRow
Killed by : pro.verron.officestamper.test.StampTableTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.StampTableTest]/[test-template:stampTableTest(pro.verron.officestamper.test.ContextFactory)]/[test-template-invocation:#2]
negated conditional → KILLED

113

1.1
Location : growAndFillRow
Killed by : pro.verron.officestamper.test.StampTableTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.StampTableTest]/[test-template:stampTableTest(pro.verron.officestamper.test.ContextFactory)]/[test-template-invocation:#2]
negated conditional → KILLED

2.2
Location : growAndFillRow
Killed by : none
changed conditional boundary → SURVIVED
Covering tests

117

1.1
Location : growAndFillRow
Killed by : pro.verron.officestamper.test.StampTableTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.StampTableTest]/[test-template:stampTableTest(pro.verron.officestamper.test.ContextFactory)]/[test-template-invocation:#2]
removed call to pro/verron/officestamper/preset/processors/table/TableResolver::setCellText → KILLED

126

1.1
Location : copyRowFromTemplate
Killed by : pro.verron.officestamper.test.StampTableTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.StampTableTest]/[test-template:stampTableTest(pro.verron.officestamper.test.ContextFactory)]/[test-template-invocation:#2]
negated conditional → KILLED

2.2
Location : copyRowFromTemplate
Killed by : pro.verron.officestamper.test.StampTableTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.StampTableTest]/[test-template:stampTableTest(pro.verron.officestamper.test.ContextFactory)]/[test-template-invocation:#2]
changed conditional boundary → KILLED

129

1.1
Location : copyRowFromTemplate
Killed by : pro.verron.officestamper.test.StampTableTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.StampTableTest]/[test-template:stampTableTest(pro.verron.officestamper.test.ContextFactory)]/[test-template-invocation:#2]
removed call to pro/verron/officestamper/preset/processors/table/TableResolver::setCellText → KILLED

131

1.1
Location : copyRowFromTemplate
Killed by : pro.verron.officestamper.test.StampTableTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.StampTableTest]/[test-template:stampTableTest(pro.verron.officestamper.test.ContextFactory)]/[test-template-invocation:#2]
replaced return value with null for pro/verron/officestamper/preset/processors/table/TableResolver::copyRowFromTemplate → KILLED

136

1.1
Location : setCellText
Killed by : pro.verron.officestamper.test.StampTableTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.StampTableTest]/[test-template:stampTableTest(pro.verron.officestamper.test.ContextFactory)]/[test-template-invocation:#2]
removed call to java/util/List::clear → KILLED

Active mutators

Tests examined


Report generated by PIT 1.21.0