RepeatProcessor.java

1
package pro.verron.officestamper.preset.processors.repeat;
2
3
import org.docx4j.TraversalUtil;
4
import org.docx4j.XmlUtils;
5
import org.docx4j.finders.ClassFinder;
6
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
7
import org.docx4j.wml.Comments;
8
import org.docx4j.wml.P;
9
import org.docx4j.wml.Tbl;
10
import org.docx4j.wml.Tr;
11
import org.springframework.lang.Nullable;
12
import pro.verron.officestamper.api.*;
13
import pro.verron.officestamper.core.CommentUtil;
14
import pro.verron.officestamper.core.StandardParagraph;
15
import pro.verron.officestamper.preset.CommentProcessorFactory;
16
17
import java.math.BigInteger;
18
import java.util.ArrayList;
19
import java.util.HashMap;
20
import java.util.List;
21
import java.util.Map;
22
import java.util.function.BiFunction;
23
24
import static java.util.Collections.emptyList;
25
import static java.util.Objects.requireNonNull;
26
27
/**
28
 * Repeats a table row for each element in a list.
29
 *
30
 * @author Joseph Verron
31
 * @author Tom Hombergs
32
 * @version ${version}
33
 * @since 1.0.0
34
 */
35
public class RepeatProcessor
36
        extends AbstractCommentProcessor
37
        implements CommentProcessorFactory.IRepeatProcessor {
38
39
    private final BiFunction<WordprocessingMLPackage, Tr, List<Tr>> nullSupplier;
40
    private Map<Tr, Iterable<Object>> tableRowsToRepeat = new HashMap<>();
41
    private Map<Tr, Comment> tableRowsCommentsToRemove = new HashMap<>();
42
43
    private RepeatProcessor(
44
            ParagraphPlaceholderReplacer placeholderReplacer,
45
            BiFunction<WordprocessingMLPackage, Tr, List<Tr>> nullSupplier1
46
    ) {
47
        super(placeholderReplacer);
48
        nullSupplier = nullSupplier1;
49
    }
50
51
    /**
52
     * Creates a new RepeatProcessor.
53
     *
54
     * @param pr The PlaceholderReplacer to use.
55
     *
56
     * @return A new RepeatProcessor.
57
     */
58
    public static CommentProcessor newInstance(ParagraphPlaceholderReplacer pr) {
59 1 1. newInstance : replaced return value with null for pro/verron/officestamper/preset/processors/repeat/RepeatProcessor::newInstance → KILLED
        return new RepeatProcessor(pr, (document, row) -> emptyList());
60
    }
61
62
    /** {@inheritDoc} */
63
    @Override public void commitChanges(DocxPart source) {
64 1 1. commitChanges : removed call to pro/verron/officestamper/preset/processors/repeat/RepeatProcessor::repeatRows → KILLED
        repeatRows(source);
65
    }
66
67
    private void repeatRows(DocxPart source) {
68
        for (Map.Entry<Tr, Iterable<Object>> entry : tableRowsToRepeat.entrySet()) {
69
            Tr row = entry.getKey();
70
            Iterable<Object> expressionContexts = entry.getValue();
71
72
            Tbl table = (Tbl) XmlUtils.unwrap(row.getParent());
73
            var content = table.getContent();
74
            int index = content.indexOf(row);
75
            content.remove(row);
76
77
            List<Tr> changes;
78 1 1. repeatRows : negated conditional → KILLED
            if (expressionContexts == null) {
79
                changes = nullSupplier.apply(source.document(), row);
80
            }
81
            else {
82
                changes = new ArrayList<>();
83
                for (Object expressionContext : expressionContexts) {
84
                    Tr rowClone = XmlUtils.deepCopy(row);
85
                    Comment commentWrapper = requireNonNull(tableRowsCommentsToRemove.get(row));
86
                    Comments.Comment comment = requireNonNull(commentWrapper.getComment());
87
                    BigInteger commentId = comment.getId();
88 1 1. repeatRows : removed call to pro/verron/officestamper/core/CommentUtil::deleteCommentFromElements → KILLED
                    CommentUtil.deleteCommentFromElements(rowClone.getContent(), commentId);
89
                    var classFinder = new ClassFinder(P.class);
90 1 1. repeatRows : removed call to org/docx4j/TraversalUtil::visit → KILLED
                    TraversalUtil.visit(rowClone, classFinder);
91
                    var objects = classFinder.results;
92
                    for (Object object : objects) {
93
                        P result = (P) object;
94
                        StandardParagraph paragraph = StandardParagraph.from(source, result);
95 1 1. repeatRows : removed call to pro/verron/officestamper/api/ParagraphPlaceholderReplacer::resolveExpressionsForParagraph → KILLED
                        placeholderReplacer.resolveExpressionsForParagraph(source, paragraph, expressionContext);
96
                    }
97
                    changes.add(rowClone);
98
                }
99
            }
100
            content.addAll(index, changes);
101
        }
102
    }
103
104
    /** {@inheritDoc} */
105
    @Override public void reset() {
106
        this.tableRowsToRepeat = new HashMap<>();
107
        this.tableRowsCommentsToRemove = new HashMap<>();
108
    }
109
110
    /** {@inheritDoc} */
111
    @Override public void repeatTableRow(@Nullable Iterable<Object> objects) {
112
        var tr = this.getParagraph()
113
                     .parent(Tr.class)
114
                     .orElseThrow(OfficeStamperException.throwing("This paragraph is not in a table row."));
115
        tableRowsToRepeat.put(tr, objects);
116
        tableRowsCommentsToRemove.put(tr, getCurrentCommentWrapper());
117
    }
118
119
}

Mutations

59

1.1
Location : newInstance
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#34]
replaced return value with null for pro/verron/officestamper/preset/processors/repeat/RepeatProcessor::newInstance → KILLED

64

1.1
Location : commitChanges
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#3]
removed call to pro/verron/officestamper/preset/processors/repeat/RepeatProcessor::repeatRows → KILLED

78

1.1
Location : repeatRows
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#3]
negated conditional → KILLED

88

1.1
Location : repeatRows
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#3]
removed call to pro/verron/officestamper/core/CommentUtil::deleteCommentFromElements → KILLED

90

1.1
Location : repeatRows
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#3]
removed call to org/docx4j/TraversalUtil::visit → KILLED

95

1.1
Location : repeatRows
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#3]
removed call to pro/verron/officestamper/api/ParagraphPlaceholderReplacer::resolveExpressionsForParagraph → KILLED

Active mutators

Tests examined


Report generated by PIT 1.17.1