You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@freemarker.apache.org by dd...@apache.org on 2017/05/14 10:53:09 UTC
[26/51] [partial] incubator-freemarker git commit: Migrated from Ant
to Gradle, and modularized the project. This is an incomplete migration;
there are some TODO-s in the build scripts, and release related tasks are
still missing. What works: Building th
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3fd56062/freemarker-core/src/main/java/org/apache/freemarker/core/model/ObjectWrapperAndUnwrapper.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/ObjectWrapperAndUnwrapper.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/ObjectWrapperAndUnwrapper.java
new file mode 100644
index 0000000..3494eb7
--- /dev/null
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/ObjectWrapperAndUnwrapper.java
@@ -0,0 +1,90 @@
+/*
+ * 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.model;
+
+/**
+ * <b>Experimental - subject to change:</b> Adds functionality to {@link ObjectWrapper} that creates a plain Java object
+ * from a {@link TemplateModel}. This is usually implemented by {@link ObjectWrapper}-s and reverses
+ * {@link ObjectWrapper#wrap(Object)}. However, an implementation of this interface should make a reasonable effort to
+ * "unwrap" {@link TemplateModel}-s that wasn't the result of object wrapping (such as those created directly in FTL),
+ * or which was created by another {@link ObjectWrapper}. The author of an {@link ObjectWrapperAndUnwrapper} should be
+ * aware of the {@link TemplateModelAdapter} and {@link WrapperTemplateModel} interfaces, which should be used for
+ * unwrapping if the {@link TemplateModel} implements them.
+ *
+ * <p>
+ * <b>Experimental status warning:</b> This interface is subject to change on non-backward compatible ways, hence, it
+ * shouldn't be implemented outside FreeMarker yet.
+ *
+ * @since 2.3.22
+ */
+public interface ObjectWrapperAndUnwrapper extends ObjectWrapper {
+
+ /**
+ * Indicates that while the unwrapping is <em>maybe</em> possible, the result surely can't be the instance of the
+ * desired class, nor it can be {@code null}.
+ *
+ * @see #tryUnwrapTo(TemplateModel, Class)
+ *
+ * @since 2.3.22
+ */
+ Object CANT_UNWRAP_TO_TARGET_CLASS = new Object();
+
+ /**
+ * Unwraps a {@link TemplateModel} to a plain Java object.
+ *
+ * @return The plain Java object. Can be {@code null}, if {@code null} is the appropriate Java value to represent
+ * the template model. {@code null} must not be used to indicate an unwrapping failure. It must NOT be
+ * {@link #CANT_UNWRAP_TO_TARGET_CLASS}.
+ *
+ * @throws TemplateModelException
+ * If the unwrapping fails from any reason.
+ *
+ * @see #tryUnwrapTo(TemplateModel, Class)
+ *
+ * @since 2.3.22
+ */
+ Object unwrap(TemplateModel tm) throws TemplateModelException;
+
+ /**
+ * Attempts to unwrap a {@link TemplateModel} to a plain Java object that's the instance of the given class (or is
+ * {@code null}).
+ *
+ * @param targetClass
+ * The class that the return value must be an instance of (except when the return value is {@code null}).
+ * Can't be {@code null}; if the caller doesn't care, it should either use {#unwrap(TemplateModel)}, or
+ * {@code Object.class} as the parameter value.
+ *
+ * @return The unwrapped value that's either an instance of {@code targetClass}, or is {@code null} (if {@code null}
+ * is the appropriate Java value to represent the template model), or is
+ * {@link #CANT_UNWRAP_TO_TARGET_CLASS} if the unwrapping can't satisfy the {@code targetClass} (nor the
+ * result can be {@code null}). However, {@link #CANT_UNWRAP_TO_TARGET_CLASS} must not be returned if the
+ * {@code targetClass} parameter was {@code Object.class}.
+ *
+ * @throws TemplateModelException
+ * If the unwrapping fails for a reason than doesn't fit the meaning of the
+ * {@link #CANT_UNWRAP_TO_TARGET_CLASS} return value.
+ *
+ * @see #unwrap(TemplateModel)
+ *
+ * @since 2.3.22
+ */
+ Object tryUnwrapTo(TemplateModel tm, Class<?> targetClass) throws TemplateModelException;
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3fd56062/freemarker-core/src/main/java/org/apache/freemarker/core/model/ObjectWrapperWithAPISupport.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/ObjectWrapperWithAPISupport.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/ObjectWrapperWithAPISupport.java
new file mode 100644
index 0000000..102a2f0
--- /dev/null
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/ObjectWrapperWithAPISupport.java
@@ -0,0 +1,46 @@
+/*
+ * 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.model;
+
+/**
+ * <b>Experimental - subject to change:</b> Implemented by {@link ObjectWrapper}-s to help {@link TemplateModel}-s to
+ * implement the {@code someValue?api} operation.
+ *
+ * <p>
+ * <b>Experimental status warning:</b> This interface is subject to change on non-backward compatible ways, hence, it
+ * shouldn't be implemented outside FreeMarker yet.
+ *
+ * @since 2.3.22
+ */
+public interface ObjectWrapperWithAPISupport extends ObjectWrapper {
+
+ /**
+ * Wraps an object to a {@link TemplateModel} that exposes the object's "native" (usually, Java) API.
+ *
+ * @param obj
+ * The object for which the API model has to be returned. Shouldn't be {@code null}.
+ *
+ * @return The {@link TemplateModel} through which the API of the object can be accessed. Can't be {@code null}.
+ *
+ * @since 2.3.22
+ */
+ TemplateHashModel wrapAsAPI(Object obj) throws TemplateModelException;
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3fd56062/freemarker-core/src/main/java/org/apache/freemarker/core/model/RichObjectWrapper.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/RichObjectWrapper.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/RichObjectWrapper.java
new file mode 100644
index 0000000..5dfa3be
--- /dev/null
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/RichObjectWrapper.java
@@ -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.
+ */
+
+package org.apache.freemarker.core.model;
+
+/**
+ * <b>Experimental - subject to change:</b> Union of the interfaces that a typical feature rich {@link ObjectWrapper} is
+ * expected to implement.
+ *
+ * <p>
+ * <b>Experimental status warning:</b> This interface is subject to change on non-backward compatible ways, hence, it
+ * shouldn't be implemented outside FreeMarker yet.
+ *
+ * @since 2.3.22
+ */
+public interface RichObjectWrapper extends ObjectWrapperAndUnwrapper, ObjectWrapperWithAPISupport {
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3fd56062/freemarker-core/src/main/java/org/apache/freemarker/core/model/SerializableTemplateBooleanModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/SerializableTemplateBooleanModel.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/SerializableTemplateBooleanModel.java
new file mode 100644
index 0000000..b01e7df
--- /dev/null
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/SerializableTemplateBooleanModel.java
@@ -0,0 +1,24 @@
+/*
+ * 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.model;
+
+import java.io.Serializable;
+
+interface SerializableTemplateBooleanModel extends TemplateBooleanModel, Serializable {}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3fd56062/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateBooleanModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateBooleanModel.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateBooleanModel.java
new file mode 100644
index 0000000..555e619
--- /dev/null
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateBooleanModel.java
@@ -0,0 +1,48 @@
+/*
+ * 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.model;
+
+import java.io.Serializable;
+
+/**
+ * "boolean" template language data type; same as in Java; either {@code true} or {@code false}.
+ *
+ * <p>
+ * Objects of this type should be immutable, that is, calling {@link #getAsBoolean()} should always return the same
+ * value as for the first time.
+ */
+public interface TemplateBooleanModel extends TemplateModel, Serializable {
+
+ /**
+ * @return whether to interpret this object as true or false in a boolean context
+ */
+ boolean getAsBoolean() throws TemplateModelException;
+
+ /**
+ * A singleton object to represent boolean false
+ */
+ TemplateBooleanModel FALSE = new FalseTemplateBooleanModel();
+
+ /**
+ * A singleton object to represent boolean true
+ */
+ TemplateBooleanModel TRUE = new TrueTemplateBooleanModel();
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3fd56062/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateCollectionModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateCollectionModel.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateCollectionModel.java
new file mode 100644
index 0000000..e870c2f
--- /dev/null
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateCollectionModel.java
@@ -0,0 +1,48 @@
+/*
+ * 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.model;
+
+import java.util.Collection;
+
+/**
+ * "collection" template language data type: a collection of values that can be enumerated, but can't be or not meant to
+ * be accessed by index or key. As such, this is not a super-interface of {@link TemplateSequenceModel}, and
+ * implementations of that interface needn't also implement this interface just because they can. They should though, if
+ * enumeration with this interface is significantly faster than enumeration by index. The {@code #list} directive will
+ * enumerate using this interface if it's available.
+ *
+ * <p>
+ * The enumeration should be repeatable if that's possible with reasonable effort, otherwise a second enumeration
+ * attempt is allowed to throw an {@link TemplateModelException}. Generally, the interface user Java code need not
+ * handle that kind of exception, as in practice only the template author can handle it, by not listing such collections
+ * twice.
+ *
+ * <p>
+ * Note that to wrap Java's {@link Collection}, you should implement {@link TemplateCollectionModelEx}, not just this
+ * interface.
+ */
+public interface TemplateCollectionModel extends TemplateModel {
+
+ /**
+ * Retrieves a template model iterator that is used to iterate over the elements in this collection.
+ */
+ TemplateModelIterator iterator() throws TemplateModelException;
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3fd56062/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateCollectionModelEx.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateCollectionModelEx.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateCollectionModelEx.java
new file mode 100644
index 0000000..92f0e3a
--- /dev/null
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateCollectionModelEx.java
@@ -0,0 +1,45 @@
+/*
+ * 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.model;
+
+import java.util.Collection;
+
+/**
+ * "extended collection" template language data type: Adds size/emptiness querybility and "contains" test to
+ * {@link TemplateCollectionModel}. The added extra operations is provided by all Java {@link Collection}-s, and
+ * this interface was added to make that accessible for templates too.
+ *
+ * @since 2.3.22
+ */
+public interface TemplateCollectionModelEx extends TemplateCollectionModel {
+
+ /**
+ * Returns the number items in this collection, or {@link Integer#MAX_VALUE}, if there are more than
+ * {@link Integer#MAX_VALUE} items.
+ */
+ int size() throws TemplateModelException;
+
+ /**
+ * Returns if the collection contains any elements. This differs from {@code size() != 0} only in that the exact
+ * number of items need not be calculated.
+ */
+ boolean isEmpty() throws TemplateModelException;
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3fd56062/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateDateModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateDateModel.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateDateModel.java
new file mode 100644
index 0000000..ab85e97
--- /dev/null
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateDateModel.java
@@ -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.
+ */
+
+package org.apache.freemarker.core.model;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * "date", "time" and "date-time" template language data types: corresponds to {@link java.util.Date}. Contrary to Java,
+ * FreeMarker distinguishes date (no time part), time and date-time values.
+ *
+ * <p>
+ * Objects of this type should be immutable, that is, calling {@link #getAsDate()} and {@link #getDateType()} should
+ * always return the same value as for the first time.
+ */
+public interface TemplateDateModel extends TemplateModel {
+
+ /**
+ * It is not known whether the date represents a date, a time, or a date-time value.
+ * This often leads to exceptions in templates due to ambiguities it causes, so avoid it if possible.
+ */
+ int UNKNOWN = 0;
+
+ /**
+ * The date model represents a time value (no date part).
+ */
+ int TIME = 1;
+
+ /**
+ * The date model represents a date value (no time part).
+ */
+ int DATE = 2;
+
+ /**
+ * The date model represents a date-time value (also known as timestamp).
+ */
+ int DATETIME = 3;
+
+ List TYPE_NAMES =
+ Collections.unmodifiableList(
+ Arrays.asList(
+ "UNKNOWN", "TIME", "DATE", "DATETIME"));
+ /**
+ * Returns the date value. The return value must not be {@code null}.
+ */
+ Date getAsDate() throws TemplateModelException;
+
+ /**
+ * Returns the type of the date. It can be any of {@link #TIME},
+ * {@link #DATE}, or {@link #DATETIME}.
+ */
+ int getDateType();
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3fd56062/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateDirectiveBody.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateDirectiveBody.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateDirectiveBody.java
new file mode 100644
index 0000000..bb54eb4
--- /dev/null
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateDirectiveBody.java
@@ -0,0 +1,45 @@
+/*
+ * 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.model;
+
+import java.io.IOException;
+import java.io.Writer;
+
+import org.apache.freemarker.core.TemplateException;
+
+/**
+ * Represents the nested content of a directive ({@link TemplateDirectiveModel}) invocation. An implementation of this
+ * class is passed to {@link TemplateDirectiveModel#execute(org.apache.freemarker.core.Environment,
+ * java.util.Map, TemplateModel[], TemplateDirectiveBody)}. The implementation of the method is
+ * free to invoke it for any number of times, with any writer.
+ *
+ * @since 2.3.11
+ */
+public interface TemplateDirectiveBody {
+ /**
+ * Renders the body of the directive body to the specified writer. The
+ * writer is not flushed after the rendering. If you pass the environment's
+ * writer, there is no need to flush it. If you supply your own writer, you
+ * are responsible to flush/close it when you're done with using it (which
+ * might be after multiple renderings).
+ * @param out the writer to write the output to.
+ */
+ void render(Writer out) throws TemplateException, IOException;
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3fd56062/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateDirectiveModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateDirectiveModel.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateDirectiveModel.java
new file mode 100644
index 0000000..c4020c9
--- /dev/null
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateDirectiveModel.java
@@ -0,0 +1,69 @@
+/*
+ * 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.model;
+
+import java.io.IOException;
+import java.util.Map;
+
+import org.apache.freemarker.core.Environment;
+import org.apache.freemarker.core.TemplateException;
+import org.apache.freemarker.core.util.DeepUnwrap;
+
+/**
+ * "directive" template language data type: used as user-defined directives
+ * (much like macros) in templates. They can do arbitrary actions, write arbitrary
+ * text to the template output, and trigger rendering of their nested content for
+ * any number of times.
+ *
+ * <p>They are used in templates like {@code <@myDirective foo=1 bar="wombat">...</...@myDirective>} (or as
+ * {@code <@myDirective foo=1 bar="wombat" />} - the nested content is optional).
+ *
+ * @since 2.3.11
+ */
+public interface TemplateDirectiveModel extends TemplateModel {
+ /**
+ * Executes this user-defined directive; called by FreeMarker when the user-defined
+ * directive is called in the template.
+ *
+ * @param env the current processing environment. Note that you can access
+ * the output {@link java.io.Writer Writer} by {@link Environment#getOut()}.
+ * @param params the parameters (if any) passed to the directive as a
+ * map of key/value pairs where the keys are {@link String}-s and the
+ * values are {@link TemplateModel} instances. This is never
+ * <code>null</code>. If you need to convert the template models to POJOs,
+ * you can use the utility methods in the {@link DeepUnwrap} class.
+ * @param loopVars an array that corresponds to the "loop variables", in
+ * the order as they appear in the directive call. ("Loop variables" are out-parameters
+ * that are available to the nested body of the directive; see in the Manual.)
+ * You set the loop variables by writing this array. The length of the array gives the
+ * number of loop-variables that the caller has specified.
+ * Never <code>null</code>, but can be a zero-length array.
+ * @param body an object that can be used to render the nested content (body) of
+ * the directive call. If the directive call has no nested content (i.e., it's like
+ * <@myDirective /> or <@myDirective></@myDirective>), then this will be
+ * <code>null</code>.
+ *
+ * @throws TemplateException If any problem occurs that's not an {@link IOException} during writing the template
+ * output.
+ * @throws IOException When writing the template output fails.
+ */
+ void execute(Environment env, Map params, TemplateModel[] loopVars,
+ TemplateDirectiveBody body) throws TemplateException, IOException;
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3fd56062/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateHashModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateHashModel.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateHashModel.java
new file mode 100644
index 0000000..647055a
--- /dev/null
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateHashModel.java
@@ -0,0 +1,41 @@
+/*
+ * 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.model;
+
+/**
+ * "hash" template language data type: an object that contains other objects accessible through string keys
+ * (sub-variable names).
+ *
+ * <p>In templates they are used like {@code myHash.myKey} or {@code myHash[myDynamicKey]}.
+ */
+public interface TemplateHashModel extends TemplateModel {
+
+ /**
+ * Gets a <tt>TemplateModel</tt> from the hash.
+ *
+ * @param key the name by which the <tt>TemplateModel</tt>
+ * is identified in the template.
+ * @return the <tt>TemplateModel</tt> referred to by the key,
+ * or null if not found.
+ */
+ TemplateModel get(String key) throws TemplateModelException;
+
+ boolean isEmpty() throws TemplateModelException;
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3fd56062/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateHashModelEx.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateHashModelEx.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateHashModelEx.java
new file mode 100644
index 0000000..c95a21d
--- /dev/null
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateHashModelEx.java
@@ -0,0 +1,51 @@
+/*
+ * 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.model;
+
+import org.apache.freemarker.core.model.impl.SimpleHash;
+
+/**
+ * "extended hash" template language data type; extends {@link TemplateHashModel} by allowing
+ * iterating through its keys and values.
+ *
+ * <p>In templates they are used like hashes, but these will also work (among others):
+ * {@code myExtHash?size}, {@code myExtHash?keys}, {@code myExtHash?values}.
+ * @see SimpleHash
+ */
+public interface TemplateHashModelEx extends TemplateHashModel {
+
+ /**
+ * @return the number of key/value mappings in the hash.
+ */
+ int size() throws TemplateModelException;
+
+ /**
+ * @return a collection containing the keys in the hash. Every element of
+ * the returned collection must implement the {@link TemplateScalarModel}
+ * (as the keys of hashes are always strings).
+ */
+ TemplateCollectionModel keys() throws TemplateModelException;
+
+ /**
+ * @return a collection containing the values in the hash. The elements of the
+ * returned collection can be any kind of {@link TemplateModel}-s.
+ */
+ TemplateCollectionModel values() throws TemplateModelException;
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3fd56062/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateHashModelEx2.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateHashModelEx2.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateHashModelEx2.java
new file mode 100644
index 0000000..86a72b1
--- /dev/null
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateHashModelEx2.java
@@ -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.
+ */
+package org.apache.freemarker.core.model;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+/**
+ * Adds key-value pair listing capability to {@link TemplateHashModelEx}. While in many cases that can also be achieved
+ * with {@link #keys()} and then {@link #get(String)}, that has some problems. One is that {@link #get(String)} only
+ * accepts string keys, while {@link #keys()} can return non-string keys too. The other is that calling {@link #keys()}
+ * and then {@link #get(String)} for each key can be slower than listing the key-value pairs in one go.
+ *
+ * @since 2.3.25
+ */
+public interface TemplateHashModelEx2 extends TemplateHashModelEx {
+
+ /**
+ * @return The iterator that walks through the key-value pairs in the hash. Not {@code null}.
+ */
+ KeyValuePairIterator keyValuePairIterator() throws TemplateModelException;
+
+ /**
+ * A key-value pair in a hash; used for {@link KeyValuePairIterator}.
+ *
+ * @since 2.3.25
+ */
+ interface KeyValuePair {
+
+ /**
+ * @return Any type of {@link TemplateModel}, maybe {@code null} (if the hash entry key is {@code null}).
+ */
+ TemplateModel getKey() throws TemplateModelException;
+
+ /**
+ * @return Any type of {@link TemplateModel}, maybe {@code null} (if the hash entry value is {@code null}).
+ */
+ TemplateModel getValue() throws TemplateModelException;
+ }
+
+ /**
+ * Iterates over the key-value pairs in a hash. This is very similar to an {@link Iterator}, but has a oms item
+ * type, can throw {@link TemplateModelException}-s, and has no {@code remove()} method.
+ *
+ * @since 2.3.25
+ */
+ interface KeyValuePairIterator {
+
+ /**
+ * Similar to {@link Iterator#hasNext()}.
+ */
+ boolean hasNext() throws TemplateModelException;
+
+ /**
+ * Similar to {@link Iterator#next()}.
+ *
+ * @return Not {@code null}
+ *
+ * @throws NoSuchElementException
+ */
+ KeyValuePair next() throws TemplateModelException;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3fd56062/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateMarkupOutputModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateMarkupOutputModel.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateMarkupOutputModel.java
new file mode 100644
index 0000000..2215926
--- /dev/null
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateMarkupOutputModel.java
@@ -0,0 +1,52 @@
+/*
+ * 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.model;
+
+import org.apache.freemarker.core.outputformat.MarkupOutputFormat;
+import org.apache.freemarker.core.outputformat.OutputFormat;
+
+/**
+ * "markup output" template language data-type; stores markup (some kind of "rich text" / structured format, as opposed
+ * to plain text) that meant to be printed as template output. This type is related to the {@link OutputFormat}
+ * mechanism. Values of this kind are exempt from {@link OutputFormat}-based automatic escaping.
+ *
+ * <p>
+ * Each implementation of this type has a {@link OutputFormat} subclass pair, whose singleton instance is returned by
+ * {@link #getOutputFormat()}. See more about how markup output values work at {@link OutputFormat}.
+ *
+ * <p>
+ * Note that {@link TemplateMarkupOutputModel}-s are by design not treated like {@link TemplateScalarModel}-s, and so
+ * the implementations of this interface usually shouldn't implement {@link TemplateScalarModel}. (Because, operations
+ * applicable on plain strings, like converting to upper case, substringing, etc., can corrupt markup.) If the template
+ * author wants to pass in the "source" of the markup as string somewhere, he should use {@code ?markup_string}.
+ *
+ * @param <MO>
+ * Refers to the interface's own type, which is useful in interfaces that extend
+ * {@link TemplateMarkupOutputModel} (Java Generics trick).
+ *
+ * @since 2.3.24
+ */
+public interface TemplateMarkupOutputModel<MO extends TemplateMarkupOutputModel<MO>> extends TemplateModel {
+
+ /**
+ * Returns the singleton {@link OutputFormat} object that implements the operations for the "markup output" value.
+ */
+ MarkupOutputFormat<MO> getOutputFormat();
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3fd56062/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateMethodModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateMethodModel.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateMethodModel.java
new file mode 100644
index 0000000..5bfe7e3
--- /dev/null
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateMethodModel.java
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ */
+
+/*
+ * 22 October 1999: This class added by Holger Arendt.
+ */
+
+package org.apache.freemarker.core.model;
+
+import java.util.List;
+
+import org.apache.freemarker.core.Environment;
+
+/**
+ * "method" template language data type: Objects that act like functions. The name comes from that their original
+ * application was calling Java methods via {@link org.apache.freemarker.core.model.impl.DefaultObjectWrapper}.
+ *
+ * <p>In templates they are used like {@code myMethod("foo", "bar")} or {@code myJavaObject.myJavaMethod("foo", "bar")}.
+ *
+ * @deprecated Use {@link TemplateMethodModelEx} instead. This interface is from the old times when the only kind of
+ * value you could pass in was string.
+ */
+@Deprecated
+public interface TemplateMethodModel extends TemplateModel {
+
+ /**
+ * Executes the method call. All arguments passed to the method call are
+ * coerced to strings before being passed, if the FreeMarker rules allow
+ * the coercion. If some of the passed arguments can not be coerced to a
+ * string, an exception will be raised in the engine and the method will
+ * not be called. If your method would like to act on actual data model
+ * objects instead of on their string representations, implement the
+ * {@link TemplateMethodModelEx} instead.
+ *
+ * @param arguments a <tt>List</tt> of <tt>String</tt> objects
+ * containing the values of the arguments passed to the method.
+ *
+ * @return the return value of the method, or {@code null}. If the returned value
+ * does not implement {@link TemplateModel}, it will be automatically
+ * wrapped using the {@link Environment#getObjectWrapper() environment
+ * object wrapper}.
+ */
+ Object exec(List arguments) throws TemplateModelException;
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3fd56062/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateMethodModelEx.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateMethodModelEx.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateMethodModelEx.java
new file mode 100644
index 0000000..2517d22
--- /dev/null
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateMethodModelEx.java
@@ -0,0 +1,54 @@
+/*
+ * 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.model;
+
+import java.util.List;
+
+import org.apache.freemarker.core.Environment;
+import org.apache.freemarker.core.util.DeepUnwrap;
+
+/**
+ * "extended method" template language data type: Objects that act like functions. Their main application is calling
+ * Java methods via {@link org.apache.freemarker.core.model.impl.DefaultObjectWrapper}, but you can implement this interface to invoke
+ * top-level functions too. They are "extended" compared to the deprecated {@link TemplateMethodModel}, which could only
+ * accept string parameters.
+ *
+ * <p>In templates they are used like {@code myMethod(1, "foo")} or {@code myJavaObject.myJavaMethod(1, "foo")}.
+ */
+public interface TemplateMethodModelEx extends TemplateMethodModel {
+
+ /**
+ * Executes the method call.
+ *
+ * @param arguments a {@link List} of {@link TemplateModel}-s,
+ * containing the arguments passed to the method. If the implementation absolutely wants
+ * to operate on POJOs, it can use the static utility methods in the {@link DeepUnwrap}
+ * class to easily obtain them. However, unwrapping is not always possible (or not perfectly), and isn't always
+ * efficient, so it's recommended to use the original {@link TemplateModel} value as much as possible.
+ *
+ * @return the return value of the method, or {@code null}. If the returned value
+ * does not implement {@link TemplateModel}, it will be automatically
+ * wrapped using the {@link Environment#getObjectWrapper() environment's
+ * object wrapper}.
+ */
+ @Override
+ Object exec(List arguments) throws TemplateModelException;
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3fd56062/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateModel.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateModel.java
new file mode 100644
index 0000000..bbe3c03
--- /dev/null
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateModel.java
@@ -0,0 +1,55 @@
+/*
+ * 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.model;
+
+import org.apache.freemarker.core.Configuration;
+import org.apache.freemarker.core.util.FTLUtil;
+
+/**
+ * The common super-interface of the interfaces that stand for the FreeMarker Template Language (FTL) data types.
+ * The template language only deals with {@link TemplateModel}-s, not directly with plain Java objects. (For example,
+ * it doesn't understand {@link java.lang.Number}, but {@link TemplateNumberModel}.) This is why the
+ * data-model (aka. the "template context" in other languages) is (automatically) mapped to a tree of
+ * {@link TemplateModel}-s.
+ *
+ * <p>Mapping the plain Java objects to {@link TemplateModel}-s (or the other way around sometimes) is the
+ * responsibility of the {@link ObjectWrapper} (see the {@link Configuration#getObjectWrapper objectWrapper} setting).
+ * But not all {@link TemplateModel}-s are for wrapping a plain object. For example, a value created within a template
+ * is not made to wrap an earlier existing object; it's a value that has always existed in the template language's
+ * domain. Users can also write {@link TemplateModel} implementations and put them directly into the data-model for
+ * full control over how that object is seen from the template. Certain {@link TemplateModel} interfaces doesn't
+ * even have equivalent in Java. For example the directive type ({@link TemplateDirectiveModel}) is like that.
+ *
+ * <p>Because {@link TemplateModel} "subclasses" are all interfaces, a value in the template language can have multiple
+ * types. However, to prevent ambiguous situations, it's not recommended to make values that implement more than one of
+ * these types: string, number, boolean, date. The intended applications are like string+hash, string+method,
+ * hash+sequence, etc.
+ *
+ * @see FTLUtil#getTypeDescription(TemplateModel)
+ */
+public interface TemplateModel {
+
+ /**
+ * A general-purpose object to represent nothing. It acts as
+ * an empty string, false, empty sequence, empty hash, and
+ * null-returning method model.
+ */
+ TemplateModel NOTHING = GeneralPurposeNothing.INSTANCE;
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3fd56062/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateModelAdapter.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateModelAdapter.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateModelAdapter.java
new file mode 100644
index 0000000..a48c065
--- /dev/null
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateModelAdapter.java
@@ -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.
+ */
+
+package org.apache.freemarker.core.model;
+
+/**
+ * Implemented by classes that serve as adapters for template model objects in
+ * some other object model. Actually a functional inverse of
+ * {@link AdapterTemplateModel}. You will rarely implement this interface
+ * directly. It is usually implemented by unwrapping adapter classes of various
+ * object wrapper implementations.
+ */
+public interface TemplateModelAdapter {
+ /**
+ * @return the template model this object is wrapping.
+ */
+ TemplateModel getTemplateModel();
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3fd56062/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateModelException.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateModelException.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateModelException.java
new file mode 100644
index 0000000..d38faa4
--- /dev/null
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateModelException.java
@@ -0,0 +1,111 @@
+/*
+ * 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.model;
+
+import org.apache.freemarker.core.Environment;
+import org.apache.freemarker.core.TemplateException;
+import org.apache.freemarker.core._ErrorDescriptionBuilder;
+
+/**
+ * {@link TemplateModel} methods throw this exception if the requested data can't be retrieved.
+ */
+public class TemplateModelException extends TemplateException {
+
+ /**
+ * Constructs a <tt>TemplateModelException</tt> with no
+ * specified detail message.
+ */
+ public TemplateModelException() {
+ this(null, null);
+ }
+
+ /**
+ * Constructs a <tt>TemplateModelException</tt> with the
+ * specified detail message.
+ *
+ * @param description the detail message.
+ */
+ public TemplateModelException(String description) {
+ this(description, null);
+ }
+
+ /**
+ * The same as {@link #TemplateModelException(Throwable)}; it's exists only for binary
+ * backward-compatibility.
+ */
+ public TemplateModelException(Exception cause) {
+ this(null, cause);
+ }
+
+ /**
+ * Constructs a <tt>TemplateModelException</tt> with the given underlying
+ * Exception, but no detail message.
+ *
+ * @param cause the underlying {@link Exception} that caused this
+ * exception to be raised
+ */
+ public TemplateModelException(Throwable cause) {
+ this(null, cause);
+ }
+
+
+ /**
+ * The same as {@link #TemplateModelException(String, Throwable)}; it's exists only for binary
+ * backward-compatibility.
+ */
+ public TemplateModelException(String description, Exception cause) {
+ super(description, cause, null);
+ }
+
+ /**
+ * Constructs a TemplateModelException with both a description of the error
+ * that occurred and the underlying Exception that caused this exception
+ * to be raised.
+ *
+ * @param description the description of the error that occurred
+ * @param cause the underlying {@link Exception} that caused this
+ * exception to be raised
+ */
+ public TemplateModelException(String description, Throwable cause) {
+ super(description, cause, null);
+ }
+
+ /**
+ * Don't use this; this is to be used internally by FreeMarker.
+ * @param preventAmbiguity its value is ignored; it's only to prevent constructor selection ambiguities for
+ * backward-compatibility
+ */
+ protected TemplateModelException(Throwable cause, Environment env, String description,
+ boolean preventAmbiguity) {
+ super(description, cause, env);
+ }
+
+ /**
+ * Don't use this; this is to be used internally by FreeMarker.
+ * @param preventAmbiguity its value is ignored; it's only to prevent constructor selection ambiguities for
+ * backward-compatibility
+ */
+ protected TemplateModelException(
+ Throwable cause, Environment env, _ErrorDescriptionBuilder descriptionBuilder,
+ boolean preventAmbiguity) {
+ super(cause, env, null, descriptionBuilder);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3fd56062/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateModelIterator.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateModelIterator.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateModelIterator.java
new file mode 100644
index 0000000..9d1e241
--- /dev/null
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateModelIterator.java
@@ -0,0 +1,39 @@
+/*
+ * 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.model;
+
+/**
+ * Used to iterate over a set of template models <em>once</em>; usually returned from
+ * {@link TemplateCollectionModel#iterator()}. Note that it's not a {@link TemplateModel}.
+ */
+public interface TemplateModelIterator {
+
+ /**
+ * Returns the next model.
+ * @throws TemplateModelException if the next model can not be retrieved
+ * (i.e. because the iterator is exhausted).
+ */
+ TemplateModel next() throws TemplateModelException;
+
+ /**
+ * @return whether there are any more items to iterate over.
+ */
+ boolean hasNext() throws TemplateModelException;
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3fd56062/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateModelWithAPISupport.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateModelWithAPISupport.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateModelWithAPISupport.java
new file mode 100644
index 0000000..c1a01fe
--- /dev/null
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateModelWithAPISupport.java
@@ -0,0 +1,39 @@
+/*
+ * 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.model;
+
+/**
+ * <b>Experimental - subject to change:</b> A {@link TemplateModel} on which the {@code ?api} operation can be applied.
+ *
+ * <p>
+ * <b>Experimental status warning:</b> This interface is subject to change on non-backward compatible ways, hence, it
+ * shouldn't be implemented outside FreeMarker yet.
+ *
+ * @since 2.3.22
+ */
+public interface TemplateModelWithAPISupport extends TemplateModel {
+
+ /**
+ * Returns the model that exposes the (Java) API of the value. This is usually implemented by delegating to
+ * {@link ObjectWrapperWithAPISupport#wrapAsAPI(Object)}.
+ */
+ TemplateModel getAPI() throws TemplateModelException;
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3fd56062/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateNodeModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateNodeModel.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateNodeModel.java
new file mode 100644
index 0000000..afa9da6
--- /dev/null
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateNodeModel.java
@@ -0,0 +1,78 @@
+/*
+ * 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.model;
+
+/**
+ * "node" template language data type: an object that is a node in a tree.
+ * A tree of nodes can be recursively <em>visited</em> using the <#visit...> and <#recurse...>
+ * directives. This API is largely based on the W3C Document Object Model
+ * (DOM_WRAPPER) API. However, it's meant to be generally useful for describing
+ * any tree of objects that you wish to navigate using a recursive visitor
+ * design pattern (or simply through being able to get the parent
+ * and child nodes).
+ *
+ * <p>See the <a href="http://freemarker.org/docs/xgui.html" target="_blank">XML
+ * Processing Guide</a> for a concrete application.
+ *
+ * @since FreeMarker 2.3
+ */
+public interface TemplateNodeModel extends TemplateModel {
+
+ /**
+ * @return the parent of this node or null, in which case
+ * this node is the root of the tree.
+ */
+ TemplateNodeModel getParentNode() throws TemplateModelException;
+
+ /**
+ * @return a sequence containing this node's children.
+ * If the returned value is null or empty, this is essentially
+ * a leaf node.
+ */
+ TemplateSequenceModel getChildNodes() throws TemplateModelException;
+
+ /**
+ * @return a String that is used to determine the processing
+ * routine to use. In the XML implementation, if the node
+ * is an element, it returns the element's tag name. If it
+ * is an attribute, it returns the attribute's name. It
+ * returns "@text" for text nodes, "@pi" for processing instructions,
+ * and so on.
+ */
+ String getNodeName() throws TemplateModelException;
+
+ /**
+ * @return a String describing the <em>type</em> of node this is.
+ * In the W3C DOM_WRAPPER, this should be "element", "text", "attribute", etc.
+ * A TemplateNodeModel implementation that models other kinds of
+ * trees could return whatever it appropriate for that application. It
+ * can be null, if you don't want to use node-types.
+ */
+ String getNodeType() throws TemplateModelException;
+
+
+ /**
+ * @return the XML namespace URI with which this node is
+ * associated. If this TemplateNodeModel implementation is
+ * not XML-related, it will almost certainly be null. Even
+ * for XML nodes, this will often be null.
+ */
+ String getNodeNamespace() throws TemplateModelException;
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3fd56062/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateNodeModelEx.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateNodeModelEx.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateNodeModelEx.java
new file mode 100644
index 0000000..acf43df
--- /dev/null
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateNodeModelEx.java
@@ -0,0 +1,40 @@
+/*
+ * 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.model;
+
+import org.apache.freemarker.dom.NodeModel;
+
+/**
+ * A {@link NodeModel} that supports navigating to the previous and next sibling nodes.
+ *
+ * @since 2.3.26
+ */
+public interface TemplateNodeModelEx extends TemplateNodeModel {
+
+ /**
+ * @return The immediate previous sibling of this node, or {@code null} if there's no such node.
+ */
+ TemplateNodeModelEx getPreviousSibling() throws TemplateModelException;
+
+ /**
+ * @return The immediate next sibling of this node, or {@code null} if there's no such node.
+ */
+ TemplateNodeModelEx getNextSibling() throws TemplateModelException;
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3fd56062/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateNumberModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateNumberModel.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateNumberModel.java
new file mode 100644
index 0000000..ba1240d
--- /dev/null
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateNumberModel.java
@@ -0,0 +1,42 @@
+/*
+ * 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.model;
+
+import org.apache.freemarker.core.arithmetic.ArithmeticEngine;
+
+/**
+ * "number" template language data type; an object that stores a number. There's only one numerical type as far as the
+ * template language is concerned, but it can store its value using whatever Java number type. Making operations between
+ * numbers (and so the coercion rules) is up to the {@link ArithmeticEngine}.
+ *
+ * <p>
+ * Objects of this type should be immutable, that is, calling {@link #getAsNumber()} should always return the same value
+ * as for the first time.
+ */
+public interface TemplateNumberModel extends TemplateModel {
+
+ /**
+ * Returns the numeric value. The return value must not be {@code null}.
+ *
+ * @return the {@link Number} instance associated with this number model.
+ */
+ Number getAsNumber() throws TemplateModelException;
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3fd56062/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateScalarModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateScalarModel.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateScalarModel.java
new file mode 100644
index 0000000..b76a097
--- /dev/null
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateScalarModel.java
@@ -0,0 +1,45 @@
+/*
+ * 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.model;
+
+import org.apache.freemarker.core.model.impl.SimpleScalar;
+
+/**
+ * "string" template language data-type; like in Java, an unmodifiable UNICODE character sequence.
+ * (The name of this interface should be {@code TemplateStringModel}. The misnomer is inherited from the
+ * old times, when this was the only single-value type in FreeMarker.)
+ */
+public interface TemplateScalarModel extends TemplateModel {
+
+ /**
+ * A constant value to use as the empty string.
+ */
+ TemplateModel EMPTY_STRING = new SimpleScalar("");
+
+ /**
+ * Returns the string representation of this model. Don't return {@code null}, as that will cause exception.
+ *
+ * <p>
+ * Objects of this type should be immutable, that is, calling {@link #getAsString()} should always return the same
+ * value as for the first time.
+ */
+ String getAsString() throws TemplateModelException;
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3fd56062/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateSequenceModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateSequenceModel.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateSequenceModel.java
new file mode 100644
index 0000000..8ca3944
--- /dev/null
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateSequenceModel.java
@@ -0,0 +1,48 @@
+/*
+ * 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.model;
+
+/**
+ * "sequence" template language data type; an object that contains other objects accessible through an integer 0-based
+ * index.
+ *
+ * <p>
+ * Used in templates like: {@code mySeq[index]}, {@code <#list mySeq as i>...</#list>}, {@code mySeq?size}, etc.
+ *
+ * @see TemplateCollectionModel
+ */
+public interface TemplateSequenceModel extends TemplateModel {
+
+ /**
+ * Retrieves the i-th template model in this sequence.
+ *
+ * @return the item at the specified index, or <code>null</code> if the index is out of bounds. Note that a
+ * <code>null</code> value is interpreted by FreeMarker as "variable does not exist", and accessing a
+ * missing variables is usually considered as an error in the FreeMarker Template Language, so the usage of
+ * a bad index will not remain hidden, unless the default value for that case was also specified in the
+ * template.
+ */
+ TemplateModel get(int index) throws TemplateModelException;
+
+ /**
+ * @return the number of items in the list.
+ */
+ int size() throws TemplateModelException;
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3fd56062/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateTransformModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateTransformModel.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateTransformModel.java
new file mode 100644
index 0000000..789d9bb
--- /dev/null
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateTransformModel.java
@@ -0,0 +1,54 @@
+/*
+ * 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.model;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.Map;
+
+import org.apache.freemarker.core.util.DeepUnwrap;
+
+/**
+ * "transform" template language data type: user-defined directives
+ * (much like macros) specialized on filtering output; you should rather use the newer {@link TemplateDirectiveModel}
+ * instead. This certainly will be deprecated in FreeMarker 2.4.
+ */
+public interface TemplateTransformModel extends TemplateModel {
+
+ /**
+ * Returns a writer that will be used by the engine to feed the
+ * transformation input to the transform. Each call to this method
+ * must return a new instance of the writer so that the transformation
+ * is thread-safe.
+ * @param out the character stream to which to write the transformed output
+ * @param args the arguments (if any) passed to the transformation as a
+ * map of key/value pairs where the keys are strings and the arguments are
+ * TemplateModel instances. This is never null. If you need to convert the
+ * template models to POJOs, you can use the utility methods in the
+ * {@link DeepUnwrap} class.
+ * @return a writer to which the engine will feed the transformation
+ * input, or null if the transform does not support nested content (body).
+ * The returned writer can implement the {@link TransformControl}
+ * interface if it needs advanced control over the evaluation of the
+ * transformation body.
+ */
+ Writer getWriter(Writer out, Map args)
+ throws TemplateModelException, IOException;
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3fd56062/freemarker-core/src/main/java/org/apache/freemarker/core/model/TransformControl.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/TransformControl.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TransformControl.java
new file mode 100644
index 0000000..cd3965c
--- /dev/null
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TransformControl.java
@@ -0,0 +1,101 @@
+/*
+ * 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.model;
+
+import java.io.IOException;
+
+import org.apache.freemarker.core.TemplateException;
+
+/**
+ * An interface that can be implemented by writers returned from
+ * {@link TemplateTransformModel#getWriter(java.io.Writer, java.util.Map)}. The
+ * methods on this
+ * interfaces are callbacks that will be called by the template engine and that
+ * give the writer a chance to better control the evaluation of the transform
+ * body. The writer can instruct the engine to skip or to repeat body
+ * evaluation, and gets notified about exceptions that are thrown during the
+ * body evaluation.
+ */
+public interface TransformControl {
+ /**
+ * Constant returned from {@link #afterBody()} that tells the
+ * template engine to repeat transform body evaluation and feed
+ * it again to the transform.
+ */
+ int REPEAT_EVALUATION = 0;
+
+ /**
+ * Constant returned from {@link #afterBody()} that tells the
+ * template engine to end the transform and close the writer.
+ */
+ int END_EVALUATION = 1;
+
+ /**
+ * Constant returned from {@link #onStart()} that tells the
+ * template engine to skip evaluation of the body.
+ */
+ int SKIP_BODY = 0;
+
+ /**
+ * Constant returned from {@link #onStart()} that tells the
+ * template engine to evaluate the body.
+ */
+ int EVALUATE_BODY = 1;
+
+ /**
+ * Called before the body is evaluated for the first time.
+ * @return
+ * <ul>
+ * <li><tt>SKIP_BODY</tt> if the transform wants to ignore the body. In this
+ * case, only {@link java.io.Writer#close()} is called next and processing ends.</li>
+ * <li><tt>EVALUATE_BODY</tt> to normally evaluate the body of the transform
+ * and feed it to the writer</li>
+ * </ul>
+ */
+ int onStart() throws TemplateModelException, IOException;
+
+ /**
+ * Called after the body has been evaluated.
+ * @return
+ * <ul>
+ * <li><tt>END_EVALUATION</tt> if the transformation should be ended.</li>
+ * <li><tt>REPEAT_EVALUATION</tt> to have the engine re-evaluate the
+ * transform body and feed it again to the writer.</li>
+ * </ul>
+ */
+ int afterBody() throws TemplateModelException, IOException;
+
+ /**
+ * Called if any exception occurs during the transform between the
+ * {@link TemplateTransformModel#getWriter(java.io.Writer, java.util.Map)} call
+ * and the {@link java.io.Writer#close()} call.
+ * @param t the throwable that represents the exception. It can be any
+ * non-checked throwable, as well as {@link TemplateException} and
+ * {@link java.io.IOException}.
+ *
+ * @throws Throwable is recommended that the methods rethrow the received
+ * throwable. If the method wants to throw another throwable, it should
+ * either throw a non-checked throwable, or an instance of
+ * {@link TemplateException} and {@link java.io.IOException}. Throwing any
+ * other checked exception will cause the engine to rethrow it as
+ * a {@link java.lang.reflect.UndeclaredThrowableException}.
+ */
+ void onError(Throwable t) throws Throwable;
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3fd56062/freemarker-core/src/main/java/org/apache/freemarker/core/model/TrueTemplateBooleanModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/TrueTemplateBooleanModel.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TrueTemplateBooleanModel.java
new file mode 100644
index 0000000..f10ae71
--- /dev/null
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TrueTemplateBooleanModel.java
@@ -0,0 +1,36 @@
+/*
+ * 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.model;
+
+/**
+ * Used for the {@link TemplateBooleanModel#FALSE} singleton.
+ */
+final class TrueTemplateBooleanModel implements SerializableTemplateBooleanModel {
+
+ @Override
+ public boolean getAsBoolean() {
+ return true;
+ }
+
+ private Object readResolve() {
+ return TRUE;
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3fd56062/freemarker-core/src/main/java/org/apache/freemarker/core/model/WrapperTemplateModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/WrapperTemplateModel.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/WrapperTemplateModel.java
new file mode 100644
index 0000000..1a30bf1
--- /dev/null
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/WrapperTemplateModel.java
@@ -0,0 +1,33 @@
+/*
+ * 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.model;
+
+/**
+ * A generic interface for template models that wrap some underlying
+ * object, and wish to provide access to that wrapped object.
+ *
+ * <p>You may also want to implement {@link org.apache.freemarker.core.model.AdapterTemplateModel}.
+ */
+public interface WrapperTemplateModel extends TemplateModel {
+ /**
+ * Retrieves the original object wrapped by this model.
+ */
+ Object getWrappedObject();
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3fd56062/freemarker-core/src/main/java/org/apache/freemarker/core/model/WrappingTemplateModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/WrappingTemplateModel.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/WrappingTemplateModel.java
new file mode 100644
index 0000000..206d9d4
--- /dev/null
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/WrappingTemplateModel.java
@@ -0,0 +1,62 @@
+/*
+ * 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.model;
+
+import org.apache.freemarker.core.util._NullArgumentException;
+
+/**
+ * Convenience base-class for containers that wrap their contained arbitrary Java objects into {@link TemplateModel}
+ * instances.
+ */
+abstract public class WrappingTemplateModel {
+
+ private final ObjectWrapper objectWrapper;
+
+ /**
+ * Protected constructor that creates a new wrapping template model using the specified object wrapper.
+ *
+ * @param objectWrapper the wrapper to use. Passing {@code null} to it
+ * is allowed but deprecated. Not {@code null}.
+ */
+ protected WrappingTemplateModel(ObjectWrapper objectWrapper) {
+ _NullArgumentException.check("objectWrapper", objectWrapper);
+ this.objectWrapper = objectWrapper;
+ }
+
+ /**
+ * Returns the object wrapper instance used by this wrapping template model.
+ */
+ public ObjectWrapper getObjectWrapper() {
+ return objectWrapper;
+ }
+
+ /**
+ * Wraps the passed object into a template model using this object's object
+ * wrapper.
+ * @param obj the object to wrap
+ * @return the template model that wraps the object
+ * @throws TemplateModelException if the wrapper does not know how to
+ * wrap the passed object.
+ */
+ protected final TemplateModel wrap(Object obj) throws TemplateModelException {
+ return objectWrapper.wrap(obj);
+ }
+
+}