http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/JSONOutputFormat.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/ast/JSONOutputFormat.java b/src/main/java/org/apache/freemarker/core/ast/JSONOutputFormat.java deleted file mode 100644 index e35e267..0000000 --- a/src/main/java/org/apache/freemarker/core/ast/JSONOutputFormat.java +++ /dev/null @@ -1,52 +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.ast; - -/** - * Represents the JSON output format (MIME type "application/json", name "JSON"). This format doesn't support escaping. - * - * @since 2.3.24 - */ -public class JSONOutputFormat extends OutputFormat { - - /** - * The only instance (singleton) of this {@link OutputFormat}. - */ - public static final JSONOutputFormat INSTANCE = new JSONOutputFormat(); - - private JSONOutputFormat() { - // Only to decrease visibility - } - - @Override - public String getName() { - return "JSON"; - } - - @Override - public String getMimeType() { - return "application/json"; - } - - @Override - public boolean isOutputFormatMixingAllowed() { - return false; - } - -}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/JavaScriptOutputFormat.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/ast/JavaScriptOutputFormat.java b/src/main/java/org/apache/freemarker/core/ast/JavaScriptOutputFormat.java deleted file mode 100644 index c601051..0000000 --- a/src/main/java/org/apache/freemarker/core/ast/JavaScriptOutputFormat.java +++ /dev/null @@ -1,53 +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.ast; - -/** - * Represents the JavaScript output format (MIME type "application/javascript", name "JavaScript"). This format doesn't - * support escaping. - * - * @since 2.3.24 - */ -public class JavaScriptOutputFormat extends OutputFormat { - - /** - * The only instance (singleton) of this {@link OutputFormat}. - */ - public static final JavaScriptOutputFormat INSTANCE = new JavaScriptOutputFormat(); - - private JavaScriptOutputFormat() { - // Only to decrease visibility - } - - @Override - public String getName() { - return "JavaScript"; - } - - @Override - public String getMimeType() { - return "application/javascript"; - } - - @Override - public boolean isOutputFormatMixingAllowed() { - return false; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/JavaTemplateDateFormat.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/ast/JavaTemplateDateFormat.java b/src/main/java/org/apache/freemarker/core/ast/JavaTemplateDateFormat.java deleted file mode 100644 index f0f683f..0000000 --- a/src/main/java/org/apache/freemarker/core/ast/JavaTemplateDateFormat.java +++ /dev/null @@ -1,72 +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.ast; - -import java.text.DateFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Date; - -import org.apache.freemarker.core.model.TemplateDateModel; -import org.apache.freemarker.core.model.TemplateModelException; - -/** - * Java {@link DateFormat}-based format. - */ -class JavaTemplateDateFormat extends TemplateDateFormat { - - private final DateFormat javaDateFormat; - - public JavaTemplateDateFormat(DateFormat javaDateFormat) { - this.javaDateFormat = javaDateFormat; - } - - @Override - public String formatToPlainText(TemplateDateModel dateModel) throws TemplateModelException { - return javaDateFormat.format(TemplateFormatUtil.getNonNullDate(dateModel)); - } - - @Override - public Date parse(String s, int dateType) throws UnparsableValueException { - try { - return javaDateFormat.parse(s); - } catch (ParseException e) { - throw new UnparsableValueException(e.getMessage(), e); - } - } - - @Override - public String getDescription() { - return javaDateFormat instanceof SimpleDateFormat - ? ((SimpleDateFormat) javaDateFormat).toPattern() - : javaDateFormat.toString(); - } - - @Override - public boolean isLocaleBound() { - return true; - } - - @Override - public boolean isTimeZoneBound() { - return true; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/JavaTemplateDateFormatFactory.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/ast/JavaTemplateDateFormatFactory.java b/src/main/java/org/apache/freemarker/core/ast/JavaTemplateDateFormatFactory.java deleted file mode 100644 index 2ab48e4..0000000 --- a/src/main/java/org/apache/freemarker/core/ast/JavaTemplateDateFormatFactory.java +++ /dev/null @@ -1,174 +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.ast; - -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Locale; -import java.util.StringTokenizer; -import java.util.TimeZone; -import java.util.concurrent.ConcurrentHashMap; - -import org.apache.freemarker.core._CoreLogs; -import org.apache.freemarker.core.model.TemplateDateModel; -import org.slf4j.Logger; - -class JavaTemplateDateFormatFactory extends TemplateDateFormatFactory { - - static final JavaTemplateDateFormatFactory INSTANCE = new JavaTemplateDateFormatFactory(); - - private static final Logger LOG = _CoreLogs.RUNTIME; - - private static final ConcurrentHashMap<CacheKey, DateFormat> GLOBAL_FORMAT_CACHE - = new ConcurrentHashMap<>(); - private static final int LEAK_ALERT_NUMBER_FORMAT_CACHE_SIZE = 1024; - - private JavaTemplateDateFormatFactory() { - // Can't be instantiated - } - - /** - * @param zonelessInput - * Has no effect in this implementation. - */ - @Override - public TemplateDateFormat get(String params, int dateType, Locale locale, TimeZone timeZone, boolean zonelessInput, - Environment env) throws UnknownDateTypeFormattingUnsupportedException, InvalidFormatParametersException { - return new JavaTemplateDateFormat(getJavaDateFormat(dateType, params, locale, timeZone)); - } - - /** - * Returns a "private" copy (not in the global cache) for the given format. - */ - private DateFormat getJavaDateFormat(int dateType, String nameOrPattern, Locale locale, TimeZone timeZone) - throws UnknownDateTypeFormattingUnsupportedException, InvalidFormatParametersException { - - // Get DateFormat from global cache: - CacheKey cacheKey = new CacheKey(dateType, nameOrPattern, locale, timeZone); - DateFormat jFormat; - - jFormat = GLOBAL_FORMAT_CACHE.get(cacheKey); - if (jFormat == null) { - // Add format to global format cache. - StringTokenizer tok = new StringTokenizer(nameOrPattern, "_"); - int tok1Style = tok.hasMoreTokens() ? parseDateStyleToken(tok.nextToken()) : DateFormat.DEFAULT; - if (tok1Style != -1) { - switch (dateType) { - case TemplateDateModel.UNKNOWN: { - throw new UnknownDateTypeFormattingUnsupportedException(); - } - case TemplateDateModel.TIME: { - jFormat = DateFormat.getTimeInstance(tok1Style, cacheKey.locale); - break; - } - case TemplateDateModel.DATE: { - jFormat = DateFormat.getDateInstance(tok1Style, cacheKey.locale); - break; - } - case TemplateDateModel.DATETIME: { - int tok2Style = tok.hasMoreTokens() ? parseDateStyleToken(tok.nextToken()) : tok1Style; - if (tok2Style != -1) { - jFormat = DateFormat.getDateTimeInstance(tok1Style, tok2Style, cacheKey.locale); - } - break; - } - } - } - if (jFormat == null) { - try { - jFormat = new SimpleDateFormat(nameOrPattern, cacheKey.locale); - } catch (IllegalArgumentException e) { - final String msg = e.getMessage(); - throw new InvalidFormatParametersException( - msg != null ? msg : "Invalid SimpleDateFormat pattern", e); - } - } - jFormat.setTimeZone(cacheKey.timeZone); - - if (GLOBAL_FORMAT_CACHE.size() >= LEAK_ALERT_NUMBER_FORMAT_CACHE_SIZE) { - boolean triggered = false; - synchronized (JavaTemplateNumberFormatFactory.class) { - if (GLOBAL_FORMAT_CACHE.size() >= LEAK_ALERT_NUMBER_FORMAT_CACHE_SIZE) { - triggered = true; - GLOBAL_FORMAT_CACHE.clear(); - } - } - if (triggered) { - LOG.warn("Global Java DateFormat cache has exceeded {} entries => cache flushed. " - + "Typical cause: Some template generates high variety of format pattern strings.", - LEAK_ALERT_NUMBER_FORMAT_CACHE_SIZE); - } - } - - DateFormat prevJFormat = GLOBAL_FORMAT_CACHE.putIfAbsent(cacheKey, jFormat); - if (prevJFormat != null) { - jFormat = prevJFormat; - } - } // if cache miss - - return (DateFormat) jFormat.clone(); // For thread safety - } - - private static final class CacheKey { - private final int dateType; - private final String pattern; - private final Locale locale; - private final TimeZone timeZone; - - CacheKey(int dateType, String pattern, Locale locale, TimeZone timeZone) { - this.dateType = dateType; - this.pattern = pattern; - this.locale = locale; - this.timeZone = timeZone; - } - - @Override - public boolean equals(Object o) { - if (o instanceof CacheKey) { - CacheKey fk = (CacheKey) o; - return dateType == fk.dateType && fk.pattern.equals(pattern) && fk.locale.equals(locale) - && fk.timeZone.equals(timeZone); - } - return false; - } - - @Override - public int hashCode() { - return dateType ^ pattern.hashCode() ^ locale.hashCode() ^ timeZone.hashCode(); - } - } - - private int parseDateStyleToken(String token) { - if ("short".equals(token)) { - return DateFormat.SHORT; - } - if ("medium".equals(token)) { - return DateFormat.MEDIUM; - } - if ("long".equals(token)) { - return DateFormat.LONG; - } - if ("full".equals(token)) { - return DateFormat.FULL; - } - return -1; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/JavaTemplateNumberFormat.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/ast/JavaTemplateNumberFormat.java b/src/main/java/org/apache/freemarker/core/ast/JavaTemplateNumberFormat.java deleted file mode 100644 index ebe50ef..0000000 --- a/src/main/java/org/apache/freemarker/core/ast/JavaTemplateNumberFormat.java +++ /dev/null @@ -1,66 +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.ast; - -import java.text.NumberFormat; - -import org.apache.freemarker.core.model.TemplateModelException; -import org.apache.freemarker.core.model.TemplateNumberModel; - -final class JavaTemplateNumberFormat extends BackwardCompatibleTemplateNumberFormat { - - private final String formatString; - private final NumberFormat javaNumberFormat; - - public JavaTemplateNumberFormat(NumberFormat javaNumberFormat, String formatString) { - this.formatString = formatString; - this.javaNumberFormat = javaNumberFormat; - } - - @Override - public String formatToPlainText(TemplateNumberModel numberModel) throws UnformattableValueException, TemplateModelException { - Number number = TemplateFormatUtil.getNonNullNumber(numberModel); - return format(number); - } - - @Override - public boolean isLocaleBound() { - return true; - } - - @Override - String format(Number number) throws UnformattableValueException { - try { - return javaNumberFormat.format(number); - } catch (ArithmeticException e) { - throw new UnformattableValueException( - "This format can't format the " + number + " number. Reason: " + e.getMessage(), e); - } - } - - public NumberFormat getJavaNumberFormat() { - return javaNumberFormat; - } - - @Override - public String getDescription() { - return formatString; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/JavaTemplateNumberFormatFactory.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/ast/JavaTemplateNumberFormatFactory.java b/src/main/java/org/apache/freemarker/core/ast/JavaTemplateNumberFormatFactory.java deleted file mode 100644 index dc26927..0000000 --- a/src/main/java/org/apache/freemarker/core/ast/JavaTemplateNumberFormatFactory.java +++ /dev/null @@ -1,121 +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.ast; - -import java.text.NumberFormat; -import java.text.ParseException; -import java.util.Locale; -import java.util.concurrent.ConcurrentHashMap; - -import org.apache.freemarker.core._CoreLogs; -import org.slf4j.Logger; - -/** - * Deals with {@link TemplateNumberFormat}-s that just wrap a Java {@link NumberFormat}. - */ -class JavaTemplateNumberFormatFactory extends TemplateNumberFormatFactory { - - static final JavaTemplateNumberFormatFactory INSTANCE = new JavaTemplateNumberFormatFactory(); - - private static final Logger LOG = _CoreLogs.RUNTIME; - - private static final ConcurrentHashMap<CacheKey, NumberFormat> GLOBAL_FORMAT_CACHE - = new ConcurrentHashMap<>(); - private static final int LEAK_ALERT_NUMBER_FORMAT_CACHE_SIZE = 1024; - - private JavaTemplateNumberFormatFactory() { - // Not meant to be instantiated - } - - @Override - public TemplateNumberFormat get(String params, Locale locale, Environment env) - throws InvalidFormatParametersException { - CacheKey cacheKey = new CacheKey(params, locale); - NumberFormat jFormat = GLOBAL_FORMAT_CACHE.get(cacheKey); - if (jFormat == null) { - if ("number".equals(params)) { - jFormat = NumberFormat.getNumberInstance(locale); - } else if ("currency".equals(params)) { - jFormat = NumberFormat.getCurrencyInstance(locale); - } else if ("percent".equals(params)) { - jFormat = NumberFormat.getPercentInstance(locale); - } else if ("computer".equals(params)) { - jFormat = env.getCNumberFormat(); - } else { - try { - jFormat = ExtendedDecimalFormatParser.parse(params, locale); - } catch (ParseException e) { - String msg = e.getMessage(); - throw new InvalidFormatParametersException( - msg != null ? msg : "Invalid DecimalFormat pattern", e); - } - } - - if (GLOBAL_FORMAT_CACHE.size() >= LEAK_ALERT_NUMBER_FORMAT_CACHE_SIZE) { - boolean triggered = false; - synchronized (JavaTemplateNumberFormatFactory.class) { - if (GLOBAL_FORMAT_CACHE.size() >= LEAK_ALERT_NUMBER_FORMAT_CACHE_SIZE) { - triggered = true; - GLOBAL_FORMAT_CACHE.clear(); - } - } - if (triggered) { - LOG.warn("Global Java NumberFormat cache has exceeded {} entries => cache flushed. " - + "Typical cause: Some template generates high variety of format pattern strings.", - LEAK_ALERT_NUMBER_FORMAT_CACHE_SIZE); - } - } - - NumberFormat prevJFormat = GLOBAL_FORMAT_CACHE.putIfAbsent(cacheKey, jFormat); - if (prevJFormat != null) { - jFormat = prevJFormat; - } - } // if cache miss - - // JFormat-s aren't thread-safe; must clone it - jFormat = (NumberFormat) jFormat.clone(); - - return new JavaTemplateNumberFormat(jFormat, params); - } - - private static final class CacheKey { - private final String pattern; - private final Locale locale; - - CacheKey(String pattern, Locale locale) { - this.pattern = pattern; - this.locale = locale; - } - - @Override - public boolean equals(Object o) { - if (o instanceof CacheKey) { - CacheKey fk = (CacheKey) o; - return fk.pattern.equals(pattern) && fk.locale.equals(locale); - } - return false; - } - - @Override - public int hashCode() { - return pattern.hashCode() ^ locale.hashCode(); - } - } - -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/LibraryLoad.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/ast/LibraryLoad.java b/src/main/java/org/apache/freemarker/core/ast/LibraryLoad.java deleted file mode 100644 index 61eb08e..0000000 --- a/src/main/java/org/apache/freemarker/core/ast/LibraryLoad.java +++ /dev/null @@ -1,131 +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.ast; - -import java.io.IOException; - -import org.apache.freemarker.core.Template; -import org.apache.freemarker.core.TemplateException; -import org.apache.freemarker.core.templateresolver.MalformedTemplateNameException; -import org.apache.freemarker.core.util._StringUtil; - -/** - * <b>Internal API - subject to change:</b> Represents an import via {@code #import}. - * - * @deprecated This is an internal FreeMarker API with no backward compatibility guarantees, so you shouldn't depend on - * it. - */ -@Deprecated -public final class LibraryLoad extends TemplateElement { - - private Expression importedTemplateNameExp; - private String targetNsVarName; - - /** - * @param template the template that this <tt>Include</tt> is a part of. - * @param importedTemplateNameExp the name of the template to be included. - * @param targetNsVarName the name of the variable to assign this library's namespace to - */ - LibraryLoad(Template template, - Expression importedTemplateNameExp, - String targetNsVarName) { - this.targetNsVarName = targetNsVarName; - this.importedTemplateNameExp = importedTemplateNameExp; - } - - @Override - TemplateElement[] accept(Environment env) throws TemplateException, IOException { - final String importedTemplateName = importedTemplateNameExp.evalAndCoerceToPlainText(env); - final String fullImportedTemplateName; - try { - fullImportedTemplateName = env.toFullTemplateName(getTemplate().getName(), importedTemplateName); - } catch (MalformedTemplateNameException e) { - throw new _MiscTemplateException(e, env, - "Malformed template name ", new _DelayedJQuote(e.getTemplateName()), ":\n", - e.getMalformednessDescription()); - } - - try { - env.importLib(fullImportedTemplateName, targetNsVarName); - } catch (IOException e) { - throw new _MiscTemplateException(e, env, - "Template importing failed (for parameter value ", - new _DelayedJQuote(importedTemplateName), - "):\n", new _DelayedGetMessage(e)); - } - return null; - } - - @Override - protected String dump(boolean canonical) { - StringBuilder buf = new StringBuilder(); - if (canonical) buf.append('<'); - buf.append(getNodeTypeSymbol()); - buf.append(' '); - buf.append(importedTemplateNameExp.getCanonicalForm()); - buf.append(" as "); - buf.append(_StringUtil.toFTLTopLevelTragetIdentifier(targetNsVarName)); - if (canonical) buf.append("/>"); - return buf.toString(); - } - - @Override - String getNodeTypeSymbol() { - return "#import"; - } - - @Override - int getParameterCount() { - return 2; - } - - @Override - Object getParameterValue(int idx) { - switch (idx) { - case 0: return importedTemplateNameExp; - case 1: return targetNsVarName; - default: throw new IndexOutOfBoundsException(); - } - } - - @Override - ParameterRole getParameterRole(int idx) { - switch (idx) { - case 0: return ParameterRole.TEMPLATE_NAME; - case 1: return ParameterRole.NAMESPACE; - default: throw new IndexOutOfBoundsException(); - } - } - - public String getTemplateName() { - return importedTemplateNameExp.toString(); - } - - @Override - boolean isNestedBlockRepeater() { - return false; - } - - @Override - boolean isShownInStackTrace() { - return true; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/ListElseContainer.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/ast/ListElseContainer.java b/src/main/java/org/apache/freemarker/core/ast/ListElseContainer.java deleted file mode 100644 index 7a0f7ee..0000000 --- a/src/main/java/org/apache/freemarker/core/ast/ListElseContainer.java +++ /dev/null @@ -1,87 +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.ast; - -import java.io.IOException; - -import org.apache.freemarker.core.TemplateException; - -class ListElseContainer extends TemplateElement { - - private final IteratorBlock listPart; - private final ElseOfList elsePart; - - public ListElseContainer(IteratorBlock listPart, ElseOfList elsePart) { - setChildBufferCapacity(2); - addChild(listPart); - addChild(elsePart); - this.listPart = listPart; - this.elsePart = elsePart; - } - - @Override - TemplateElement[] accept(Environment env) throws TemplateException, IOException { - if (!listPart.acceptWithResult(env)) { - return elsePart.accept(env); - } - return null; - } - - @Override - boolean isNestedBlockRepeater() { - return false; - } - - @Override - protected String dump(boolean canonical) { - if (canonical) { - StringBuilder buf = new StringBuilder(); - int ln = getChildCount(); - for (int i = 0; i < ln; i++) { - TemplateElement element = getChild(i); - buf.append(element.dump(canonical)); - } - buf.append("</#list>"); - return buf.toString(); - } else { - return getNodeTypeSymbol(); - } - } - - @Override - String getNodeTypeSymbol() { - return "#list-#else-container"; - } - - @Override - int getParameterCount() { - return 0; - } - - @Override - Object getParameterValue(int idx) { - throw new IndexOutOfBoundsException(); - } - - @Override - ParameterRole getParameterRole(int idx) { - throw new IndexOutOfBoundsException(); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/ListLiteral.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/ast/ListLiteral.java b/src/main/java/org/apache/freemarker/core/ast/ListLiteral.java deleted file mode 100644 index 2c9f97b..0000000 --- a/src/main/java/org/apache/freemarker/core/ast/ListLiteral.java +++ /dev/null @@ -1,196 +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.ast; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; - -import org.apache.freemarker.core.TemplateException; -import org.apache.freemarker.core.model.TemplateMethodModel; -import org.apache.freemarker.core.model.TemplateMethodModelEx; -import org.apache.freemarker.core.model.TemplateModel; -import org.apache.freemarker.core.model.TemplateSequenceModel; -import org.apache.freemarker.core.model.impl.SimpleSequence; - -final class ListLiteral extends Expression { - - final ArrayList/*<Expression>*/ items; - - ListLiteral(ArrayList items) { - this.items = items; - items.trimToSize(); - } - - @Override - TemplateModel _eval(Environment env) throws TemplateException { - SimpleSequence list = new SimpleSequence(items.size()); - for (Iterator it = items.iterator(); it.hasNext(); ) { - Expression exp = (Expression) it.next(); - TemplateModel tm = exp.eval(env); - exp.assertNonNull(tm, env); - list.add(tm); - } - return list; - } - - /** - * For {@link TemplateMethodModel} calls, but not for {@link TemplateMethodModelEx}-es, returns the list of - * arguments as {@link String}-s. - */ - List/*<String>*/ getValueList(Environment env) throws TemplateException { - int size = items.size(); - switch(size) { - case 0: { - return Collections.EMPTY_LIST; - } - case 1: { - return Collections.singletonList(((Expression) items.get(0)).evalAndCoerceToPlainText(env)); - } - default: { - List result = new ArrayList(items.size()); - for (ListIterator iterator = items.listIterator(); iterator.hasNext(); ) { - Expression exp = (Expression) iterator.next(); - result.add(exp.evalAndCoerceToPlainText(env)); - } - return result; - } - } - } - - /** - * For {@link TemplateMethodModelEx} calls, returns the list of arguments as {@link TemplateModel}-s. - */ - List/*<TemplateModel>*/ getModelList(Environment env) throws TemplateException { - int size = items.size(); - switch(size) { - case 0: { - return Collections.EMPTY_LIST; - } - case 1: { - return Collections.singletonList(((Expression) items.get(0)).eval(env)); - } - default: { - List result = new ArrayList(items.size()); - for (ListIterator iterator = items.listIterator(); iterator.hasNext(); ) { - Expression exp = (Expression) iterator.next(); - result.add(exp.eval(env)); - } - return result; - } - } - } - - @Override - public String getCanonicalForm() { - StringBuilder buf = new StringBuilder("["); - int size = items.size(); - for (int i = 0; i < size; i++) { - Expression value = (Expression) items.get(i); - buf.append(value.getCanonicalForm()); - if (i != size - 1) { - buf.append(", "); - } - } - buf.append("]"); - return buf.toString(); - } - - @Override - String getNodeTypeSymbol() { - return "[...]"; - } - - @Override - boolean isLiteral() { - if (constantValue != null) { - return true; - } - for (int i = 0; i < items.size(); i++) { - Expression exp = (Expression) items.get(i); - if (!exp.isLiteral()) { - return false; - } - } - return true; - } - - // A hacky routine used by VisitNode and RecurseNode - - TemplateSequenceModel evaluateStringsToNamespaces(Environment env) throws TemplateException { - TemplateSequenceModel val = (TemplateSequenceModel) eval(env); - SimpleSequence result = new SimpleSequence(val.size()); - for (int i = 0; i < items.size(); i++) { - Object itemExpr = items.get(i); - if (itemExpr instanceof StringLiteral) { - String s = ((StringLiteral) itemExpr).getAsString(); - try { - Environment.Namespace ns = env.importLib(s, null); - result.add(ns); - } catch (IOException ioe) { - throw new _MiscTemplateException(((StringLiteral) itemExpr), - "Couldn't import library ", new _DelayedJQuote(s), ": ", - new _DelayedGetMessage(ioe)); - } - } else { - result.add(val.get(i)); - } - } - return result; - } - - @Override - protected Expression deepCloneWithIdentifierReplaced_inner( - String replacedIdentifier, Expression replacement, ReplacemenetState replacementState) { - ArrayList clonedValues = (ArrayList) items.clone(); - for (ListIterator iter = clonedValues.listIterator(); iter.hasNext(); ) { - iter.set(((Expression) iter.next()).deepCloneWithIdentifierReplaced( - replacedIdentifier, replacement, replacementState)); - } - return new ListLiteral(clonedValues); - } - - @Override - int getParameterCount() { - return items != null ? items.size() : 0; - } - - @Override - Object getParameterValue(int idx) { - checkIndex(idx); - return items.get(idx); - } - - @Override - ParameterRole getParameterRole(int idx) { - checkIndex(idx); - return ParameterRole.ITEM_VALUE; - } - - private void checkIndex(int idx) { - if (items == null || idx >= items.size()) { - throw new IndexOutOfBoundsException(); - } - } - -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/ListableRightUnboundedRangeModel.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/ast/ListableRightUnboundedRangeModel.java b/src/main/java/org/apache/freemarker/core/ast/ListableRightUnboundedRangeModel.java deleted file mode 100644 index d5a28e8..0000000 --- a/src/main/java/org/apache/freemarker/core/ast/ListableRightUnboundedRangeModel.java +++ /dev/null @@ -1,97 +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.ast; - -import java.math.BigInteger; - -import org.apache.freemarker.core.model.TemplateCollectionModel; -import org.apache.freemarker.core.model.TemplateModel; -import org.apache.freemarker.core.model.TemplateModelException; -import org.apache.freemarker.core.model.TemplateModelIterator; -import org.apache.freemarker.core.model.impl.SimpleNumber; - -/** - * This is the model used for right-unbounded ranges since Incompatible Improvements 2.3.21. - * - * @since 2.3.21 - */ -final class ListableRightUnboundedRangeModel extends RightUnboundedRangeModel implements TemplateCollectionModel { - - ListableRightUnboundedRangeModel(int begin) { - super(begin); - } - - @Override - public int size() throws TemplateModelException { - return Integer.MAX_VALUE; - } - - @Override - public TemplateModelIterator iterator() throws TemplateModelException { - return new TemplateModelIterator() { - boolean needInc; - int nextType = 1; - int nextInt = getBegining(); - long nextLong; - BigInteger nextBigInteger; - - @Override - public TemplateModel next() throws TemplateModelException { - if (needInc) { - switch (nextType) { - case 1: - if (nextInt < Integer.MAX_VALUE) { - nextInt++; - } else { - nextType = 2; - nextLong = nextInt + 1L; - } - break; - - case 2: - if (nextLong < Long.MAX_VALUE) { - nextLong++; - } else { - nextType = 3; - nextBigInteger = BigInteger.valueOf(nextLong); - nextBigInteger = nextBigInteger.add(BigInteger.ONE); - } - break; - - default: // 3 - nextBigInteger = nextBigInteger.add(BigInteger.ONE); - } - } - needInc = true; - return nextType == 1 ? new SimpleNumber(nextInt) - : (nextType == 2 ? new SimpleNumber(nextLong) - : new SimpleNumber(nextBigInteger)); - } - - @Override - public boolean hasNext() throws TemplateModelException { - return true; - } - - }; - - } - -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/LocalContext.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/ast/LocalContext.java b/src/main/java/org/apache/freemarker/core/ast/LocalContext.java deleted file mode 100644 index ceef734..0000000 --- a/src/main/java/org/apache/freemarker/core/ast/LocalContext.java +++ /dev/null @@ -1,38 +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.ast; - -import java.util.Collection; - -import org.apache.freemarker.core.model.TemplateModel; -import org.apache.freemarker.core.model.TemplateModelException; - -/** - * An interface that represents a local context. This is used as the abstraction for - * the context of a Macro invocation, a loop, or the nested block call from within - * a macro. - * <a href="mailto:[email protected]">Jonathan Revusky</a> - */ - -public interface LocalContext { - TemplateModel getLocalVariable(String name) throws TemplateModelException; - Collection getLocalVariableNames() throws TemplateModelException; - -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/LocalContextStack.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/ast/LocalContextStack.java b/src/main/java/org/apache/freemarker/core/ast/LocalContextStack.java deleted file mode 100644 index 19d6131..0000000 --- a/src/main/java/org/apache/freemarker/core/ast/LocalContextStack.java +++ /dev/null @@ -1,57 +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.ast; - -/** - * Class that's a little bit more efficient than using an {@code ArrayList<LocalContext>}. - * - * @since 2.3.24 - */ -final class LocalContextStack { - - private LocalContext[] buffer = new LocalContext[8]; - private int size; - - void push(LocalContext localContext) { - final int newSize = ++size; - LocalContext[] buffer = this.buffer; - if (buffer.length < newSize) { - final LocalContext[] newBuffer = new LocalContext[newSize * 2]; - for (int i = 0; i < buffer.length; i++) { - newBuffer[i] = buffer[i]; - } - buffer = newBuffer; - this.buffer = newBuffer; - } - buffer[newSize - 1] = localContext; - } - - void pop() { - buffer[--size] = null; - } - - public LocalContext get(int index) { - return buffer[index]; - } - - public int size() { - return size; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/Macro.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/ast/Macro.java b/src/main/java/org/apache/freemarker/core/ast/Macro.java deleted file mode 100644 index 2a8b072..0000000 --- a/src/main/java/org/apache/freemarker/core/ast/Macro.java +++ /dev/null @@ -1,330 +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.ast; - -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Map; - -import org.apache.freemarker.core.TemplateException; -import org.apache.freemarker.core.model.TemplateModel; -import org.apache.freemarker.core.model.TemplateModelException; -import org.apache.freemarker.core.model.TemplateModelIterator; -import org.apache.freemarker.core.util._StringUtil; - -/** - * An element representing a macro declaration. - * - * @deprecated Subject to be changed or renamed any time; no "stable" replacement exists yet. - */ -@Deprecated -public final class Macro extends TemplateElement implements TemplateModel { - - static final Macro DO_NOTHING_MACRO = new Macro(".pass", - Collections.EMPTY_LIST, - Collections.EMPTY_MAP, - null, false, - TemplateElements.EMPTY); - - final static int TYPE_MACRO = 0; - final static int TYPE_FUNCTION = 1; - - private final String name; - private final String[] paramNames; - private final Map paramDefaults; - private final String catchAllParamName; - private final boolean function; - - Macro(String name, List argumentNames, Map args, - String catchAllParamName, boolean function, - TemplateElements children) { - this.name = name; - paramNames = (String[]) argumentNames.toArray( - new String[argumentNames.size()]); - paramDefaults = args; - - this.function = function; - this.catchAllParamName = catchAllParamName; - - setChildren(children); - } - - public String getCatchAll() { - return catchAllParamName; - } - - public String[] getArgumentNames() { - return paramNames.clone(); - } - - String[] getArgumentNamesInternal() { - return paramNames; - } - - boolean hasArgNamed(String name) { - return paramDefaults.containsKey(name); - } - - public String getName() { - return name; - } - - @Override - TemplateElement[] accept(Environment env) { - env.visitMacroDef(this); - return null; - } - - @Override - protected String dump(boolean canonical) { - StringBuilder sb = new StringBuilder(); - if (canonical) sb.append('<'); - sb.append(getNodeTypeSymbol()); - sb.append(' '); - sb.append(_StringUtil.toFTLTopLevelTragetIdentifier(name)); - if (function) sb.append('('); - int argCnt = paramNames.length; - for (int i = 0; i < argCnt; i++) { - if (function) { - if (i != 0) { - sb.append(", "); - } - } else { - sb.append(' '); - } - String argName = paramNames[i]; - sb.append(_StringUtil.toFTLTopLevelIdentifierReference(argName)); - if (paramDefaults != null && paramDefaults.get(argName) != null) { - sb.append('='); - Expression defaultExpr = (Expression) paramDefaults.get(argName); - if (function) { - sb.append(defaultExpr.getCanonicalForm()); - } else { - MessageUtil.appendExpressionAsUntearable(sb, defaultExpr); - } - } - } - if (catchAllParamName != null) { - if (function) { - if (argCnt != 0) { - sb.append(", "); - } - } else { - sb.append(' '); - } - sb.append(catchAllParamName); - sb.append("..."); - } - if (function) sb.append(')'); - if (canonical) { - sb.append('>'); - sb.append(getChildrenCanonicalForm()); - sb.append("</").append(getNodeTypeSymbol()).append('>'); - } - return sb.toString(); - } - - @Override - String getNodeTypeSymbol() { - return function ? "#function" : "#macro"; - } - - public boolean isFunction() { - return function; - } - - class Context implements LocalContext { - final Environment.Namespace localVars; - final TemplateElement[] nestedContentBuffer; - final Environment.Namespace nestedContentNamespace; - final List nestedContentParameterNames; - final LocalContextStack prevLocalContextStack; - final Context prevMacroContext; - - Context(Environment env, - TemplateElement[] nestedContentBuffer, - List nestedContentParameterNames) { - localVars = env.new Namespace(); - this.nestedContentBuffer = nestedContentBuffer; - nestedContentNamespace = env.getCurrentNamespace(); - this.nestedContentParameterNames = nestedContentParameterNames; - prevLocalContextStack = env.getLocalContextStack(); - prevMacroContext = env.getCurrentMacroContext(); - } - - - Macro getMacro() { - return Macro.this; - } - - // Set default parameters, check if all the required parameters are defined. - void sanityCheck(Environment env) throws TemplateException { - boolean resolvedAnArg, hasUnresolvedArg; - Expression firstUnresolvedExpression; - InvalidReferenceException firstReferenceException; - do { - firstUnresolvedExpression = null; - firstReferenceException = null; - resolvedAnArg = hasUnresolvedArg = false; - for (int i = 0; i < paramNames.length; ++i) { - String argName = paramNames[i]; - if (localVars.get(argName) == null) { - Expression valueExp = (Expression) paramDefaults.get(argName); - if (valueExp != null) { - try { - TemplateModel tm = valueExp.eval(env); - if (tm == null) { - if (!hasUnresolvedArg) { - firstUnresolvedExpression = valueExp; - hasUnresolvedArg = true; - } - } else { - localVars.put(argName, tm); - resolvedAnArg = true; - } - } catch (InvalidReferenceException e) { - if (!hasUnresolvedArg) { - hasUnresolvedArg = true; - firstReferenceException = e; - } - } - } else { - boolean argWasSpecified = localVars.containsKey(argName); - throw new _MiscTemplateException(env, - new _ErrorDescriptionBuilder( - "When calling macro ", new _DelayedJQuote(name), - ", required parameter ", new _DelayedJQuote(argName), - " (parameter #", Integer.valueOf(i + 1), ") was ", - (argWasSpecified - ? "specified, but had null/missing value." - : "not specified.") - ).tip(argWasSpecified - ? new Object[] { - "If the parameter value expression on the caller side is known to " - + "be legally null/missing, you may want to specify a default " - + "value for it with the \"!\" operator, like " - + "paramValue!defaultValue." } - : new Object[] { - "If the omission was deliberate, you may consider making the " - + "parameter optional in the macro by specifying a default value " - + "for it, like ", "<#macro macroName paramName=defaultExpr>", ")" } - )); - } - } - } - } while (resolvedAnArg && hasUnresolvedArg); - if (hasUnresolvedArg) { - if (firstReferenceException != null) { - throw firstReferenceException; - } else { - throw InvalidReferenceException.getInstance(firstUnresolvedExpression, env); - } - } - } - - /** - * @return the local variable of the given name - * or null if it doesn't exist. - */ - @Override - public TemplateModel getLocalVariable(String name) throws TemplateModelException { - return localVars.get(name); - } - - Environment.Namespace getLocals() { - return localVars; - } - - /** - * Set a local variable in this macro - */ - void setLocalVar(String name, TemplateModel var) { - localVars.put(name, var); - } - - @Override - public Collection getLocalVariableNames() throws TemplateModelException { - HashSet result = new HashSet(); - for (TemplateModelIterator it = localVars.keys().iterator(); it.hasNext(); ) { - result.add(it.next().toString()); - } - return result; - } - } - - @Override - int getParameterCount() { - return 1/*name*/ + paramNames.length * 2/*name=default*/ + 1/*catchAll*/ + 1/*type*/; - } - - @Override - Object getParameterValue(int idx) { - if (idx == 0) { - return name; - } else { - final int argDescsEnd = paramNames.length * 2 + 1; - if (idx < argDescsEnd) { - String paramName = paramNames[(idx - 1) / 2]; - if (idx % 2 != 0) { - return paramName; - } else { - return paramDefaults.get(paramName); - } - } else if (idx == argDescsEnd) { - return catchAllParamName; - } else if (idx == argDescsEnd + 1) { - return Integer.valueOf(function ? TYPE_FUNCTION : TYPE_MACRO); - } else { - throw new IndexOutOfBoundsException(); - } - } - } - - @Override - ParameterRole getParameterRole(int idx) { - if (idx == 0) { - return ParameterRole.ASSIGNMENT_TARGET; - } else { - final int argDescsEnd = paramNames.length * 2 + 1; - if (idx < argDescsEnd) { - if (idx % 2 != 0) { - return ParameterRole.PARAMETER_NAME; - } else { - return ParameterRole.PARAMETER_DEFAULT; - } - } else if (idx == argDescsEnd) { - return ParameterRole.CATCH_ALL_PARAMETER_NAME; - } else if (idx == argDescsEnd + 1) { - return ParameterRole.AST_NODE_SUBTYPE; - } else { - throw new IndexOutOfBoundsException(); - } - } - } - - @Override - boolean isNestedBlockRepeater() { - // Because of recursive calls - return true; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/MarkReleaserTemplateSpecifiedEncodingHandler.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/ast/MarkReleaserTemplateSpecifiedEncodingHandler.java b/src/main/java/org/apache/freemarker/core/ast/MarkReleaserTemplateSpecifiedEncodingHandler.java deleted file mode 100644 index 66d1a78..0000000 --- a/src/main/java/org/apache/freemarker/core/ast/MarkReleaserTemplateSpecifiedEncodingHandler.java +++ /dev/null @@ -1,56 +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.ast; - -import java.io.InputStream; - -import org.apache.freemarker.core.Template.WrongEncodingException; - -/** - * A {@link TemplateSpecifiedEncodingHandler} that discards the mark of the specified {@link InputStream} when - * the template parsing gets to a point where it's known that we can't receive a template specified encoding anymore. - * This allows freeing up the mark buffer early during parsing. - * - * @since 2.3.16 - */ -public class MarkReleaserTemplateSpecifiedEncodingHandler implements TemplateSpecifiedEncodingHandler { - - private final InputStream markedInputStream; - - /** - * @param markedInputStream Input stream with marked template content start position - */ - public MarkReleaserTemplateSpecifiedEncodingHandler(InputStream markedInputStream) { - this.markedInputStream = markedInputStream; - } - - @Override - public void handle(String templateSpecificEncoding, String constructorSpecifiedEncoding) - throws WrongEncodingException { - TemplateSpecifiedEncodingHandler.DEFAULT.handle(templateSpecificEncoding, constructorSpecifiedEncoding); - - // There was no WrongEncodingException exception, release mark buffer: - markedInputStream.mark(0); // - } - - public InputStream getMarkedInputStream() { - return markedInputStream; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/MarkupOutputFormat.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/ast/MarkupOutputFormat.java b/src/main/java/org/apache/freemarker/core/ast/MarkupOutputFormat.java deleted file mode 100644 index 83c5373..0000000 --- a/src/main/java/org/apache/freemarker/core/ast/MarkupOutputFormat.java +++ /dev/null @@ -1,132 +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.ast; - -import java.io.IOException; -import java.io.Writer; - -import org.apache.freemarker.core.Configuration; -import org.apache.freemarker.core.model.TemplateModelException; - -/** - * Superclass of {@link OutputFormat}-s that represent a "markup" format, which is any format where certain character - * sequences have special meaning and thus may need escaping. (Escaping is important for FreeMarker, as typically it has - * to insert non-markup text from the data-model into the output markup. See also: - * {@link Configuration#setOutputFormat(OutputFormat)}.) - * - * <p> - * An {@link OutputFormat} subclass always has a corresponding {@link TemplateMarkupOutputModel} subclass pair (like - * {@link HTMLOutputFormat} has {@link TemplateHTMLOutputModel}). The {@link OutputFormat} implements the operations - * related to {@link TemplateMarkupOutputModel} objects of that kind, while the {@link TemplateMarkupOutputModel} only - * encapsulates the data (the actual markup or text). - * - * <p> - * To implement a custom output format, you may want to extend {@link CommonMarkupOutputFormat}. - * - * @param <MO> - * The {@link TemplateMarkupOutputModel} class this output format can deal with. - * - * @since 2.3.24 - */ -public abstract class MarkupOutputFormat<MO extends TemplateMarkupOutputModel> extends OutputFormat { - - protected MarkupOutputFormat() { - // Only to decrease visibility - } - - /** - * Converts a {@link String} that's assumed to be plain text to {@link TemplateMarkupOutputModel}, by escaping any - * special characters in the plain text. This corresponds to {@code ?esc}, or, to outputting with auto-escaping if - * that wasn't using {@link #output(String, Writer)} as an optimization. - * - * @see #escapePlainText(String) - * @see #getSourcePlainText(TemplateMarkupOutputModel) - */ - public abstract MO fromPlainTextByEscaping(String textToEsc) throws TemplateModelException; - - /** - * Wraps a {@link String} that's already markup to {@link TemplateMarkupOutputModel} interface, to indicate its - * format. This corresponds to {@code ?noEsc}. (This methods is allowed to throw {@link TemplateModelException} if - * the parameter markup text is malformed, but it's unlikely that an implementation chooses to parse the parameter - * until, and if ever, that becomes necessary.) - * - * @see #getMarkupString(TemplateMarkupOutputModel) - */ - public abstract MO fromMarkup(String markupText) throws TemplateModelException; - - /** - * Prints the parameter model to the output. - */ - public abstract void output(MO mo, Writer out) throws IOException, TemplateModelException; - - /** - * Equivalent to calling {@link #fromPlainTextByEscaping(String)} and then - * {@link #output(TemplateMarkupOutputModel, Writer)}, but the implementation may uses a more efficient solution. - */ - public abstract void output(String textToEsc, Writer out) throws IOException, TemplateModelException; - - /** - * If this {@link TemplateMarkupOutputModel} was created with {@link #fromPlainTextByEscaping(String)}, it returns - * the original plain text, otherwise it returns {@code null}. Useful for converting between different types - * of markups, as if the source format can be converted to plain text without loss, then that just has to be - * re-escaped with the target format to do the conversion. - */ - public abstract String getSourcePlainText(MO mo) throws TemplateModelException; - - /** - * Returns the content as markup text; never {@code null}. If this {@link TemplateMarkupOutputModel} was created - * with {@link #fromMarkup(String)}, it might returns the original markup text literally, but this is not required - * as far as the returned markup means the same. If this {@link TemplateMarkupOutputModel} wasn't created - * with {@link #fromMarkup(String)} and it doesn't yet have the markup, it has to generate the markup now. - */ - public abstract String getMarkupString(MO mo) throws TemplateModelException; - - /** - * Returns a {@link TemplateMarkupOutputModel} that contains the content of both {@link TemplateMarkupOutputModel} - * objects concatenated. - */ - public abstract MO concat(MO mo1, MO mo2) throws TemplateModelException; - - /** - * Should give the same result as {@link #fromPlainTextByEscaping(String)} and then - * {@link #getMarkupString(TemplateMarkupOutputModel)}, but the implementation may uses a more efficient solution. - */ - public abstract String escapePlainText(String plainTextContent) throws TemplateModelException; - - /** - * Returns if the markup is empty (0 length). This is used by at least {@code ?hasContent}. - */ - public abstract boolean isEmpty(MO mo) throws TemplateModelException; - - /** - * Tells if a string built-in that can't handle a {@link TemplateMarkupOutputModel} left hand operand can bypass - * this object as is. A typical such case would be when a {@link TemplateHTMLOutputModel} of "HTML" format bypasses - * {@code ?html}. - */ - public abstract boolean isLegacyBuiltInBypassed(String builtInName) throws TemplateModelException; - - /** - * Tells if by default auto-escaping should be on for this format. It should be {@code true} if you need to escape - * on most of the places where you insert values. - * - * @see Configuration#setAutoEscapingPolicy(int) - */ - public abstract boolean isAutoEscapedByDefault(); - -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/MarkupOutputFormatBoundBuiltIn.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/ast/MarkupOutputFormatBoundBuiltIn.java b/src/main/java/org/apache/freemarker/core/ast/MarkupOutputFormatBoundBuiltIn.java deleted file mode 100644 index d1c0dc5..0000000 --- a/src/main/java/org/apache/freemarker/core/ast/MarkupOutputFormatBoundBuiltIn.java +++ /dev/null @@ -1,46 +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.ast; - -import org.apache.freemarker.core.TemplateException; -import org.apache.freemarker.core.model.TemplateModel; -import org.apache.freemarker.core.util._NullArgumentException; - -abstract class MarkupOutputFormatBoundBuiltIn extends SpecialBuiltIn { - - protected MarkupOutputFormat outputFormat; - - void bindToMarkupOutputFormat(MarkupOutputFormat outputFormat) { - _NullArgumentException.check(outputFormat); - this.outputFormat = outputFormat; - } - - @Override - TemplateModel _eval(Environment env) throws TemplateException { - if (outputFormat == null) { - // The parser should prevent this situation - throw new NullPointerException("outputFormat was null"); - } - return calculateResult(env); - } - - protected abstract TemplateModel calculateResult(Environment env) - throws TemplateException; - -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/MessageUtil.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/ast/MessageUtil.java b/src/main/java/org/apache/freemarker/core/ast/MessageUtil.java deleted file mode 100644 index 9e53b50..0000000 --- a/src/main/java/org/apache/freemarker/core/ast/MessageUtil.java +++ /dev/null @@ -1,352 +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.ast; - -import java.util.ArrayList; - -import org.apache.freemarker.core.Template; -import org.apache.freemarker.core.TemplateException; -import org.apache.freemarker.core.model.TemplateModel; -import org.apache.freemarker.core.model.TemplateModelException; -import org.apache.freemarker.core.util._StringUtil; - -/** - * Utilities for creating error messages (and other messages). - */ -class MessageUtil { - - static final String UNKNOWN_DATE_TO_STRING_ERROR_MESSAGE - = "Can't convert the date-like value to string because it isn't " - + "known if it's a date (no time part), time or date-time value."; - - static final String UNKNOWN_DATE_PARSING_ERROR_MESSAGE - = "Can't parse the string to date-like value because it isn't " - + "known if it's desired result should be a date (no time part), a time, or a date-time value."; - - static final String UNKNOWN_DATE_TYPE_ERROR_TIP = - "Use ?date, ?time, or ?datetime to tell FreeMarker the exact type."; - - static final Object[] UNKNOWN_DATE_TO_STRING_TIPS = { - UNKNOWN_DATE_TYPE_ERROR_TIP, - "If you need a particular format only once, use ?string(pattern), like ?string('dd.MM.yyyy HH:mm:ss'), " - + "to specify which fields to display. " - }; - - static final String EMBEDDED_MESSAGE_BEGIN = "---begin-message---\n"; - - static final String EMBEDDED_MESSAGE_END = "\n---end-message---"; - - // Can't be instantiated - private MessageUtil() { } - - static String formatLocationForSimpleParsingError(Template template, int line, int column) { - return formatLocation("in", template, line, column); - } - - static String formatLocationForSimpleParsingError(String templateSourceName, int line, int column) { - return formatLocation("in", templateSourceName, line, column); - } - - static String formatLocationForDependentParsingError(Template template, int line, int column) { - return formatLocation("on", template, line, column); - } - - static String formatLocationForDependentParsingError(String templateSourceName, int line, int column) { - return formatLocation("on", templateSourceName, line, column); - } - - static String formatLocationForEvaluationError(Template template, int line, int column) { - return formatLocation("at", template, line, column); - } - - static String formatLocationForEvaluationError(Macro macro, int line, int column) { - Template t = macro.getTemplate(); - return formatLocation("at", t != null ? t.getSourceName() : null, macro.getName(), macro.isFunction(), line, column); - } - - static String formatLocationForEvaluationError(String templateSourceName, int line, int column) { - return formatLocation("at", templateSourceName, line, column); - } - - private static String formatLocation(String preposition, Template template, int line, int column) { - return formatLocation(preposition, template != null ? template.getSourceName() : null, line, column); - } - - private static String formatLocation(String preposition, String templateSourceName, int line, int column) { - return formatLocation( - preposition, templateSourceName, - null, false, - line, column); - } - - private static String formatLocation( - String preposition, String templateSourceName, - String macroOrFuncName, boolean isFunction, - int line, int column) { - String templateDesc; - if (line < 0) { - templateDesc = "?eval-ed string"; - macroOrFuncName = null; - } else { - templateDesc = templateSourceName != null - ? "template " + _StringUtil.jQuoteNoXSS(templateSourceName) - : "nameless template"; - } - return "in " + templateDesc - + (macroOrFuncName != null - ? " in " + (isFunction ? "function " : "macro ") + _StringUtil.jQuote(macroOrFuncName) - : "") - + " " - + preposition + " " + formatPosition(line, column); - } - - static String formatPosition(int line, int column) { - return "line " + (line >= 0 ? line : line - (TemplateObject.RUNTIME_EVAL_LINE_DISPLACEMENT - 1)) - + ", column " + column; - } - - /** - * Returns a single line string that is no longer than {@code maxLength}. - * If will truncate the string at line-breaks too. - * The truncation is always signaled with a a {@code "..."} at the end of the result string. - */ - static String shorten(String s, int maxLength) { - if (maxLength < 5) maxLength = 5; - - boolean isTruncated = false; - - int brIdx = s.indexOf('\n'); - if (brIdx != -1) { - s = s.substring(0, brIdx); - isTruncated = true; - }; - brIdx = s.indexOf('\r'); - if (brIdx != -1) { - s = s.substring(0, brIdx); - isTruncated = true; - } - - if (s.length() > maxLength) { - s = s.substring(0, maxLength - 3); - isTruncated = true; - } - - if (!isTruncated) { - return s; - } else { - if (s.endsWith(".")) { - if (s.endsWith("..")) { - if (s.endsWith("...")) { - return s; - } else { - return s + "."; - } - } else { - return s + ".."; - } - } else { - return s + "..."; - } - } - } - - static StringBuilder appendExpressionAsUntearable(StringBuilder sb, Expression argExp) { - boolean needParen = - !(argExp instanceof NumberLiteral) - && !(argExp instanceof StringLiteral) - && !(argExp instanceof BooleanLiteral) - && !(argExp instanceof ListLiteral) - && !(argExp instanceof HashLiteral) - && !(argExp instanceof Identifier) - && !(argExp instanceof Dot) - && !(argExp instanceof DynamicKeyName) - && !(argExp instanceof MethodCall) - && !(argExp instanceof BuiltIn); - if (needParen) sb.append('('); - sb.append(argExp.getCanonicalForm()); - if (needParen) sb.append(')'); - return sb; - } - - static TemplateModelException newArgCntError(String methodName, int argCnt, int expectedCnt) { - return newArgCntError(methodName, argCnt, expectedCnt, expectedCnt); - } - - static TemplateModelException newArgCntError(String methodName, int argCnt, int minCnt, int maxCnt) { - ArrayList/*<Object>*/ desc = new ArrayList(20); - - desc.add(methodName); - - desc.add("("); - if (maxCnt != 0) desc.add("..."); - desc.add(") expects "); - - if (minCnt == maxCnt) { - if (maxCnt == 0) { - desc.add("no"); - } else { - desc.add(Integer.valueOf(maxCnt)); - } - } else if (maxCnt - minCnt == 1) { - desc.add(Integer.valueOf(minCnt)); - desc.add(" or "); - desc.add(Integer.valueOf(maxCnt)); - } else { - desc.add(Integer.valueOf(minCnt)); - if (maxCnt != Integer.MAX_VALUE) { - desc.add(" to "); - desc.add(Integer.valueOf(maxCnt)); - } else { - desc.add(" or more (unlimited)"); - } - } - desc.add(" argument"); - if (maxCnt > 1) desc.add("s"); - - desc.add(" but has received "); - if (argCnt == 0) { - desc.add("none"); - } else { - desc.add(Integer.valueOf(argCnt)); - } - desc.add("."); - - return new _TemplateModelException(desc.toArray()); - } - - static TemplateModelException newMethodArgMustBeStringException(String methodName, int argIdx, TemplateModel arg) { - return newMethodArgUnexpectedTypeException(methodName, argIdx, "string", arg); - } - - static TemplateModelException newMethodArgMustBeNumberException(String methodName, int argIdx, TemplateModel arg) { - return newMethodArgUnexpectedTypeException(methodName, argIdx, "number", arg); - } - - static TemplateModelException newMethodArgMustBeBooleanException(String methodName, int argIdx, TemplateModel arg) { - return newMethodArgUnexpectedTypeException(methodName, argIdx, "boolean", arg); - } - - static TemplateModelException newMethodArgMustBeExtendedHashException( - String methodName, int argIdx, TemplateModel arg) { - return newMethodArgUnexpectedTypeException(methodName, argIdx, "extended hash", arg); - } - - static TemplateModelException newMethodArgMustBeSequenceException( - String methodName, int argIdx, TemplateModel arg) { - return newMethodArgUnexpectedTypeException(methodName, argIdx, "sequence", arg); - } - - static TemplateModelException newMethodArgMustBeSequenceOrCollectionException( - String methodName, int argIdx, TemplateModel arg) { - return newMethodArgUnexpectedTypeException(methodName, argIdx, "sequence or collection", arg); - } - - static TemplateModelException newMethodArgUnexpectedTypeException( - String methodName, int argIdx, String expectedType, TemplateModel arg) { - return new _TemplateModelException( - methodName, "(...) expects ", new _DelayedAOrAn(expectedType), " as argument #", Integer.valueOf(argIdx + 1), - ", but received ", new _DelayedAOrAn(new _DelayedFTLTypeDescription(arg)), "."); - } - - /** - * The type of the argument was good, but it's value wasn't. - */ - static TemplateModelException newMethodArgInvalidValueException( - String methodName, int argIdx, Object... details) { - return new _TemplateModelException( - methodName, "(...) argument #", Integer.valueOf(argIdx + 1), - " had invalid value: ", details); - } - - /** - * The type of the argument was good, but the values of two or more arguments are inconsistent with each other. - */ - static TemplateModelException newMethodArgsInvalidValueException( - String methodName, Object... details) { - return new _TemplateModelException(methodName, "(...) arguments have invalid value: ", details); - } - - static TemplateException newInstantiatingClassNotAllowedException(String className, Environment env) { - return new _MiscTemplateException(env, - "Instantiating ", className, " is not allowed in the template for security reasons."); - } - - static _TemplateModelException newCantFormatUnknownTypeDateException( - Expression dateSourceExpr, UnknownDateTypeFormattingUnsupportedException cause) { - return new _TemplateModelException(cause, null, new _ErrorDescriptionBuilder( - MessageUtil.UNKNOWN_DATE_TO_STRING_ERROR_MESSAGE) - .blame(dateSourceExpr) - .tips(MessageUtil.UNKNOWN_DATE_TO_STRING_TIPS)); - } - - static TemplateException newCantFormatDateException(TemplateDateFormat format, Expression dataSrcExp, - TemplateValueFormatException e, boolean useTempModelExc) { - _ErrorDescriptionBuilder desc = new _ErrorDescriptionBuilder( - "Failed to format date/time/datetime with format ", new _DelayedJQuote(format.getDescription()), ": ", - e.getMessage()) - .blame(dataSrcExp); - return useTempModelExc - ? new _TemplateModelException(e, null, desc) - : new _MiscTemplateException(e, null, desc); - } - - static TemplateException newCantFormatNumberException(TemplateNumberFormat format, Expression dataSrcExp, - TemplateValueFormatException e, boolean useTempModelExc) { - _ErrorDescriptionBuilder desc = new _ErrorDescriptionBuilder( - "Failed to format number with format ", new _DelayedJQuote(format.getDescription()), ": ", - e.getMessage()) - .blame(dataSrcExp); - return useTempModelExc - ? new _TemplateModelException(e, null, desc) - : new _MiscTemplateException(e, null, desc); - } - - /** - * @return "a" or "an" or "a(n)" (or "" for empty string) for an FTL type name - */ - static String getAOrAn(String s) { - if (s == null) return null; - if (s.length() == 0) return ""; - - char fc = Character.toLowerCase(s.charAt(0)); - if (fc == 'a' || fc == 'e' || fc == 'i') { - return "an"; - } else if (fc == 'h') { - String ls = s.toLowerCase(); - if (ls.startsWith("has") || ls.startsWith("hi")) { - return "a"; - } else if (ls.startsWith("ht")) { - return "an"; - } else { - return "a(n)"; - } - } else if (fc == 'u' || fc == 'o') { - return "a(n)"; - } else { - char sc = (s.length() > 1) ? s.charAt(1) : '\0'; - if (fc == 'x' && !(sc == 'a' || sc == 'e' || sc == 'i' || sc == 'a' || sc == 'o' || sc == 'u')) { - return "an"; - } else { - return "a"; - } - } - } - -}
