1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.myfaces.shared.renderkit.html;
21
22 import javax.faces.component.UIComponent;
23 import javax.faces.component.UIInput;
24 import javax.faces.context.FacesContext;
25 import javax.faces.context.ResponseWriter;
26 import javax.faces.convert.ConverterException;
27 import javax.servlet.ServletException;
28 import javax.servlet.http.HttpServletRequest;
29 import javax.servlet.http.Part;
30 import java.io.IOException;
31 import java.util.List;
32 import java.util.Map;
33 import java.util.logging.Level;
34 import java.util.logging.Logger;
35 import javax.faces.FacesException;
36 import javax.faces.application.FacesMessage;
37 import javax.faces.application.ProjectStage;
38 import javax.faces.component.UIViewRoot;
39 import javax.faces.component.behavior.ClientBehavior;
40 import javax.faces.component.behavior.ClientBehaviorHolder;
41 import javax.faces.component.html.HtmlForm;
42 import javax.faces.component.html.HtmlInputText;
43 import org.apache.myfaces.shared.renderkit.html.util.FormInfo;
44 import org.apache.myfaces.shared.renderkit.html.util.HttpPartWrapper;
45 import org.apache.myfaces.shared.util._ComponentUtils;
46
47 public class HtmlInputFileRendererBase extends HtmlRenderer
48 {
49 private static final Logger log = Logger.getLogger(HtmlInputFileRendererBase.class.getName());
50
51 private static final String AUTOCOMPLETE_VALUE_OFF = "off";
52
53 @Override
54 public void decode(FacesContext facesContext, UIComponent component)
55 {
56 try
57 {
58 Part part = ((HttpServletRequest) facesContext.getExternalContext().getRequest()).
59 getPart(component.getClientId());
60
61 if (part == null)
62 {
63 return;
64 }
65 ((UIInput) component).setSubmittedValue(new HttpPartWrapper(part));
66 }
67 catch (IOException e)
68 {
69 throw new FacesException(e);
70 }
71 catch (ServletException e)
72 {
73 throw new FacesException(e);
74 }
75
76 if (component instanceof ClientBehaviorHolder &&
77 !HtmlRendererUtils.isDisabled(component))
78 {
79 HtmlRendererUtils.decodeClientBehaviors(facesContext, component);
80 }
81 }
82
83 @Override
84 public void encodeEnd(FacesContext facesContext, UIComponent component)
85 throws IOException
86 {
87 renderInput(facesContext, component);
88
89 if(!facesContext.isProjectStage(ProjectStage.Production)
90 && facesContext.isPostback() &&
91 (facesContext.getPartialViewContext().isPartialRequest() ||
92 facesContext.getPartialViewContext().isAjaxRequest()))
93 {
94 FormInfo formInfo = _ComponentUtils.findNestingForm(component, facesContext);
95 if (formInfo != null && formInfo.getForm() instanceof HtmlForm)
96 {
97 HtmlForm form = (HtmlForm) formInfo.getForm();
98 String content = form.getEnctype();
99 if (content==null || !content.contains("multipart/form-data"))
100 {
101 FacesMessage message = new FacesMessage("file upload requires a form with"+
102 " enctype equal to multipart/form-data");
103 facesContext.addMessage(component.getClientId(), message);
104 }
105 }
106 }
107 }
108
109 @Override
110 public Object getConvertedValue(FacesContext context, UIComponent component, Object submittedValue)
111 throws ConverterException
112 {
113 if (context == null)
114 {
115 throw new NullPointerException("context");
116 }
117 if (component == null)
118 {
119 throw new NullPointerException("component");
120 }
121 return submittedValue;
122 }
123
124
125
126
127 protected String getInputHtmlType(UIComponent component)
128 {
129
130 return HTML.INPUT_TYPE_FILE;
131 }
132
133 protected void renderValue(FacesContext facesContext, UIComponent component, ResponseWriter writer)
134 throws IOException
135 {
136
137 }
138
139 protected boolean isRenderOutputEventAttributes()
140 {
141 return true;
142 }
143
144 protected void renderInput(FacesContext facesContext, UIComponent component)
145 throws IOException
146 {
147
148 renderInputBegin(facesContext, component);
149 renderInputEnd(facesContext, component);
150 }
151
152
153 protected void renderInputBegin(FacesContext facesContext,
154 UIComponent component) throws IOException
155 {
156 ResponseWriter writer = facesContext.getResponseWriter();
157
158 String clientId = component.getClientId(facesContext);
159
160 writer.startElement(HTML.INPUT_ELEM, component);
161 writer.writeAttribute(HTML.ID_ATTR, clientId, null);
162 writer.writeAttribute(HTML.NAME_ATTR, clientId, null);
163
164
165 String inputHtmlType = getInputHtmlType(component);
166 writer.writeAttribute(HTML.TYPE_ATTR, inputHtmlType, null);
167
168 renderValue(facesContext, component, writer);
169
170 Map<String, List<ClientBehavior>> behaviors = null;
171 if (component instanceof ClientBehaviorHolder)
172 {
173 behaviors = ((ClientBehaviorHolder) component).getClientBehaviors();
174
175 long commonPropertiesMarked = 0L;
176 if (isCommonPropertiesOptimizationEnabled(facesContext))
177 {
178 commonPropertiesMarked = CommonPropertyUtils.getCommonPropertiesMarked(component);
179 }
180 if (behaviors.isEmpty() && isCommonPropertiesOptimizationEnabled(facesContext))
181 {
182 CommonPropertyUtils.renderChangeEventProperty(writer,
183 commonPropertiesMarked, component);
184 CommonPropertyUtils.renderEventProperties(writer,
185 commonPropertiesMarked, component);
186 CommonPropertyUtils.renderFieldEventPropertiesWithoutOnchange(writer,
187 commonPropertiesMarked, component);
188 }
189 else
190 {
191 HtmlRendererUtils.renderBehaviorizedOnchangeEventHandler(facesContext, writer, component, behaviors);
192 if (isCommonEventsOptimizationEnabled(facesContext))
193 {
194 Long commonEventsMarked = CommonEventUtils.getCommonEventsMarked(component);
195 CommonEventUtils.renderBehaviorizedEventHandlers(facesContext, writer,
196 commonPropertiesMarked, commonEventsMarked, component, behaviors);
197 CommonEventUtils.renderBehaviorizedFieldEventHandlersWithoutOnchange(
198 facesContext, writer, commonPropertiesMarked, commonEventsMarked, component, behaviors);
199 }
200 else
201 {
202 HtmlRendererUtils.renderBehaviorizedEventHandlers(facesContext, writer, component, behaviors);
203 HtmlRendererUtils.renderBehaviorizedFieldEventHandlersWithoutOnchange(
204 facesContext, writer, component, behaviors);
205 }
206 }
207 if (isCommonPropertiesOptimizationEnabled(facesContext))
208 {
209 CommonPropertyUtils.renderInputPassthroughPropertiesWithoutDisabledAndEvents(writer,
210 commonPropertiesMarked, component);
211 }
212 else
213 {
214 HtmlRendererUtils.renderHTMLAttributes(writer, component,
215 HTML.INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_EVENTS);
216 }
217 }
218 else
219 {
220 if (isCommonPropertiesOptimizationEnabled(facesContext))
221 {
222 CommonPropertyUtils.renderInputPassthroughPropertiesWithoutDisabled(writer,
223 CommonPropertyUtils.getCommonPropertiesMarked(component), component);
224 }
225 else
226 {
227 HtmlRendererUtils.renderHTMLAttributes(writer, component,
228 HTML.INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED);
229 }
230 }
231
232 if (isDisabled(facesContext, component))
233 {
234 writer.writeAttribute(HTML.DISABLED_ATTR, Boolean.TRUE, null);
235 }
236
237 if (isAutocompleteOff(facesContext, component))
238 {
239 writer.writeAttribute(HTML.AUTOCOMPLETE_ATTR, AUTOCOMPLETE_VALUE_OFF, HTML.AUTOCOMPLETE_ATTR);
240 }
241 }
242
243 protected void renderInputEnd(FacesContext facesContext, UIComponent component) throws IOException
244 {
245 ResponseWriter writer = facesContext.getResponseWriter();
246
247 writer.endElement(HTML.INPUT_ELEM);
248 }
249
250 protected boolean isDisabled(FacesContext facesContext, UIComponent component)
251 {
252
253 if (component instanceof HtmlInputText)
254 {
255 return ((HtmlInputText)component).isDisabled();
256 }
257
258 return org.apache.myfaces.shared.renderkit.RendererUtils.getBooleanAttribute(component,
259 HTML.DISABLED_ATTR, false);
260
261 }
262
263
264
265
266 protected boolean isAutocompleteOff(FacesContext facesContext, UIComponent component)
267 {
268 if (component instanceof HtmlInputText)
269 {
270 String autocomplete = ((HtmlInputText)component).getAutocomplete();
271 if (autocomplete != null)
272 {
273 return autocomplete.equals(AUTOCOMPLETE_VALUE_OFF);
274 }
275 }
276
277 return false;
278 }
279
280 public static void renderOutputText(FacesContext facesContext,
281 UIComponent component, String text, boolean escape)
282 throws IOException
283 {
284 if (text != null)
285 {
286 ResponseWriter writer = facesContext.getResponseWriter();
287 boolean span = false;
288
289 if (component.getId() != null
290 && !component.getId().startsWith(
291 UIViewRoot.UNIQUE_ID_PREFIX))
292 {
293 span = true;
294
295 writer.startElement(HTML.SPAN_ELEM, component);
296
297 HtmlRendererUtils.writeIdIfNecessary(writer, component,
298 facesContext);
299
300 HtmlRendererUtils.renderHTMLAttributes(writer, component,
301 HTML.COMMON_PASSTROUGH_ATTRIBUTES);
302
303 }
304 else
305 {
306 span = HtmlRendererUtils
307 .renderHTMLAttributesWithOptionalStartElement(writer,
308 component, HTML.SPAN_ELEM,
309 HTML.COMMON_PASSTROUGH_ATTRIBUTES);
310 }
311
312 if (escape)
313 {
314 if (log.isLoggable(Level.FINE))
315 {
316 log.fine("renderOutputText writing '" + text + "'");
317 }
318 writer.writeText(text,
319 org.apache.myfaces.shared.renderkit.JSFAttr.VALUE_ATTR);
320 }
321 else
322 {
323 writer.write(text);
324 }
325
326 if (span)
327 {
328 writer.endElement(org.apache.myfaces.shared.renderkit.html.HTML.SPAN_ELEM);
329 }
330 }
331 }
332 }