1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.apache.struts2.views.freemarker.tags;
22
23 import java.io.IOException;
24 import java.io.Writer;
25 import java.util.HashMap;
26 import java.util.Iterator;
27 import java.util.Map;
28
29 import javax.servlet.http.HttpServletRequest;
30 import javax.servlet.http.HttpServletResponse;
31
32 import org.apache.commons.logging.Log;
33 import org.apache.commons.logging.LogFactory;
34 import org.apache.struts2.components.Component;
35 import org.apache.struts2.dispatcher.Dispatcher;
36
37 import com.opensymphony.xwork2.inject.Container;
38 import com.opensymphony.xwork2.util.ValueStack;
39
40 import freemarker.template.DefaultObjectWrapper;
41 import freemarker.template.SimpleNumber;
42 import freemarker.template.SimpleSequence;
43 import freemarker.template.TemplateModel;
44 import freemarker.template.TemplateModelException;
45 import freemarker.template.TemplateTransformModel;
46
47 public abstract class TagModel implements TemplateTransformModel {
48 private static final Log LOG = LogFactory.getLog(TagModel.class);
49
50 protected ValueStack stack;
51 protected HttpServletRequest req;
52 protected HttpServletResponse res;
53
54 public TagModel(ValueStack stack, HttpServletRequest req, HttpServletResponse res) {
55 this.stack = stack;
56 this.req = req;
57 this.res = res;
58 }
59
60 public Writer getWriter(Writer writer, Map params)
61 throws TemplateModelException, IOException {
62 Component bean = getBean();
63 Container container = Dispatcher.getInstance().getConfigurationManager().getConfiguration().getContainer();
64 container.inject(bean);
65
66 Map unwrappedParameters = unwrapParameters(params);
67 bean.copyParams(unwrappedParameters);
68
69 return new CallbackWriter(bean, writer);
70 }
71
72 protected abstract Component getBean();
73
74 protected Map unwrapParameters(Map params) {
75 Map map = new HashMap(params.size());
76 DefaultObjectWrapper objectWrapper = new DefaultObjectWrapper();
77 for (Iterator iterator = params.entrySet().iterator(); iterator.hasNext();) {
78 Map.Entry entry = (Map.Entry) iterator.next();
79
80 Object value = entry.getValue();
81
82 if (value != null) {
83
84 if (value instanceof TemplateModel) {
85 try {
86 map.put(entry.getKey(), objectWrapper
87 .unwrap((TemplateModel) value));
88 } catch (TemplateModelException e) {
89 LOG.error("failed to unwrap [" + value
90 + "] it will be ignored", e);
91 }
92 }
93
94 else {
95 map.put(entry.getKey(), value.toString());
96 }
97 }
98 }
99 return map;
100 }
101
102 protected Map convertParams(Map params) {
103 HashMap map = new HashMap(params.size());
104 for (Iterator iterator = params.entrySet().iterator(); iterator.hasNext();) {
105 Map.Entry entry = (Map.Entry) iterator.next();
106 Object value = entry.getValue();
107 if (value != null && !complexType(value)) {
108 map.put(entry.getKey(), value.toString());
109 }
110 }
111 return map;
112 }
113
114 protected Map getComplexParams(Map params) {
115 HashMap map = new HashMap(params.size());
116 for (Iterator iterator = params.entrySet().iterator(); iterator.hasNext();) {
117 Map.Entry entry = (Map.Entry) iterator.next();
118 Object value = entry.getValue();
119 if (value != null && complexType(value)) {
120 if (value instanceof freemarker.ext.beans.BeanModel) {
121 map.put(entry.getKey(), ((freemarker.ext.beans.BeanModel) value).getWrappedObject());
122 } else if (value instanceof SimpleNumber) {
123 map.put(entry.getKey(), ((SimpleNumber) value).getAsNumber());
124 } else if (value instanceof SimpleSequence) {
125 try {
126 map.put(entry.getKey(), ((SimpleSequence) value).toList());
127 } catch (TemplateModelException e) {
128 LOG.error("There was a problem converting a SimpleSequence to a list", e);
129 }
130 }
131 }
132 }
133 return map;
134 }
135
136 protected boolean complexType(Object value) {
137 return value instanceof freemarker.ext.beans.BeanModel
138 || value instanceof SimpleNumber
139 || value instanceof SimpleSequence;
140 }
141 }