Removed the legacy predefined shared variables: "html_escape", "normalize_newlines", "xml_escape", "capture_output", "compress". It had to be done now as TemplateTransformModel will be removed as part of FREEMARKER-63.
Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/1e27397d Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/1e27397d Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/1e27397d Branch: refs/heads/3 Commit: 1e27397dd9570ac2f48be6100afd2bba7b42b8b8 Parents: 146c425 Author: ddekany <[email protected]> Authored: Thu Jul 27 20:45:01 2017 +0200 Committer: ddekany <[email protected]> Committed: Thu Jul 27 20:45:01 2017 +0200 ---------------------------------------------------------------------- FM3-CHANGE-LOG.txt | 2 + .../core/TagSyntaxVariationsTest.java | 30 ++- .../models/TransformHashWrapper.java | 79 ------ .../models/TransformMethodWrapper1.java | 49 ---- .../models/TransformMethodWrapper2.java | 64 ----- .../templatesuite/models/TransformModel1.java | 175 -------------- .../core/templatesuite/expected/compress.txt | 4 - .../core/templatesuite/expected/newlines1.txt | 29 --- .../core/templatesuite/expected/newlines2.txt | 30 --- .../core/templatesuite/expected/transforms.txt | 68 ------ .../templatesuite/expected/type-builtins.txt | 29 ++- .../core/templatesuite/templates/compress.ftl | 17 -- .../core/templatesuite/templates/newlines1.ftl | 29 --- .../core/templatesuite/templates/newlines2.ftl | 33 --- .../core/templatesuite/templates/transforms.ftl | 100 -------- .../templatesuite/templates/type-builtins.ftl | 5 +- .../freemarker/core/templatesuite/testcases.xml | 3 - .../apache/freemarker/core/ASTDirCompress.java | 140 ++++++++++- .../apache/freemarker/core/Configuration.java | 19 +- .../freemarker/core/util/CaptureOutput.java | 147 ------------ .../apache/freemarker/core/util/HtmlEscape.java | 109 --------- .../freemarker/core/util/NormalizeNewlines.java | 115 --------- .../freemarker/core/util/StandardCompress.java | 239 ------------------- .../apache/freemarker/core/util/XmlEscape.java | 92 ------- .../servlet/jsp/webapps/basic/customTags1.ftl | 4 +- 25 files changed, 183 insertions(+), 1428 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1e27397d/FM3-CHANGE-LOG.txt ---------------------------------------------------------------------- diff --git a/FM3-CHANGE-LOG.txt b/FM3-CHANGE-LOG.txt index c357c28..7943289 100644 --- a/FM3-CHANGE-LOG.txt +++ b/FM3-CHANGE-LOG.txt @@ -412,6 +412,8 @@ Core / Miscellaneous future.) - util.ObjectFactory was renamed to CommonSupplier, and its createObject() method was renamed to get(), to be more similar to the Java 8 API. +- Removed the legacy predefined shared variables: "html_escape", "normalize_newlines", "xml_escape", "capture_output", + "compress" Build / development process changes http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1e27397d/freemarker-core-test/src/test/java/org/apache/freemarker/core/TagSyntaxVariationsTest.java ---------------------------------------------------------------------- diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/TagSyntaxVariationsTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/TagSyntaxVariationsTest.java index 536be44..02c74df 100644 --- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/TagSyntaxVariationsTest.java +++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/TagSyntaxVariationsTest.java @@ -22,7 +22,12 @@ package org.apache.freemarker.core; import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; +import java.util.Collections; +import java.util.Map; +import org.apache.freemarker.core.model.TemplateDirectiveBody; +import org.apache.freemarker.core.model.TemplateDirectiveModel; +import org.apache.freemarker.core.model.TemplateModel; import org.apache.freemarker.core.util._StringUtil; import org.apache.freemarker.test.TestConfigurationBuilder; @@ -46,9 +51,9 @@ public class TagSyntaxVariationsTest extends TestCase { private static final String WRONG_SQU = squarify(WRONG_ANG); private static final String WRONGC_ANG = "</#wrong>"; private static final String WRONGC_SQU = squarify(WRONGC_ANG ); - private static final String CUST_ANG = "<@compress> z </@>"; + private static final String CUST_ANG = "<@upperCase>z</@>"; private static final String CUST_SQU = squarify(CUST_ANG); - private static final String CUST_OUT = "z"; + private static final String CUST_OUT = "Z"; public TagSyntaxVariationsTest(String name) { super(name); @@ -60,6 +65,9 @@ public class TagSyntaxVariationsTest extends TestCase { public final void test() throws TemplateException, IOException { + Map<String, UpperCaseDirective> sharedVariables = + Collections.singletonMap("upperCase", UpperCaseDirective.INSTANCE); + // Permutations for (int ifOrAssign = 0; ifOrAssign < 2; ifOrAssign++) { String dir_ang = ifOrAssign == 0 ? IF_ANG : ASSIGN_ANG; @@ -72,6 +80,7 @@ public class TagSyntaxVariationsTest extends TestCase { .tagSyntax(angOrSqu == 0 ? TagSyntax.ANGLE_BRACKET : TagSyntax.SQUARE_BRACKET) + .sharedVariables(sharedVariables) .build(); String dir_xxx = angOrSqu == 0 ? dir_ang : dir_squ; @@ -109,6 +118,7 @@ public class TagSyntaxVariationsTest extends TestCase { { Configuration cfg = new TestConfigurationBuilder() .tagSyntax(TagSyntax.AUTO_DETECT) + .sharedVariables(sharedVariables) .build(); for (int perm = 0; perm < 4; perm++) { // All 4 permutations @@ -124,6 +134,7 @@ public class TagSyntaxVariationsTest extends TestCase { { Configuration cfg = new TestConfigurationBuilder() .tagSyntax(TagSyntax.AUTO_DETECT) + .sharedVariables(sharedVariables) .build(); // Permutations for (int angOrSquStart = 0; angOrSquStart < 2; angOrSquStart++) { @@ -183,4 +194,19 @@ public class TagSyntaxVariationsTest extends TestCase { assertEquals(expected, out.toString()); } + // This will be removed when the legacy TemplateDirectiveModel is removed; the use the other UpperCaseDirective + // instead! + private static class UpperCaseDirective implements TemplateDirectiveModel { + + private static final UpperCaseDirective INSTANCE = new UpperCaseDirective(); + + @Override + public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body) + throws TemplateException, IOException { + StringWriter sw = new StringWriter(); + body.render(sw); + env.getOut().write(sw.toString().toUpperCase()); + } + } + } http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1e27397d/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/TransformHashWrapper.java ---------------------------------------------------------------------- diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/TransformHashWrapper.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/TransformHashWrapper.java deleted file mode 100644 index 7771d6d..0000000 --- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/TransformHashWrapper.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * 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 org.apache.freemarker.core.templatesuite.models; - -import org.apache.freemarker.core.Configuration; -import org.apache.freemarker.core.model.ObjectWrapper; -import org.apache.freemarker.core.model.TemplateHashModel; -import org.apache.freemarker.core.model.TemplateModel; -import org.apache.freemarker.core.model.TemplateModelException; -import org.apache.freemarker.core.model.TemplateScalarModel; -import org.apache.freemarker.core.model.impl.DefaultObjectWrapper; -import org.apache.freemarker.core.model.impl.SimpleHash; -import org.apache.freemarker.core.util.HtmlEscape; -import org.apache.freemarker.core.util.StandardCompress; - -/** - * Part of the TestTransform testcase suite. - */ -public class TransformHashWrapper implements TemplateHashModel, - TemplateScalarModel { - - private ObjectWrapper ow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build(); - private SimpleHash m_cHashModel = new SimpleHash(ow); - - /** Creates new TransformHashWrapper */ - public TransformHashWrapper() { - m_cHashModel.put( "htmlEscape", new HtmlEscape() ); - m_cHashModel.put( "compress", new StandardCompress() ); - m_cHashModel.put( "escape", new TransformMethodWrapper1() ); - m_cHashModel.put( "special", new TransformMethodWrapper2() ); - } - - /** - * Gets a <tt>TemplateModel</tt> from the hash. - * - * @param key the name by which the <tt>TemplateModel</tt> - * is identified in the template. - * @return the <tt>TemplateModel</tt> referred to by the key, - * or null if not found. - */ - @Override - public TemplateModel get(String key) throws TemplateModelException { - return m_cHashModel.get( key ); - } - - /** - * @return true if this object is empty. - */ - @Override - public boolean isEmpty() { - return false; - } - - /** - * Returns the scalar's value as a String. - * @return the String value of this scalar. - */ - @Override - public String getAsString() { - return "Utility transformations"; - } -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1e27397d/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/TransformMethodWrapper1.java ---------------------------------------------------------------------- diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/TransformMethodWrapper1.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/TransformMethodWrapper1.java deleted file mode 100644 index 0fc9205..0000000 --- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/TransformMethodWrapper1.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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 org.apache.freemarker.core.templatesuite.models; - -import java.util.List; - -import org.apache.freemarker.core.model.TemplateMethodModel; -import org.apache.freemarker.core.util.HtmlEscape; -import org.apache.freemarker.core.util.XmlEscape; - -/** - * Simple test of the interaction between MethodModels and TransformModels. - */ -public class TransformMethodWrapper1 implements TemplateMethodModel { - - /** - * Executes a method call. - * - * @param arguments a <tt>List</tt> of <tt>String</tt> objects containing - * the values of the arguments passed to the method. - * @return the <tt>TemplateModel</tt> produced by the method, or null. - */ - @Override - public Object exec(List arguments) { - - if (( arguments.size() > 0 ) && ( arguments.get( 0 ).toString().equals( "xml" ))) { - return new XmlEscape(); - } else { - return new HtmlEscape(); - } - } -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1e27397d/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/TransformMethodWrapper2.java ---------------------------------------------------------------------- diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/TransformMethodWrapper2.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/TransformMethodWrapper2.java deleted file mode 100644 index 75a5b68..0000000 --- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/TransformMethodWrapper2.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * 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 org.apache.freemarker.core.templatesuite.models; - -import java.util.Iterator; -import java.util.List; - -import org.apache.freemarker.core.model.TemplateMethodModel; - -/** - * Another test of the interaction between MethodModels and TransformModels. - */ -public class TransformMethodWrapper2 implements TemplateMethodModel { - - /** - * Executes a method call. - * - * @param arguments a <tt>List</tt> of <tt>String</tt> objects containing - * the values of the arguments passed to the method. - * @return the <tt>TemplateModel</tt> produced by the method, or null. - */ - @Override - public Object exec(List arguments) { - TransformModel1 cTransformer = new TransformModel1(); - Iterator iArgument = arguments.iterator(); - - // Sets up properties of the Transform model based on the arguments - // passed into this method - - while ( iArgument.hasNext() ) { - String aArgument = (String) iArgument.next(); - - if ( aArgument.equals( "quote" )) { - cTransformer.setQuotes( true ); - } else if ( aArgument.equals( "tag" )) { - cTransformer.setTags( true ); - } else if ( aArgument.equals( "ampersand" )) { - cTransformer.setAmpersands( true ); - } else { - cTransformer.setComment( aArgument ); - } - } - - // Now return the transform class. - return cTransformer; - } -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1e27397d/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/TransformModel1.java ---------------------------------------------------------------------- diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/TransformModel1.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/TransformModel1.java deleted file mode 100644 index 2fac758..0000000 --- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/TransformModel1.java +++ /dev/null @@ -1,175 +0,0 @@ -/* - * 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 org.apache.freemarker.core.templatesuite.models; - -import java.io.IOException; -import java.io.Reader; -import java.io.StringReader; -import java.io.StringWriter; -import java.io.Writer; -import java.util.Map; - -import org.apache.freemarker.core.model.TemplateTransformModel; - -/** - * A TemplateTransformModel that includes properties. These properties can be - * set at model construction time, or, for the purposes of this demonstration, - * can be passed in from a wrapper TemplateMethodModel. - */ -public class TransformModel1 implements TemplateTransformModel { - - private boolean m_bAmpersands = false; - private boolean m_bQuotes = false; - private boolean m_bTags = false; - private String m_aComment = ""; - - private static final int READER_BUFFER_SIZE = 4096; - - @Override - public Writer getWriter(final Writer out, - final Map args) { - final StringBuilder buf = new StringBuilder(); - return new Writer(out) { - @Override - public void write(char cbuf[], int off, int len) { - buf.append(cbuf, off, len); - } - - @Override - public void flush() { - } - - @Override - public void close() throws IOException { - StringReader sr = new StringReader(buf.toString()); - StringWriter sw = new StringWriter(); - transform(sr, sw); - out.write(sw.toString()); - } - }; - } - - - /** - * Indicates whether we escape ampersands. This property can be set either - * while the model is being constructed, or via a property passed in through - * a <code>TemplateMethodModel</code>. - */ - public void setAmpersands( boolean bAmpersands ) { - m_bAmpersands = bAmpersands; - } - - /** - * Indicates whether we escape quotes. This property can be set either - * while the model is being constructed, or via a property passed in through - * a <code>TemplateMethodModel</code>. - */ - public void setQuotes( boolean bQuotes ) { - m_bQuotes = bQuotes; - } - - /** - * Indicates whether we escape tags. This property can be set either - * while the model is being constructed, or via a property passed in through - * a <code>TemplateMethodModel</code>. - */ - public void setTags( boolean bTags ) { - m_bTags = bTags; - } - - /** - * Sets a comment for this transformation. This property can be set either - * while the model is being constructed, or via a property passed in through - * a <code>TemplateMethodModel</code>. - */ - public void setComment( String aComment ) { - m_aComment = aComment; - } - - /** - * Performs a transformation/filter on FreeMarker output. - * - * @param source the input to be transformed - * @param output the destination of the transformation - */ - public void transform(Reader source, Writer output) - throws IOException { - // Output the source, converting unsafe certain characters to their - // equivalent entities. - int n = 0; - boolean bCommentSent = false; - char[] aBuffer = new char[ READER_BUFFER_SIZE ]; - int i = source.read( aBuffer ); - while (i >= 0) { - for ( int j = 0; j < i; j++ ) { - char c = aBuffer[j]; - switch (c) { - case '&': - if ( m_bAmpersands ) { - output.write("&"); - } else { - output.write( c ); - } - break; - case '<': - if ( m_bTags ) { - output.write("<"); - } else { - output.write( c ); - } - break; - case '>': - if ( m_bTags ) { - output.write(">"); - } else { - output.write( c ); - } - break; - case '"': - if ( m_bQuotes ) { - output.write("""); - } else { - output.write( c ); - } - break; - case '\'': - if ( m_bQuotes ) { - output.write("'"); - } else { - output.write( c ); - } - break; - case '*': - if ( ! bCommentSent ) { - output.write( m_aComment ); - bCommentSent = true; - } else { - output.write( c ); - } - break; - default: - output.write(c); - } - n++; - } - i = source.read( aBuffer ); - } - } -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1e27397d/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/compress.txt ---------------------------------------------------------------------- diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/compress.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/compress.txt index 43c7eed..707e299 100644 --- a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/compress.txt +++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/compress.txt @@ -28,10 +28,6 @@ <p>This is the same message, using the "compress" tag:</p> <p>Hello, world!</p> -<p>This is the same message, using the "StandardCompress" transform model:</p> -<p>Hello, world!</p> -<p>This multi-line message should be compressed to a single line.</p> - <p>An example where the first character is not whitespace but the second character is:</p> <p>x y</p> http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1e27397d/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/newlines1.txt ---------------------------------------------------------------------- diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/newlines1.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/newlines1.txt deleted file mode 100644 index bc58731..0000000 --- a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/newlines1.txt +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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. - */ -<html> -<head> -<title>FreeMarker: Newlines Test</title> -</head> -<body> -<p>A simple test follows:</p> - -<p>Hello, world!</p> - -</body> -</html> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1e27397d/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/newlines2.txt ---------------------------------------------------------------------- diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/newlines2.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/newlines2.txt deleted file mode 100644 index c131421..0000000 --- a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/newlines2.txt +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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. - */ -<html> -<head> -<title>FreeMarker: Newlines the Second Test</title> -</head> -<body> -<p>A simple test follows:</p> - -<p>Hello, world! -</p> - -</body> -</html> http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1e27397d/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/transforms.txt ---------------------------------------------------------------------- diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/transforms.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/transforms.txt deleted file mode 100644 index 6b7f986..0000000 --- a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/transforms.txt +++ /dev/null @@ -1,68 +0,0 @@ -/* - * 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. - */ -<html> -<head> -<title>FreeMarker: Transformation Test</title> -</head> -<body> - -<p>A simple test follows:</p> - -<p>Hello, world!</p> - -<p>Hello, world!</p> - -<P>Now try the Utility package:</p> -<p>Utility transformations</p> - -<p>Utility transformations</p> - -<p>Now some nested transforms:</p> -<p >This tests the compress transformation</p ><p >This tests the compress transformation</p ><p >This tests the compress transformation</p > -<p>Now try method and transform interactions:</p> -<p>This isn't a valid XML string.</p> -<p>This isn't a valid HTML string.</p> - -<p>A more advanced interaction involves getting a TemplateMethodModel -to initialise a TemplateTransformModel, as follow:</p> - -Comment: This is a comment - -A test string containing quotes: "This isn't a test". -A test string containing amps: Fish & Chips. -A test string containing tags: <p>Fish & Chips.</p> - -Comment: This is a second comment - -A test string containing quotes: "This isn't a test". -A test string containing amps: Fish & Chips. -A test string containing tags: <p>Fish & Chips.</p> -Comment: This is a third comment - -A test string containing quotes: "This isn't a test". -A test string containing amps: Fish & Chips. -A test string containing tags: <p>Fish &amp; Chips.</p> -Comment: Utility transformations - -A test string containing quotes: "This isn't a test". -A test string containing amps: Fish & Chips. -A test string containing tags: <p>Fish & Chips.</p> - -</body> -</html> http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1e27397d/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/type-builtins.txt ---------------------------------------------------------------------- diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/type-builtins.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/type-builtins.txt index 0b4e23a..eeb191e 100644 --- a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/type-builtins.txt +++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/type-builtins.txt @@ -16,18 +16,17 @@ * specific language governing permissions and limitations * under the License. */ -StNuBoMeTaMaHaHxSeCoCxEnInDiNo -1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 -0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 -0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 1 0 0 1 1 0 0 -0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 -0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 -1 0 0 0 0 0 1 1 0 0 0 0 0 0 0 -0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 +StNuBoMeMaHaHxSeCoCxEnInDiNo +1 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 1 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 1 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 1 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 1 0 0 0 0 0 0 0 1 0 +0 0 0 0 0 1 1 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 1 0 0 1 1 0 0 +0 0 0 0 0 0 0 0 1 0 1 0 0 0 +0 0 0 0 0 0 0 0 1 1 1 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 1 +1 0 0 0 0 1 1 0 0 0 0 0 0 0 +0 0 0 1 0 0 0 0 0 0 0 0 0 0 +0 0 0 1 0 0 0 0 0 0 0 0 0 0 http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1e27397d/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/compress.ftl ---------------------------------------------------------------------- diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/compress.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/compress.ftl index faf4ad6..2edd306 100644 --- a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/compress.ftl +++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/compress.ftl @@ -22,7 +22,6 @@ </head> <body> -<#assign utility={'standardCompress': "org.apache.freemarker.core.util.StandardCompress"?new()}> <p>A simple test follows:</p> <p>${message}</p> @@ -35,22 +34,6 @@ <p>${message}</p> </#compress> -<@utility.standardCompress buffer_size=8> - - <p>This is the same message, using the "StandardCompress" transform model:</p> - - -<p>${message}</p> -</@> - -<@utility.standardCompress single_line=true> - -<p>This - multi-line message - should -be compressed - to a single line.</p></@> - <p>An example where the first character is not whitespace but the second character is:</p> <p><#compress>x y</#compress></p> http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1e27397d/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/newlines1.ftl ---------------------------------------------------------------------- diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/newlines1.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/newlines1.ftl deleted file mode 100644 index 18f4b32..0000000 --- a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/newlines1.ftl +++ /dev/null @@ -1,29 +0,0 @@ -<#-- - 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. ---> -<html> -<head> -<title>FreeMarker: Newlines Test</title> -</head> -<body> -<p>A simple test follows:</p> - -<p>${message}</p> - -</body> -</html> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1e27397d/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/newlines2.ftl ---------------------------------------------------------------------- diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/newlines2.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/newlines2.ftl deleted file mode 100644 index ac8337c..0000000 --- a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/newlines2.ftl +++ /dev/null @@ -1,33 +0,0 @@ -<#-- - 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. ---> -<#assign message="Hello, world!\n"> -<#assign normalizeNewlines = "org.apache.freemarker.core.util.NormalizeNewlines"?new()> -<@normalizeNewlines> -<html> -<head> -<title>FreeMarker: Newlines the Second Test</title> -</head> -<body> -<p>A simple test follows:</p> - -<p>${message}</p> - -</body> -</html> -</@normalizeNewlines> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1e27397d/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/transforms.ftl ---------------------------------------------------------------------- diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/transforms.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/transforms.ftl deleted file mode 100644 index 9b1e55a..0000000 --- a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/transforms.ftl +++ /dev/null @@ -1,100 +0,0 @@ -<#-- - 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. ---> -<#assign htmlEscape = "org.apache.freemarker.core.util.HtmlEscape"?new(), - utility = "org.apache.freemarker.core.templatesuite.models.TransformHashWrapper"?new()> -<html> -<head> -<title>FreeMarker: Transformation Test</title> -</head> -<body> - -<p>A simple test follows:</p> - -<p>${message}</p> - -<@htmlEscape> -<p>${message}</p> -</@htmlEscape> - -<P>Now try the Utility package:</p> -<p>${utility}</p> - -<@utility.htmlEscape> -<p>${utility}</p> -</@> - -<p>Now some nested transforms:</p> -<@utility.compress> -<p >This tests the compress transformation</p > -</@> -<@utility.compress> -<@utility.htmlEscape> -<p >This tests the compress transformation</p > -</@> -</@utility.compress> -<#assign html_transform = "org.apache.freemarker.core.util.HtmlEscape"?new() /> -<@html_transform><#--Using the transform via an instantiation --> -<@utility.compress> -<p >This tests the compress transformation</p > -</@> -</@> - -<p>Now try method and transform interactions:</p> -<@utility.escape("xml")> -<p>This isn't a valid XML string.</p> -</@> -<@utility.escape("html")> -<p>This isn't a valid HTML string.</p> -</@> - -<p>A more advanced interaction involves getting a TemplateMethodModel -to initialise a TemplateTransformModel, as follow:</p> - -<@utility.special("This is a comment")> -Comment: * - -A test string containing quotes: "This isn't a test". -A test string containing amps: Fish & Chips. -A test string containing tags: <p>Fish & Chips.</p> -</@> - -<@utility.special("This is a second comment", "quote")> -Comment: * - -A test string containing quotes: "This isn't a test". -A test string containing amps: Fish & Chips. -A test string containing tags: <p>Fish & Chips.</p> -</@> -<@utility.special("This is a third comment", "ampersand", "quote")> -Comment: * - -A test string containing quotes: "This isn't a test". -A test string containing amps: Fish & Chips. -A test string containing tags: <p>Fish & Chips.</p> -</@> -<@utility.special("tag", utility)> -Comment: * - -A test string containing quotes: "This isn't a test". -A test string containing amps: Fish & Chips. -A test string containing tags: <p>Fish & Chips.</p> -</@> - -</body> -</html> http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1e27397d/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/type-builtins.ftl ---------------------------------------------------------------------- diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/type-builtins.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/type-builtins.ftl index 3e0a942..695bd76 100644 --- a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/type-builtins.ftl +++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/type-builtins.ftl @@ -17,10 +17,10 @@ under the License. --> <#setting booleanFormat="1,0"> -StNuBoMeTaMaHaHxSeCoCxEnInDiNo +StNuBoMeMaHaHxSeCoCxEnInDiNo <#list [ "a", 1, false, - testmethod, testmacro, html_escape, + testmethod, testmacro, {"a":1}, [1], testcollection, testcollectionEx, testnode, bean, bean.m, bean.mOverloaded @@ -30,7 +30,6 @@ StNuBoMeTaMaHaHxSeCoCxEnInDiNo ${x?isBoolean} <#t> ${x?isMethod} <#t> ${x?isMacro} <#t> - ${x?isTransform} <#t> ${x?isHash} <#t> ${x?isHashEx} <#t> ${x?isSequence} <#t> http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1e27397d/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/testcases.xml ---------------------------------------------------------------------- diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/testcases.xml b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/testcases.xml index a02ad3c..d79ee43 100644 --- a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/testcases.xml +++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/testcases.xml @@ -121,8 +121,6 @@ Note that for the incompatibleImprovements setting you can specify a list of ver <testCase name="macros-return"/> <testCase name="multimodels"/> <testCase name="nested" /> - <testCase name="newlines1" /> - <testCase name="newlines2" /> <testCase name="noparse" /> <testCase name="number-format" /> <testCase name="number-literal" > @@ -162,7 +160,6 @@ Note that for the incompatibleImprovements setting you can specify a list of ver <testCase name="if" /> <testCase name="switch" /> <testCase name="switch-builtin" noOutput="true" /> - <testCase name="transforms"/> <testCase name="type-builtins" /> <testCase name="date-type-builtins" noOutput="true" /> <testCase name="url" noOutput="true" /> http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1e27397d/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirCompress.java ---------------------------------------------------------------------- diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirCompress.java b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirCompress.java index ca3fd0a..6bdda37 100644 --- a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirCompress.java +++ b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirCompress.java @@ -20,15 +20,12 @@ package org.apache.freemarker.core; import java.io.IOException; - -import org.apache.freemarker.core.util.StandardCompress; +import java.io.Writer; /** * AST directive node: {@code #compress}. * An instruction that reduces all sequences of whitespace to a single * space or newline. In addition, leading and trailing whitespace is removed. - * - * @see org.apache.freemarker.core.util.StandardCompress */ final class ASTDirCompress extends ASTDirective { @@ -40,7 +37,12 @@ final class ASTDirCompress extends ASTDirective { ASTElement[] accept(Environment env) throws TemplateException, IOException { ASTElement[] childBuffer = getChildBuffer(); if (childBuffer != null) { - env.visitAndTransform(childBuffer, StandardCompress.INSTANCE, null); + CompressWriter out = new CompressWriter(env.getOut(), 2048, false); + try { + env.visit(childBuffer, out); + } finally { + out.close(); + } } return null; } @@ -83,5 +85,131 @@ final class ASTDirCompress extends ASTDirective { boolean isNestedBlockRepeater() { return false; } - + + // TODO [FM3] Blindly copied from FM2 StandaradCompress; review + private static class CompressWriter extends Writer { + private static final int MAX_EOL_LENGTH = 2; // CRLF is two bytes + + private static final int AT_BEGINNING = 0; + private static final int SINGLE_LINE = 1; + private static final int INIT = 2; + private static final int SAW_CR = 3; + private static final int LINEBREAK_CR = 4; + private static final int LINEBREAK_CRLF = 5; + private static final int LINEBREAK_LF = 6; + + private final Writer out; + private final char[] buf; + private final boolean singleLine; + + private int pos = 0; + private boolean inWhitespace = true; + private int lineBreakState = AT_BEGINNING; + + public CompressWriter(Writer out, int bufSize, boolean singleLine) { + this.out = out; + this.singleLine = singleLine; + buf = new char[bufSize]; + } + + @Override + public void write(char[] cbuf, int off, int len) throws IOException { + for (; ; ) { + // Need to reserve space for the EOL potentially left in the state machine + int room = buf.length - pos - MAX_EOL_LENGTH; + if (room >= len) { + writeHelper(cbuf, off, len); + break; + } else if (room <= 0) { + flushInternal(); + } else { + writeHelper(cbuf, off, room); + flushInternal(); + off += room; + len -= room; + } + } + } + + private void writeHelper(char[] cbuf, int off, int len) { + for (int i = off, end = off + len; i < end; i++) { + char c = cbuf[i]; + if (Character.isWhitespace(c)) { + inWhitespace = true; + updateLineBreakState(c); + } else if (inWhitespace) { + inWhitespace = false; + writeLineBreakOrSpace(); + buf[pos++] = c; + } else { + buf[pos++] = c; + } + } + } + + /* + \r\n => CRLF + \r[^\n] => CR + \r$ => CR + [^\r]\n => LF + ^\n => LF + */ + private void updateLineBreakState(char c) { + switch (lineBreakState) { + case INIT: + if (c == '\r') { + lineBreakState = SAW_CR; + } else if (c == '\n') { + lineBreakState = LINEBREAK_LF; + } + break; + case SAW_CR: + if (c == '\n') { + lineBreakState = LINEBREAK_CRLF; + } else { + lineBreakState = LINEBREAK_CR; + } + } + } + + private void writeLineBreakOrSpace() { + switch (lineBreakState) { + case SAW_CR: + // whitespace ended with CR, fall through + case LINEBREAK_CR: + buf[pos++] = '\r'; + break; + case LINEBREAK_CRLF: + buf[pos++] = '\r'; + // fall through + case LINEBREAK_LF: + buf[pos++] = '\n'; + break; + case AT_BEGINNING: + // ignore leading whitespace + break; + case INIT: + case SINGLE_LINE: + buf[pos++] = ' '; + } + lineBreakState = (singleLine) ? SINGLE_LINE : INIT; + } + + private void flushInternal() throws IOException { + out.write(buf, 0, pos); + pos = 0; + } + + @Override + public void flush() throws IOException { + flushInternal(); + out.flush(); + } + + @Override + public void close() throws IOException { + flushInternal(); + } + } + } http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1e27397d/freemarker-core/src/main/java/org/apache/freemarker/core/Configuration.java ---------------------------------------------------------------------- diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/Configuration.java b/freemarker-core/src/main/java/org/apache/freemarker/core/Configuration.java index cd3a524..3eea7b9 100644 --- a/freemarker-core/src/main/java/org/apache/freemarker/core/Configuration.java +++ b/freemarker-core/src/main/java/org/apache/freemarker/core/Configuration.java @@ -80,11 +80,6 @@ import org.apache.freemarker.core.templateresolver.impl.DefaultTemplateNameForma import org.apache.freemarker.core.templateresolver.impl.DefaultTemplateResolver; import org.apache.freemarker.core.templateresolver.impl.MruCacheStorage; import org.apache.freemarker.core.templateresolver.impl.SoftCacheStorage; -import org.apache.freemarker.core.util.CaptureOutput; -import org.apache.freemarker.core.util.HtmlEscape; -import org.apache.freemarker.core.util.NormalizeNewlines; -import org.apache.freemarker.core.util.StandardCompress; -import org.apache.freemarker.core.util.XmlEscape; import org.apache.freemarker.core.util._ClassUtil; import org.apache.freemarker.core.util._CollectionUtil; import org.apache.freemarker.core.util._NullArgumentException; @@ -2304,18 +2299,6 @@ public final class Configuration implements TopLevelConfiguration, CustomStateSc return Collections.emptyMap(); } - private static final Map<String, Object> DEFAULT_SHARED_VARIABLES; - static { - // TODO [FM3] Get rid of these - Map<String, Object> sharedVariables = new HashMap<>(); - sharedVariables.put("capture_output", new CaptureOutput()); - sharedVariables.put("compress", StandardCompress.INSTANCE); - sharedVariables.put("html_escape", new HtmlEscape()); - sharedVariables.put("normalize_newlines", new NormalizeNewlines()); - sharedVariables.put("xml_escape", new XmlEscape()); - DEFAULT_SHARED_VARIABLES = Collections.unmodifiableMap(sharedVariables); - } - /** * The shared variables that will be added to the built {@link Configuration} before the ones coming from * {@link #getSharedVariables()}. When overriding this method, always consider adding to the return value @@ -2324,7 +2307,7 @@ public final class Configuration implements TopLevelConfiguration, CustomStateSc * @return Immutable {@link Map}; not {@code null} */ protected Map<String, Object> getImpliedSharedVariables() { - return DEFAULT_SHARED_VARIABLES; + return Collections.emptyMap(); } /** http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1e27397d/freemarker-core/src/main/java/org/apache/freemarker/core/util/CaptureOutput.java ---------------------------------------------------------------------- diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/util/CaptureOutput.java b/freemarker-core/src/main/java/org/apache/freemarker/core/util/CaptureOutput.java deleted file mode 100644 index 93109e0..0000000 --- a/freemarker-core/src/main/java/org/apache/freemarker/core/util/CaptureOutput.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * 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 org.apache.freemarker.core.util; - -import java.io.IOException; -import java.io.Writer; -import java.util.Map; - -import org.apache.freemarker.core.Environment; -import org.apache.freemarker.core.model.TemplateModel; -import org.apache.freemarker.core.model.TemplateModelException; -import org.apache.freemarker.core.model.TemplateScalarModel; -import org.apache.freemarker.core.model.TemplateTransformModel; -import org.apache.freemarker.core.model.impl.SimpleScalar; - -/** - * A transform that captures the output of a block of FTL code and stores that in a variable. - * - * <p>As this transform is initially present in the shared variable set, you can always - * access it from the templates:</p> - * - * <pre> - * <@capture_output var="captured"> - * ... - * </@capture_output> - * </pre> - * - * <p>And later in the template you can use the captured output:</p> - * - * ${captured} - * - * <p>This transform requires one of three parameters: <code>var</code>, <code>local</code>, or <code>global</code>. - * Each of them specifies the name of the variable that stores the captured output, but the first creates a - * variable in a name-space (as <#assign>), the second creates a macro-local variable (as <#local>), - * and the last creates a global variable (as <#global>). - * </p> - * <p>In the case of an assignment within a namespace, there is an optional parameter - * <code>namespace</code> that indicates in which namespace to do the assignment. - * if this is omitted, the current namespace is used, and this will be, by far, the most - * common usage pattern.</p> - * - * @deprecated Use block-assignments instead, like <code><assign x>...</assign></code>. - */ -@Deprecated -public class CaptureOutput implements TemplateTransformModel { - - @Override - public Writer getWriter(final Writer out, final Map args) throws TemplateModelException { - String errmsg = "Must specify the name of the variable in " - + "which to capture the output with the 'var' or 'local' or 'global' parameter."; - if (args == null) throw new TemplateModelException(errmsg); - - boolean local = false, global = false; - final TemplateModel nsModel = (TemplateModel) args.get("namespace"); - Object varNameModel = args.get("var"); - if (varNameModel == null) { - varNameModel = args.get("local"); - if (varNameModel == null) { - varNameModel = args.get("global"); - global = true; - } else { - local = true; - } - if (varNameModel == null) { - throw new TemplateModelException(errmsg); - } - } - if (args.size() == 2) { - if (nsModel == null) { - throw new TemplateModelException("Second parameter can only be namespace"); - } - if (local) { - throw new TemplateModelException("Cannot specify namespace for a local assignment"); - } - if (global) { - throw new TemplateModelException("Cannot specify namespace for a global assignment"); - } - if (!(nsModel instanceof Environment.Namespace)) { - throw new TemplateModelException("namespace parameter does not specify a namespace. It is a " + nsModel.getClass().getName()); - } - } else if (args.size() != 1) throw new TemplateModelException( - "Bad parameters. Use only one of 'var' or 'local' or 'global' parameters."); - - if (!(varNameModel instanceof TemplateScalarModel)) { - throw new TemplateModelException("'var' or 'local' or 'global' parameter doesn't evaluate to a string"); - } - final String varName = ((TemplateScalarModel) varNameModel).getAsString(); - if (varName == null) { - throw new TemplateModelException("'var' or 'local' or 'global' parameter evaluates to null string"); - } - - final StringBuilder buf = new StringBuilder(); - final Environment env = Environment.getCurrentEnvironment(); - final boolean localVar = local; - final boolean globalVar = global; - - return new Writer() { - - @Override - public void write(char cbuf[], int off, int len) { - buf.append(cbuf, off, len); - } - - @Override - public void flush() throws IOException { - out.flush(); - } - - @Override - public void close() throws IOException { - SimpleScalar result = new SimpleScalar(buf.toString()); - try { - if (localVar) { - env.setLocalVariable(varName, result); - } else if (globalVar) { - env.setGlobalVariable(varName, result); - } else { - if (nsModel == null) { - env.setVariable(varName, result); - } else { - ((Environment.Namespace) nsModel).put(varName, result); - } - } - } catch (java.lang.IllegalStateException ise) { // if somebody uses 'local' outside a macro - throw new IOException("Could not set variable " + varName + ": " + ise.getMessage()); - } - } - }; - } -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1e27397d/freemarker-core/src/main/java/org/apache/freemarker/core/util/HtmlEscape.java ---------------------------------------------------------------------- diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/util/HtmlEscape.java b/freemarker-core/src/main/java/org/apache/freemarker/core/util/HtmlEscape.java deleted file mode 100644 index 3aa8d1d..0000000 --- a/freemarker-core/src/main/java/org/apache/freemarker/core/util/HtmlEscape.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * 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 org.apache.freemarker.core.util; - -import java.io.IOException; -import java.io.Writer; -import java.util.Map; - -import org.apache.freemarker.core.model.TemplateTransformModel; - -/** - * Performs an HTML escape of a given template fragment. Specifically, - * < > " and & are all turned into entities. - * - * <p>Usage:<br> - * From java:</p> - * <pre> - * SimpleHash root = new SimpleHash(); - * - * root.put( "htmlEscape", new org.apache.freemarker.core.util.HtmlEscape() ); - * - * ... - * </pre> - * - * <p>From your FreeMarker template:</p> - * <pre> - * - * The following is HTML-escaped: - * <transform htmlEscape> - * <p>This paragraph has all HTML special characters escaped.</p> - * </transform> - * - * ... - * </pre> - * - * @see org.apache.freemarker.core.util.XmlEscape - */ -// [FM3] Remove (or move to o.a.f.test) -public class HtmlEscape implements TemplateTransformModel { - - private static final char[] LT = "<".toCharArray(); - private static final char[] GT = ">".toCharArray(); - private static final char[] AMP = "&".toCharArray(); - private static final char[] QUOT = """.toCharArray(); - - @Override - public Writer getWriter(final Writer out, Map args) { - return new Writer() - { - @Override - public void write(int c) - throws IOException { - switch(c) - { - case '<': out.write(LT, 0, 4); break; - case '>': out.write(GT, 0, 4); break; - case '&': out.write(AMP, 0, 5); break; - case '"': out.write(QUOT, 0, 6); break; - default: out.write(c); - } - } - - @Override - public void write(char cbuf[], int off, int len) - throws IOException { - int lastoff = off; - int lastpos = off + len; - for (int i = off; i < lastpos; i++) { - switch (cbuf[i]) - { - case '<': out.write(cbuf, lastoff, i - lastoff); out.write(LT, 0, 4); lastoff = i + 1; break; - case '>': out.write(cbuf, lastoff, i - lastoff); out.write(GT, 0, 4); lastoff = i + 1; break; - case '&': out.write(cbuf, lastoff, i - lastoff); out.write(AMP, 0, 5); lastoff = i + 1; break; - case '"': out.write(cbuf, lastoff, i - lastoff); out.write(QUOT, 0, 6); lastoff = i + 1; break; - } - } - int remaining = lastpos - lastoff; - if (remaining > 0) { - out.write(cbuf, lastoff, remaining); - } - } - @Override - public void flush() throws IOException { - out.flush(); - } - - @Override - public void close() { - } - }; - } -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1e27397d/freemarker-core/src/main/java/org/apache/freemarker/core/util/NormalizeNewlines.java ---------------------------------------------------------------------- diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/util/NormalizeNewlines.java b/freemarker-core/src/main/java/org/apache/freemarker/core/util/NormalizeNewlines.java deleted file mode 100644 index f4bc5a6..0000000 --- a/freemarker-core/src/main/java/org/apache/freemarker/core/util/NormalizeNewlines.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * 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 org.apache.freemarker.core.util; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.PrintWriter; -import java.io.Reader; -import java.io.StringReader; -import java.io.StringWriter; -import java.io.Writer; -import java.util.Map; - -import org.apache.freemarker.core.model.TemplateTransformModel; - -/** - * <p>Transformer that supports FreeMarker legacy behavior: all newlines appearing - * within the transformed area will be transformed into the platform's default - * newline. Unlike the old behavior, however, newlines generated by the data - * model are also converted. Legacy behavior was to leave newlines in the - * data model unaltered.</p> - * - * <p>Usage:<br> - * From java:</p> - * <pre> - * SimpleHash root = new SimpleHash(); - * - * root.put( "normalizeNewlines", new org.apache.freemarker.core.util.NormalizeNewlines() ); - * - * ... - * </pre> - * - * <p>From your FreeMarker template:</p> - * <pre> - * <transform normalizeNewlines> - * <html> - * <head> - * ... - * <p>This template has all newlines normalized to the current platform's - * default.</p> - * ... - * </body> - * </html> - * </transform> - * </pre> - */ -// [FM3] Remove (or move to o.a.f.test) -public class NormalizeNewlines implements TemplateTransformModel { - - @Override - public Writer getWriter(final Writer out, - final Map args) { - final StringBuilder buf = new StringBuilder(); - return new Writer() { - @Override - public void write(char cbuf[], int off, int len) { - buf.append(cbuf, off, len); - } - - @Override - public void flush() throws IOException { - out.flush(); - } - - @Override - public void close() throws IOException { - StringReader sr = new StringReader(buf.toString()); - StringWriter sw = new StringWriter(); - transform(sr, sw); - out.write(sw.toString()); - } - }; - } - - /** - * Performs newline normalization on FreeMarker output. - * - * @param in the input to be transformed - * @param out the destination of the transformation - */ - public void transform(Reader in, Writer out) throws IOException { - BufferedReader br = (in instanceof BufferedReader) - ? (BufferedReader) in - : new BufferedReader(in); - PrintWriter pw = (out instanceof PrintWriter) - ? (PrintWriter) out - : new PrintWriter(out); - String line = br.readLine(); - if (line != null) { - if ( line.length() > 0 ) { - pw.println(line); - } - } - while ((line = br.readLine()) != null) { - pw.println(line); - } - } -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1e27397d/freemarker-core/src/main/java/org/apache/freemarker/core/util/StandardCompress.java ---------------------------------------------------------------------- diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/util/StandardCompress.java b/freemarker-core/src/main/java/org/apache/freemarker/core/util/StandardCompress.java deleted file mode 100644 index 0943622..0000000 --- a/freemarker-core/src/main/java/org/apache/freemarker/core/util/StandardCompress.java +++ /dev/null @@ -1,239 +0,0 @@ -/* - * 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 org.apache.freemarker.core.util; - -import java.io.IOException; -import java.io.Writer; -import java.util.Map; - -import org.apache.freemarker.core.model.TemplateBooleanModel; -import org.apache.freemarker.core.model.TemplateModelException; -import org.apache.freemarker.core.model.TemplateNumberModel; -import org.apache.freemarker.core.model.TemplateTransformModel; - -/** - * <p>A filter that compresses each sequence of consecutive whitespace - * to a single line break (if the sequence contains a line break) or a - * single space. In addition, leading and trailing whitespace is - * completely removed.</p> - * - * <p>Specify the transform parameter <code>single_line = true</code> - * to always compress to a single space instead of a line break.</p> - * - * <p>The default buffer size can be overridden by specifying a - * <code>buffer_size</code> transform parameter (in bytes).</p> - * - * <p><b>Note:</b> The compress tag is implemented using this filter</p> - * - * <p>Usage:<br> - * From java:</p> - * <pre> - * SimpleHash root = new SimpleHash(); - * - * root.put( "standardCompress", new org.apache.freemarker.core.util.StandardCompress() ); - * - * ... - * </pre> - * - * <p>From your FreeMarker template:</p> - * <pre> - * <transform standardCompress> - * <p>This paragraph will have - * extraneous - * - * whitespace removed.</p> - * </transform> - * </pre> - * - * <p>Output:</p> - * <pre> - * <p>This paragraph will have - * extraneous - * whitespace removed.</p> - * </pre> - */ -// [FM3] Remove (or move to o.a.f.test), instead extend #compress -public class StandardCompress implements TemplateTransformModel { - private static final String BUFFER_SIZE_KEY = "buffer_size"; - private static final String SINGLE_LINE_KEY = "single_line"; - private int defaultBufferSize; - - public static final StandardCompress INSTANCE = new StandardCompress(); - - public StandardCompress() { - this(2048); - } - - /** - * @param defaultBufferSize the default amount of characters to buffer - */ - public StandardCompress(int defaultBufferSize) { - this.defaultBufferSize = defaultBufferSize; - } - - @Override - public Writer getWriter(final Writer out, Map args) - throws TemplateModelException { - int bufferSize = defaultBufferSize; - boolean singleLine = false; - if (args != null) { - try { - TemplateNumberModel num = (TemplateNumberModel) args.get(BUFFER_SIZE_KEY); - if (num != null) - bufferSize = num.getAsNumber().intValue(); - } catch (ClassCastException e) { - throw new TemplateModelException("Expecting numerical argument to " + BUFFER_SIZE_KEY); - } - try { - TemplateBooleanModel flag = (TemplateBooleanModel) args.get(SINGLE_LINE_KEY); - if (flag != null) - singleLine = flag.getAsBoolean(); - } catch (ClassCastException e) { - throw new TemplateModelException("Expecting boolean argument to " + SINGLE_LINE_KEY); - } - } - return new StandardCompressWriter(out, bufferSize, singleLine); - } - - private static class StandardCompressWriter extends Writer { - private static final int MAX_EOL_LENGTH = 2; // CRLF is two bytes - - private static final int AT_BEGINNING = 0; - private static final int SINGLE_LINE = 1; - private static final int INIT = 2; - private static final int SAW_CR = 3; - private static final int LINEBREAK_CR = 4; - private static final int LINEBREAK_CRLF = 5; - private static final int LINEBREAK_LF = 6; - - private final Writer out; - private final char[] buf; - private final boolean singleLine; - - private int pos = 0; - private boolean inWhitespace = true; - private int lineBreakState = AT_BEGINNING; - - public StandardCompressWriter(Writer out, int bufSize, boolean singleLine) { - this.out = out; - this.singleLine = singleLine; - buf = new char[bufSize]; - } - - @Override - public void write(char[] cbuf, int off, int len) throws IOException { - for (; ; ) { - // Need to reserve space for the EOL potentially left in the state machine - int room = buf.length - pos - MAX_EOL_LENGTH; - if (room >= len) { - writeHelper(cbuf, off, len); - break; - } else if (room <= 0) { - flushInternal(); - } else { - writeHelper(cbuf, off, room); - flushInternal(); - off += room; - len -= room; - } - } - } - - private void writeHelper(char[] cbuf, int off, int len) { - for (int i = off, end = off + len; i < end; i++) { - char c = cbuf[i]; - if (Character.isWhitespace(c)) { - inWhitespace = true; - updateLineBreakState(c); - } else if (inWhitespace) { - inWhitespace = false; - writeLineBreakOrSpace(); - buf[pos++] = c; - } else { - buf[pos++] = c; - } - } - } - - /* - \r\n => CRLF - \r[^\n] => CR - \r$ => CR - [^\r]\n => LF - ^\n => LF - */ - private void updateLineBreakState(char c) { - switch (lineBreakState) { - case INIT: - if (c == '\r') { - lineBreakState = SAW_CR; - } else if (c == '\n') { - lineBreakState = LINEBREAK_LF; - } - break; - case SAW_CR: - if (c == '\n') { - lineBreakState = LINEBREAK_CRLF; - } else { - lineBreakState = LINEBREAK_CR; - } - } - } - - private void writeLineBreakOrSpace() { - switch (lineBreakState) { - case SAW_CR: - // whitespace ended with CR, fall through - case LINEBREAK_CR: - buf[pos++] = '\r'; - break; - case LINEBREAK_CRLF: - buf[pos++] = '\r'; - // fall through - case LINEBREAK_LF: - buf[pos++] = '\n'; - break; - case AT_BEGINNING: - // ignore leading whitespace - break; - case INIT: - case SINGLE_LINE: - buf[pos++] = ' '; - } - lineBreakState = (singleLine) ? SINGLE_LINE : INIT; - } - - private void flushInternal() throws IOException { - out.write(buf, 0, pos); - pos = 0; - } - - @Override - public void flush() throws IOException { - flushInternal(); - out.flush(); - } - - @Override - public void close() throws IOException { - flushInternal(); - } - } -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1e27397d/freemarker-core/src/main/java/org/apache/freemarker/core/util/XmlEscape.java ---------------------------------------------------------------------- diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/util/XmlEscape.java b/freemarker-core/src/main/java/org/apache/freemarker/core/util/XmlEscape.java deleted file mode 100644 index 43a2344..0000000 --- a/freemarker-core/src/main/java/org/apache/freemarker/core/util/XmlEscape.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * 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 org.apache.freemarker.core.util; - -import java.io.IOException; -import java.io.Writer; -import java.util.Map; - -import org.apache.freemarker.core.model.TemplateTransformModel; - -/** - * Performs an XML escaping of a given template fragment. Specifically, - * <tt><</tt> <tt>></tt> <tt>"</tt> <tt>'</tt> and <tt>&</tt> are all turned into entity references. - * - * <p>An instance of this transform is initially visible as shared - * variable called <tt>xml_escape</tt>.</p> - */ -// [FM3] Remove (or move to o.a.f.test) -public class XmlEscape implements TemplateTransformModel { - - private static final char[] LT = "<".toCharArray(); - private static final char[] GT = ">".toCharArray(); - private static final char[] AMP = "&".toCharArray(); - private static final char[] QUOT = """.toCharArray(); - private static final char[] APOS = "'".toCharArray(); - - @Override - public Writer getWriter(final Writer out, Map args) { - return new Writer() - { - @Override - public void write(int c) - throws IOException { - switch(c) - { - case '<': out.write(LT, 0, 4); break; - case '>': out.write(GT, 0, 4); break; - case '&': out.write(AMP, 0, 5); break; - case '"': out.write(QUOT, 0, 6); break; - case '\'': out.write(APOS, 0, 6); break; - default: out.write(c); - } - } - - @Override - public void write(char cbuf[], int off, int len) - throws IOException { - int lastoff = off; - int lastpos = off + len; - for (int i = off; i < lastpos; i++) { - switch (cbuf[i]) - { - case '<': out.write(cbuf, lastoff, i - lastoff); out.write(LT, 0, 4); lastoff = i + 1; break; - case '>': out.write(cbuf, lastoff, i - lastoff); out.write(GT, 0, 4); lastoff = i + 1; break; - case '&': out.write(cbuf, lastoff, i - lastoff); out.write(AMP, 0, 5); lastoff = i + 1; break; - case '"': out.write(cbuf, lastoff, i - lastoff); out.write(QUOT, 0, 6); lastoff = i + 1; break; - case '\'': out.write(cbuf, lastoff, i - lastoff); out.write(APOS, 0, 6); lastoff = i + 1; break; - } - } - int remaining = lastpos - lastoff; - if (remaining > 0) { - out.write(cbuf, lastoff, remaining); - } - } - @Override - public void flush() throws IOException { - out.flush(); - } - - @Override - public void close() { - } - }; - } -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1e27397d/freemarker-servlet/src/test/resources/org/apache/freemarker/servlet/jsp/webapps/basic/customTags1.ftl ---------------------------------------------------------------------- diff --git a/freemarker-servlet/src/test/resources/org/apache/freemarker/servlet/jsp/webapps/basic/customTags1.ftl b/freemarker-servlet/src/test/resources/org/apache/freemarker/servlet/jsp/webapps/basic/customTags1.ftl index 9334853..0f029b4 100644 --- a/freemarker-servlet/src/test/resources/org/apache/freemarker/servlet/jsp/webapps/basic/customTags1.ftl +++ b/freemarker-servlet/src/test/resources/org/apache/freemarker/servlet/jsp/webapps/basic/customTags1.ftl @@ -44,11 +44,11 @@ <!-- Test nested execution with intermittent non-JSP transform --> <@t.testtag repeatCount=2 throwException=false> Outer Blah -<@compress> +<#compress> <@t.testtag repeatCount=2 throwException=false> Inner Blah </@> -</@> +</#compress> </@> <@t.simpletag bodyLoopCount=2 name="simpletag1">
