package org.businessmanager.service.docgen; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.docx4j.XmlUtils; import org.docx4j.jaxb.Context; import org.docx4j.wml.BooleanDefaultTrue; import org.docx4j.wml.Br; import org.docx4j.wml.R; import org.docx4j.wml.RPr; import org.docx4j.wml.Text; public class VariableSubstitution { private Text text; private Object parent; private Map<String, Object> replacements; private Integer line = null; private RPr style = null; public VariableSubstitution(Text text, Object parent, Map<String, Object> replacements) { this.text = text; this.parent = parent; this.replacements = replacements; if (parent instanceof R) { this.style = ((R) parent).getRPr(); } } public void execute() { String value = text.getValue(); value = replaceTokens(value); String[] lines = value.split("\n"); int index = 0; for (String line : lines) { if (index > 0) { if (parent instanceof R) { R run = (R) parent; List<Object> content = run.getContent(); int textIndex = content.indexOf(text.getParent()); text = XmlUtils.deepCopy(text); run.getContent().add(textIndex + index, text); Br createBr = Context.getWmlObjectFactory().createBr(); run.getContent().add(textIndex + index, createBr); } } text.setSpace("preserve"); text.setValue(line); index++; } if (style != null && parent instanceof R) { ((R) parent).setRPr(style); } } private String replaceTokens(String text) { Pattern pattern = Pattern.compile("\\$\\{(.+?)\\}"); Matcher matcher = pattern.matcher(text); StringBuffer buffer = new StringBuffer(); while (matcher.find()) { String[] variableInfo = matcher.group(1).split("\\["); Object replacement = replacements.get(variableInfo[0]); if (replacement != null) { if (variableInfo.length > 1) { handleVariableOptions(variableInfo[1].replace("]", "")); } String replacementString = replacement.toString(); if (line != null) { String[] split = replacementString.split("\n"); if (line > split.length || line < 1) { replacementString = ""; } else { replacementString = split[line - 1]; } } matcher.appendReplacement(buffer, ""); buffer.append(replacementString); } } matcher.appendTail(buffer); return buffer.toString(); } private void handleVariableOptions(String optionsString) { String[] options = optionsString.split(","); for (String option : options) { String[] optionHolder = option.split("="); String key = optionHolder[0]; String value = optionHolder[1]; setOption(key, value); } } private void setOption(String key, String value) { if ("line".equals(key)) { line = Integer.valueOf(value); } else if ("i".equals(key)) { BooleanDefaultTrue italic = toBooleanDefaultTrue(value); if(italic != null) { style.setI(italic); } } else if("b".equals(key)) { BooleanDefaultTrue bold = toBooleanDefaultTrue(value); if(bold != null) { style.setB(bold); } } } private BooleanDefaultTrue toBooleanDefaultTrue(String value) { BooleanDefaultTrue x = new BooleanDefaultTrue(); if ("0".equals(value)) { x.setVal(false); } else if ("1".equals(value)) { x.setVal(true); } else { return null; } return x; } }