1 | |
|
2 | |
|
3 | |
|
4 | |
|
5 | |
|
6 | |
|
7 | |
|
8 | |
|
9 | |
|
10 | |
|
11 | |
|
12 | |
|
13 | |
|
14 | |
|
15 | |
|
16 | |
package org.seasar.teeda.core.render; |
17 | |
|
18 | |
import java.io.IOException; |
19 | |
import java.util.HashMap; |
20 | |
import java.util.Iterator; |
21 | |
import java.util.Map; |
22 | |
import java.util.Set; |
23 | |
import java.util.Map.Entry; |
24 | |
|
25 | |
import javax.faces.component.UIComponent; |
26 | |
import javax.faces.component.UIOutput; |
27 | |
import javax.faces.context.FacesContext; |
28 | |
import javax.faces.context.ResponseWriter; |
29 | |
import javax.faces.convert.ConverterException; |
30 | |
import javax.faces.internal.IgnoreAttribute; |
31 | |
import javax.faces.internal.UIComponentUtil; |
32 | |
import javax.faces.render.Renderer; |
33 | |
|
34 | |
import org.seasar.framework.beans.BeanDesc; |
35 | |
import org.seasar.framework.beans.PropertyDesc; |
36 | |
import org.seasar.framework.beans.factory.BeanDescFactory; |
37 | |
import org.seasar.framework.util.ArrayUtil; |
38 | |
import org.seasar.framework.util.AssertionUtil; |
39 | |
import org.seasar.framework.util.StringUtil; |
40 | |
import org.seasar.teeda.core.JsfConstants; |
41 | |
import org.seasar.teeda.core.util.LoopIterator; |
42 | |
import org.seasar.teeda.core.util.RenderedComponentIterator; |
43 | |
import org.seasar.teeda.core.util.RendererUtil; |
44 | |
|
45 | |
|
46 | |
|
47 | |
|
48 | |
public abstract class AbstractRenderer extends Renderer { |
49 | |
|
50 | |
private ComponentIdLookupStrategy idLookupStartegy; |
51 | |
|
52 | 1172 | public AbstractRenderer() { |
53 | 1172 | idLookupStartegy = new DefaultComponentIdLookupStrategy(); |
54 | 1172 | } |
55 | |
|
56 | |
public Object getConvertedValue(FacesContext context, |
57 | |
UIComponent component, Object submittedValue) |
58 | |
throws ConverterException { |
59 | 40 | assertNotNull(context, component); |
60 | 4 | return RendererUtil.getConvertedUIOutputValue(context, |
61 | |
(UIOutput) component, submittedValue); |
62 | |
} |
63 | |
|
64 | |
protected String getIdForRender(FacesContext context, UIComponent component) { |
65 | 299 | return idLookupStartegy.getId(context, component); |
66 | |
} |
67 | |
|
68 | |
protected UIComponent toNullIfNotRendered(UIComponent component) { |
69 | 82 | if (component != null && !component.isRendered()) { |
70 | 4 | return null; |
71 | |
} |
72 | 78 | return component; |
73 | |
} |
74 | |
|
75 | |
protected void encodeComponent(FacesContext context, UIComponent component) |
76 | |
throws IOException { |
77 | 135 | component.encodeBegin(context); |
78 | 135 | if (component.getRendersChildren()) { |
79 | 4 | component.encodeChildren(context); |
80 | |
} else { |
81 | 131 | encodeDescendantComponent(context, component); |
82 | |
} |
83 | 135 | component.encodeEnd(context); |
84 | 135 | } |
85 | |
|
86 | |
protected void encodeDescendantComponent(FacesContext context, |
87 | |
UIComponent component) throws IOException { |
88 | 182 | for (Iterator it = getRenderedChildrenIterator(component); it.hasNext();) { |
89 | 61 | UIComponent child = (UIComponent) it.next(); |
90 | 61 | encodeComponent(context, child); |
91 | |
} |
92 | 182 | } |
93 | |
|
94 | |
|
95 | |
protected void assertNotNull(FacesContext context, UIComponent component) { |
96 | 770 | AssertionUtil.assertNotNull("context", context); |
97 | 698 | AssertionUtil.assertNotNull("component", component); |
98 | 626 | } |
99 | |
|
100 | |
|
101 | |
protected String[] splitByComma(String s) { |
102 | 23 | String[] split = StringUtil.split(s, ","); |
103 | 46 | for (int i = 0; i < split.length; i++) { |
104 | 23 | split[i] = split[i].trim(); |
105 | |
} |
106 | 23 | return split; |
107 | |
} |
108 | |
|
109 | |
protected LoopIterator toStyleLoopIterator(String s) { |
110 | 22 | return new LoopIterator(splitByComma(s)); |
111 | |
} |
112 | |
|
113 | |
protected Iterator getRenderedChildrenIterator(UIComponent component) { |
114 | 230 | return new RenderedComponentIterator(component.getChildren()); |
115 | |
} |
116 | |
|
117 | |
protected String getLabelStyleClass(UIComponent component, boolean disabled) { |
118 | 138 | if (disabled) { |
119 | 42 | return UIComponentUtil.getStringAttribute(component, |
120 | |
JsfConstants.DISABLED_CLASS_ATTR); |
121 | |
} else { |
122 | 96 | return UIComponentUtil.getStringAttribute(component, |
123 | |
JsfConstants.ENABLED_CLASS_ATTR); |
124 | |
} |
125 | |
} |
126 | |
|
127 | |
protected void renderRemainAttributes(final UIComponent component, |
128 | |
final ResponseWriter writer, final IgnoreAttribute ignore) |
129 | |
throws IOException { |
130 | 261 | final Map map = getAllAttributesAndProperties(component, ignore); |
131 | 261 | renderAttributes(map, writer); |
132 | 261 | } |
133 | |
|
134 | |
protected void renderAttributes(Map attributes, ResponseWriter writer) |
135 | |
throws IOException { |
136 | 289 | for (final Iterator it = attributes.entrySet().iterator(); it.hasNext();) { |
137 | 5997 | final Map.Entry entry = (Entry) it.next(); |
138 | 5997 | final String key = (String) entry.getKey(); |
139 | 5997 | if (isRenderAttributeName(key)) { |
140 | 5995 | RendererUtil.renderAttribute(writer, key, entry.getValue()); |
141 | |
} |
142 | |
} |
143 | 289 | } |
144 | |
|
145 | |
protected Map getAllAttributesAndProperties(final UIComponent component, |
146 | |
final IgnoreAttribute ignore) { |
147 | 433 | final Map map = new HashMap(64); |
148 | 433 | final BeanDesc beanDesc = BeanDescFactory.getBeanDesc(component |
149 | |
.getClass()); |
150 | 433 | final Object[] attributeNames = ignore.getAttributeNames(); |
151 | 16148 | for (int i = 0; i < beanDesc.getPropertyDescSize(); i++) { |
152 | 15715 | final PropertyDesc propertyDesc = beanDesc.getPropertyDesc(i); |
153 | 15715 | final String propertyName = propertyDesc.getPropertyName(); |
154 | 15715 | if (ArrayUtil.contains(attributeNames, propertyName)) { |
155 | 8613 | continue; |
156 | |
} |
157 | 7102 | if (propertyDesc.isReadable()) { |
158 | 6462 | final Object value = propertyDesc.getValue(component); |
159 | 6462 | map.put(propertyName, value); |
160 | |
} |
161 | |
} |
162 | 433 | for (Iterator itr = component.getAttributes().entrySet().iterator(); itr |
163 | 497 | .hasNext();) { |
164 | 64 | Map.Entry entry = (Entry) itr.next(); |
165 | 64 | final String name = (String) entry.getKey(); |
166 | 64 | if (!isRenderAttributeName(name)) { |
167 | 17 | continue; |
168 | |
} |
169 | 47 | if (ArrayUtil.contains(attributeNames, name)) { |
170 | 20 | continue; |
171 | |
} |
172 | 27 | map.put(name, entry.getValue()); |
173 | |
} |
174 | 433 | return map; |
175 | |
} |
176 | |
|
177 | |
|
178 | |
|
179 | |
|
180 | |
|
181 | |
protected boolean isRenderAttributeName(final String key) { |
182 | 6071 | return -1 == key.indexOf('.'); |
183 | |
} |
184 | |
|
185 | |
public void setComponentIdLookupStrategy( |
186 | |
ComponentIdLookupStrategy idLookupStartegy) { |
187 | 1005 | this.idLookupStartegy = idLookupStartegy; |
188 | 1005 | } |
189 | |
|
190 | |
public ComponentIdLookupStrategy getComponentIdLookupStrategy() { |
191 | 0 | return idLookupStartegy; |
192 | |
} |
193 | |
|
194 | |
protected boolean containsAttributeForRender(final UIComponent component, |
195 | |
final IgnoreAttribute ignore) { |
196 | 179 | if (RendererUtil.shouldRenderIdAttribute(component)) { |
197 | 8 | return true; |
198 | |
} |
199 | 171 | final Map map = getAllAttributesAndProperties(component, ignore); |
200 | 171 | final Set keys = map.keySet(); |
201 | 171 | final String[] names = new String[keys.size()]; |
202 | 171 | keys.toArray(names); |
203 | 171 | if (RendererUtil.containsAttributesForRender(component, names)) { |
204 | 8 | return true; |
205 | |
} |
206 | 163 | return containsAttributeForRender(component.getAttributes()); |
207 | |
} |
208 | |
|
209 | |
protected boolean containsAttributeForRender(Map attributes) { |
210 | 190 | for (final Iterator it = attributes.entrySet().iterator(); it.hasNext();) { |
211 | 10 | final Map.Entry entry = (Entry) it.next(); |
212 | 10 | final String key = (String) entry.getKey(); |
213 | 10 | if (isRenderAttributeName(key)) { |
214 | 2 | final Object value = entry.getValue(); |
215 | 2 | if (RendererUtil.shouldRenderAttribute(key, value)) { |
216 | 2 | return true; |
217 | |
} |
218 | |
} |
219 | |
} |
220 | 188 | return false; |
221 | |
} |
222 | |
|
223 | |
|
224 | |
protected void renderCheckedAttribute(ResponseWriter writer) |
225 | |
throws IOException { |
226 | 6 | RendererUtil.renderAttribute(writer, JsfConstants.CHECKED_ATTR, |
227 | |
JsfConstants.CHECKED_ATTR); |
228 | 6 | } |
229 | |
|
230 | |
protected void renderDisabledAttribute(ResponseWriter writer) |
231 | |
throws IOException { |
232 | 34 | RendererUtil.renderAttribute(writer, JsfConstants.DISABLED_ATTR, |
233 | |
JsfConstants.DISABLED_ATTR); |
234 | 34 | } |
235 | |
|
236 | |
|
237 | |
protected void renderSelectedAttribute(ResponseWriter writer) |
238 | |
throws IOException { |
239 | 13 | RendererUtil.renderAttribute(writer, JsfConstants.SELECTED_ATTR, |
240 | |
JsfConstants.SELECTED_ATTR); |
241 | 13 | } |
242 | |
|
243 | |
protected void renderJavaScriptElement(final ResponseWriter writer, |
244 | |
final String scriptBody) throws IOException { |
245 | 4 | if (StringUtil.isBlank(scriptBody)) { |
246 | 0 | return; |
247 | |
} |
248 | 4 | writer.write(JsfConstants.LINE_SP); |
249 | 4 | writer.startElement(JsfConstants.SCRIPT_ELEM, null); |
250 | 4 | writer.writeAttribute(JsfConstants.LANGUAGE_ATTR, |
251 | |
JsfConstants.JAVASCRIPT_VALUE, null); |
252 | 4 | writer.writeAttribute(JsfConstants.TYPE_ATTR, |
253 | |
JsfConstants.TEXT_JAVASCRIPT_VALUE, null); |
254 | 4 | writer.write(JsfConstants.LINE_SP); |
255 | 4 | writer.write("<!--"); |
256 | 4 | writer.write(JsfConstants.LINE_SP); |
257 | 4 | writer.write(scriptBody); |
258 | 4 | writer.write(JsfConstants.LINE_SP); |
259 | 4 | writer.write("//-->"); |
260 | 4 | writer.write(JsfConstants.LINE_SP); |
261 | 4 | writer.endElement(JsfConstants.SCRIPT_ELEM); |
262 | 4 | } |
263 | |
|
264 | |
protected void renderIncludeJavaScript(final ResponseWriter writer, |
265 | |
final String path) throws IOException { |
266 | 1 | if (StringUtil.isBlank(path)) { |
267 | 0 | return; |
268 | |
} |
269 | 1 | writer.startElement(JsfConstants.SCRIPT_ELEM, null); |
270 | 1 | writer.writeAttribute(JsfConstants.LANGUAGE_ATTR, |
271 | |
JsfConstants.JAVASCRIPT_VALUE, null); |
272 | 1 | writer.writeAttribute(JsfConstants.TYPE_ATTR, |
273 | |
JsfConstants.TEXT_JAVASCRIPT_VALUE, null); |
274 | 1 | writer.writeAttribute(JsfConstants.SRC_ATTR, path, null); |
275 | 1 | writer.endElement(JsfConstants.SCRIPT_ELEM); |
276 | 1 | } |
277 | |
|
278 | |
protected void renderStyleSheet(final ResponseWriter writer, |
279 | |
final String path) throws IOException { |
280 | 1 | if (StringUtil.isBlank(path)) { |
281 | 0 | return; |
282 | |
} |
283 | 1 | writer.startElement(JsfConstants.LINK_ELEM, null); |
284 | 1 | writer.writeAttribute(JsfConstants.TYPE_ATTR, |
285 | |
JsfConstants.TEXT_CSS_VALUE, null); |
286 | 1 | writer.writeAttribute(JsfConstants.REL_ATTR, |
287 | |
JsfConstants.STYLESHEET_VALUE, null); |
288 | 1 | writer.writeAttribute(JsfConstants.HREF_ATTR, path, null); |
289 | 1 | writer.endElement(JsfConstants.LINK_ELEM); |
290 | 1 | } |
291 | |
} |