Repository: incubator-freemarker
Updated Branches:
  refs/heads/3 4c6e08a1c -> 2af16e4f2


In XML processing, the @@ names are now also converted to camel case (like 
node.@@nested_markup to node.@@nestedMarkup).


Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/a04ab89c
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/a04ab89c
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/a04ab89c

Branch: refs/heads/3
Commit: a04ab89c6830c43d531f09c7fe9fae42b0cdf915
Parents: 4c6e08a
Author: ddekany <ddek...@apache.org>
Authored: Sun Jul 16 01:26:09 2017 +0200
Committer: ddekany <ddek...@apache.org>
Committed: Sun Jul 16 01:32:55 2017 +0200

----------------------------------------------------------------------
 FM3-CHANGE-LOG.txt                              |  8 ++--
 .../core/FM2ASTToFM3SourceConverter.java        | 48 +++++++++++++++++--
 .../freemarker/ext/dom/AtAtKeyAccessor.java     | 35 ++++++++++++++
 .../converter/FM2ToFM3ConverterTest.java        | 14 +++++-
 .../java/org/apache/freemarker/dom/AtAtKey.java | 14 +++---
 .../apache/freemarker/dom/DOMSiblingTest.java   | 12 ++---
 .../java/org/apache/freemarker/dom/DOMTest.java | 50 ++++++++++----------
 7 files changed, 136 insertions(+), 45 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/a04ab89c/FM3-CHANGE-LOG.txt
----------------------------------------------------------------------
diff --git a/FM3-CHANGE-LOG.txt b/FM3-CHANGE-LOG.txt
index 52b00c9..7cbd223 100644
--- a/FM3-CHANGE-LOG.txt
+++ b/FM3-CHANGE-LOG.txt
@@ -18,13 +18,15 @@
  */
  
 Because the Manual won't be updated for a good while, we will lead
-the FreeMarer 3 changelog here:
+the FreeMarker 3 changelog here:
 
 - Switched to camel case as the only supported naming convention. This is as 
if in FM2 you set the "namingConvention"
   configuration setting to "camelCase", however the "namingConvention" setting 
was removed, as no other convention will
   be supported (for the default dialect at least). Also, configuration setting 
names and values must use camel case
-  too (FM2 was forgiving there). This means `#elseif` becomes to ``#elseIf`, 
``?upper_case`, `?upperCase`, and
-  if you configure FreeMarker with Properties, then `template_loader` becomes 
to `templateLoader`.
+  too (FM2 was forgiving there). Also, in XML processing, the @@ names were 
also converted to camel case. This means
+  `#elseif` becomes to ``#elseIf`, ``?upper_case`, `?upperCase`, and if you 
configure FreeMarker with Properties,
+  then `template_loader` becomes to `templateLoader`, and if you use the XML 
features, then `node.@@nested_markup`
+  becomes to `node.@@nestedMarkup`.
   Note that the template converter tool takes care of this conversion.
 - Increased version number to 3.0.0 (nightly aka. SNAPSHOT)
 - Removed legacy extensions: rhyno, jython, xml (not to be confused with dom), 
jdom, ant.

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/a04ab89c/freemarker-converter/src/main/java/freemarker/core/FM2ASTToFM3SourceConverter.java
----------------------------------------------------------------------
diff --git 
a/freemarker-converter/src/main/java/freemarker/core/FM2ASTToFM3SourceConverter.java
 
b/freemarker-converter/src/main/java/freemarker/core/FM2ASTToFM3SourceConverter.java
index e4a3e12..03eb9c5 100644
--- 
a/freemarker-converter/src/main/java/freemarker/core/FM2ASTToFM3SourceConverter.java
+++ 
b/freemarker-converter/src/main/java/freemarker/core/FM2ASTToFM3SourceConverter.java
@@ -46,6 +46,7 @@ import com.google.common.collect.ImmutableSet;
 
 import freemarker.cache.StringTemplateLoader;
 import freemarker.cache.TemplateLoader;
+import freemarker.ext.dom.AtAtKeyAccessor;
 import freemarker.template.Configuration;
 import freemarker.template.Template;
 import freemarker.template.utility.StringUtil;
@@ -1524,10 +1525,36 @@ public class FM2ASTToFM3SourceConverter {
         Expression lho = getParam(node, 0, ParameterRole.LEFT_HAND_OPERAND, 
Expression.class);
         String rho = getParam(node, 1, ParameterRole.RIGHT_HAND_OPERAND, 
String.class);
         printNode(lho);
+
         printSeparatorAndWSAndExpComments(getEndPositionExclusive(lho), ".");
+
+        rho = mapStringHashKey(rho);
         print(rho.startsWith("*") ? rho : FTLUtil.escapeIdentifier(rho));
     }
 
+    private String mapStringHashKey(String key) {
+        if (key.startsWith("@@")) {
+            String mappedKey = DOM_KEY_MAPPING.get(key);
+            if (mappedKey != null) {
+                key = mappedKey;
+            }
+        }
+        return key;
+    }
+
+    private static final Map<String, String> DOM_KEY_MAPPING;
+    static {
+        Map<String, String> domKeyMapping = new HashMap<>();
+        for (String atAtKey : AtAtKeyAccessor.getAtAtKeys()) {
+            String atAtKeyCC = ConverterUtils.snakeCaseToCamelCase(atAtKey);
+            if (!atAtKeyCC.equals(atAtKey)) {
+                domKeyMapping.put(atAtKey, atAtKeyCC);
+            }
+        }
+
+        DOM_KEY_MAPPING = Collections.unmodifiableMap(domKeyMapping);
+    }
+
     private void printExpDynamicKeyName(DynamicKeyName node) throws 
ConverterException {
         assertParamCount(node, 2);
 
@@ -1536,7 +1563,12 @@ public class FM2ASTToFM3SourceConverter {
 
         Expression keyExp = getParam(node, 1, ParameterRole.ENCLOSED_OPERAND, 
Expression.class);
         printParameterSeparatorSource(collExp, keyExp);
-        printExp(keyExp);
+        if (keyExp instanceof StringLiteral && keyExp.isLiteral()) {
+            StringLiteral keyStringLiteral = (StringLiteral) keyExp;
+            printExpStringLiteral(keyStringLiteral, 
mapStringHashKey((keyStringLiteral).getAsString()));
+        } else {
+            printExp(keyExp);
+        }
 
         printWithParamsTrailingSkippedTokens("]", node, 1);
     }
@@ -1725,6 +1757,10 @@ public class FM2ASTToFM3SourceConverter {
     private int stringLiteralNestingLevel;
 
     private void printExpStringLiteral(StringLiteral node) throws 
ConverterException {
+        printExpStringLiteral(node, node.isLiteral()     ? node.getAsString() 
: null);
+    }
+
+    private void printExpStringLiteral(StringLiteral node, String value) 
throws ConverterException {
         boolean escapeAmp, escapeLT, escapeGT;
         if (stringLiteralNestingLevel == 0) {
             // We check if the source code has avoided '&', '<', and '>'. If 
it did, we will escape them in the output.
@@ -1775,12 +1811,18 @@ public class FM2ASTToFM3SourceConverter {
 
         int parameterCount = node.getParameterCount();
         if (parameterCount == 0) {
+            _NullArgumentException.check("value", value);
             if (!rawString) {
-                print(FTLUtil.escapeStringLiteralPart(node.getAsString(), 
quote, escapeAmp, escapeLT, escapeGT));
+                print(FTLUtil.escapeStringLiteralPart(value, quote, escapeAmp, 
escapeLT, escapeGT));
             } else {
-                print(node.getAsString());
+                print(value);
             }
         } else {
+            if (value != null) {
+                throw new IllegalArgumentException("\"value\" argument must be 
null when the string contains "
+                        + "interpolations.");
+            }
+
             // Not really a literal; contains interpolations
             for (int paramIdx = 0; paramIdx < parameterCount; paramIdx++) {
                 Object param = getParam(node, paramIdx, 
ParameterRole.VALUE_PART, Object.class);

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/a04ab89c/freemarker-converter/src/main/java/freemarker/ext/dom/AtAtKeyAccessor.java
----------------------------------------------------------------------
diff --git 
a/freemarker-converter/src/main/java/freemarker/ext/dom/AtAtKeyAccessor.java 
b/freemarker-converter/src/main/java/freemarker/ext/dom/AtAtKeyAccessor.java
new file mode 100644
index 0000000..460b407
--- /dev/null
+++ b/freemarker-converter/src/main/java/freemarker/ext/dom/AtAtKeyAccessor.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package freemarker.ext.dom;
+
+import java.util.HashSet;
+import java.util.Set;
+
+public class AtAtKeyAccessor {
+
+    public static Set<String> getAtAtKeys() {
+        Set<String> keys = new HashSet<>();
+        for (AtAtKey atAtKey : AtAtKey.values()) {
+            keys.add(atAtKey.getKey());
+        }
+        return keys;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/a04ab89c/freemarker-converter/src/test/java/org/freemarker/converter/FM2ToFM3ConverterTest.java
----------------------------------------------------------------------
diff --git 
a/freemarker-converter/src/test/java/org/freemarker/converter/FM2ToFM3ConverterTest.java
 
b/freemarker-converter/src/test/java/org/freemarker/converter/FM2ToFM3ConverterTest.java
index b4bb719..aaa523c 100644
--- 
a/freemarker-converter/src/test/java/org/freemarker/converter/FM2ToFM3ConverterTest.java
+++ 
b/freemarker-converter/src/test/java/org/freemarker/converter/FM2ToFM3ConverterTest.java
@@ -480,7 +480,19 @@ public class FM2ToFM3ConverterTest extends ConverterTest {
 
     @Test
     public void testSquareBracketTagSyntax() throws IOException, 
ConverterException {
-        assertConvertedSame("[#if true <#-- c -->[#-- c --]]${v}[/#if]", true);
+        assertConverted("[#if true <#-- c -->[#-- c --]]${v}[#else][/#if]",
+                "[#if true <#-- c -->[#-- c --]]${v}[#else/][/#if]", true);
+        assertConverted("[#ftl][#if true <#-- c -->[#-- c 
--]]${v}[#else][/#if]",
+                "[#ftl][#if true <#-- c -->[#-- c --]]${v}[#else/][/#if]");
+    }
+
+    @Test
+    public void testXmlProcessing() throws IOException, ConverterException {
+        assertConverted("${node.@@nestedMarkup}", "${node.@@nested_markup}");
+        assertConverted("${node['@@nestedMarkup']}", 
"${node['@@nested_markup']}");
+
+        assertConvertedSame("${node.@@markup}");
+        assertConvertedSame("${node['@@markup']}");
     }
 
     @Test

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/a04ab89c/freemarker-dom/src/main/java/org/apache/freemarker/dom/AtAtKey.java
----------------------------------------------------------------------
diff --git 
a/freemarker-dom/src/main/java/org/apache/freemarker/dom/AtAtKey.java 
b/freemarker-dom/src/main/java/org/apache/freemarker/dom/AtAtKey.java
index ca6ac6b..1139b18 100644
--- a/freemarker-dom/src/main/java/org/apache/freemarker/dom/AtAtKey.java
+++ b/freemarker-dom/src/main/java/org/apache/freemarker/dom/AtAtKey.java
@@ -24,17 +24,17 @@ package org.apache.freemarker.dom;
 enum AtAtKey {
     
     MARKUP("@@markup"),
-    NESTED_MARKUP("@@nested_markup"),
-    ATTRIBUTES_MARKUP("@@attributes_markup"),
+    NESTED_MARKUP("@@nestedMarkup"),
+    ATTRIBUTES_MARKUP("@@attributesMarkup"),
     TEXT("@@text"),
-    START_TAG("@@start_tag"),
-    END_TAG("@@end_tag"),
+    START_TAG("@@startTag"),
+    END_TAG("@@endTag"),
     QNAME("@@qname"),
     NAMESPACE("@@namespace"),
-    LOCAL_NAME("@@local_name"),
+    LOCAL_NAME("@@localName"),
     ATTRIBUTES("@@"),
-    PREVIOUS_SIBLING_ELEMENT("@@previous_sibling_element"),
-    NEXT_SIBLING_ELEMENT("@@next_sibling_element");
+    PREVIOUS_SIBLING_ELEMENT("@@previousSiblingElement"),
+    NEXT_SIBLING_ELEMENT("@@nextSiblingElement");
 
     private final String key;
 

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/a04ab89c/freemarker-dom/src/test/java/org/apache/freemarker/dom/DOMSiblingTest.java
----------------------------------------------------------------------
diff --git 
a/freemarker-dom/src/test/java/org/apache/freemarker/dom/DOMSiblingTest.java 
b/freemarker-dom/src/test/java/org/apache/freemarker/dom/DOMSiblingTest.java
index af874fa..f69f0f2 100644
--- a/freemarker-dom/src/test/java/org/apache/freemarker/dom/DOMSiblingTest.java
+++ b/freemarker-dom/src/test/java/org/apache/freemarker/dom/DOMSiblingTest.java
@@ -64,32 +64,32 @@ public class DOMSiblingTest extends TemplateTest {
 
     @Test
     public void testSignificantPreviousSibling() throws IOException, 
TemplateException {
-        assertOutput("${doc.person.name.@@previous_sibling_element}", "male");
+        assertOutput("${doc.person.name.@@previousSiblingElement}", "male");
     }
 
     @Test
     public void testSignificantNextSibling() throws IOException, 
TemplateException {
-        assertOutput("${doc.person.name.@@next_sibling_element}", "12th 
August");
+        assertOutput("${doc.person.name.@@nextSiblingElement}", "12th August");
     }
 
     @Test
     public void testNullSignificantPreviousSibling() throws IOException, 
TemplateException {
-        assertOutput("${doc.person.phone.@@next_sibling_element?size}", "0");
+        assertOutput("${doc.person.phone.@@nextSiblingElement?size}", "0");
     }
 
     @Test
     public void testSkippingCommentNode() throws IOException, 
TemplateException {
-        assertOutput("${doc.person.profession.@@previous_sibling_element}", 
"Chennai, India");
+        assertOutput("${doc.person.profession.@@previousSiblingElement}", 
"Chennai, India");
     }
 
     @Test
     public void testSkippingEmptyCDataNode() throws IOException, 
TemplateException {
-        assertOutput("${doc.person.hobby.@@previous_sibling_element}", 
"Software Engineer");
+        assertOutput("${doc.person.hobby.@@previousSiblingElement}", "Software 
Engineer");
     }
 
     @Test
     public void testValidCDataNode() throws IOException, TemplateException {
-        assertOutput("${doc.person.phone.@@previous_sibling_element?size}", 
"0");
+        assertOutput("${doc.person.phone.@@previousSiblingElement?size}", "0");
     }
     
 }

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/a04ab89c/freemarker-dom/src/test/java/org/apache/freemarker/dom/DOMTest.java
----------------------------------------------------------------------
diff --git 
a/freemarker-dom/src/test/java/org/apache/freemarker/dom/DOMTest.java 
b/freemarker-dom/src/test/java/org/apache/freemarker/dom/DOMTest.java
index 36f7226..84187c7 100644
--- a/freemarker-dom/src/test/java/org/apache/freemarker/dom/DOMTest.java
+++ b/freemarker-dom/src/test/java/org/apache/freemarker/dom/DOMTest.java
@@ -78,8 +78,8 @@ public class DOMTest extends TemplateTest {
         assertOutput(ftlHeader + 
"${doc?children[0]?children[2]['@*'][0].@@qname}", "a1");
         assertOutput(ftlHeader + 
"${doc?children[0]?children[2]['@*'][1].@@qname}", "n2:a2");
         // Unfortunately these include the xmlns attributes, but that would be 
non-BC to fix now:
-        assertThat(getOutput(ftlHeader + "${doc?children[0].@@start_tag}"), 
startsWith("<root"));
-        assertThat(getOutput(ftlHeader + 
"${doc?children[0]?children[1].@@start_tag}"), startsWith("<n2:b"));
+        assertThat(getOutput(ftlHeader + "${doc?children[0].@@startTag}"), 
startsWith("<root"));
+        assertThat(getOutput(ftlHeader + 
"${doc?children[0]?children[1].@@startTag}"), startsWith("<n2:b"));
     }
     
     @Test
@@ -115,45 +115,45 @@ public class DOMTest extends TemplateTest {
     public void testInvalidAtAtKeyErrors() throws Exception {
         addDocToDataModel("<r><multipleMatches /><multipleMatches /></r>");
         assertErrorContains("${doc.r.@@invalid_key}", "Unsupported @@ key", 
"@invalid_key");
-        assertErrorContains("${doc.@@start_tag}", "@@start_tag", "not 
supported", "document");
+        assertErrorContains("${doc.@@startTag}", "@@startTag", "not 
supported", "document");
         assertErrorContains("${doc.@@}", "\"@@\"", "not supported", 
"document");
         assertErrorContains("${doc.r.noMatch.@@invalid_key}", "Unsupported @@ 
key", "@invalid_key");
         assertErrorContains("${doc.r.multipleMatches.@@invalid_key}", 
"Unsupported @@ key", "@invalid_key");
-        assertErrorContains("${doc.r.noMatch.@@attributes_markup}", "single 
XML node", "@@attributes_markup");
-        assertErrorContains("${doc.r.multipleMatches.@@attributes_markup}", 
"single XML node", "@@attributes_markup");
+        assertErrorContains("${doc.r.noMatch.@@attributesMarkup}", "single XML 
node", "@@attributesMarkup");
+        assertErrorContains("${doc.r.multipleMatches.@@attributesMarkup}", 
"single XML node", "@@attributesMarkup");
     }
     
     @Test
     public void testAtAtSiblingElement() throws Exception {
         addDocToDataModel("<r><a/><b/></r>");
-        assertOutput("${doc.r.@@previous_sibling_element?size}", "0");
-        assertOutput("${doc.r.@@next_sibling_element?size}", "0");
-        assertOutput("${doc.r.a.@@previous_sibling_element?size}", "0");
-        assertOutput("${doc.r.a.@@next_sibling_element.@@qname}", "b");
-        assertOutput("${doc.r.b.@@previous_sibling_element.@@qname}", "a");
-        assertOutput("${doc.r.b.@@next_sibling_element?size}", "0");
+        assertOutput("${doc.r.@@previousSiblingElement?size}", "0");
+        assertOutput("${doc.r.@@nextSiblingElement?size}", "0");
+        assertOutput("${doc.r.a.@@previousSiblingElement?size}", "0");
+        assertOutput("${doc.r.a.@@nextSiblingElement.@@qname}", "b");
+        assertOutput("${doc.r.b.@@previousSiblingElement.@@qname}", "a");
+        assertOutput("${doc.r.b.@@nextSiblingElement?size}", "0");
         
         addDocToDataModel("<r>\r\n\t <a/>\r\n\t <b/>\r\n\t </r>");
-        assertOutput("${doc.r.@@previous_sibling_element?size}", "0");
-        assertOutput("${doc.r.@@next_sibling_element?size}", "0");
-        assertOutput("${doc.r.a.@@previous_sibling_element?size}", "0");
-        assertOutput("${doc.r.a.@@next_sibling_element.@@qname}", "b");
-        assertOutput("${doc.r.b.@@previous_sibling_element.@@qname}", "a");
-        assertOutput("${doc.r.b.@@next_sibling_element?size}", "0");
+        assertOutput("${doc.r.@@previousSiblingElement?size}", "0");
+        assertOutput("${doc.r.@@nextSiblingElement?size}", "0");
+        assertOutput("${doc.r.a.@@previousSiblingElement?size}", "0");
+        assertOutput("${doc.r.a.@@nextSiblingElement.@@qname}", "b");
+        assertOutput("${doc.r.b.@@previousSiblingElement.@@qname}", "a");
+        assertOutput("${doc.r.b.@@nextSiblingElement?size}", "0");
         
         addDocToDataModel("<r>t<a/>t<b/>t</r>");
-        assertOutput("${doc.r.a.@@previous_sibling_element?size}", "0");
-        assertOutput("${doc.r.a.@@next_sibling_element?size}", "0");
-        assertOutput("${doc.r.b.@@previous_sibling_element?size}", "0");
-        assertOutput("${doc.r.b.@@next_sibling_element?size}", "0");
+        assertOutput("${doc.r.a.@@previousSiblingElement?size}", "0");
+        assertOutput("${doc.r.a.@@nextSiblingElement?size}", "0");
+        assertOutput("${doc.r.b.@@previousSiblingElement?size}", "0");
+        assertOutput("${doc.r.b.@@nextSiblingElement?size}", "0");
         
         addDocToDataModelNoSimplification("<r><a/> <!-- 
--><?pi?>&#x20;<b/></r>");
-        assertOutput("${doc.r.a.@@next_sibling_element.@@qname}", "b");
-        assertOutput("${doc.r.b.@@previous_sibling_element.@@qname}", "a");
+        assertOutput("${doc.r.a.@@nextSiblingElement.@@qname}", "b");
+        assertOutput("${doc.r.b.@@previousSiblingElement.@@qname}", "a");
         
         addDocToDataModelNoSimplification("<r><a/> <!-- -->t<!-- --> 
<b/></r>");
-        assertOutput("${doc.r.a.@@next_sibling_element?size}", "0");
-        assertOutput("${doc.r.b.@@previous_sibling_element?size}", "0");
+        assertOutput("${doc.r.a.@@nextSiblingElement?size}", "0");
+        assertOutput("${doc.r.b.@@previousSiblingElement?size}", "0");
     }
     
 }

Reply via email to