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