diff --git a/src/main/java/org/scriptlet4docx/docx/DocxTemplaterBulk.java b/src/main/java/org/scriptlet4docx/docx/DocxTemplaterBulk.java new file mode 100644 index 0000000..3aaf553 --- /dev/null +++ b/src/main/java/org/scriptlet4docx/docx/DocxTemplaterBulk.java @@ -0,0 +1,199 @@ +package org.scriptlet4docx.docx; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.logging.Level; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.commons.lang3.StringUtils; +import org.codehaus.groovy.control.CompilationFailedException; +import org.scriptlet4docx.docx.Placeholder.PlaceholderType; +import org.scriptlet4docx.docx.Placeholder.ScriptWraps; +import org.scriptlet4docx.util.string.StringUtil; +import org.scriptlet4docx.util.xml.XMLUtils; + +/** + * + * Extend DocxTemplate to give you the ability to process .docx with many more scripts. + * Eliminating the problem of "Method code too large!" Do not confuse with + * {@link groovy.text.StreamingTemplateEngine} + * + *

Use:

Each N number of scriptlets in your .docx insert a mark "<!=BREAK!>" + * This will tell the engine that it can execute the scripts up to that point. + * Then, it will continue processing until the next <!=BREAK!> + * + * @author ortizman@gmail.com + * @author manuel.ortiz@fluxit.com.ar + * + */ +public class DocxTemplaterBulk extends DocxTemplater { + + final static String UTIL_FUNC_HOLDER = "__docxTemplaterInstance"; + final static String NULL_REPLACER_REF = UTIL_FUNC_HOLDER + ".replaceIfNull"; + private static String NEW_LINE_PLACEHOLDER = "26f679ad-e7fd-4d42-9e05-946f393c277d"; + + @SuppressWarnings("unused") + private String replaceIfNull(Object o) { + return o == null ? nullReplacement : String.valueOf(o); + } + + /** + * + * @param nullReplacement + * When scriptlet output is null this value take its place.
+ * Useful when you want nothing to be printed, or custom value + * like "UNKNOWN". + */ + public void setNullReplacement(String nullReplacement) { + this.nullReplacement = nullReplacement; + } + + private String nullReplacement = ""; + + private static Pattern scriptPattern = Pattern.compile( + "((<%=?(.*?)%>)|\\$\\{(.*?)\\}|(<\\!=?(.*?)\\!>))", Pattern.DOTALL | Pattern.MULTILINE); + + public DocxTemplaterBulk(File pathToDocx) { + super(pathToDocx); + } + + public DocxTemplaterBulk(InputStream inputStream, String templateKey) { + super(inputStream, templateKey); + } + + @Override + protected String processCleanedTemplate(String template, Map params) + throws CompilationFailedException, ClassNotFoundException, IOException { + + params = processParams(params); + + String replacement = UUID.randomUUID().toString(); + + List scripts = new ArrayList(); + + Matcher m = scriptPattern.matcher(template); + + while (m.find()) { + String scriptText = m.group(0); + Placeholder ph = new Placeholder(UUID.randomUUID().toString(), scriptText, PlaceholderType.SCRIPT); + + if (ph.scriptWrap == ScriptWraps.DOLLAR_PRINT) { + ph.setScriptTextNoWrap(m.group(4)); + } else if (ph.scriptWrap == ScriptWraps.SCRIPLET || ph.scriptWrap == ScriptWraps.SCRIPLET_PRINT) { + ph.setScriptTextNoWrap(m.group(3)); + } else if (ph.scriptWrap == ScriptWraps.BREAK) { + ph.setScriptTextNoWrap(""); + } + + scripts.add(ph); + } + + String replacedScriptsTemplate = m.replaceAll(replacement); + + List pieces = Arrays + .asList(StringUtils.splitByWholeSeparatorPreserveAllTokens(replacedScriptsTemplate, replacement)); + + if (pieces.size() != scripts.size() + 1) { + throw new IllegalStateException( + String.format( + "Programming bug was detected. Text pieces size does not match scripts size (%s, %s)." + + " Please report this as a bug to the library author.", + pieces.size(), scripts.size())); + } + + List tplSkeleton = new ArrayList(); + + int i = 0; + for (String piece : pieces) { + tplSkeleton.add(new Placeholder(UUID.randomUUID().toString(), piece, PlaceholderType.TEXT)); + + if (i < scripts.size()) { + tplSkeleton.add(scripts.get(i)); + } + i++; + } + + StringBuilder builder = new StringBuilder(); + StringBuilder partialResult = new StringBuilder(); + + for (Placeholder placeholder : tplSkeleton) { + if (PlaceholderType.SCRIPT == placeholder.type) { + + String cleanScriptNoWrap = XMLUtils.getNoTagsTrimText(placeholder.getScriptTextNoWrap()); + cleanScriptNoWrap = StringUtils.replaceEach(cleanScriptNoWrap, + new String[] { "&", ">", "<", """, "«", "»", "“", "”", "‘", "’" }, + new String[] { "&", ">", "<", "\"", "\"", "\"", "\"", "\"", "\"", "\"" }); + + cleanScriptNoWrap = cleanScriptNoWrap.trim(); + // Replacing missing replacements, at least on top level + if (cleanScriptNoWrap.matches("\\w+")) { + if (!params.containsKey(cleanScriptNoWrap)) { + params.put(cleanScriptNoWrap, null); + } + } + + if (placeholder.scriptWrap == ScriptWraps.DOLLAR_PRINT + || placeholder.scriptWrap == ScriptWraps.SCRIPLET_PRINT + || placeholder.scriptWrap == ScriptWraps.BREAK) { + cleanScriptNoWrap = NULL_REPLACER_REF + "(" + cleanScriptNoWrap + ")"; + } + String script = placeholder.constructWithCurrentScriptWrap(cleanScriptNoWrap); + builder.append(script); + + if (placeholder.scriptWrap == ScriptWraps.BREAK) { + partialResult.append(processPartialTemplate(builder.toString(), params)); + builder.setLength(0); // reset builder + } + + } else { + builder.append(placeholder.ph); + } + } + + String scriptAppliedStr; + + if (builder != null && builder.length() > 0) { + partialResult.append(processPartialTemplate(builder.toString(), params)); + } + scriptAppliedStr = partialResult.toString(); + + scriptAppliedStr = StringUtil.escapeSimpleSet(scriptAppliedStr); + + scriptAppliedStr = StringUtils.replace(scriptAppliedStr, NEW_LINE_PLACEHOLDER, ""); + + String result = scriptAppliedStr; + for (Placeholder placeholder : tplSkeleton) { + if (PlaceholderType.TEXT == placeholder.type) { + result = StringUtils.replace(result, placeholder.ph, placeholder.text); + } + } + + return result; + } + + private String processPartialTemplate(String template, Map params) { + final String methodName = "processPartialTemplate"; + + params.put(UTIL_FUNC_HOLDER, this); + + if (logger.isLoggable(Level.FINEST)) { + logger.logp(Level.FINEST, CLASS_NAME, methodName, String.format("\ntemplate = \n%s\n", template)); + } + + try { + return String.valueOf(getTemplateEngine().createTemplate(template).make(params)); + } catch (Throwable e) { + logger.logp(Level.SEVERE, CLASS_NAME, methodName, String.format("Cannot process template: [%s].", template), + e); + throw new RuntimeException(e); + } + } + +} diff --git a/src/main/java/org/scriptlet4docx/docx/Placeholder.java b/src/main/java/org/scriptlet4docx/docx/Placeholder.java index ea9ee65..c748f63 100644 --- a/src/main/java/org/scriptlet4docx/docx/Placeholder.java +++ b/src/main/java/org/scriptlet4docx/docx/Placeholder.java @@ -20,7 +20,7 @@ public String constructWithCurrentScriptWrap(String scriptTextNoWrap) { format = "${%s}"; } else if (scriptWrap == ScriptWraps.SCRIPLET) { format = "<%%%s%%>"; - } else if (scriptWrap == ScriptWraps.SCRIPLET_PRINT) { + } else if (scriptWrap == ScriptWraps.SCRIPLET_PRINT || scriptWrap == ScriptWraps.BREAK) { format = "<%%=%s%%>"; } else { throw new RuntimeException(String.format("ScriptWrap is undefined: %s", scriptWrap)); @@ -47,6 +47,8 @@ private void detectScriptWrap() { scriptWrap = ScriptWraps.SCRIPLET_PRINT; } else if (noSpaces.startsWith("<%")) { scriptWrap = ScriptWraps.SCRIPLET; + } else if(noSpaces.startsWith("<!")) { + scriptWrap = ScriptWraps.BREAK; } else { throw new IllegalArgumentException(String.format("Script wrap cannot be detected: [%s]", text)); } @@ -55,7 +57,8 @@ private void detectScriptWrap() { static enum ScriptWraps { DOLLAR_PRINT, // ${} SCRIPLET, // <%%> - SCRIPLET_PRINT // <%=%> + SCRIPLET_PRINT, // <%=%> + BREAK // } static enum PlaceholderType { diff --git a/src/test/java/org/scriptlet4docx/docx/DocxTemplaterBulkTest.java b/src/test/java/org/scriptlet4docx/docx/DocxTemplaterBulkTest.java new file mode 100644 index 0000000..826ba84 --- /dev/null +++ b/src/test/java/org/scriptlet4docx/docx/DocxTemplaterBulkTest.java @@ -0,0 +1,665 @@ +package org.scriptlet4docx.docx; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.lang3.StringUtils; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; +import org.scriptlet4docx.docx.TemplateContent.ContentItem; +import org.scriptlet4docx.util.test.TestUtils; + +import mockit.Expectations; +import mockit.Mocked; +import mockit.NonStrictExpectations; +import mockit.Verifications; + +public class DocxTemplaterBulkTest extends Assert { + + static HashMap params; + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + params = new HashMap(); + HashMap contract = new HashMap(); + contract.put("number", "123#445"); + params.put("value", 1); + params.put("contract", contract); + params.put("escapeTest", "This should be escaped: &, <, >."); + + List personList = new ArrayList(); + personList.add("vasya"); + personList.add("petya"); + + params.put("personList", personList); + params.put("menList", personList); + + List> employeeList = new ArrayList>(); + HashMap p1 = new HashMap(); + p1.put("name", "Tom"); + p1.put("address", "Moscow"); + HashMap p2 = new HashMap(); + p2.put("name", "John"); + p2.put("address", "New York"); + employeeList.add(p1); + employeeList.add(p2); + + params.put("employeeList", employeeList); + HashMap p3 = new HashMap(); + p3.put("nomeCliente", "Bob Smith"); + + params.put("crm", p3); + + } + + @Test + public void testProcessScriptedTemplateBulk() throws Exception { + String template = TestUtils.readResource("/docx/DocxTemplaterTest-13.xml"); + + DocxTemplaterBulk templater = new DocxTemplaterBulk(none); + template = templater.cleanupTemplate(template); + String result = templater.processCleanedTemplate(template, params); + + assertTrue(result != null); + assertTrue(result.contains("123#445")); + assertTrue(StringUtils.countMatches(result, "123#445") == 4); + assertFalse(result.contains("BREAK")); + } + + @Test + public void testProcessScriptedTemplate() throws Exception { + String template = TestUtils.readResource("/docx/DocxTemplaterTest-1.xml"); + + DocxTemplaterBulk templater = new DocxTemplaterBulk(none); + template = templater.cleanupTemplate(template); + String result = templater.processCleanedTemplate(template, params); + + assertTrue(result != null); + assertTrue(result.contains("123#445")); + assertTrue(StringUtils.countMatches(result, "123#445") == 4); + } + + + @Test + public void testProcessScriptedTemplate_brokenType1() throws Exception { + String template = TestUtils.readResource("/docx/DocxTemplaterTest-2.xml"); + + DocxTemplaterBulk templater = new DocxTemplaterBulk(none); + template = templater.cleanupTemplate(template); + String result = templater.processCleanedTemplate(template, params); + + assertTrue(result != null); + assertTrue(result.contains("123#445")); + assertTrue(StringUtils.countMatches(result, "123#445") == 1); + } + + @Test + public void testPreProcessTableScripting_multiTr() throws Exception { + String template = TestUtils.readResource("/docx/DocxTemplaterTest-5.xml"); + + String result = TableScriptingProcessor.process(template); + + assertTrue(result != null); + assertTrue(!result.contains("$[")); + + assertTrue(result.contains("<% def iterStatus=0; for ( wawawa in tour.wawawa ) { iterStatus++; %>")); + assertTrue(result.contains("${wawawa.myway}")); + + assertTrue(result.contains("<% iterStatus=0; for ( mamama in tour1.mamama ) { iterStatus++; %>")); + assertTrue(result.contains("${mamama.myway}")); + + } + + @Test + public void testProcessScriptedTemplate_tableScripting() throws Exception { + String template = TestUtils.readResource("/docx/DocxTemplaterTest-6.xml"); + DocxTemplaterBulk templater = new DocxTemplaterBulk(none); + template = templater.cleanupTemplate(template); + String result = templater.processCleanedTemplate(template, params); + + assertTrue(result != null); + assertTrue(!result.contains("$[")); + + assertTrue(result.contains(">vasya<")); + assertTrue(result.contains(">petya<")); + + } + + @Test + public void testProcessScriptedTemplate_brokenType2() throws Exception { + String template = TestUtils.readResource("/docx/DocxTemplaterTest-3.xml"); + DocxTemplaterBulk templater = new DocxTemplaterBulk(none); + template = templater.cleanupTemplate(template); + String result = templater.processCleanedTemplate(template, params); + + assertTrue(result != null); + assertTrue(result.contains("123#445")); + assertTrue(StringUtils.countMatches(result, "123#445") == 1); + } + + @Test + public void testProcessScriptedTemplate_brokenType2_noProcess() throws Exception { + String template = TestUtils.readResource("/docx/DocxTemplaterTest-7.xml"); + DocxTemplaterBulk templater = new DocxTemplaterBulk(none); + String result = templater.processCleanedTemplate(template, params); + + assertTrue(result != null); + assertTrue(template.equals(result)); + } + + @Test + public void testProcessScriptedTemplate_tableScripting_iterStatus() throws Exception { + String template = TestUtils.readResource("/docx/DocxTemplaterTest-8.xml"); + DocxTemplaterBulk templater = new DocxTemplaterBulk(none); + template = templater.cleanupTemplate(template); + String result = templater.processCleanedTemplate(template, params); + + assertTrue(result != null); + assertTrue(!result.contains("$[")); + + assertTrue(result.contains(">vasya<")); + assertTrue(result.contains(">petya<")); + + assertTrue(!result.contains(">${iterStatus}<")); + + assertTrue(result.contains(">1<")); + assertTrue(result.contains(">2<")); + + } + + @Test + public void testProcessScriptedTemplate_tableScripting_iterStatus_multiTable() throws Exception { + String template = TestUtils.readResource("/docx/DocxTemplaterTest-4.xml"); + DocxTemplaterBulk templater = new DocxTemplaterBulk(none); + template = templater.cleanupTemplate(template); + String result = templater.processCleanedTemplate(template, params); + + assertTrue(result != null); + assertTrue(!result.contains("$[")); + + assertTrue(result.contains(">vasya<")); + assertTrue(result.contains(">petya<")); + + assertTrue(!result.contains(">${iterStatus}<")); + + assertTrue(result.contains(">1<")); + assertTrue(result.contains(">2<")); + + assertTrue(StringUtils.countMatches(result, ">1<") == 2); + assertTrue(StringUtils.countMatches(result, ">2<") == 2); + + } + + @Test + public void testProcessScriptedTemplate_logicScriptlets() throws Exception { + String template = TestUtils.readResource("/docx/DocxTemplaterTest-9.xml"); + + HashMap params1 = new HashMap(); + params1.put("value", 1); + DocxTemplaterBulk templater = new DocxTemplaterBulk(none); + template = templater.cleanupTemplate(template); + String result = templater.processCleanedTemplate(template, params1); + + assertTrue(result != null); + assertTrue(!result.contains("else")); + assertTrue(!result.contains("if")); + + assertTrue(result.contains("mom and dad")); + assertTrue(result.contains("like kitties")); + + params1 = new HashMap(); + params1.put("value", 0); + + template = templater.cleanupTemplate(template); + result = templater.processCleanedTemplate(template, params1); + + assertTrue(result != null); + assertTrue(!result.contains("else")); + assertTrue(!result.contains("if")); + + assertTrue(result.contains("mom and dad")); + assertTrue(result.contains("like dogs")); + } + + @Test + public void testProcessScriptedTemplate_logicScriptlets_gt() throws Exception { + String template = TestUtils.readResource("/docx/DocxTemplaterTest-15.xml"); + + HashMap params1 = new HashMap(); + params1.put("value", 1); + DocxTemplaterBulk templater = new DocxTemplaterBulk(none); + template = templater.cleanupTemplate(template); + String result = templater.processCleanedTemplate(template, params1); + + assertTrue(result != null); + assertTrue(!result.contains("else")); + assertTrue(!result.contains("if")); + + assertTrue(result.contains("mom and dad")); + assertTrue(result.contains("like dogs")); + + params1 = new HashMap(); + params1.put("value", 2); + + template = templater.cleanupTemplate(template); + result = templater.processCleanedTemplate(template, params1); + + assertTrue(result != null); + assertTrue(!result.contains("else")); + assertTrue(!result.contains("if")); + + assertTrue(result.contains("mom and dad")); + assertTrue(result.contains("like kitties")); + } + + @Test + public void testProcessScriptedTemplate_logicScriptlets_lt() throws Exception { + String template = TestUtils.readResource("/docx/DocxTemplaterTest-16.xml"); + + HashMap params1 = new HashMap(); + params1.put("value", 1); + DocxTemplaterBulk templater = new DocxTemplaterBulk(none); + template = templater.cleanupTemplate(template); + String result = templater.processCleanedTemplate(template, params1); + + assertTrue(result != null); + assertTrue(!result.contains("else")); + assertTrue(!result.contains("if")); + + assertTrue(result.contains("mom and dad")); + assertTrue(result.contains("like kitties")); + + params1 = new HashMap(); + params1.put("value", 2); + + template = templater.cleanupTemplate(template); + result = templater.processCleanedTemplate(template, params1); + + assertTrue(result != null); + assertTrue(!result.contains("else")); + assertTrue(!result.contains("if")); + + assertTrue(result.contains("mom and dad")); + assertTrue(result.contains("like dogs")); + } + + @Test + public void testProcessScriptedTemplate_logicScriptlets_quote() throws Exception { + String template = TestUtils.readResource("/docx/DocxTemplaterTest-17.xml"); + + HashMap params1 = new HashMap(); + params1.put("value", "kitties"); + DocxTemplaterBulk templater = new DocxTemplaterBulk(none); + template = templater.cleanupTemplate(template); + String result = templater.processCleanedTemplate(template, params1); + + assertTrue(result != null); + assertTrue(!result.contains("else")); + assertTrue(!result.contains("if")); + + assertTrue(result.contains("mom and dad")); + assertTrue(result.contains("like kitties")); + + params1 = new HashMap(); + params1.put("value", "dogs"); + + template = templater.cleanupTemplate(template); + result = templater.processCleanedTemplate(template, params1); + + assertTrue(result != null); + assertTrue(!result.contains("else")); + assertTrue(!result.contains("if")); + + assertTrue(result.contains("mom and dad")); + assertTrue(result.contains("like dogs")); + } + + @Test + public void testProcessScriptedTemplate_logicScriptlets_quoteCurly() throws Exception { + String template = TestUtils.readResource("/docx/DocxTemplaterTest-18.xml"); + + HashMap params1 = new HashMap(); + params1.put("value", "kitties"); + DocxTemplaterBulk templater = new DocxTemplaterBulk(none); + template = templater.cleanupTemplate(template); + String result = templater.processCleanedTemplate(template, params1); + + assertTrue(result != null); + assertTrue(!result.contains("else")); + assertTrue(!result.contains("if")); + + assertTrue(result.contains("mom and dad")); + assertTrue(result.contains("like kitties")); + + params1 = new HashMap(); + params1.put("value", "dogs"); + + template = templater.cleanupTemplate(template); + result = templater.processCleanedTemplate(template, params1); + + assertTrue(result != null); + assertTrue(!result.contains("else")); + assertTrue(!result.contains("if")); + + assertTrue(result.contains("mom and dad")); + assertTrue(result.contains("like dogs")); + } + + @Test + public void testProcessScriptedTemplate_spacePreserve() throws Exception { + String template = TestUtils.readResource("/docx/DocxTemplaterTest-10.xml"); + DocxTemplaterBulk templater = new DocxTemplaterBulk(none); + template = templater.cleanupTemplate(template); + String result = templater.processCleanedTemplate(template, params); + + assertTrue(result != null); + assertTrue(!result.contains("print")); + + assertTrue(result.contains("like dogs")); + } + + @Test + public void testProcess_file() throws Exception { + File inFile = new File("src/test/resources/docx/DocxTemplaterTest-1.docx"); + File resFile = new File("target/test-files/DocxTemplaterTest-1-file-result-1.docx"); + resFile.delete(); + + DocxTemplaterBulk docxTemplater = new DocxTemplaterBulk(inFile); + + docxTemplater.process(resFile, params); + + assertTrue(resFile.exists()); + assertTrue(resFile.length() > 0); + } + + @Test + public void testProcess_file2() throws Exception { + File inFile = new File("src/test/resources/docx/DocxTemplaterTest-13.docx"); + File resFile = new File("target/test-files/DocxTemplaterTest-1-file-result-2.docx"); + resFile.delete(); + + DocxTemplaterBulk docxTemplater = new DocxTemplaterBulk(inFile); + + docxTemplater.process(resFile, params); + + assertTrue(resFile.exists()); + assertTrue(resFile.length() > 0); + } + + @Test + public void testProcess_file3() throws Exception { + File inFile = new File("src/test/resources/docx/DocxTemplaterTest-14.docx"); + File resFile = new File("target/test-files/DocxTemplaterTest-1-file-result-3.docx"); + resFile.delete(); + + DocxTemplaterBulk docxTemplater = new DocxTemplaterBulk(inFile); + + docxTemplater.process(resFile, params); + + assertTrue(resFile.exists()); + assertTrue(resFile.length() > 0); + } + + @Test + public void testProcess_file4() throws Exception { + File inFile = new File("src/test/resources/docx/DocxTemplaterTest-large.docx"); + File resFile = new File("target/test-files/DocxTemplaterTest-1-file-result-large.docx"); + resFile.delete(); + + DocxTemplaterBulk docxTemplater = new DocxTemplaterBulk(inFile); + + docxTemplater.process(resFile, params); + + assertTrue(resFile.exists()); + assertTrue(resFile.length() > 0); + } + + @Test + public void testProcess_withInputStreamAsOutput() throws Exception { + File inFile = new File("src/test/resources/docx/DocxTemplaterTest-1.docx"); + File resFile = new File("target/test-files/DocxTemplaterTest-stream-2-result.docx"); + resFile.delete(); + + DocxTemplaterBulk templater = new DocxTemplaterBulk(inFile); + + InputStream resStream = templater.processAndReturnInputStream(params); + + FileUtils.copyInputStreamToFile(resStream, resFile); + + assertTrue(resFile.exists()); + assertTrue(resFile.length() > 0); + + assertTrue(new File(TemplateFileManager.getInstance().getTemplatesDir(), + TemplateFileManager.DOC_READY_STREAM_FOLDER_NAME).listFiles().length == 0); + } + + @Test + public void testProcess_withOutputStream() throws Exception { + File inFile = new File("src/test/resources/docx/DocxTemplaterTest-1.docx"); + File resFile = new File("target/test-files/DocxTemplaterTest-stream-3-result.docx"); + resFile.delete(); + + DocxTemplaterBulk docxTemplater = new DocxTemplaterBulk(inFile); + + docxTemplater.process(new FileOutputStream(resFile), params); + + assertTrue(resFile.exists()); + assertTrue(resFile.length() > 0); + } + + @Test + public void testProcess_fileMultiRun(final @Mocked TemplateFileManager mgr) throws Exception { + File inFile = new File("1"); + final File resFile = new File("2"); + + final DocxTemplaterBulk docxTemplater1 = new DocxTemplaterBulk(inFile); + + new NonStrictExpectations() { + { + TemplateFileManager.getInstance(); + result = mgr; + } + }; + + final TemplateContent c1 = new TemplateContent(Arrays.asList(new ContentItem("", ""))); + final TemplateContent c2 = new TemplateContent(Arrays.asList(new ContentItem("", ""))); + final TemplateContent c3 = new TemplateContent(Arrays.asList(new ContentItem("", ""))); + + new Expectations(docxTemplater1) { + { + docxTemplater1.setupTemplate(); + result = "t1"; + + mgr.getTemplateContent("t1"); + result = c1; + + mgr.isPreProcessedTemplateExists("t1"); + result = false; + + docxTemplater1.cleanupTemplate(c1); + result = c2; + + mgr.savePreProcessed("t1", c2); + + docxTemplater1.processCleanedTemplate(c2, params); + result = c3; + + docxTemplater1.processResult(resFile, "t1", c3); + } + }; + + docxTemplater1.process(resFile, params); + } + + @Test + public void testProcess_stream() throws Exception { + File inFile = new File("src/test/resources/docx/DocxTemplaterTest-1.docx"); + File resFile = new File("target/test-files/DocxTemplaterTest-1-stream-result.docx"); + resFile.delete(); + + DocxTemplaterBulk docxTemplater = new DocxTemplaterBulk(new FileInputStream(inFile), "k1"); + + docxTemplater.process(resFile, params); + + assertTrue(resFile.exists()); + assertTrue(resFile.length() > 0); + } + + @Test + public void testProcess_header() throws Exception { + File inFile = new File("src/test/resources/docx/DocxTemplaterTest-2-header.docx"); + File resFile = new File("target/test-files/DocxTemplaterTest-2-header.docx"); + resFile.delete(); + + DocxTemplaterBulk docxTemplater = new DocxTemplaterBulk(new FileInputStream(inFile), "k1"); + + docxTemplater.process(resFile, params); + + assertTrue(resFile.exists()); + assertTrue(resFile.length() > 0); + } + + @Test + public void testProcess_streamMultiRun() throws Exception { + File inFile = new File("src/test/resources/docx/DocxTemplaterTest-1.docx"); + File resFile = new File("target/test-files/DocxTemplaterTest-1-stream-result1.docx"); + resFile.delete(); + + final InputStream stream1 = new FileInputStream(inFile); + final InputStream stream2 = new FileInputStream(inFile); + + final DocxTemplaterBulk docxTemplater1 = new DocxTemplaterBulk(stream1, "k2"); + final DocxTemplaterBulk docxTemplater2 = new DocxTemplaterBulk(stream2, "k2"); + + new NonStrictExpectations(stream2) { + }; + + docxTemplater1.process(resFile, params); + docxTemplater2.process(resFile, params); + + // testing that stream2 was not actuall read but was closed + new Verifications() { + { + stream2.read((byte[]) any); + times = 0; + } + }; + new Verifications() { + { + stream2.read((byte[]) any, anyInt, anyInt); + times = 0; + } + }; + new Verifications() { + { + stream2.close(); + } + }; + + assertTrue(resFile.exists()); + assertTrue(resFile.length() > 0); + } + + private File none; + + @Test + public void testProcessScriptedTemplate_escapeAmpLtGt() throws Exception { + String template = TestUtils.readResource("/docx/DocxTemplaterTest-11.xml"); + + HashMap params = new HashMap(); + + params.put("escapeTest", "This should be escaped: &, <, >."); + DocxTemplaterBulk templater = new DocxTemplaterBulk(none); + template = templater.cleanupTemplate(template); + String result = templater.processCleanedTemplate(template, params); + + assertTrue(result.contains(">This should be escaped: &, <, >.<")); + } + + @Test + public void testProcessScriptedTemplate_nullsReplacement() throws Exception { + String template = TestUtils.readResource("/docx/DocxTemplaterTest-12.xml"); + + HashMap params = new HashMap(); + + params.put("someNullyVar", null); + DocxTemplaterBulk templater = new DocxTemplaterBulk(none); + template = templater.cleanupTemplate(template); + String result = templater.processCleanedTemplate(template, params); + + assertFalse(result.contains("space=\"preserve\">null<")); + assertTrue(result.contains("space=\"preserve\"><")); + + assertFalse(result.contains("space=\"arg1\">null<")); + assertTrue(result.contains("space=\"arg1\"><")); + + templater.setNullReplacement("UNKNOWD"); + result = templater.processCleanedTemplate(template, params); + + assertTrue(result.contains("space=\"preserve\">UNKNOWD<")); + assertTrue(result.contains("space=\"arg1\">UNKNOWD<")); + } + + @Test + public void testProcessScriptedTemplate_noSuchPropertyNullsReplacement() throws Exception { + String template = TestUtils.readResource("/docx/DocxTemplaterTest-12.xml"); + + HashMap params = new HashMap(); + + DocxTemplaterBulk templater = new DocxTemplaterBulk(none); + template = templater.cleanupTemplate(template); + String result = templater.processCleanedTemplate(template, params); + + assertFalse(result.contains("space=\"preserve\">null<")); + assertTrue(result.contains("space=\"preserve\"><")); + + assertFalse(result.contains("space=\"arg1\">null<")); + assertTrue(result.contains("space=\"arg1\"><")); + + templater.setNullReplacement("UNKNOWD"); + result = templater.processCleanedTemplate(template, params); + + assertTrue(result.contains("space=\"preserve\">UNKNOWD<")); + assertTrue(result.contains("space=\"arg1\">UNKNOWD<")); + } + + @Test + public void testProcessScriptedTemplate_booleanAndCond() throws Exception { + String template = TestUtils.readResource("/docx/DocxTemplaterTest-19.xml"); + + HashMap params = new HashMap(); + + params.put("cond1", "1"); + params.put("cond2", true); + DocxTemplaterBulk templater = new DocxTemplaterBulk(none); + template = templater.cleanupTemplate(template); + String result = templater.processCleanedTemplate(template, params); + assertTrue(result.contains("like kitties")); + + params.put("cond1", false); + result = templater.processCleanedTemplate(template, params); + assertFalse(result.contains("like kitties")); + } + + @Test + public void testProcessScriptedTemplate_newLine() throws Exception { + String template = TestUtils.readResource("/docx/DocxTemplaterTest-20.xml"); + + DocxTemplaterBulk templater = new DocxTemplaterBulk(none); + template = templater.cleanupTemplate(template); + params.put("hasNewLines", "this is A\n this is B\r\n this is C"); + String result = templater.processCleanedTemplate(template, DocxTemplater.processParams(params)); + + assertTrue(result != null); + assertTrue(result.contains("this is A")); + assertTrue(StringUtils.countMatches(result, "this is A") == 4); + } +} diff --git a/src/test/java/org/scriptlet4docx/docx/DocxTemplaterTest.java b/src/test/java/org/scriptlet4docx/docx/DocxTemplaterTest.java index 280284d..feabc5b 100644 --- a/src/test/java/org/scriptlet4docx/docx/DocxTemplaterTest.java +++ b/src/test/java/org/scriptlet4docx/docx/DocxTemplaterTest.java @@ -22,6 +22,8 @@ import org.scriptlet4docx.docx.TemplateContent.ContentItem; import org.scriptlet4docx.util.test.TestUtils; +import groovy.lang.GroovyRuntimeException; + public class DocxTemplaterTest extends Assert { static HashMap params; @@ -62,7 +64,7 @@ public static void setUpBeforeClass() throws Exception { @Test public void testProcessScriptedTemplate() throws Exception { - String template = TestUtils.readResource("/docx/DocxTemplaterTest-1.xml"); + String template = TestUtils.readResource("/docx/DocxTemplaterTest-13.xml"); DocxTemplater templater = new DocxTemplater(none); template = templater.cleanupTemplate(template); @@ -71,7 +73,9 @@ public void testProcessScriptedTemplate() throws Exception { assertTrue(result != null); assertTrue(result.contains("123#445")); assertTrue(StringUtils.countMatches(result, "123#445") == 4); + } + @Test public void testProcessScriptedTemplate_brokenType1() throws Exception { @@ -393,6 +397,21 @@ public void testProcess_file3() throws Exception { assertTrue(resFile.length() > 0); } + @Test(expected = RuntimeException.class) + public void testProcess_file4() throws Exception { + File inFile = new File("src/test/resources/docx/DocxTemplaterTest-large.docx"); + File resFile = new File("target/test-files/DocxTemplaterTest-1-file-result-large.docx"); + resFile.delete(); + + DocxTemplater docxTemplater = new DocxTemplater(inFile); + + docxTemplater.process(resFile, params); + + assertTrue(resFile.exists()); + assertTrue(resFile.length() > 0); + } + + @Test public void testProcess_withInputStreamAsOutput() throws Exception { File inFile = new File("src/test/resources/docx/DocxTemplaterTest-1.docx"); diff --git a/src/test/java/org/scriptlet4docx/docx/PlaceholderTest.java b/src/test/java/org/scriptlet4docx/docx/PlaceholderTest.java index b9dd732..2c2db64 100644 --- a/src/test/java/org/scriptlet4docx/docx/PlaceholderTest.java +++ b/src/test/java/org/scriptlet4docx/docx/PlaceholderTest.java @@ -25,6 +25,11 @@ public void testConstructWithCurrentScriptWrap() { "<% foo.bar() %>", PlaceholderType.SCRIPT); assertEquals("<% foo.bar() %>", ph.constructWithCurrentScriptWrap(" foo.bar() ")); + + ph = new Placeholder(UUID.randomUUID().toString(), + "<!=BREAK !>", PlaceholderType.SCRIPT); + + assertEquals("<%= BREAK %>", ph.constructWithCurrentScriptWrap(" BREAK ")); } } diff --git a/src/test/resources/docx/DocxTemplaterTest-13.xml b/src/test/resources/docx/DocxTemplaterTest-13.xml new file mode 100644 index 0000000..ece4e74 --- /dev/null +++ b/src/test/resources/docx/DocxTemplaterTest-13.xml @@ -0,0 +1,49 @@ + + + + + + + + ${contract.number} > <!=BREAK!> + + + + + + + + + ${ + contract.number + } + + + + + + + + + <%= contract.number %> <!=BREAK!> + + + + + + + + + <% contract.number %> + + + + + + + + + <%= + contract.number + %> + \ No newline at end of file diff --git a/src/test/resources/docx/DocxTemplaterTest-large.docx b/src/test/resources/docx/DocxTemplaterTest-large.docx new file mode 100644 index 0000000..1a7acc5 Binary files /dev/null and b/src/test/resources/docx/DocxTemplaterTest-large.docx differ