SectionUtil.java
package pro.verron.officestamper.core;
import org.docx4j.XmlUtils;
import org.docx4j.jaxb.Context;
import org.docx4j.wml.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.lang.Nullable;
import pro.verron.officestamper.api.OfficeStamperException;
import java.util.List;
import static java.util.Optional.ofNullable;
/**
* Utility class to handle section breaks in paragraphs.
*
* @author Joseph Verron
* @version ${version}
* @since 1.6.2
*/
public class SectionUtil {
private static final Logger log = LoggerFactory.getLogger(SectionUtil.class);
private SectionUtil() {
throw new OfficeStamperException("Utility class shouldn't be instantiated");
}
private static final ObjectFactory factory = Context.getWmlObjectFactory();
/**
* Creates a new section break object.
*
* @param firstObject a {@link Object} object
* @param parent a {@link ContentAccessor} object
* @return a new section break object.
*/
@Nullable
public static SectPr getPreviousSectionBreakIfPresent(Object firstObject, ContentAccessor parent) {
List<Object> parentContent = parent.getContent();
int pIndex = parentContent.indexOf(firstObject);
int i = pIndex - 1;
while (i >= 0) {
if (parentContent.get(i) instanceof P prevParagraph) {
// the first P preceding the object is the one potentially carrying a section break
PPr pPr = prevParagraph.getPPr();
if (pPr != null && pPr.getSectPr() != null) {
return pPr.getSectPr();
} else return null;
}
i--;
}
log.info("No previous section break found from : {}, first object index={}", parent, pIndex);
return null;
}
/**
* Creates a new section break object.
*
* @return a new section break object.
* @param p a {@link P} object
*/
@Nullable
public static SectPr getParagraphSectionBreak(P p) {
return p.getPPr() != null && p.getPPr().getSectPr() != null
? p.getPPr().getSectPr()
: null;
}
/**
* Creates a new section break object.
*
* @return a new section break object.
* @param objects a {@link List} object
*/
public static boolean isOddNumberOfSectionBreaks(List<Object> objects) {
long count = objects.stream()
.filter(P.class::isInstance)
.map(P.class::cast)
.filter(p -> p.getPPr() != null && p.getPPr().getSectPr() != null)
.count();
return count % 2 != 0;
}
/**
* Creates a new section break object.
*
* @param sectPr a {@link SectPr} object
* @param paragraph a {@link P} object
*/
public static void applySectionBreakToParagraph(SectPr sectPr, P paragraph) {
PPr nextPPr = ofNullable(paragraph.getPPr())
.orElseGet(factory::createPPr);
nextPPr.setSectPr(XmlUtils.deepCopy(sectPr));
paragraph.setPPr(nextPPr);
}
}