mirror of
https://github.com/apache/struts.git
synced 2026-08-11 01:27:14 +00:00
WW-3009 Extensibility Improvements to javatemplates plugin - patch (project scope)
submitted by Eric Chijioke git-svn-id: https://svn.apache.org/repos/asf/struts/struts2/trunk@767518 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
@@ -30,6 +30,8 @@ import java.util.LinkedHashMap;
|
||||
*/
|
||||
public class Attributes extends LinkedHashMap<String, String> {
|
||||
|
||||
private static final long serialVersionUID = 4103241472140545630L;
|
||||
|
||||
public Attributes add(String key, String value) {
|
||||
return add(key, value, true);
|
||||
}
|
||||
|
||||
+43
-2
@@ -38,7 +38,7 @@ public class DefaultTheme implements Theme {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(DefaultTheme.class);
|
||||
|
||||
private String name;
|
||||
private Map<String, List<TagHandlerFactory>> handlerFactories;
|
||||
protected Map<String, List<TagHandlerFactory>> handlerFactories;
|
||||
|
||||
protected void setName(String name) {
|
||||
this.name = name;
|
||||
@@ -48,6 +48,47 @@ public class DefaultTheme implements Theme {
|
||||
this.handlerFactories = handlers;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set (replace if exists) the tag handler factories for specific tag
|
||||
*
|
||||
* @param tagName
|
||||
* @param handlers
|
||||
*/
|
||||
protected void setTagHandlerFactories(String tagName, List<TagHandlerFactory> handlers) {
|
||||
if (tagName != null && handlers != null && this.handlerFactories != null) {
|
||||
handlerFactories.put(tagName, handlers);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert a new tag handler into a sequence of tag handlers for a specific tag
|
||||
* TODO: Need to take care of serializers, if handler specified is not a TagSerializer it should never
|
||||
* be placed after the serializer, but if it is not a TagSerializer, it should never
|
||||
*
|
||||
* @param tagName
|
||||
* @param sequence
|
||||
* @param factory
|
||||
*/
|
||||
protected void insertTagHandlerFactory(String tagName, int sequence, TagHandlerFactory factory) {
|
||||
|
||||
if (tagName != null && factory != null && this.handlerFactories != null) {
|
||||
|
||||
List<TagHandlerFactory> tagHandlerFactories = handlerFactories.get(tagName);
|
||||
|
||||
if (tagHandlerFactories == null) {
|
||||
tagHandlerFactories = new ArrayList<TagHandlerFactory>(); //TODO: Could use public FactoryList here
|
||||
}
|
||||
|
||||
if (sequence > tagHandlerFactories.size()) {
|
||||
sequence = tagHandlerFactories.size();
|
||||
}
|
||||
|
||||
//TODO, need to account for TagHandlers vs. TagSerializers here
|
||||
tagHandlerFactories.add(sequence, factory);
|
||||
}
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
@@ -70,7 +111,7 @@ public class DefaultTheme implements Theme {
|
||||
handlers.add(0, prev);
|
||||
}
|
||||
|
||||
TagSerializer ser = (TagSerializer) handlers.get(handlers.size() - 1);
|
||||
// TagSerializer ser = (TagSerializer) handlers.get(handlers.size() - 1);
|
||||
|
||||
TagGenerator gen = (TagGenerator) handlers.get(0);
|
||||
try {
|
||||
|
||||
+38
@@ -27,12 +27,20 @@ import org.apache.struts2.components.template.TemplateRenderingContext;
|
||||
import org.apache.struts2.views.java.simple.SimpleTheme;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import com.opensymphony.xwork2.util.logging.LoggerFactory;
|
||||
import com.opensymphony.xwork2.util.logging.Logger;
|
||||
import com.opensymphony.xwork2.util.ClassLoaderUtil;
|
||||
import com.opensymphony.xwork2.inject.Inject;
|
||||
|
||||
/**
|
||||
* Template engine that renders tags using java implementations
|
||||
*/
|
||||
public class JavaTemplateEngine extends BaseTemplateEngine {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(JavaTemplateEngine.class);
|
||||
|
||||
private Themes themes = new Themes() {{
|
||||
add(new SimpleTheme());
|
||||
}};
|
||||
@@ -64,4 +72,34 @@ public class JavaTemplateEngine extends BaseTemplateEngine {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows for providing custom theme classes (implementations of the org.apache.struts2.views.java.Theme) interface
|
||||
* for custom rendering of tags using the javatemplates engine
|
||||
*
|
||||
* @param themeClasses a comma delimited list of custom theme class names
|
||||
*/
|
||||
@Inject("struts.javatemplates.customThemes")
|
||||
public void setThemeClasses(String themeClasses) {
|
||||
|
||||
StringTokenizer customThemes = new StringTokenizer(themeClasses, ",");
|
||||
|
||||
while (customThemes.hasMoreTokens()) {
|
||||
String themeClass = customThemes.nextToken().trim();
|
||||
try {
|
||||
LOG.info("Registering custom theme '" + themeClass + "' to javatemplates engine");
|
||||
|
||||
|
||||
//FIXME: This means Themes must have no-arg constructor - should use object factory here
|
||||
//ObjectFactory.getObjectFactory().buildBean(ClassLoaderUtil.loadClass(themeClass, getClass()), null);
|
||||
themes.add((Theme) ClassLoaderUtil.loadClass(themeClass, getClass()).newInstance());
|
||||
|
||||
} catch (ClassCastException cce) {
|
||||
LOG.error("Invalid java them class '" + themeClass + "'. Class does not implement 'org.apache.struts2.views.java.Theme' interface");
|
||||
} catch (ClassNotFoundException cnf) {
|
||||
LOG.error("Invalid java theme class '" + themeClass + "'. Class not found");
|
||||
} catch (Exception e) {
|
||||
LOG.error("Could not find messages file " + themeClass + ".properties. Skipping");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -32,7 +32,7 @@ import java.io.Writer;
|
||||
*/
|
||||
public class XHTMLTagSerializer implements TagSerializer {
|
||||
|
||||
private Writer writer;
|
||||
protected Writer writer;
|
||||
|
||||
public void characters(String text) throws IOException {
|
||||
characters(text, true);
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ public class DivHandler extends AbstractTagHandler implements TagGenerator {
|
||||
.addIfExists("class", params.get("cssClass"))
|
||||
.addIfExists("style", params.get("cssStyle"))
|
||||
.addIfExists("title", params.get("title"));
|
||||
start("div", attrs);
|
||||
super.start("div", attrs);
|
||||
}
|
||||
|
||||
public static class CloseHandler extends AbstractTagHandler implements TagGenerator {
|
||||
|
||||
+5
-1
@@ -37,9 +37,13 @@ public class HeadHandler extends AbstractTagHandler implements TagGenerator {
|
||||
attrs.put("type", "text/javascript");
|
||||
|
||||
String base = ServletActionContext.getRequest().getContextPath();
|
||||
attrs.put("base", base);
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (base != null)
|
||||
if (base != null) {
|
||||
sb.append(base);
|
||||
}
|
||||
|
||||
sb.append("/struts/utils.js");
|
||||
attrs.put("src", sb.toString());
|
||||
|
||||
|
||||
+2
-2
@@ -76,10 +76,10 @@ public class SelectHandler extends AbstractTagHandler implements TagGenerator {
|
||||
|
||||
//key
|
||||
Object itemKey = findValue(listKey != null ? listKey : "top");
|
||||
String itemKeyStr = StringUtils.defaultString(itemKey.toString());
|
||||
String itemKeyStr = StringUtils.defaultString(itemKey == null ? null : itemKey.toString());
|
||||
//value
|
||||
Object itemValue = findValue(listValue != null ? listValue : "top");
|
||||
String itemValueStr = StringUtils.defaultString(itemValue.toString());
|
||||
String itemValueStr = StringUtils.defaultString(itemValue == null ? null : itemValue.toString());
|
||||
|
||||
boolean selected = ContainUtil.contains(value, itemKey);
|
||||
writeOption(itemKeyStr, itemValueStr, selected);
|
||||
|
||||
+31
-26
@@ -32,36 +32,41 @@ import java.util.List;
|
||||
public class SimpleTheme extends DefaultTheme {
|
||||
|
||||
public SimpleTheme() {
|
||||
setHandlerFactories(new HashMap<String, List<TagHandlerFactory>>() {{
|
||||
put("text", new FactoryList(TextFieldHandler.class, ScriptingEventsHandler.class, CommonAttributesHandler.class));
|
||||
put("textfield", new FactoryList(TextFieldHandler.class, ScriptingEventsHandler.class, CommonAttributesHandler.class));
|
||||
put("select", new FactoryList(SelectHandler.class, ScriptingEventsHandler.class, CommonAttributesHandler.class));
|
||||
put("form", new FactoryList(FormHandler.class, ScriptingEventsHandler.class, CommonAttributesHandler.class));
|
||||
put("form-close", new FactoryList(FormHandler.CloseHandler.class));
|
||||
put("a", new FactoryList(AnchorHandler.class, ScriptingEventsHandler.class, CommonAttributesHandler.class));
|
||||
put("a-close", new FactoryList(AnchorHandler.CloseHandler.class));
|
||||
put("checkbox", new FactoryList(CheckboxHandler.class, ScriptingEventsHandler.class, CommonAttributesHandler.class));
|
||||
put("file", new FactoryList(FileHandler.class, ScriptingEventsHandler.class, CommonAttributesHandler.class));
|
||||
put("password", new FactoryList(PasswordHandler.class, ScriptingEventsHandler.class, CommonAttributesHandler.class));
|
||||
put("label", new FactoryList(LabelHandler.class, ScriptingEventsHandler.class, CommonAttributesHandler.class));
|
||||
put("reset", new FactoryList(ResetHandler.class, ScriptingEventsHandler.class, CommonAttributesHandler.class));
|
||||
put("submit", new FactoryList(SubmitHandler.class, ScriptingEventsHandler.class, CommonAttributesHandler.class));
|
||||
put("submit-close", new FactoryList(SubmitHandler.CloseHandler.class));
|
||||
put("textarea", new FactoryList(TextAreaHandler.class, ScriptingEventsHandler.class, CommonAttributesHandler.class));
|
||||
put("actionerror", new FactoryList(ActionErrorHandler.class));
|
||||
put("token", new FactoryList(TokenHandler.class));
|
||||
put("actionmessage", new FactoryList(ActionMessageHandler.class));
|
||||
put("head", new FactoryList(HeadHandler.class));
|
||||
put("hidden", new FactoryList(HiddenHandler.class));
|
||||
put("fielderror", new FactoryList(FieldErrorHandler.class));
|
||||
put("div", new FactoryList(DivHandler.class, ScriptingEventsHandler.class, CommonAttributesHandler.class));
|
||||
put("div-close", new FactoryList(DivHandler.CloseHandler.class));
|
||||
put("empty", new FactoryList(EmptyHandler.class));
|
||||
}});
|
||||
setHandlerFactories(new HashMap<String, List<TagHandlerFactory>>() {
|
||||
{
|
||||
put("text", new FactoryList(TextFieldHandler.class, ScriptingEventsHandler.class, CommonAttributesHandler.class));
|
||||
put("textfield", new FactoryList(TextFieldHandler.class, ScriptingEventsHandler.class, CommonAttributesHandler.class));
|
||||
put("select", new FactoryList(SelectHandler.class, ScriptingEventsHandler.class, CommonAttributesHandler.class));
|
||||
put("form", new FactoryList(FormHandler.class, ScriptingEventsHandler.class, CommonAttributesHandler.class));
|
||||
put("form-close", new FactoryList(FormHandler.CloseHandler.class));
|
||||
put("a", new FactoryList(AnchorHandler.class, ScriptingEventsHandler.class, CommonAttributesHandler.class));
|
||||
put("a-close", new FactoryList(AnchorHandler.CloseHandler.class));
|
||||
put("checkbox", new FactoryList(CheckboxHandler.class, ScriptingEventsHandler.class, CommonAttributesHandler.class));
|
||||
put("file", new FactoryList(FileHandler.class, ScriptingEventsHandler.class, CommonAttributesHandler.class));
|
||||
put("password", new FactoryList(PasswordHandler.class, ScriptingEventsHandler.class, CommonAttributesHandler.class));
|
||||
put("label", new FactoryList(LabelHandler.class, ScriptingEventsHandler.class, CommonAttributesHandler.class));
|
||||
put("reset", new FactoryList(ResetHandler.class, ScriptingEventsHandler.class, CommonAttributesHandler.class));
|
||||
put("submit", new FactoryList(SubmitHandler.class, ScriptingEventsHandler.class, CommonAttributesHandler.class));
|
||||
put("submit-close", new FactoryList(SubmitHandler.CloseHandler.class));
|
||||
put("textarea", new FactoryList(TextAreaHandler.class, ScriptingEventsHandler.class, CommonAttributesHandler.class));
|
||||
put("actionerror", new FactoryList(ActionErrorHandler.class));
|
||||
put("token", new FactoryList(TokenHandler.class));
|
||||
put("actionmessage", new FactoryList(ActionMessageHandler.class));
|
||||
put("head", new FactoryList(HeadHandler.class));
|
||||
put("hidden", new FactoryList(HiddenHandler.class));
|
||||
put("fielderror", new FactoryList(FieldErrorHandler.class));
|
||||
put("div", new FactoryList(DivHandler.class, ScriptingEventsHandler.class, CommonAttributesHandler.class));
|
||||
put("div-close", new FactoryList(DivHandler.CloseHandler.class));
|
||||
put("empty", new FactoryList(EmptyHandler.class));
|
||||
}
|
||||
});
|
||||
setName("simple");
|
||||
}
|
||||
|
||||
private class FactoryList extends ArrayList<TagHandlerFactory> {
|
||||
|
||||
private static final long serialVersionUID = -1551895041394434032L;
|
||||
|
||||
public FactoryList(Class... classes) {
|
||||
super();
|
||||
for (Class cls : classes) {
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@ public class HeadTest extends AbstractTest {
|
||||
map.putAll(tag.getParameters());
|
||||
theme.renderTag(getTagName(), context);
|
||||
String output = writer.getBuffer().toString();
|
||||
String expected = s("<script type='text/javascript' src='/some/path/struts/utils.js'></script>");
|
||||
String expected = s("<script type='text/javascript' base='/some/path' src='/some/path/struts/utils.js'></script>");
|
||||
assertEquals(expected, output);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user