Repository: incubator-freemarker Updated Branches: refs/heads/2.3-gae 6e15268f7 -> aa7ab1cfb
- Changed @@..._significant to @@..._sibling_element. This differs from @@..._significant in that if the sibling is not an element, it won't return it at all (because the sibling is not an element, there's simply no sibling element) - ElementModel.isSignificantNode fixes Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/aa7ab1cf Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/aa7ab1cf Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/aa7ab1cf Branch: refs/heads/2.3-gae Commit: aa7ab1cfb77ac5f4677c3f5d7cde363594f7d81f Parents: 6e15268 Author: ddekany <[email protected]> Authored: Thu Jan 12 15:03:10 2017 +0100 Committer: ddekany <[email protected]> Committed: Thu Jan 12 15:03:10 2017 +0100 ---------------------------------------------------------------------- src/main/java/freemarker/ext/dom/AtAtKey.java | 4 +- .../java/freemarker/ext/dom/ElementModel.java | 59 +++++++++++--------- .../freemarker/template/utility/StringUtil.java | 1 - src/test/java/freemarker/core/SiblingTest.java | 14 ++--- 4 files changed, 41 insertions(+), 37 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/aa7ab1cf/src/main/java/freemarker/ext/dom/AtAtKey.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/ext/dom/AtAtKey.java b/src/main/java/freemarker/ext/dom/AtAtKey.java index a3c7166..6efc127 100644 --- a/src/main/java/freemarker/ext/dom/AtAtKey.java +++ b/src/main/java/freemarker/ext/dom/AtAtKey.java @@ -33,8 +33,8 @@ enum AtAtKey { NAMESPACE("@@namespace"), LOCAL_NAME("@@local_name"), ATTRIBUTES("@@"), - PREVIOUS_SIGNIFICANT("@@previous_significant"), - NEXT_SIGNIFICANT("@@next_significant"); + PREVIOUS_SIBLING_ELEMENT("@@previous_sibling_element"), + NEXT_SIBLING_ELEMENT("@@next_sibling_element"); private final String key; http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/aa7ab1cf/src/main/java/freemarker/ext/dom/ElementModel.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/ext/dom/ElementModel.java b/src/main/java/freemarker/ext/dom/ElementModel.java index 3fbc15c..1d0c2b5 100644 --- a/src/main/java/freemarker/ext/dom/ElementModel.java +++ b/src/main/java/freemarker/ext/dom/ElementModel.java @@ -33,7 +33,6 @@ import freemarker.template.TemplateModel; import freemarker.template.TemplateModelException; import freemarker.template.TemplateScalarModel; import freemarker.template.TemplateSequenceModel; -import freemarker.template.utility.StringUtil; class ElementModel extends NodeModel implements TemplateScalarModel { @@ -85,26 +84,20 @@ class ElementModel extends NodeModel implements TemplateScalarModel { NodeOutputter nu = new NodeOutputter(node); nu.outputContent(node.getAttributes(), buf); return new SimpleScalar(buf.toString().trim()); - } else if (key.equals(AtAtKey.PREVIOUS_SIGNIFICANT.getKey())) { + } else if (key.equals(AtAtKey.PREVIOUS_SIBLING_ELEMENT.getKey())) { Node previousSibling = node.getPreviousSibling(); - while(previousSibling != null && !this.isSignificantNode(previousSibling)) { + while (previousSibling != null && !this.isSignificantNode(previousSibling)) { previousSibling = previousSibling.getPreviousSibling(); } - if(previousSibling == null) { - return new NodeListModel(Collections.emptyList(), null); - } else { - return wrap(previousSibling); - } - } else if (key.equals(AtAtKey.NEXT_SIGNIFICANT.getKey())) { + return previousSibling != null && previousSibling.getNodeType() == Node.ELEMENT_NODE + ? wrap(previousSibling) : new NodeListModel(Collections.emptyList(), null); + } else if (key.equals(AtAtKey.NEXT_SIBLING_ELEMENT.getKey())) { Node nextSibling = node.getNextSibling(); - while(nextSibling != null && !this.isSignificantNode(nextSibling)) { + while (nextSibling != null && !this.isSignificantNode(nextSibling)) { nextSibling = nextSibling.getNextSibling(); } - if(nextSibling == null) { - return new NodeListModel(Collections.emptyList(), null); - } else { - return wrap(nextSibling); - } + return nextSibling != null && nextSibling.getNodeType() == Node.ELEMENT_NODE + ? wrap(nextSibling) : new NodeListModel(Collections.emptyList(), null); } else { // We don't know anything like this that's element-specific; fall back return super.get(key); @@ -133,17 +126,6 @@ class ElementModel extends NodeModel implements TemplateScalarModel { } } - public boolean isSignificantNode(Node node) throws TemplateModelException { - boolean significantNode = false; - if(node != null) { - boolean isEmpty = StringUtil.isTrimmableToEmpty(node.getTextContent().toCharArray()); - boolean isPINode = node.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE; - boolean isCommentNode = node.getNodeType() == Node.COMMENT_NODE; - significantNode = !(isEmpty || isPINode || isCommentNode); - } - return significantNode; - } - public String getAsString() throws TemplateModelException { NodeList nl = node.getChildNodes(); String result = ""; @@ -218,6 +200,31 @@ class ElementModel extends NodeModel implements TemplateScalarModel { return result; } + private boolean isSignificantNode(Node node) throws TemplateModelException { + return (node.getNodeType() == Node.TEXT_NODE || node.getNodeType() == Node.CDATA_SECTION_NODE) + ? !isBlankXMLText(node.getTextContent()) + : node.getNodeType() != Node.PROCESSING_INSTRUCTION_NODE && node.getNodeType() != Node.COMMENT_NODE; + } + + private boolean isBlankXMLText(String s) { + if (s == null) { + return true; + } + for (int i = 0; i < s.length(); i++) { + if (!isXMLWhiteSpace(s.charAt(i))) { + return false; + } + } + return true; + } + + /** + * White space according the XML spec. + */ + private boolean isXMLWhiteSpace(char c) { + return c == ' ' || c == '\t' || c == '\n' | c == '\r'; + } + boolean matchesName(String name, Environment env) { return DomStringUtil.matchesName(name, getNodeName(), getNodeNamespace(), env); } http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/aa7ab1cf/src/main/java/freemarker/template/utility/StringUtil.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/template/utility/StringUtil.java b/src/main/java/freemarker/template/utility/StringUtil.java index 55ba617..d807f90 100644 --- a/src/main/java/freemarker/template/utility/StringUtil.java +++ b/src/main/java/freemarker/template/utility/StringUtil.java @@ -31,7 +31,6 @@ import java.util.regex.Pattern; import freemarker.core.Environment; import freemarker.core.ParseException; import freemarker.ext.dom._ExtDomApi; -import freemarker.template.Template; import freemarker.template.Version; /** http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/aa7ab1cf/src/test/java/freemarker/core/SiblingTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/freemarker/core/SiblingTest.java b/src/test/java/freemarker/core/SiblingTest.java index d27b1bd..d0d5779 100644 --- a/src/test/java/freemarker/core/SiblingTest.java +++ b/src/test/java/freemarker/core/SiblingTest.java @@ -67,35 +67,33 @@ public class SiblingTest extends TemplateTest { @Test public void testSignificantPreviousSibling() throws IOException, TemplateException { - String ftl = "${doc.person.name.@@previous_significant}"; + String ftl = "${doc.person.name.@@previous_sibling_element}"; assertOutput(ftl, "male"); } - @Test public void testSignificantNextSibling() throws IOException, TemplateException { - String ftl = "${doc.person.name.@@next_significant}"; + String ftl = "${doc.person.name.@@next_sibling_element}"; assertOutput(ftl, "12th August"); } @Test public void testNullSignificantPreviousSibling() throws IOException, TemplateException { - assertOutput("${doc.person.phone.@@next_significant?size}", "0"); - + assertOutput("${doc.person.phone.@@next_sibling_element?size}", "0"); } @Test public void testSkippingCommentNode() throws IOException, TemplateException { - assertOutput("${doc.person.profession.@@previous_significant}", "Chennai, India"); + assertOutput("${doc.person.profession.@@previous_sibling_element}", "Chennai, India"); } @Test public void testSkippingEmptyCDataNode() throws IOException, TemplateException { - assertOutput("${doc.person.hobby.@@previous_significant}", "Software Engineer"); + assertOutput("${doc.person.hobby.@@previous_sibling_element}", "Software Engineer"); } @Test public void testValidCDataNode() throws IOException, TemplateException { - assertOutput("${doc.person.phone.@@previous_significant}", "\n this is a valid cdata\n "); + assertOutput("${doc.person.phone.@@previous_sibling_element?size}", "0"); } }
