-
Notifications
You must be signed in to change notification settings - Fork 0
TeaServlet User Manual
Table of Contents | Next - Embedding Tea
The following sections describe the various configuration related to the TeaServlet and setting it up properly.
As with any servlet-based framework, the TeaServlet contains an actual servlet that must be provided in the web.xml
configuration. The TeaServlet servlet is conveniently named org.teatrove.teaservlet.TeaServlet
. The following is the most basic example of a configuration:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5">
<servlet>
<servlet-name>TeaServlet</servlet-name>
<servlet-class>org.teatrove.teaservlet.TeaServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>TeaServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
This example registers the TeaServlet and binds it to any path. TeaServlet routes requests to a Tea file named the same as the path. For example, the URL http://localhost:8080/context/about/location
would load the about/location.tea
template. For more information on routing within the TeaServlet, see [LINK TO SECTION].
As part of the TeaServlet initialization, it loads a TeaServlet Configuration [LINK TO SECTION] file that configures the servlet. By default, this is either the /WEB-INF/teaservlet.xml
or /WEB-INF/teaservlet.properties
file, but may be overridden by the properties.file
initialization parameter. The TeaServlet also supports the following initialization parameters.
debug
This specifies a boolean expression of whether detailed logging statements should be output to the servlet log during initialization of the TeaServlet. The default is false
.
properties.file
This specifies the path of the TeaServlet configuration file. The default is either /WEB-INF/teaservlet.xml
or /WEB-INF/teaservlet.properties
, depending on which file exists. TeaServlet supports two types of configuration formats: XML and enhanced properties. See [LINK TO SECTION] for more information. The path is relative to the web application, although it may also use any URL-supported protocol such as file:
or http:
. See [LINK TO SECTION] for more information on how configuration resources are accessed.
properties.factory.class
This specifies the fully-qualified class name of a class that implements the org.teatrove.trove.util.PropertyMapFactory
interface and contains a constructor that takes a java.util.Map
. The map parameter will either be an empty map or be the properties defined by the properties.factory.init configuration. The factory class provides the ability to load properties in alternative means. For more information on property factories, see [LINK TO SECTION].
substitutions.file
This specifies the path to a properties file that contains key/value pairs that may be used within TeaServlet configuration files as variable expressions (ie: ${property.name}
). The path is relative to the web application, although it may also use any URL-supported protocol such as file:
or http:
. See [LINK TO SECTION] for more information on how configuration resources are accessed.
substititions.env
This specifies a boolean expression of whether the system environment variables should be loaded as substitution properties. The default is true
.
substitutions.system
This specifies a boolean expression of whether the system properties (ie: -Dproperty=value
) should be loaded as substitution properties. The default is true
.
substitutions.properties This specifies a map of properties that should be loaded as substitution properties. This allows the properties to be used inline with the configuration rather than as a separate properties file.
substitutions.factory.class
This specifies the fully-qualified class name of a class that implements the org.teatrove.trove.util.PropertyMapFactory
interface and contains a constructor that takes a java.util.Map
. The map parameter will either be an empty map or be the properties defined by the substitutions.factory.init configuration. The factory class provides the ability to load substitution properties in alternative means. For more information on property factories, see [LINK TO SECTION].
TeaServlet uses a custom org.teatrove.trove.util.resources.ResourceFactory
class to load external configuration files.
TeaServlet, by default, creates a custom resource factory (org.teatrove.teaservlet.TeaServletResourceFactory
) that supports loading resources by the following mechanisms:
-
Local file system relative to the startup directory of the servlet container. This is not recommended as it is not portable from container to container and not all containers support file-based operations. Paths may include the optional
file:
protocol. -
Web application resources relative to the web application. The paths must begin with a leading '/' (ie:
/WEB-INF/teaservlet.xml
). Paths may include the optionalweb:
protocol. -
Class path artifacts relative to the class loader of the web application (ie:
META-INF/teaservlet.xml
). Paths may include the optionalclasspath:
protocol. -
Any
java.net.URL
supported resource such ashttp:
,https:
,ftp:
, etc. The paths must contain the associated protocol and the resource factory delegates to the underlying URL implementation of the JVM.
The ResouceFactory may lookup a resource as a URL, as an input stream, or as a set of properties using the property map factory support. Further, you may pass in custom substitutions to automatically evaluate property expressions.
TeaServlet loads configuration files and the associated properties using custom org.teatrove.trove.util.PropertyMapFactory
implementations. The default implementation supports loading both XML-based formats and enhanced property formats. See [INCLUDE LINK] for more information on the formats. Custom property map factories may be used to provide custom support. The following rules must be met.
- Implement the
org.teatrove.trove.util.PropertyMapFactory
interface - Include a constructor that takes a
java.util.Map
argument - Implement the
createProperties
methods returning the associated properties as a PropertyMap
The following is a simple example:
import java.util.Map;
import org.teatrove.trove.util.*;
public class MyPropertyMapFactory implements PropertyMapFactory {
public MyPropertyMapFactory(Map config) {
// do optional stuff with the config from properties.factory.init
}
public PropertyMap createProperties() {
return createProperties(null);
}
public PropertyMap createProperties(PropertyChangeListener listener) {
PropertyMap map = new PropertyMap();
// do stuff
return map;
}
}
Note that the PropertyChangeListener property is currently not supported directly by the TeaServlet. TeaServlet provides the org.teatrove.trove.util.XMLPropertyMapFactory
for parsing XML resources and org.teatrove.trove.util.SimplePropertyMapFactory
for parsing enhanced property resources.
The TeaServlet configuration contains the properties to setup the TeaServlet, the templates, the plugins, and the applications. See [INCLUDE LINK] for the various formats of this configuration file and [INCLUDE LINK] for the various options and properties.
TeaServlet supports two native configuration formats: XML and enhanced properties. The XML format is a standard XML file:
<teaservlet>
<property>value</property>
<section>
<property>value</property>
</section>
</teaservlet>
Alternatively, this could be rewritten in standard Java properties format via:
property=value
section.property=value
The enhanced properties format extends the Java properties format to support nesting sections and properties via:
property=value
section {
property=value
}
All of these formats are equivalent. TeaServlet automatically selects the format based on the file extension. The enhanced properties follow all the rules for standard Java properties with the following additions:
- Values have trailing whitespace trimmed.
- Quotation marks (" or ') can be used to define keys and values that have embedded spaces.
- Quotation marks can also be used to define multi-line keys and values without having to use continuation characters.
- Properties may be nested using braces '{' and '}'.
TeaServlet supports the ability to automatically discover and include the TeaServlet configuration within other libraries. TeaServlet will include the META-INF/teaservlet.xml
or META-INF/teaservlet.properties
configuration of any library in the class path. The configuration will not overwrite values defined in the application configuration file (ie: /WEB-INF/teaservlet.xml), with the exception of a few specific cases. The exceptions are that templates.path
and template.imports
will be aggregated together. The libraries are loaded and processed in a non-deterministic order. The automatic discovery allows libraries to automatically configure their plugins or applications rather than relying on the end user to manually configure. The TeaServlet uses this process internally for its Tea applications and Tea administration consoles.
The configuration file contains various sections as described below.
<teaservlet>
<cluster>
<!-- information to cluster multiple servers together -->
</cluster>
<templates>
<!-- information on templates, locations, class files, etc -->
</templates>
<log>
<!-- information on logging within TeaServlet -->
</log>
<admin>
<!-- information on the administration console within TeaServlet -->
</admin>
<plugins>
<!-- information on custom plugins -->
</plugins>
<applications>
<!-- information on custom applications exposed to Tea -->
</applications>
</teaservlet>
TeaServlet supports clustering of multiple TeaServlet instances across multiple servers. Clustering is primarily used to allow templates to be compiled once across the cluster rather than individually on each server. The most common practice for clustering is one staging server with multiple user-facing servers. The staging server is used to initially test and validate on and then compile to the cluster of user-facing servers.
The clustering support in TeaServlet is based on multicast through the following configuration:
<teaservlet>
<cluster>
<name><!-- name of application cluster --></name>
<localNet><!-- the local network address: ie: 10.1.1.0/21 --></localNet>
<rmi.port><!-- the RMI port of the service --></rmi.port>
<multicast>
<port><!-- the multicast port to send/listen on --></port>
<group><!-- the IP address of the multicast group --></group>
</multicast>
</cluster>
</teaservlet>
The multicast port and group should be the same for all instances in the cluster and different for services in different clusters. In general, all services in the cluster should use the same TeaServlet configuration.
TeaServlet supports precompiled templates, automatically compiled templates, and manually compiled templates. Precompiled templates are compiled at build time (using the Tea Compiler for Maven [INCLUDE LINK]) and included in the class path artifacts. Automatically compiled templates are similar to JSP and PHP in that they are compiled on demand and re-compiled when changes occur. Manually compiled templates require an administrator to selectively compile the templates through the Administration console. Both automatically and manually compiled templates may output the resulting class file to a working directory to avoid re-compiling on restarts.
The TeaServlet templates configuration also includes properties relevant to the Tea language including the automatic imports feature.
<teaservlet>
<templates>
<path><!-- semicolon delimited path to one or more template sources --></path>
<classes><!-- filesystem path to where classes should be stored --></classes>
<default><!-- default template when accessing a directory --></default>
<preload><!-- whether templates should be compiled immediately on startup --></preload>
<autocompile><!-- whether to automatically compile templates --></autocompile>
<imports><!-- semicolon delimited packages to automatically import --></imports>
<server><!-- properties relevant to the template server --></server>
</templates>
</teaservlet>
path
The path specifies one or more additional paths to search on for templates. This does not include precompiled templates that are available in the class path automatically. The path may be a path relative to the web application directory, a file-based path via the file:
protocol, or a HTTP-based path via the http:
protocol and the Template Server [INCLUDE LINK]. The template server is a more efficient web server for hosting templates remotely rather than using network shares. Multiple paths should be separated by semi-colons, such as /WEB-INF/templates;file://c:/templates;http://server/templates
classes This specifies an optional property of where to store generated class files. This only applies to templates compiled from the path property and not to precompiled templates. The path is a path relative to the file system. The generated classes will be stored in the given path. This allows the TeaServlet to reuse those class files on restarts without having to recompile. If not specified, then templates will be recompiled after restarts.
default
This specifies the default template within the directory when a directory is specified as the path to the TeaServlet. By default, this is index
.
preload
The preload property specifies whether templates should be compiled on startup, rather than on demand. This is recommended for performance reasons and is true
by default.
autocompile
This autocompile property specifies whether templates should be automatically compiled on access or after changes rather
than manually compiled. The default is false
.
imports
This specifies the list of packages to automatically import into Tea. Tea will make any classes within the given packages available to any template without fully-qualifying. The default is java.lang;java.util
and multiple packages are separated by semi-colons. See [INCLUDE LINK] for more information.
server The server properties control various configuration options for handling the Template Server such as timeout.
The logging section control the TeaServlet logging. The properties specifies what portions of content to log: debug, info, warn, and error.
<teaservlet>
<log>
<enabled>true</enabled>
<debug>false</debug>
<info>true</info>
<warn>true</warn>
<error>true</error>
</log>
</teaservlet>
The admin section controls the configuration of the Administration console. The key specifies the name of the query parameter to access the administration console and the value specifies the password.
<teaservlet>
<admin>
<key>admin</key>
<value>password</value>
</admin>
</teaservlet>
This particular example would require the following query parameter to access the console: http://server/context/system/console?admin=password
The plugins section controls the inclusion of plugins [INCLUDE LINK FOR MORE INFO]. Each defined plugin should have its own section. The name of the section provides the name of the plugin within the TeaServlet plugin context. Each plugin definition should contain a class property and an optional init section.
<teaservlet>
<plugins>
<DataSourcePlugin>
<class>com.mycompany.plugins.DataSourcePlugin</class>
<init>
<!-- data source properties -->
</init>
</DataSourcePlugin>
</plugins>
</teaservlet>
See [INCLUDE LINK] for more information on plugins.
The applications section controls the inclusion of applications [INCLUDE LINK FOR MORE INFO]. Each defined application should have its own section. The name of the section provides the name of the application within the TeaServletapplication context. The name of the application is also the name that is used when fully-qualifying application-based context methods in Tea templates. Each application definition should contain a class property and an optional init section.
<teaservlet>
<applications>
<TestApplication>
<class>com.mycompany.apps.TestApplication</class>
<init>
<!-- application properties -->
</init>
</TestApplication>
</applications>
</teaservlet>
See [INCLUDE LINK] for more information on applications.
Plugins in TeaServlet provide the ability to load custom classes that may be used by other plugins or applications. The most typical example is a data source plugin. The data source plugin could provide a standard API for accessing any type of general data source. Specific implementations of that plugin may provide access through JDBC, Hibernate, etc. A given application could utilize that plugin and its API to retrieve data and provide the resulting data to the templates.
Plugins must implement the org.teatrove.trove.util.plugin.Plugin
interface. Generally, plugins will extend the org.teatrove.trove.util.plugin.PluginAdapter
class that provides basic stubbed methods. Plugins will then implement the getName
method and init
method. The init
method provides configuration for the plugin via the associated init section.
The following is an example XML and class for a custom plugin.
<teaservlet>
<plugins>
<UserDatabase>
<class>com.example.DataSourcePlugin</class>
<init>
<databaseName>User</databaseName>
</init>
</UserDatabase>
</plugins>
</teaservlet>
import org.teatrove.trove.uti.plugin.*;
public class DataSourcePlugin extends PluginAdapter {
private String databaseName;
public DataSourcePlugin() { super(); }
@Override
public void init(PluginConfig config) {
this.databaseName = config.getProperties().getProperty("databaseName");
// initialize database connection
}
public Object getObject(Object key) {
// lookup from database for the given key
}
}
The PluginConfig contains more than just the initialization properties, however. The following are some of the more important methods:
Plugin getPlugin(String name)
This will look up a previously declared plugin. If the plugin does not exist, then null
is returned. Note that plugins are loaded sequentially in the order they are defined. As such, dependent plugins of a plugin must be defined first.
Plugin[] getPlugins() This will return all currently loaded plugins. Note that plugins are loaded sequentially in the order they are defined. As such, only those plugins previously specified will be returned.
PropertyMap getProperties() This will return the list of properties within the init section of the plugin.
Log getLog() This will return the logger associated with this specific plugin that may be used to log data. The individual log settings may be configured by providing a log section within the plugin section.
PluginContext getPluginContext() This provides access to the underlying PluginContext that the TeaServlet uses to manage the plugins. The PluginContext has three main purposes. First, it provides access to the already created plugins through the getPlugins and getPlugin methods. Second, it provides the ability to add plugins to the system directly through the addPlugin methods. Finally, it provides access to the underlying ResourceFactory to lookup resources. For example, if a plugin needed to load another configuration file, it could use the ResourceFactory to lookup that configuration and support the TeaServlet configuration formats and locations. See [INCLUDE LINK] for more information on resource factories and configuration files.
Plugins may be used for any number of use cases. Plugins are also not exposed to the Tea templates other than through applications that choose to expose them.
Applications in Tea are essential to the Tea templates. They provide the context methods that are accessible within Tea templates. Applications implement the org.teatrove.teaservlet.Application' interface. Applications provide an
init(ApplicationConfig)`` method to provide the application configuration and initialize the application. The configuration is available through the init section of the application. The ApplicationConfig also provides access to the servlet context of the TeaServlet. More importantly, the ApplicationConfig provides the ability to lookup plugins. This allows an application to utilize plugins to provide further data. For example, an application may be bound to the general DataSourcePlugin, but the actual implementation (JDBC, Hibernate, etc) is controlled by the plugin configuration completely independent of the application. If we consider the UserDatabase plugin example in the Plugin section above [INCLUDE LINK], we could use that plugin accordingly:
<teaservlet>
<applications>
<UserApplication>
<class>com.example.UserApplication</class>
<init>
<dataSourceName>UserDatabase</dataSourceName>
</init>
</UserApplication>
</applications>
</teaservlet>
public class UserApplication implements Application {
...
public void init(ApplicationConfig config) {
String dataSourceName = config.getProperties().getString("dataSourceName");
this.dataSource = (DataSource) config.getPlugin(dataSourceName);
}
public User getUser(Integer userId) {
return (User) this.dataSource.getObject(userId);
}
}
Applications are just the configuration points. Applications provide a context that provides the actual methods for Tea templates. The getContextType method should return the type of context that the application will use. Generally, this is an appropriate interface of the implementation class. The getContext method returns the actual implementation instance of the context. The resulting context instance is provided to the TeaServlet and invoked whenever a Tea template invokes a method on the context. All public methods of the context type are accessible by Tea templates.
Contexts in Tea generally take on two forms: stateless and stateful. Stateless contexts do not maintain internal state and are thread safe. Stateful contexts have internal state or are bound to each request and/or response. Stateless contexts are generally only created once and returned on subsequent invocations (ie: singleton). Stateless contexts are also the most performant. Stateful contexts, on the other hand, have to be created with each request/response.
Stateless applications almost never have application-specific configuration. To avoid creating an application per stateless context, TeaServlet provides the org.teatrove.teaapps.apps.DefaultApplication
that instantiates the context once and returns the same instance per request. The associated context is configured via the DefaultApplication init block. The contextClass property specifies the fully-qualified name of the context class to instantiate. The class must have a public default constructor. If the context class implements org.teatrove.teaapps.Context
interface, then the configuation properties of the applications will be accessible through the init(ContextConfig)
method.
<teaservlet>
<applications>
<GreetingApplication>
<class>org.teatrove.teaapps.apps.DefaultApplication</class>
<init>
<contextClass>com.example.GreetingContext</contextClass>
<greeting>Hello</greeting>
</init>
</GreetingApplication>
</applications>
</teaservlet>
Deciding between a stateless and a stateful context all depends on the use case. If the context methods require access to the request or response details, then a custom application is most likely needed to create the context per request. Generally, stateless contexts should be used unless specific reasons not to.
Deciding between using the DefaultApplication or custom application depends on what type of initialization needs to occur. If the context is stateless, has a default constructor, and has no configuration or only simple configuration, then the DefaultApplication will suffice. Otherwise, a custom application may need to exist to properly configure and return the context.
Methods within contexts generally have two forms. The first is a standard method such as toLowerCase(String)
, getSomeData()
, etc. These methods may also support variable arguments within JDK 1.5 (ie: avg(int... numbers)
). The second method contains an additional parameter org.teatrove.tea.runtime.Substitution
. Substitution blocks [LINK TO TEA DOC] are used to pass Tea code to a method. You can think of substitution blocks as a tag library in JSTL with a body. The method may use the substitution parameter to invoke the body zero or more times. Consider the following Tea template
<% template test(Integer count)
count = count ?: 10
invoke(count) {
'Hello World'
}
public class InvokeContext {
public void invoke(int count, Substitution substitution) {
for (int i = 0; i < count; i++) {
substitution.substitute();
}
}
}
This will invoke and print 'Hello World' the given count number of times. Substitutions are great for loops/repetition and logic. Consider a cache(int ttl, Substitution s)
method. This will either invoke the substitution and cache it or it will not invoke it returning the previously cached data. See the Substitution JavaDocs for more information.
As part of the TeaServlet Administration console [LINK TO DOCS], TeaServlet provides another form of an application as org.teatrove.teaservlet.AdminApp
. Administration applications provide one or more Tea templates as administration links that are added to the Administration console via the getAdminLinks
method. The getAdminLinks method takes a org.teatrove.teaservlet.AppAdminLinks
that may have one more links added containing the link title and the link template. The link template is the fully-qualified dotted-notation of the template.
The administration application must also provide a context as with all applications. The context generally contains the administration functions used by the admin templates.
The templates and the TeaServlet configuration for an administration application are generally bundled together as a library. The templates are also generally precompiled so that an end user only needs to include the library dependency without further configuration. See [INCLUDE LINK] for more information on precompiling Tea templates and see [INCLUDE LINK] for automatic discovery of Tea configuration files within libraries.
The TeaAdmin project itself is a great example of an administration application.
The TeaServlet administration console [LINK TO SECTION] contains the ability to display all applications and their resulting methods they may invoke. This provides an alternative to standard JavaDocs that allow template developers to easily see from the administration console what methods are available. However, by default, only the general signature is provided (ie: String doSomething(int, String, int)
). This, by itself, has limited meaning as it does not describe what the actual arguments are or what the method does.
Tea contains a special Maven plugin that generates metadata classes for applications and contexts known as BeanInfo. TeaServlet knows how to discover these classes and retrieve the metadata to display on the administration console. If using Maven, it is suggested to configure this plugin in order to generate the necessary metadata. The following is a basic example of including the plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.7</version>
<executions>
<execution>
<id>generate-beaninfo</id>
<phase>generate-sources</phase>
<configuration>
<useStandardDocletOptions>false</useStandardDocletOptions>
<reportOutputDirectory>${project.build.directory}/generated-sources/beaninfo</reportOutputDirectory>
<destDir>.</destDir>
<doclet>org.teatrove.toolbox.beandoc.BeanDocDoclet</doclet>
<docletArtifact>
<groupId>org.teatrove</groupId>
<artifactId>toolbox</artifactId>
<version>${toolbox.version}</version>
</docletArtifact>
</configuration>
<goals>
<goal>javadoc</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<id>add-beaninfo-sources</id>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${project.build.directory}/generated-sources/beaninfo</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
The plugin basically works by utilizing the JavaDoc process to inspect all sources. For each class and method, it adds metadata for the javadocs, the parameter names, and the parameter docs. This makes viewing the functions on the administration console much richer and more explanatory.
TeaServlet supports both the GET
and the POST
operations in HTTP. Both operations are handled exactly the same to simplify the end templates and processing. All other operations are unhandled and not supported.
When a request is made, TeaServlet inspects the path excluding the context path and servlet path mapping, if any. The resulting path is used to lookup the associated Tea template. If the autocompile flag is enabled, TeaServlet will first check if a physical template exists for the given template by appending the path to each template path. If any are found, then it is checked for modifications and recompiled if necessary. Otherwise, the path is converted to a fully qualified class name and looked up in the class path. If the template class file cannot be found, then TeaServlet will attempt to resolve the path as a directory by appending the default template to the path (ie: index
). If the template still cannot be found, then a 404 response is returned.
Tea compiles templates into class files with a known structure that allows them to be easily executed as well as providing information on the template parameters. For more information on the structure of the class files, see [INCLUDE LINK]. The main method in the class file is the execute
method. The execute
method takes one parameter for the execution context and then one parameter for each defined template parameter. For example, consider the following template definition:
<% template test(String name, Integer age) %>
The resulting method in the class file will be: Object execute(Object context, String name, Integer age)
. In order to invoke this method, TeaServlet must construct the necessary parameters.
The first parameter is the execution context. The execution context is a specially created class that contains an aggregation of the TeaServlet environment and all of the application context methods. TeaServlet dynamically creates this class at startup called the MergedContext by invoking the getContextType
method of each application and introspecting all the public methods of the resulting type. The merged context then creates a method of the same signature as each application context method. When that method is invoked (ie: through a Tea template), the merged context delegates to the TeaServlet environment to invoke the actual method on the actual application context. Because this code is all dynamically created at startup, the actual class file is statically typed meaning there is no reflection or otherwise dynamic operations invoked. Combining this notion with the static typing of the Tea templates is what powers the low latency, high throughput performance of the TeaServlet.
The subsequent parameters of the execute method are from the template definition. The class file contains methods that return the metadata of the template including the template definition parameters, their types, and their names. This allows the TeaServlet to map the query parameters accordingly. For each template parameter, the TeaServlet checks to see if a query parameter exists of the same name. If the query parameter exist, TeaServlet automatically converts the value to the proper type, since all query parameters are strings. At this time, TeaServlet can only convert from strings to primitives or their corresponding object wrappers. All other objects must be specified as java.lang.String
and manually converted by the template. Note that template parameters mapped as primitives that map to query parameters that do not exist will result in a ServletException being thrown.
TeaServlet can now invoke the associated execute method. It first instantiates the merged context with the current environment including the active request and response. For each application, it also invokes the getContext
method passing in the active request and response. For stateless applications, this will usually return the singleton context. For stateful applications, this will usually create a new instance of the context. These contexts are then made available in the merged context so that the method delegates invokes the method on the associated context instance.
Once the TeaServlet invokes the execute method, the actual template code is invoked (in its compiled form). This includes invoking any of the application context methods, calling other templates, or printing text to the response. Once the template completes, any return value of the template is also output to the response. The response is then committed and flushed and control is returned to the web application to finish the request.
When a Tea template calls or invokes another template, it follows a similar process. The compiled class file invokes the calling template directly passing the execution context and required parameters. Substitution templates are slightly different. Substitution templates maintain a state so that they can process the included portion of the page accordingly. Because substitution templates maintain state, they are also instantiated per request, whereas most templates are static to ensure high throughput.
The administration console, when included with the teaadmin dependency, allows compiling templates, viewing information on the TeaServlet environment, and statistics. The administration console is available at http://[server]:[port]/[context]/system/console?[key]=[value]
where [key]=[value]
is defined in the admin section of the TeaServlet configuration [INCLUDE LINK].
The template section allows viewing the active templates available to the TeaServlet as well as compiling templates. Templates may be set to compile templates selectively, compile all templates with changes, or re-compile all templates.
The functions section shows all methods in alphabetical order, regardless of application, that Tea templates may invoke.
The applications section shows all applications and their associated methods that Tea templates may invoke.
The logging section shows any logs including errors, warnings, etc that have resulted from invoking templates. The logging levels are controlled via the logs section of the TeaServlet configuration [INCLUDE LINK].
The statistics and information sections show general information about the servlet container, templates, service, etc. The statistics also includes runtime statistics and breakdown from invoking the templates. This includes a breakdown per template of time spent invoking other methods, invoking other templates, and general processing. The stats allow a developer the ability to easily profile templates to resolve potential bottlenecks in the system.