CommentHooker.java
package pro.verron.officestamper.api;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.utils.TraversalUtilVisitor;
import org.docx4j.wml.CommentRangeStart;
import org.docx4j.wml.ContentAccessor;
import pro.verron.officestamper.utils.wml.WmlUtils;
import java.util.ArrayList;
import java.util.List;
import static pro.verron.officestamper.utils.wml.WmlFactory.newCtAttr;
import static pro.verron.officestamper.utils.wml.WmlFactory.newSmartTag;
/// The [CommentHooker] class is responsible for preparing comment processors in a Word document. It implements the
/// [PreProcessor] interface and provides functionality to process comment range starts and wrap them with smart tags
/// for further processing by the OfficeStamper engine.
///
/// This pre-processor is typically used to identify and mark comment-based expressions, making them recognizable as
/// hooks for subsequent processing steps.
public final class CommentHooker
implements PreProcessor {
/// Default constructor for CommentHooker.
public CommentHooker() {
}
@Override
public void process(WordprocessingMLPackage document) {
var visitor = new CRSCollector();
WmlUtils.visitDocument(document, visitor);
// Replaces comment range starts with smart tags
for (var commentRangeStart : visitor.commentRangeStarts()) {
var parent = (ContentAccessor) commentRangeStart.getParent();
var siblings = parent.getContent();
var crsIndex = siblings.indexOf(commentRangeStart);
var tag = newSmartTag("officestamper", newCtAttr("type", "processor"), commentRangeStart);
siblings.set(crsIndex, tag);
}
}
/// A collector class that gathers [CommentRangeStart] elements during document traversal. This class extends
/// [TraversalUtilVisitor] to collect all [CommentRangeStart] objects encountered while traversing a DOCX document
/// structure.
public static class CRSCollector
extends TraversalUtilVisitor<CommentRangeStart> {
private final List<CommentRangeStart> results = new ArrayList<>();
/// Default constructor for CRSCollector.
public CRSCollector() {
}
@Override
public void apply(CommentRangeStart element) {
results.add(element);
}
/// Returns the list of collected CommentRangeStart elements.
///
/// @return a list of CommentRangeStart objects that have been collected during document traversal
public List<CommentRangeStart> commentRangeStarts() {
return results;
}
}
}