Struts2 StringTemplate support
<struts>
<include file="webwork-default.xml" />
<package name="regular" namespace="/" extends="struts-default">
<result-types>
<result-type name="stringtemplate" class="org.apache.struts2.dispatcher.StringTemplateResult"/>
</result-types>
<action name="st"
class="com.mysite.StringTemplateTestAction">
<result name="success" type="stringtemplate">/WEB-INF/st/page.st</result>
</action>
</package>
</struts>
package org.apache.struts2.dispatcher;
import java.util.Map;
/**
* Interface defining the required behavior from a StringTemplate result type.
* <p>
* The result should prepare the model for the page to display.
* The model is a map of attributes -> Objects where each object may either be a simple string, int,
* etc or another map.<p>
* So. for example $username$ is accessible from the template of the model contains a String under
* the value "username" and $strings.hello$ is accessible if the model contains a map under the key
* "strings" and this map contains an attribute under the key "hello"
*
* @author Ran Tavory (ran@outbrain.com)
*
*/
public interface StringTemplateAction {
/**
* Get the root of the display model.
*
* The display model is a map of attributes interpolated by StringTemplate at runtime by
* substituting the $values$ in the template source.
* For example to replace $user$ with Ran add
* <code>map.put("user", "Ran");</code>
* @return A map of attributes used by StringTemplate to replace in the template.
*/
public Map<String, Object> getModel();
}
package org.apache.struts2.dispatcher;
import java.io.IOException;
import java.io.InputStream;
import java.io.Writer;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.antlr.stringtemplate.NoIndentWriter;
import org.antlr.stringtemplate.StringTemplate;
import org.antlr.stringtemplate.StringTemplateGroup;
import org.antlr.stringtemplate.StringTemplateWriter;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.StrutsConstants;
import org.apache.struts2.views.util.ContextUtil;
import org.apache.struts2.views.util.ResourceUtil;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.LocaleProvider;
import com.opensymphony.xwork2.inject.Inject;
import com.opensymphony.xwork2.util.ValueStack;
import freemarker.template.Configuration;
import freemarker.template.TemplateException;
/**
* Defines the StringTemplate result type for struts2.
* <p>
* To use this result type add the following configuration to your struts.xml:
* <p>
* <code>
* <result-types><p>
* <result-type name="stringtemplate"
* class="org.apache.struts2.dispatcher.StringTemplateResult"/><p>
* </result-types><p>
*</code>
*
* Template files should be located relative to /WEB-INF/st/, so for example a common layout
* would be:
* <ul>
* <li>/WEB-INF/st/pages/page1.st</li>
* <li>/WEB-INF/st/layouts/layout1.st</li>
* <li>/WEB-INF/st/snippets/header.st</li>
* <li>/WEB-INF/st/snippets/footer.st</li>
* </ul>
*
* So page1.st would look like:<p>
* <code>
* $layouts/layout1(header=snippets/header(), footer=snippets/footer())$
* </code>
* <p>
* And the associated struts action would be:
* <p>
* <code>
* <action name="page1"
* class="com.mycompany.Page1Action"> <p>
* <result name="success"
* type="stringtemplate">/WEB-INF/st/pages/page1.st</result><p>
* </action>
* </code>
*<p>
* Localization:
* All string property files should be packed into the classpath (in one of the jars) at
* /lang/.<p>
* For example: <p>
* <ul>
* <li>/lang/en_US.properties</li>
* <li>/lang/fr_FR.properties</li>
* </ul>
*
* @author Ran Tavory (ran@outbrain.com)
*
*/
public class StringTemplateResult extends StrutsResultSupport {
/**
* Base path of StringTemplate template files.
* This is usually something like /WEB-INF/ or /WEB-INF/st/.
* Must end with /.
* All templates should reside in subdirectories of this base path and when referencing
* each other the reference point should be relative to this path.
* For example, if you have /WEB-INF/pages/page1.st and /WEB-INF/layouts/layout1.st, and assuming
* the base path is at /WEB-INF then page1 is pages/page1 and layout1 is layouts/layout1.
* To reference layout1 from page1: $layouts/layout1()$
*/
public static final String TEMPLATES_BASE =
"/WEB-INF/st/";
/**
* Path to the language resource files within the classpath.
*
* Resource should be packed inside a jar under /lang/.
* For example: /lang/en_US.properties
*/
public static final String LANG_RESOURCE_BASE = "/lang/";
/**
* If there was an exception during execution it's accessible via $exception$
*/
public static final String KEY_EXCEPTION = "exception";
/**
* Session values are accessible via $session.key$
*/
public static final String KEY_SESSION = "session";
/**
* All localized strings are accessible via $strings.string_key$
*/
public static final String KEY_STRINGS = "strings";
/**
* Request parameters are accessible via $params.key$
*/
public static final String KEY_REQUEST_PARAMETERS = "params";
/**
* Request attributes are accessible via $request.attribute$
*/
public static final String KEY_REQUEST = "request";
private static final Log log = LogFactory.getLog(StringTemplateResult.class);
private static final long serialVersionUID = -2390940981629097944L;