http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3fd56062/freemarker-core/src/main/misc/identifierChars/src/main/freemarker/adhoc/IdentifierCharGenerator.java ---------------------------------------------------------------------- diff --git a/freemarker-core/src/main/misc/identifierChars/src/main/freemarker/adhoc/IdentifierCharGenerator.java b/freemarker-core/src/main/misc/identifierChars/src/main/freemarker/adhoc/IdentifierCharGenerator.java new file mode 100644 index 0000000..abb9e91 --- /dev/null +++ b/freemarker-core/src/main/misc/identifierChars/src/main/freemarker/adhoc/IdentifierCharGenerator.java @@ -0,0 +1,546 @@ +/* + * 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.adhoc; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Predicate; + +/** + * This was used for generating the JavaCC pattern and the Java method to check if a character + * can appear in an FTL identifier. + */ +public class IdentifierCharGenerator { + + public static void main(String[] args) { + new IdentifierCharGenerator().run(); + } + + private void run() { + List<Range> ranges = generateRanges(this::generatorPredicate); + List<Range> ranges2 = generateRanges(IdentifierCharGenerator::isFTLIdentifierStart); + + if (!ranges.equals(ranges2)) { + throw new AssertionError(); + } + + ranges.forEach(r -> p(toJavaCC(r) + ", ")); + + int firstSplit = 0; + while (firstSplit < ranges.size() && ranges.get(firstSplit).getEnd() < 0x80) { + firstSplit++; + } + printJava(ranges, firstSplit, ""); + } + + private List<Range> generateRanges(Predicate<Integer> charCodePredicate) { + List<Range> ranges = new ArrayList<Range>(); + + int startedRange = -1; + int i; + for (i = 0; i < 0x10000; i++) { + if (charCodePredicate.test(i)) { + if (startedRange == -1) { + startedRange = i; + } + } else { + if (startedRange != -1) { + ranges.add(new Range(startedRange, i)); + } + startedRange = -1; + } + } + if (startedRange != -1) { + ranges.add(new Range(startedRange, i)); + } + + return ranges; + } + + private static void printJava(List<Range> ranges, int splitUntil, String indentation) { + final int rangeCount = ranges.size(); + if (rangeCount > 2) { + Range secondHalfStart = ranges.get(splitUntil); + pp(indentation); + pp("if (c < "); pp(toJavaCharCode(secondHalfStart.getStart())); p(") {"); + { + List<Range> firstHalf = ranges.subList(0, splitUntil); + printJava(firstHalf, (firstHalf.size() + 1) / 2, indentation + " "); + } + pp(indentation); + pp("} else { // c >= "); p(toJavaCharCode(secondHalfStart.start)); + { + List<Range> secondHalf = ranges.subList(splitUntil, ranges.size()); + printJava(secondHalf, (secondHalf.size() + 1) / 2, indentation + " "); + } + pp(indentation); + p("}"); + } else if (rangeCount == 2) { + pp(indentation); + pp("return "); + printJavaCondition(ranges.get(0)); + pp(" || "); + printJavaCondition(ranges.get(1)); + p(";"); + } else if (rangeCount == 1) { + pp(indentation); + pp("return "); + printJavaCondition(ranges.get(0)); + p(";"); + } else { + throw new IllegalArgumentException("Empty range list"); + } + } + + private static void printJavaCondition(Range range) { + if (range.size() > 1) { + pp("c >= "); pp(toJavaCharCode(range.getStart())); + pp(" && c <= "); pp(toJavaCharCode(range.getEnd() - 1)); + } else { + pp("c == "); pp(toJavaCharCode(range.getStart())); + } + } + + private boolean generatorPredicate(int c) { + return isLegacyFTLIdStartChar(c) + || (Character.isJavaIdentifierPart(c) && Character.isLetterOrDigit(c) && !(c >= '0' && c <= '9')); + } + + private static boolean isLegacyFTLIdStartChar(int i) { + return i == '$' || i == '_' + || (i >= 'a' && i <= 'z') + || (i >= '@' && i <= 'Z') + || (i >= '\u00c0' && i <= '\u00d6') + || (i >= '\u00d8' && i <= '\u00f6') + || (i >= '\u00f8' && i <= '\u1fff') + || (i >= '\u3040' && i <= '\u318f') + || (i >= '\u3300' && i <= '\u337f') + || (i >= '\u3400' && i <= '\u3d2d') + || (i >= '\u4e00' && i <= '\u9fff') + || (i >= '\uf900' && i <= '\ufaff'); + } + + private static boolean isXML11NameChar(int i) { + return isXML11NameStartChar(i) + || i == '-' || i == '.' || (i >= '0' && i <= '9') || i == 0xB7 + || (i >= 0x0300 && i <= 0x036F) || (i >= 0x203F && i <= 0x2040); + } + + private static boolean isXML11NameStartChar(int i) { + return i == ':' || (i >= 'A' && i <= 'Z') || i == '_' || (i >= 'a' && i <= 'z') + || i >= 0xC0 && i <= 0xD6 + || i >= 0xD8 && i <= 0xF6 + || i >= 0xF8 && i <= 0x2FF + || i >= 0x370 && i <= 0x37D + || i >= 0x37F && i <= 0x1FFF + || i >= 0x200C && i <= 0x200D + || i >= 0x2070 && i <= 0x218F + || i >= 0x2C00 && i <= 0x2FEF + || i >= 0x3001 && i <= 0xD7FF + || i >= 0xF900 && i <= 0xFDCF + || i >= 0xFDF0 && i <= 0xFFFD; + } + + private static String toJavaCC(Range range) { + final int start = range.getStart(), end = range.getEnd(); + if (start == end) { + throw new IllegalArgumentException("Empty range"); + } + if (end - start == 1) { + return toJavaCCCharString(start); + } else { + return toJavaCCCharString(start) + " - " + toJavaCCCharString(end - 1); + } + } + + private static String toJavaCCCharString(int cc) { + StringBuilder sb = new StringBuilder(); + + sb.append('"'); + if (cc < 0x7F && cc >= 0x20) { + sb.append((char) cc); + } else { + sb.append("\\u"); + sb.append(toHexDigit((cc >> 12) & 0xF)); + sb.append(toHexDigit((cc >> 8) & 0xF)); + sb.append(toHexDigit((cc >> 4) & 0xF)); + sb.append(toHexDigit(cc & 0xF)); + } + sb.append('"'); + + return sb.toString(); + } + + private static String toJavaCharCode(int cc) { + StringBuilder sb = new StringBuilder(); + + if (cc < 0x7F && cc >= 0x20) { + sb.append('\''); + sb.append((char) cc); + sb.append('\''); + } else { + sb.append("0x"); + if (cc > 0xFF) { + sb.append(toHexDigit((cc >> 12) & 0xF)); + sb.append(toHexDigit((cc >> 8) & 0xF)); + } + sb.append(toHexDigit((cc >> 4) & 0xF)); + sb.append(toHexDigit(cc & 0xF)); + } + + return sb.toString(); + } + + private static char toHexDigit(int d) { + return (char) (d < 0xA ? d + '0' : d - 0xA + 'A'); + } + + private static class Range { + + final int start; + final int end; + + public Range(int start, int end) { + this.start = start; + this.end = end; + } + + public int getStart() { + return start; + } + + public int getEnd() { + return end; + } + + public int size() { + return end - start; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + end; + result = prime * result + start; + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + Range other = (Range) obj; + if (end != other.end) return false; + if (start != other.start) return false; + return true; + } + + } + + static void p(final Object o) { + System.out.println(o); + } + + static void pp(final Object o) { + System.out.print(o); + } + + static void p(final Object[] o) { + System.out.println("["); + for (final Object i : o) { + System.out.println(" " + i); + } + System.out.println("]"); + } + + static void p() { + System.out.println(); + } + + // This is a copy of the generated code (somewhat modified), so that we can compare it with the generatorPredicate. + public static boolean isFTLIdentifierStart(int cc) { + char c = (char) cc; + + if (c < 0xAA) { + if (c >= 'a' && c <= 'z' || c >= '@' && c <= 'Z') { + return true; + } else { + return c == '$' || c == '_'; + } + } else { // c >= 0xAA + if (c < 0xA7F8) { + if (c < 0x2D6F) { + if (c < 0x2128) { + if (c < 0x2090) { + if (c < 0xD8) { + if (c < 0xBA) { + return c == 0xAA || c == 0xB5; + } else { // c >= 0xBA + return c == 0xBA || c >= 0xC0 && c <= 0xD6; + } + } else { // c >= 0xD8 + if (c < 0x2071) { + return c >= 0xD8 && c <= 0xF6 || c >= 0xF8 && c <= 0x1FFF; + } else { // c >= 0x2071 + return c == 0x2071 || c == 0x207F; + } + } + } else { // c >= 0x2090 + if (c < 0x2115) { + if (c < 0x2107) { + return c >= 0x2090 && c <= 0x209C || c == 0x2102; + } else { // c >= 0x2107 + return c == 0x2107 || c >= 0x210A && c <= 0x2113; + } + } else { // c >= 0x2115 + if (c < 0x2124) { + return c == 0x2115 || c >= 0x2119 && c <= 0x211D; + } else { // c >= 0x2124 + return c == 0x2124 || c == 0x2126; + } + } + } + } else { // c >= 0x2128 + if (c < 0x2C30) { + if (c < 0x2145) { + if (c < 0x212F) { + return c == 0x2128 || c >= 0x212A && c <= 0x212D; + } else { // c >= 0x212F + return c >= 0x212F && c <= 0x2139 || c >= 0x213C && c <= 0x213F; + } + } else { // c >= 0x2145 + if (c < 0x2183) { + return c >= 0x2145 && c <= 0x2149 || c == 0x214E; + } else { // c >= 0x2183 + return c >= 0x2183 && c <= 0x2184 || c >= 0x2C00 && c <= 0x2C2E; + } + } + } else { // c >= 0x2C30 + if (c < 0x2D00) { + if (c < 0x2CEB) { + return c >= 0x2C30 && c <= 0x2C5E || c >= 0x2C60 && c <= 0x2CE4; + } else { // c >= 0x2CEB + return c >= 0x2CEB && c <= 0x2CEE || c >= 0x2CF2 && c <= 0x2CF3; + } + } else { // c >= 0x2D00 + if (c < 0x2D2D) { + return c >= 0x2D00 && c <= 0x2D25 || c == 0x2D27; + } else { // c >= 0x2D2D + return c == 0x2D2D || c >= 0x2D30 && c <= 0x2D67; + } + } + } + } + } else { // c >= 0x2D6F + if (c < 0x31F0) { + if (c < 0x2DD0) { + if (c < 0x2DB0) { + if (c < 0x2DA0) { + return c == 0x2D6F || c >= 0x2D80 && c <= 0x2D96; + } else { // c >= 0x2DA0 + return c >= 0x2DA0 && c <= 0x2DA6 || c >= 0x2DA8 && c <= 0x2DAE; + } + } else { // c >= 0x2DB0 + if (c < 0x2DC0) { + return c >= 0x2DB0 && c <= 0x2DB6 || c >= 0x2DB8 && c <= 0x2DBE; + } else { // c >= 0x2DC0 + return c >= 0x2DC0 && c <= 0x2DC6 || c >= 0x2DC8 && c <= 0x2DCE; + } + } + } else { // c >= 0x2DD0 + if (c < 0x3031) { + if (c < 0x2E2F) { + return c >= 0x2DD0 && c <= 0x2DD6 || c >= 0x2DD8 && c <= 0x2DDE; + } else { // c >= 0x2E2F + return c == 0x2E2F || c >= 0x3005 && c <= 0x3006; + } + } else { // c >= 0x3031 + if (c < 0x3040) { + return c >= 0x3031 && c <= 0x3035 || c >= 0x303B && c <= 0x303C; + } else { // c >= 0x3040 + return c >= 0x3040 && c <= 0x318F || c >= 0x31A0 && c <= 0x31BA; + } + } + } + } else { // c >= 0x31F0 + if (c < 0xA67F) { + if (c < 0xA4D0) { + if (c < 0x3400) { + return c >= 0x31F0 && c <= 0x31FF || c >= 0x3300 && c <= 0x337F; + } else { // c >= 0x3400 + return c >= 0x3400 && c <= 0x4DB5 || c >= 0x4E00 && c <= 0xA48C; + } + } else { // c >= 0xA4D0 + if (c < 0xA610) { + return c >= 0xA4D0 && c <= 0xA4FD || c >= 0xA500 && c <= 0xA60C; + } else { // c >= 0xA610 + return c >= 0xA610 && c <= 0xA62B || c >= 0xA640 && c <= 0xA66E; + } + } + } else { // c >= 0xA67F + if (c < 0xA78B) { + if (c < 0xA717) { + return c >= 0xA67F && c <= 0xA697 || c >= 0xA6A0 && c <= 0xA6E5; + } else { // c >= 0xA717 + return c >= 0xA717 && c <= 0xA71F || c >= 0xA722 && c <= 0xA788; + } + } else { // c >= 0xA78B + if (c < 0xA7A0) { + return c >= 0xA78B && c <= 0xA78E || c >= 0xA790 && c <= 0xA793; + } else { // c >= 0xA7A0 + return c >= 0xA7A0 && c <= 0xA7AA; + } + } + } + } + } + } else { // c >= 0xA7F8 + if (c < 0xAB20) { + if (c < 0xAA44) { + if (c < 0xA8FB) { + if (c < 0xA840) { + if (c < 0xA807) { + return c >= 0xA7F8 && c <= 0xA801 || c >= 0xA803 && c <= 0xA805; + } else { // c >= 0xA807 + return c >= 0xA807 && c <= 0xA80A || c >= 0xA80C && c <= 0xA822; + } + } else { // c >= 0xA840 + if (c < 0xA8D0) { + return c >= 0xA840 && c <= 0xA873 || c >= 0xA882 && c <= 0xA8B3; + } else { // c >= 0xA8D0 + return c >= 0xA8D0 && c <= 0xA8D9 || c >= 0xA8F2 && c <= 0xA8F7; + } + } + } else { // c >= 0xA8FB + if (c < 0xA984) { + if (c < 0xA930) { + return c == 0xA8FB || c >= 0xA900 && c <= 0xA925; + } else { // c >= 0xA930 + return c >= 0xA930 && c <= 0xA946 || c >= 0xA960 && c <= 0xA97C; + } + } else { // c >= 0xA984 + if (c < 0xAA00) { + return c >= 0xA984 && c <= 0xA9B2 || c >= 0xA9CF && c <= 0xA9D9; + } else { // c >= 0xAA00 + return c >= 0xAA00 && c <= 0xAA28 || c >= 0xAA40 && c <= 0xAA42; + } + } + } + } else { // c >= 0xAA44 + if (c < 0xAAC0) { + if (c < 0xAA80) { + if (c < 0xAA60) { + return c >= 0xAA44 && c <= 0xAA4B || c >= 0xAA50 && c <= 0xAA59; + } else { // c >= 0xAA60 + return c >= 0xAA60 && c <= 0xAA76 || c == 0xAA7A; + } + } else { // c >= 0xAA80 + if (c < 0xAAB5) { + return c >= 0xAA80 && c <= 0xAAAF || c == 0xAAB1; + } else { // c >= 0xAAB5 + return c >= 0xAAB5 && c <= 0xAAB6 || c >= 0xAAB9 && c <= 0xAABD; + } + } + } else { // c >= 0xAAC0 + if (c < 0xAAF2) { + if (c < 0xAADB) { + return c == 0xAAC0 || c == 0xAAC2; + } else { // c >= 0xAADB + return c >= 0xAADB && c <= 0xAADD || c >= 0xAAE0 && c <= 0xAAEA; + } + } else { // c >= 0xAAF2 + if (c < 0xAB09) { + return c >= 0xAAF2 && c <= 0xAAF4 || c >= 0xAB01 && c <= 0xAB06; + } else { // c >= 0xAB09 + return c >= 0xAB09 && c <= 0xAB0E || c >= 0xAB11 && c <= 0xAB16; + } + } + } + } + } else { // c >= 0xAB20 + if (c < 0xFB46) { + if (c < 0xFB13) { + if (c < 0xAC00) { + if (c < 0xABC0) { + return c >= 0xAB20 && c <= 0xAB26 || c >= 0xAB28 && c <= 0xAB2E; + } else { // c >= 0xABC0 + return c >= 0xABC0 && c <= 0xABE2 || c >= 0xABF0 && c <= 0xABF9; + } + } else { // c >= 0xAC00 + if (c < 0xD7CB) { + return c >= 0xAC00 && c <= 0xD7A3 || c >= 0xD7B0 && c <= 0xD7C6; + } else { // c >= 0xD7CB + return c >= 0xD7CB && c <= 0xD7FB || c >= 0xF900 && c <= 0xFB06; + } + } + } else { // c >= 0xFB13 + if (c < 0xFB38) { + if (c < 0xFB1F) { + return c >= 0xFB13 && c <= 0xFB17 || c == 0xFB1D; + } else { // c >= 0xFB1F + return c >= 0xFB1F && c <= 0xFB28 || c >= 0xFB2A && c <= 0xFB36; + } + } else { // c >= 0xFB38 + if (c < 0xFB40) { + return c >= 0xFB38 && c <= 0xFB3C || c == 0xFB3E; + } else { // c >= 0xFB40 + return c >= 0xFB40 && c <= 0xFB41 || c >= 0xFB43 && c <= 0xFB44; + } + } + } + } else { // c >= 0xFB46 + if (c < 0xFF21) { + if (c < 0xFDF0) { + if (c < 0xFD50) { + return c >= 0xFB46 && c <= 0xFBB1 || c >= 0xFBD3 && c <= 0xFD3D; + } else { // c >= 0xFD50 + return c >= 0xFD50 && c <= 0xFD8F || c >= 0xFD92 && c <= 0xFDC7; + } + } else { // c >= 0xFDF0 + if (c < 0xFE76) { + return c >= 0xFDF0 && c <= 0xFDFB || c >= 0xFE70 && c <= 0xFE74; + } else { // c >= 0xFE76 + return c >= 0xFE76 && c <= 0xFEFC || c >= 0xFF10 && c <= 0xFF19; + } + } + } else { // c >= 0xFF21 + if (c < 0xFFCA) { + if (c < 0xFF66) { + return c >= 0xFF21 && c <= 0xFF3A || c >= 0xFF41 && c <= 0xFF5A; + } else { // c >= 0xFF66 + return c >= 0xFF66 && c <= 0xFFBE || c >= 0xFFC2 && c <= 0xFFC7; + } + } else { // c >= 0xFFCA + if (c < 0xFFDA) { + return c >= 0xFFCA && c <= 0xFFCF || c >= 0xFFD2 && c <= 0xFFD7; + } else { // c >= 0xFFDA + return c >= 0xFFDA && c <= 0xFFDC; + } + } + } + } + } + } + } + } + +}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3fd56062/freemarker-core/src/main/misc/overloadedNumberRules/README.txt ---------------------------------------------------------------------- diff --git a/freemarker-core/src/main/misc/overloadedNumberRules/README.txt b/freemarker-core/src/main/misc/overloadedNumberRules/README.txt new file mode 100644 index 0000000..ec6eebe --- /dev/null +++ b/freemarker-core/src/main/misc/overloadedNumberRules/README.txt @@ -0,0 +1,34 @@ +/* + * 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. + */ + +This FMPP project is used for generating the source code of some +`OverloadedNumberUtil` methods based on the content of `prices.ods` +(LibreOffice spreadsheet). + +Usage: +1. Edit `prices.ods` +3. If you have introduced new types in it, also update `toCsFreqSorted` and + `toCsCostBoosts` and `toCsContCosts` in `config.fmpp`. +4. Save it into `prices.csv` (use comma as field separator) +5. Run FMPP from this directory. It will generate + `<freemarkerProjectDir>/build/getArgumentConversionPrice.java`. +6. Copy-pase its content into `OverloadedNumberUtil.java`. +7. Ensure that the value of OverloadedNumberUtil.BIG_MANTISSA_LOSS_PRICE + still matches the value coming from the ODS and the cellValue + multipier coming from generator.ftl. \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3fd56062/freemarker-core/src/main/misc/overloadedNumberRules/config.fmpp ---------------------------------------------------------------------- diff --git a/freemarker-core/src/main/misc/overloadedNumberRules/config.fmpp b/freemarker-core/src/main/misc/overloadedNumberRules/config.fmpp new file mode 100644 index 0000000..cf32e92 --- /dev/null +++ b/freemarker-core/src/main/misc/overloadedNumberRules/config.fmpp @@ -0,0 +1,73 @@ +# 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. + +sources: generator.ftl +outputFile: ../../../../build/overloadedNumberRules.java +data: { + t: csv(prices.csv, { separator: ',' }) + + # Conversion target types sorted by decreasing probablity of occurence + toCsFreqSorted: [ Integer, Long, Double, Float, Byte, Short, BigDecimal, BigInteger ] + + # Conversion target types associated to conversion price boost. The prices from the spreadsheet + # will be multipied by 10000 and the boost will be added to it. Thus, if the price of two possible + # targets are the same according the spreadsheet (and only then!), the choice will depend on + # this boost. + # The more specific the (the smaller) type is, the lower the boost should be. This is improtant, + # because this number is also used for comparing the specificity of numerical types where + # there's no argument type available. + # Note where the price from the spreadsheet is 0 or "-" or "N/A", the boost is not used. + toCsCostBoosts: { + 'Byte': 1, 'Short': 2, 'Integer': 3, 'Long': 4, 'BigInteger': 5, + 'Float': 6, 'Double': 7, + 'BigDecimal': 8 + } + + # Conversion source types sorted by decreasing probablity of occurence + fromCsFreqSorted: [ + Integer, + IntegerBigDecimal, + BigDecimal, + Long, + Double, + Float, + Byte, + BigInteger, + LongOrInteger + DoubleOrFloat, + DoubleOrIntegerOrFloat, + DoubleOrInteger, + DoubleOrLong, + IntegerOrByte, + DoubleOrByte, + LongOrByte + Short, + LongOrShort + ShortOrByte + FloatOrInteger, + FloatOrByte, + FloatOrShort, + BigIntegerOrInteger, + BigIntegerOrLong, + BigIntegerOrDouble, + BigIntegerOrFloat, + BigIntegerOrByte, + IntegerOrShort, + DoubleOrShort, + BigIntegerOrShort, + ] +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3fd56062/freemarker-core/src/main/misc/overloadedNumberRules/generator.ftl ---------------------------------------------------------------------- diff --git a/freemarker-core/src/main/misc/overloadedNumberRules/generator.ftl b/freemarker-core/src/main/misc/overloadedNumberRules/generator.ftl new file mode 100644 index 0000000..2a2bfde --- /dev/null +++ b/freemarker-core/src/main/misc/overloadedNumberRules/generator.ftl @@ -0,0 +1,80 @@ +<#-- + 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. +--> + static int getArgumentConversionPrice(Class fromC, Class toC) { + // DO NOT EDIT, generated code! + // See: src\main\misc\overloadedNumberRules\README.txt + if (toC == fromC) { + return 0; + <#list toCsFreqSorted as toC><#t> + } else if (toC == ${toC}.class) { + <#assign firstFromC = true> + <#list fromCsFreqSorted as fromC> + <#if toC != fromC> + <#assign row = []> + <#list t as i> + <#if i[0] == fromC> + <#assign row = i> + <#break> + </#if> + </#list> + <#if !row?has_content><#stop "Not found: " + fromC></#if> + <#if !firstFromC>else </#if>if (fromC == ${fromC}.class) return ${toPrice(row[toC], toCsCostBoosts[toC])}; + <#assign firstFromC = false> + </#if> + </#list> + else return Integer.MAX_VALUE; + </#list> + } else { + // Unknown toC; we don't know how to convert to it: + return Integer.MAX_VALUE; + } + } + + static int compareNumberTypeSpecificity(Class c1, Class c2) { + // DO NOT EDIT, generated code! + // See: src\main\misc\overloadedNumberRules\README.txt + c1 = ClassUtil.primitiveClassToBoxingClass(c1); + c2 = ClassUtil.primitiveClassToBoxingClass(c2); + + if (c1 == c2) return 0; + + <#list toCsFreqSorted as c1><#t> + if (c1 == ${c1}.class) { + <#list toCsFreqSorted as c2><#if c1 != c2><#t> + if (c2 == ${c2}.class) return ${toCsCostBoosts[c2]} - ${toCsCostBoosts[c1]}; + </#if></#list> + return 0; + } + </#list> + return 0; + } + +<#function toPrice cellValue, boost> + <#if cellValue?starts_with("BC ")> + <#local cellValue = cellValue[3..]> + <#elseif cellValue == '-' || cellValue == 'N/A'> + <#return 'Integer.MAX_VALUE'> + </#if> + <#local cellValue = cellValue?number> + <#if cellValue != 0> + <#return cellValue * 10000 + boost> + <#else> + <#return 0> + </#if> +</#function> http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3fd56062/freemarker-core/src/main/misc/overloadedNumberRules/prices.ods ---------------------------------------------------------------------- diff --git a/freemarker-core/src/main/misc/overloadedNumberRules/prices.ods b/freemarker-core/src/main/misc/overloadedNumberRules/prices.ods new file mode 100644 index 0000000..4beabcf Binary files /dev/null and b/freemarker-core/src/main/misc/overloadedNumberRules/prices.ods differ http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3fd56062/freemarker-core/src/main/resources/META-INF/DISCLAIMER ---------------------------------------------------------------------- diff --git a/freemarker-core/src/main/resources/META-INF/DISCLAIMER b/freemarker-core/src/main/resources/META-INF/DISCLAIMER new file mode 100644 index 0000000..569ba05 --- /dev/null +++ b/freemarker-core/src/main/resources/META-INF/DISCLAIMER @@ -0,0 +1,8 @@ +Apache FreeMarker is an effort undergoing incubation at The Apache Software +Foundation (ASF), sponsored by the Apache Incubator. Incubation is required of +all newly accepted projects until a further review indicates that the +infrastructure, communications, and decision making process have stabilized in +a manner consistent with other successful ASF projects. While incubation +status is not necessarily a reflection of the completeness or stability of the +code, it does indicate that the project has yet to be fully endorsed by the +ASF. \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3fd56062/freemarker-core/src/main/resources/META-INF/LICENSE ---------------------------------------------------------------------- diff --git a/freemarker-core/src/main/resources/META-INF/LICENSE b/freemarker-core/src/main/resources/META-INF/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/freemarker-core/src/main/resources/META-INF/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed 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. http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3fd56062/freemarker-core/src/main/resources/org/apache/freemarker/core/model/impl/unsafeMethods.properties ---------------------------------------------------------------------- diff --git a/freemarker-core/src/main/resources/org/apache/freemarker/core/model/impl/unsafeMethods.properties b/freemarker-core/src/main/resources/org/apache/freemarker/core/model/impl/unsafeMethods.properties new file mode 100644 index 0000000..05c1981 --- /dev/null +++ b/freemarker-core/src/main/resources/org/apache/freemarker/core/model/impl/unsafeMethods.properties @@ -0,0 +1,98 @@ +# 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. + +java.lang.Object.wait() +java.lang.Object.wait(long) +java.lang.Object.wait(long,int) +java.lang.Object.notify() +java.lang.Object.notifyAll() + +java.lang.Class.getClassLoader() +java.lang.Class.newInstance() +java.lang.Class.forName(java.lang.String) +java.lang.Class.forName(java.lang.String,boolean,java.lang.ClassLoader) + +java.lang.reflect.Constructor.newInstance([Ljava.lang.Object;) + +java.lang.reflect.Method.invoke(java.lang.Object,[Ljava.lang.Object;) + +java.lang.reflect.Field.set(java.lang.Object,java.lang.Object) +java.lang.reflect.Field.setBoolean(java.lang.Object,boolean) +java.lang.reflect.Field.setByte(java.lang.Object,byte) +java.lang.reflect.Field.setChar(java.lang.Object,char) +java.lang.reflect.Field.setDouble(java.lang.Object,double) +java.lang.reflect.Field.setFloat(java.lang.Object,float) +java.lang.reflect.Field.setInt(java.lang.Object,int) +java.lang.reflect.Field.setLong(java.lang.Object,long) +java.lang.reflect.Field.setShort(java.lang.Object,short) + +java.lang.reflect.AccessibleObject.setAccessible([Ljava.lang.reflect.AccessibleObject;,boolean) +java.lang.reflect.AccessibleObject.setAccessible(boolean) + +java.lang.Thread.destroy() +java.lang.Thread.getContextClassLoader() +java.lang.Thread.interrupt() +java.lang.Thread.join() +java.lang.Thread.join(long) +java.lang.Thread.join(long,int) +java.lang.Thread.resume() +java.lang.Thread.run() +java.lang.Thread.setContextClassLoader(java.lang.ClassLoader) +java.lang.Thread.setDaemon(boolean) +java.lang.Thread.setName(java.lang.String) +java.lang.Thread.setPriority(int) +java.lang.Thread.sleep(long) +java.lang.Thread.sleep(long,int) +java.lang.Thread.start() +java.lang.Thread.stop() +java.lang.Thread.stop(java.lang.Throwable) +java.lang.Thread.suspend() + +java.lang.ThreadGroup.allowThreadSuspension(boolean) +java.lang.ThreadGroup.destroy() +java.lang.ThreadGroup.interrupt() +java.lang.ThreadGroup.resume() +java.lang.ThreadGroup.setDaemon(boolean) +java.lang.ThreadGroup.setMaxPriority(int) +java.lang.ThreadGroup.stop() +java.lang.Thread.suspend() + +java.lang.Runtime.addShutdownHook(java.lang.Thread) +java.lang.Runtime.exec(java.lang.String) +java.lang.Runtime.exec([Ljava.lang.String;) +java.lang.Runtime.exec([Ljava.lang.String;,[Ljava.lang.String;) +java.lang.Runtime.exec([Ljava.lang.String;,[Ljava.lang.String;,java.io.File) +java.lang.Runtime.exec(java.lang.String,[Ljava.lang.String;) +java.lang.Runtime.exec(java.lang.String,[Ljava.lang.String;,java.io.File) +java.lang.Runtime.exit(int) +java.lang.Runtime.halt(int) +java.lang.Runtime.load(java.lang.String) +java.lang.Runtime.loadLibrary(java.lang.String) +java.lang.Runtime.removeShutdownHook(java.lang.Thread) +java.lang.Runtime.traceInstructions(boolean) +java.lang.Runtime.traceMethodCalls(boolean) + +java.lang.System.exit(int) +java.lang.System.load(java.lang.String) +java.lang.System.loadLibrary(java.lang.String) +java.lang.System.runFinalizersOnExit(boolean) +java.lang.System.setErr(java.io.PrintStream) +java.lang.System.setIn(java.io.InputStream) +java.lang.System.setOut(java.io.PrintStream) +java.lang.System.setProperties(java.util.Properties) +java.lang.System.setProperty(java.lang.String,java.lang.String) +java.lang.System.setSecurityManager(java.lang.SecurityManager) http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3fd56062/freemarker-core/src/main/resources/org/apache/freemarker/core/version.properties ---------------------------------------------------------------------- diff --git a/freemarker-core/src/main/resources/org/apache/freemarker/core/version.properties b/freemarker-core/src/main/resources/org/apache/freemarker/core/version.properties new file mode 100644 index 0000000..ff1f446 --- /dev/null +++ b/freemarker-core/src/main/resources/org/apache/freemarker/core/version.properties @@ -0,0 +1,100 @@ +# 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. + +# Version info for the builds. + +# Version number +# -------------- +# +# The version number format is (since FreeMarker 3): +# +# Version ::= major '.' minor '.' micro ('-' Qualifier)? +# Qualifier :: = NightlyQualifier +# | +# ( ('pre'|'rc') twoDigitPositiveInteger ('-' NightlyQualifier)? ) +# '-incubating'? +# NightlyQualifier :: = 'nightly' +# +# This format is compatible both with Maven and JSR 277, and it must +# remain so. Stable versions must not have a qualifier. +# Note that qualifiers are compared with String.compareTo, +# thus "nightly" < "pre" < "rc", etc. +# +# Examples: +# Version number Means +# 3.0.0 3.0.0 stable release +# 3.3.12 3.3.12 stable release +# 3.3.13-nightly +# Modified version after 3.3.12, which will +# become to 3.3.13 one day. +# 3.4.0-pre03 The 3rd preview of version 3.4.0 +# 3.4.0-pre04-nightly +# Unreleased nightly version of the yet unfinished +# 3.4.0-pre04. +# 3.4.0-rc01 1st release candidate of 3.4.0 +# +# Backward-compatibility policy (since FreeMarker 2.3.20): +# - When only the micro version number is increased, full backward +# compatibility is expected (ignoring extreme cases where the user +# code or template breaks if an exception is *not* thrown anymore +# as the FreeMarker bug causing it was fixed). +# - When the minor version number is increased, some minor backward +# compatibility violations are allowed. Most dependent code should +# continue working without modification or recompilation. +# - When the major version number is increased, major backward +# compatibility violations are allowed, but still should be avoided. +# During Apache Incubation, "-incubating" is added to this string. +version=3.0.0-nightly-incubating +# This exists as oss.sonatype only allows SNAPSHOT and final releases, +# so instead 2.3.21-rc01 and such we have to use 2.3.21-SNAPSHOT there. +# For final releases it's the same as "version". +# During Apache Incubation, "-incubating" is added to this string. +mavenVersion=3.0.0-SNAPSHOT-incubating + +# Version string that conforms to OSGi +# ------------------------------------ +# +# This is different from the plain version string: +# - "." is used instead of a "-" before the qualifier. +# - The stable releases must use "stable" qualifier. +# Examples: +# 2.4.0.stable +# 2.4.0.rc01 +# 2.4.0.pre01 +# 2.4.0.nightly_@timestampInVersion@ +# During Apache Incubation, "-incubating" is added to this string. +versionForOSGi=3.0.0.nightly_@timestampInVersion@-incubating + +# Version string that conforms to legacy MF +# ----------------------------------------- +# +# Examples: +# version -> versionForMf +# 2.2.5 -> 2.2.5 +# 2.3.0 -> 2.3.0 +# 2.3.0.pre13 -> 2.2.98.13 +# 2.3.0.pre13-nightly -> 2.2.98.13.97 +# 2.3.0.rc1 -> 2.2.99.1 +# 2.3.0.nightly -> 2.2.97 +# 3.0.0.pre2 -> 2.98.2 +# +# "97 denotes "nightly", 98 denotes "pre", 99 denotes "rc" build. +# In general, for the nightly/preview/rc Y of version 2.X, the versionForMf is +# 2.X-1.(99|98).Y. Note the X-1. +versionForMf=2.99.97 + +isGAECompliant=true http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3fd56062/freemarker-core/src/manual/en_US/FM3-CHANGE-LOG.txt ---------------------------------------------------------------------- diff --git a/freemarker-core/src/manual/en_US/FM3-CHANGE-LOG.txt b/freemarker-core/src/manual/en_US/FM3-CHANGE-LOG.txt new file mode 100644 index 0000000..e5a898e --- /dev/null +++ b/freemarker-core/src/manual/en_US/FM3-CHANGE-LOG.txt @@ -0,0 +1,226 @@ +/* + * 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. + */ + +Because the Manual won't be updated for a good while, I will lead +the FreeMarer 3 changelog here: + +- Increased version number to 3.0.0 (nightly aka. SNAPSHOT) +- Removed legacy extensions: rhyno, jython, xml (not to be confused with dom), jdom, ant. +- Removed JSP 2.0 support (2.1 and Servlet 2.5 is the minimum for now, but maybe it will be 2.2 and Servlet 3.0 later). +- Removed freemarker.ext.log, our log abstraction layer from the old times when there was no clear winner on this field. + Added org.slf4j:slf4j-api as required dependency instead. +- Removed all classes with "main" methods that were part of freemarker.jar. Such tools should be separate artifacts, + not part of the library, and they are often classified as CWE-489 "Leftover Debug Code". The removed classes are: + freemarker.core.CommandLine, freemarker.ext.dom.Transform, freemarker.template.utility.ToCanonical +- Removed classic_compatible (classicCompatible) setting, which was used to emulate some of the FreeMarker 1.x behavior +- Removed utility TemplateModel-s that can very easily mean a security problem: freemarker.template.utility.Execute and + freemarker.template.utility.ObjectConstructor +- Removed TemplateClassResolver.SAFER_RESOLVER, because the classes it has blocked were removed from FreeMarker, so it's + the same as UNRESTRICTED_RESOLVER +- Removed the strict_syntax setting, and so also the support for FTL tags without #. This was a FreeMarker 1.x + compatibility option. +- Removed deprecated FMParser contstructors. +- Minimum Java version increased to 7, but without try-with-resource as that's unavailable before Android 4.4 KitKat. +- Totally redesigned TemplateLoader interface. The FM2 TemplateLoader can't be adapted (wrapped) to it, but usually + it's fairly trivial to "rearrange" an old custom TemplateLoader for the new interface. The new TemplateLoader comes + with several advantages, such as: + - It can work more efficiently with sophisticated storage mechanisms like a database, as it's now possible to pack + together the existence check, the last modification change check, and reading operations into less storage level + operations (like you can do all of them with a single SQL statement). + - The new TemplateLoader allows returning the template content either as an InputStream or as a Reader. Almost all + TemplateLoader-s should return InputStream, and FreeMarker takes care of charset issues transparently (as a result, + TemplateLoader-s don't have to support re-reading a template anymore, as we solve charset detection misses in + memory). TemplateLoader-s that are inherently backed by text (String-s), such as templates stored in a varchar or + CLOB column, should return a Reader. Note that templates created from a Reader will have template.getEncoding() + null (logically, as no charset was involved), which was impossible in FreeMarker 2. + - The change detection of the template doesn't have to rely on a millisecond resolution timestamp anymore; you can + use what's most appropriate for the storage mechanism, such as a cryptographic hash or a revision number. + - Template lookups (where you try multiple names until you find the best template) can now be transactional and/or + atomic if the backing storage mechanism supports that, by utilizing the TemplateLoaderSession interface. + - TemplateLoader can now return template-level settings like the output format (MIME type basically) of the loaded + template, in case the backing storage stores such extra information. This mechanism can be used together with + the TemplateConfiguration mechanism (already familiar from FreeMarker 2), and overrides the individual settings + coming from there. +- Template constructors won't close the Reader passed in as agrument anymore (because a Reader should be closed + by who has created it). This avoids some surprises from the past, such as the unablility to reset a Reader to a mark + after parsing. If you call those constructors, be sure that you close the Reader yourself. (Obviously, it doesn't + mater for StringReader-s.) +- Renamed top level java package from freemarker to org.apache.freemarker +- Reorganized package structure. We will have a freemarker-core and a freemarker-servlet module later, so + we got org.apache.freemarker.core (has nothing to do with the old freemarker.core) and + org.apache.freemarker.servlet (this replaced freemarker.ext.servlet and freemarker.ext.jsp). + Directly inside org.apache.freemarker.core we have most of the classes that were in + freemarker.template and freemarker.core, however, model related classes (and object wrappers) + were moved to org.apache.freemarker.core.model, and template loading and caching related classes + to org.apache.freemarker.core.templateresolver (because later we will have a class called + TemplateResolver, which is the central class of loading and caching and template name rules). + OutputFormat realted classes were moved to org.apache.freemarker.core.outputformat. + ValueFormat related classes were moved to org.apache.freemarker.core.valueformat. + ArithmeticEngine related classes were moved to org.apache.freemarker.core.arithmetic. + freemarker.ext.dom was moved into org.apache.freemarker.dom. +- Moved the all the static final ObjectWrapper-s to the new _StaticObjectWrappers class, and made them + write protected (non-configurable). Also now they come from the pool that ObjectWrapper builders use. +- WrappingTemplateModel.objectWrapper is now final, and its statically stored default value can't be set anymore. +- Removed SimpleObjectWrapper deprecated paramerless constructor +- Removed ResourceBundleLocalizedString and LocalizedString: Hardly anybody has discovered these, and they had no + JUnit coverage. +- Added early draft of TemplateResolver, renamed TemplateCache to DefaultTemplateResolver. TemplateResolver is not + yet directly used in Configuration. This was only added in a hurry, so that it's visible why the + o.a.f.core.templateresolver subpackage name makes sense. +- Marked most static utility classes as internal, and renamed them to start with "_" (for example StringUtils was + renamed to _StringUtil, thus people won't accidentally use it when they wanted to autocomplete to Apache Commons + StringUtil). Created published static utility class, o.a.f.core.util.FTLUtil, which contains some methods moved + over from the now internal utility classes. +- Deleted o.a.f.core.util.DOMNodeModel (it has noting to do with the standard XML support, o.a.f.core.model.dom) +- All CacheStorage-s must be thread safe from now on (removed ConcurrentCacheStorage marker interface) +- Removed support for incompatibleImprovements before 3.0.0. So currently 3.0.0 is the only support value. +- Changed the default of logTemplateExceptions to false. +- Removed `String Configurable.getSetting(String)` and `Properties getSettings()`. It has never worked well, + and is impossible to implement properly. +- Even for setting values that are class names without following `()` or other argument list, the INSTANCE field and + the builder class will be searched now, and used instead of the constructor of the class. Earlier they weren't for + backward compatibility. +- Removed several deprecated methods and constants. Some notes: + - strict_bean_models configuration setting was removed, as it should be set on the BeansWrapper itself + - .template_name now means the same as .current_template_name (it doesn't emulate 2.3 glitches anymore) + - Removed the deprecated BeansWrapper.nullModel setting. So null is always wrapped to null now. + - Removed the overridable BeansWrapper.finetuneMethodAppearance method, which was deprecated by the + finetuneMethodAppearance setting (BeansWrapper.setFinetuneMethodAppearance). + - Removed NodeModel static utility classes dealing with parsing XML to DOM. How it's best to do that is environment + and application dependent, and it has security implications. Since XML loading/parsing is not the topic of the + project, these were removed. Static methods that simplify an already loaded DOM have remained, because that's + FreeMarker-specific functionality. + - Removed parameterless DefaultObjectWrapper and BeansWrapper constructors. Now specifying the + incomplatibleImprovement version is required. + - Removed the static default Configuration instance. (It's not possible to create a template with null Configuration + constructor argument anymore.) + - When specifying the templateUpdateDelay configuration setting with a String (with Properties), the time unit is + required, unless the value is 0. +- setSetting (and the like) doesn't throw ParseException (the same exception used when parsing templates) anymore, + but ConfigurationException. Also, on the places where ParseException was used for other than template parsing, + o.a.f.core.util.GenericParseException is used now instead, which doesn't have the template parsing related fields + that we can't fill. +- Removed DefaultObjectWrapper settings that only exist so that you can set backward compatible behavior instead of + the recommended value: useAdaptersForContainers, forceLegacyNonListCollections, iterableSupport, simpleMapWrapper +- Removed BeansWrapper, which was the superclass of DefaultObjectWrapper, but wasn't recommended to be used as is. + Removed many BeansWrapper-related classes that DefaultObjectWrapper doesn't use. This includes ModelCache and + related classes, because DefaultObjectWrapper has only used the cache for "generic" classes (because that's where it + has fallen back to BeansWrapper.wrap), which is inconsistent and doesn't worth the caching overhead and complexity. +- Java methods (when using DefaultObjectWrapper) won't be accessible as sequences anyore. That is, earlier, instead of + obj.m(1), you could write obj.m[1]. This strange feature has led to some tricky cases, while almost nobody has + utilized it. +- SimpleObjectWrapper was renamed to RestrictedObjectWrapper, also the "simple" setting value was rename to + "restricted". +- Removed the global static final ObjectWrapper-s. It had a "few" consequences: + - Standard TemplateModel implementations that can have an ObjectWrapper contrucor parameter don't allow null there anymore. + Also, any constructor overloads where you cold omit the ObjectWrapper were removed (these were deprecated in FM2 too). + In FM2, such overloads has used the global static default DefaltObjectWrapper, but that was removed. + - If the ObjectWrapper is not a DefaultObjectWrapper (or a subclass of it), `className?new(args)` will only accept 0 arguments. + (Earlier we have fallen back to using the global static default DefaultObjectWrapper instance to handle argument unwrapping + and overloaded constructors.) Note that ?new is only used to instantiate TemplateModel-s, typically, template language + functions/directives implemented in Java, and so they hardly ever has an argument. + - FreemarkerServlet now requires that the ObjectWrapper it uses implements ObjectWrapperAndUnwrapper. (Thus, the return type + of FreemarerServlet.createDefaultObjectWrapper() has changed to ObjectWrapperAndUnwrapper.) The unwrapping functionality is + required when calling JSP custom tags/functions, and in FreeMarker 2 this was worked around with using the + global static default DefaultObjectWrapper when the ObjectWrapper wasn't an ObjectWrapperAndUnwrapper. +- Removed some long deprecated template language directives: + - <#call ...> (deprecated by <@... />) + - <#comment>...</#comment> (deprecated by <#-- ... -->) + - <#transform ...>...</#transform> (deprecated by <@...>...</@...>) + - <#foreach x in xs>...</#foreach> (deprecated by <#list xs as x>...</#list>) +- If for an indexed JavaBean property there's both an indexed read method (like `Foo getFoo(int index)`) and a normal read method + (like Foo[] getFoo()), we prefer the normal read method, and so the result will be a clean FTL sequence (not a multi-type value + with sequence+method type). If there's only an indexed read method, then we don't expose the property anymore, but the indexed + read method can still be called as an usual method (as `myObj.getFoo(index)`). These changes were made because building on the + indexed read method we can't create a proper sequence (which the value of the property should be), since sequences are required + to support returning their size. (In FreeMarker 2 such sequences has thrown exception on calling size(), which caused more + problems and confusion than it solved.) +- When looking for a builder class in builder expressions used in setting values like `com.example.Foo()`, now we first + look for com.example.Foo.Builder, and only then com.example.FooBuilder. +- Removed DefaultObjectWrapper.methodsShadowItems setting, in effect defaulting it to true. This has decided if the generic + get method (`get(String)`) had priority over methods of similar name. The generic get method is only recognized from its + name and parameter type, so it's a quite consfusing feature, and might will be removed alltogether. +- DefaultObjectWrapper is now immutable (has no setter methods), and can only be constructed with DefaultObjectWrapper.Builder +- Configuration.getTemplate has no "parse" parameter anymore. Similarly #include has no "parse" parameter anymore. Whether a + template is parsed can be specified via Configuration.templateConfigurations, for example based on the file extension. Thus, + a certain template is either always parsed or never parsed, and whoever gets or include it need not know about that. + Also added a new setting, "templateLanguage", which decides this; the two available values are + TemplateLanguage.FTL and TemplateLanguage.STATIC_TEXT. +- Configuration.getTemplate has no "encoding" parameter anymore. Similarly #include has no "encoding" parameter either. The charset + of templates can be specified via Configuration.defaultEncoding and Configuration.templateConfigurations (for example based on the + directory it is in), or wirh the #ftl directive inside the template. Thus, a given template always has the same charset, no mater how + it's accessed. +- #include-d/#import-ed templates don't inheirit the charset (encoding) of the #include-ing/#import-ing template. (Because, + again, the charset of a template file is independent of how you access it.) +- Removed Configuration.setEncoding(java.util.Locale, String) and the related other methods. Because of the new logic of template + encodings, the locale to encoding mapping doesn't make much sense anymore. +- Require customLookupCondition-s to be Serializable. +- Various refactorings of Configurable and its subclasses. This is part of the preparation for making such classes immutable, and offer + builders to create them. + - Removed CustomAttribute class. Custom attribute keys can be anything at the moment (this will be certainly restricted later) + - As customAttributes won't be modifiable after Builder.build(), they can't be used for on-demand created data structures anymore (such as + Template-scoped caches) anymore. To fulfill that role, the CustomStateKey class and the CustomStateScope interface was introduced, which + is somewhat similar to the now removed CustomAttribute. CustomStateScope contains one method, Object getCustomState(CustomStateKey), which + may calls CustomStateKey.create() to lazily create the state object for the key. Configuration, Template and Environment implements + CustomStateScope. + - Added getter/setter to access custom attributes as a Map. (This is to make it less an exceptional setting.) + - Environment.setCustomState(Object, Object) and getCustomState(Object) was replaced with CustomStateScope.getCustomState(CustomStateKey). + - Added ProcessingConfiguration interface for the read-only access of template processing settings. This is similar to the + already existing (in FM2) ParserConfiguration interface. + - Renamed Configurable to MutableProcessingAndParserConfiguration. Made it abstract too. + - Renamed Configuration.defaultEncoding to sourceEncoding, also added sourceEncoding to ParserConfiguration, and renamed + TemplateConfiguration.encoding and Template.encoding to sourceEncoding. (Before this, defaultEncoding was exclusive + to Configuration, but now it's like any other ParserConfiguration setting that can be overidden on the 3 levels.) + - Made TemplateConfiguration immutable, added a TemplateConfiguration.Builder. + - Made Template immutable (via public API-s). Template-specific settings now can only come from the TemplateConfiguration associated + to the template, or from the #ftl header for some settings (most notably for custom attributes). + - Renamed ParserConfiguration to ParsingConfiguration, so that the name is more consistent with the new ProcessingConfiguration. +- Settings that have contained a charset name (sourceEncoding, outputEncoding, URLEscapingCharset) are now of type Charset, + not String. For string based configuration sources (such as .properties files) this means that: + - Unrecognized charset names are now errors + - For recognized names the charset name will be normalized (like "latin1" becomes to "ISO-8859-1"). + - In "object builder expressions" Charset values can now be constructed like `Charset("ISO-8859-5")`. + Note that as the type of the settings have changed, now you can't just write something like + `TemplateConfiguration(sourceEncoding = "UTF-8")`, but `TemplateConfiguration(sourceEncoding = Charset("UTF-8"))`. +- Removed Template.templateLanguageVersion, as we solely rely on incompatibleImprovements instead. +- Template.sourceEncoding was renamed to Template.actualSourceEncoding, to emphasize that it's not the template-layer + equivalent of the sourceEncoding ParserConfiguration setting. This is in line with Template.actualTagSyntax and the + other "actual" properties. (Just as in FM2, Template.getParserConfiguration() still can be used get the + sourceEncoding used during parsing.) +- Made TemplateModel classes used by the parser for literals Serializable. (Without this attribute values set in the #ftl + header wouldn't be always Serializable, which in turn will sabotage making Template-s Serializable in the future.) +- Removed hasCustomFormats() from configuration related API-s (we don't need it anymore) +- Template.name (getName()) was renamed to Template.lookupName (getLookupName()), and Template.sourceName (Template.getSourceName()) + doesn't fall back to the lookup name anymore when it's null (however, Template.getSourceOrLookupName() was added for that). There's + no Template.name anymore, because since sourceName was introduced, and hence the concept of template name was split into the + lookup and the source name, its meaning wasn't clean (but it meant the lookup name). TemplateException and ParseException + now also have the same properites: getTemplateSourceName(), getTemplateLookupName(), and even getSourceOrLookupName(). + Location information in error messages show getTemplateSourceOrLookupName(). +- Configuration.setSharedVaribles (not the typo in it) was renamed to setSharedVariables +- Configuration is now immutable. Instead, you should use Configuration.Builder to set up the setting values, then create + the Configuration with the builder's build() method. Further notes: + - Most of the mutator methods (like setters) were moved from Configuration to Configuration.Builder. However, + setClassForTemplateLoader, setDirectoryForTemplateLoading and the like were removed, instead there's just + setTemplateLoader. So for example. instead of setClassForTemplateLoader(Foo.class, "templates") now you have + to write setTemplateLoader(new ClassTemplateLoader(Foo.class, "templates")). While it's a bit longer, it shows + more clearly what's happening, and always supports all TemplateLoader constructor overloads. + - It's now possible to change the Configuration setting defaults by using a custom Configuration.ExtendableBuilder + subclass instead of Configuration.Builder (which is also an ExtendableBuilder subclass). FreemarkerServlet has + switched to this approach, using its own builder subclass to provide defaults that makes the sense in that particular + application. Its API-s which were used for customizing FreemarkerServlet has bean changed accordingly. \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3fd56062/freemarker-core/src/manual/en_US/book.xml ---------------------------------------------------------------------- diff --git a/freemarker-core/src/manual/en_US/book.xml b/freemarker-core/src/manual/en_US/book.xml new file mode 100644 index 0000000..72bf6bc --- /dev/null +++ b/freemarker-core/src/manual/en_US/book.xml @@ -0,0 +1,82 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + 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. +--> +<book conformance="docgen" version="5.0" xml:lang="en" + xmlns="http://docbook.org/ns/docbook" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:xi="http://www.w3.org/2001/XInclude" + xmlns:ns5="http://www.w3.org/1999/xhtml" + xmlns:ns4="http://www.w3.org/2000/svg" + xmlns:ns3="http://www.w3.org/1998/Math/MathML" + xmlns:ns="http://docbook.org/ns/docbook"> + <info> + <title>Apache FreeMarker Manual</title> + + <titleabbrev>Manual</titleabbrev> + + <productname>Freemarker 3.0.0</productname> + </info> + + <preface role="index.html" xml:id="preface"> + <title>TODO</title> + + <para>TODO... Eventually, we might copy the FM2 Manual and rework + it.</para> + + <para>Anchors to satisfy Docgen:</para> + + <itemizedlist> + <listitem> + <para xml:id="app_versions">app_versions</para> + </listitem> + + <listitem> + <para xml:id="app_license">app_license</para> + </listitem> + + <listitem> + <para xml:id="exp_cheatsheet">exp_cheatsheet</para> + </listitem> + + <listitem> + <para xml:id="ref_directive_alphaidx">ref_directive_alphaidx</para> + </listitem> + + <listitem> + <para xml:id="ref_builtins_alphaidx">ref_builtins_alphaidx</para> + </listitem> + + <listitem> + <para xml:id="ref_specvar">ref_specvar</para> + </listitem> + + <listitem> + <para xml:id="alphaidx">alphaidx</para> + </listitem> + + <listitem> + <para xml:id="gloss">gloss</para> + </listitem> + + <listitem> + <para xml:id="app_faq">app_faq</para> + </listitem> + </itemizedlist> + </preface> +</book> http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3fd56062/freemarker-core/src/manual/en_US/docgen-help/editors-readme.txt ---------------------------------------------------------------------- diff --git a/freemarker-core/src/manual/en_US/docgen-help/editors-readme.txt b/freemarker-core/src/manual/en_US/docgen-help/editors-readme.txt new file mode 100644 index 0000000..24436e8 --- /dev/null +++ b/freemarker-core/src/manual/en_US/docgen-help/editors-readme.txt @@ -0,0 +1,130 @@ +/* + * 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. + */ + +Guide to FreeMarker Manual for Editors +====================================== + +Non-technical +------------- + +- The Template Author's Guide is for Web designers. Assume that a + designer is not a programmer, (s)he doesn't even know what is Java. + Forget that FM is implemented in Java when you edit the Template + Author's Guide. Try to avoid technical writing. + +- In the Guide chapters, be careful not to mention things that were + not explained earlier. The Guide chapters should be understandable + if you read them continuously. + +- If you add a new topic or term, don't forget to add it to the Index. + Also, consider adding entries for it to the Glossary. + +- Don't use too sophisticated English. Use basic words and grammar. + + +Technical +--------- + +- For the editing use XXE (XMLmind XML Editor), with its default XML + *source* formatting settings (identation, max line length and like). + You should install the "DocBook 5 for Freemarker" addon, which you can + find inside the "docgen" top-level SVN module. + +- The HTML is generated with Docgen (docgen.jar), which will check some + of the rules described here. To invoke it, issue "ant manual" from + the root of the "freemarker" module. (Note: you may need to check out + and build "docgen" first.) + +- Understand all document conventions in the Preface chapter. Note that + all "programlisting"-s should have a "role" attribute with a value that + is either: "template", "dataModel", "output", "metaTemplate" or + "unspecified". (If you miss this, the XXE addon will show the + "programlisting" in red.) + +- Verbatim content in flow text: + + * In flow text, all data object names, class names, FTL fragments, + HTML fragments, and all other verbatim content is inside "literal" + element. + + * Use replaceable element inside literal element for replaceable + parts and meta-variables like: + <literal<if <replaceable>condition</replaceable>></literal> + <literal><replaceable>templateDir</replaceable>/copyright.ftl</literal> + +- Hierarchy: + + * The hierarchy should look like: + + book -> part -> chapter -> section -> section -> section -> section + + where the "part" and the "section"-s are optional. + Instead of chapter you may have "preface" or "appendix". + + * Don't use "sect1", "sect2", etc. Instead nest "section"-s into each other, + but not deeper than 3 levels. + + * Use "simplesect" if you want to divide up something visually, but + you don't want those sections to appear in the ToC, or go into their own + HTML page. "simplesect"-s can appear under all "section" nesting + levels, and they always look the same regardless of the "section" + nesting levels. + +- Lists: + + * When you have list where the list items are short (a few words), + you should give spacing="compact" to the "itemizedlist" or + "orderedlist" element. + + * Don't putting listings inside "para"-s. Put them between "para"-s instead. + +- Xrefs, id-s, links: + + * id-s of parts, chapters, sections and similar elements must + contain US-ASCII lower case letters, US-ASCII numbers, and + underscore only. id-s of parts and chapters are used as the + filenames of HTML-s generated for that block. + When you find out the id, deduce it from the position in the ToC + hierarchy. The underscore is used as the separator between the path + steps. + + * All other id-s must use prefix: + - example: E.g.: id="example.foreach" + - ref: Reference information... + * directive: about a directive. E.g.: "ref.directive.foreach" + * builtin + - gloss: Term in the Glossary + - topic: The recommended point of document in a certain topic + * designer: for designers. + E.g.: id="topic.designer.methodDataObject" + * programmer: for programmers + * or omit the secondary category if it is for everybody + - misc: Anything doesn't fit in the above categories + + * When you refer to a part, chapter or section, often you should use + xref, not link. The xreflabel attribute of the link-end should not be set; + then it's deduced from the titles. + +- The "book" element must have this attribute: conformance="docgen" + +- It sometimes happens that you want to change some content that you see in + the generated output, which you can't find in the DocBook XML. In such case, + check the contents docgen.cjson, which should be in the same directory as + the XML. If it's not there either, it's perhaps hard-wired into the + templates in docgen. http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3fd56062/freemarker-core/src/manual/en_US/docgen-misc/copyrightComment.txt ---------------------------------------------------------------------- diff --git a/freemarker-core/src/manual/en_US/docgen-misc/copyrightComment.txt b/freemarker-core/src/manual/en_US/docgen-misc/copyrightComment.txt new file mode 100644 index 0000000..60b675e --- /dev/null +++ b/freemarker-core/src/manual/en_US/docgen-misc/copyrightComment.txt @@ -0,0 +1,16 @@ +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. http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3fd56062/freemarker-core/src/manual/en_US/docgen-misc/googleAnalytics.html ---------------------------------------------------------------------- diff --git a/freemarker-core/src/manual/en_US/docgen-misc/googleAnalytics.html b/freemarker-core/src/manual/en_US/docgen-misc/googleAnalytics.html new file mode 100644 index 0000000..759564e --- /dev/null +++ b/freemarker-core/src/manual/en_US/docgen-misc/googleAnalytics.html @@ -0,0 +1,14 @@ +<!-- + This snippet was generated by Google Analytics. + Thus, the standard FreeMarker copyright comment was intentionally omitted. + <#DO_NOT_UPDATE_COPYRIGHT> +--> +<script> + (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ + (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), + m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) + })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); + + ga('create', 'UA-55420501-1', 'auto'); + ga('send', 'pageview'); +</script>
