1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.custom.fileupload;
20
21 import java.io.IOException;
22 import java.util.List;
23 import java.util.Map;
24
25 import javax.faces.FacesException;
26 import javax.faces.application.ProjectStage;
27 import javax.faces.component.UIComponent;
28 import javax.faces.component.behavior.ClientBehavior;
29 import javax.faces.component.behavior.ClientBehaviorHolder;
30 import javax.faces.context.ExternalContext;
31 import javax.faces.context.FacesContext;
32 import javax.faces.context.ResponseWriter;
33 import javax.faces.convert.ConverterException;
34 import javax.servlet.ServletRequest;
35 import javax.servlet.http.HttpServletRequestWrapper;
36
37 import org.apache.commons.fileupload.FileItem;
38 import org.apache.commons.logging.Log;
39 import org.apache.commons.logging.LogFactory;
40 import org.apache.myfaces.component.UserRoleUtils;
41 import org.apache.myfaces.shared_tomahawk.util.WebConfigParamUtils;
42 import org.apache.myfaces.shared_tomahawk.renderkit.RendererUtils;
43 import org.apache.myfaces.shared_tomahawk.renderkit.html.HTML;
44 import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRenderer;
45 import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRendererUtils;
46 import org.apache.myfaces.shared_tomahawk.renderkit.html.util.ResourceUtils;
47 import org.apache.myfaces.tomahawk.util.ExternalContextUtils;
48 import org.apache.myfaces.webapp.filter.ExtensionsFilter;
49 import org.apache.myfaces.webapp.filter.MultipartRequestWrapper;
50 import org.apache.myfaces.webapp.filter.TomahawkFacesContextFactory;
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65 public class HtmlFileUploadRenderer
66 extends HtmlRenderer
67 {
68 private static final Log log = LogFactory.getLog(HtmlFileUploadRenderer.class);
69
70 private static boolean getBooleanInitParameterValue(String initParameter, boolean defaultVal)
71 {
72 if(initParameter == null || initParameter.trim().length()==0)
73 return defaultVal;
74
75 return (initParameter.equalsIgnoreCase("on") || initParameter.equals("1") || initParameter.equalsIgnoreCase("true"));
76 }
77
78 public void encodeEnd(FacesContext facesContext, UIComponent uiComponent)
79 throws IOException
80 {
81 super.encodeEnd(facesContext, uiComponent);
82
83
84 boolean isDisabledTomahawkFacesContextWrapper = getBooleanInitParameterValue(
85 WebConfigParamUtils.getStringInitParameter(facesContext.getExternalContext(),
86 TomahawkFacesContextFactory.DISABLE_TOMAHAWK_FACES_CONTEXT_WRAPPER),
87 TomahawkFacesContextFactory.DISABLE_TOMAHAWK_FACES_CONTEXT_WRAPPER_DEFAULT);
88
89 if (!facesContext.isProjectStage(ProjectStage.Production))
90 {
91 boolean isPortlet = ExternalContextUtils.getRequestType(facesContext.getExternalContext()).isPortlet();
92
93
94
95 boolean requestInterceptedByFilter = facesContext.getExternalContext().getRequestMap().containsKey(ExtensionsFilter.DOFILTER_CALLED);
96 boolean extensionsFilterInitialized = facesContext.getExternalContext().getApplicationMap().containsKey(ExtensionsFilter.EXTENSIONS_FILTER_INITIALIZED);
97 if ( (isPortlet && isDisabledTomahawkFacesContextWrapper) ||
98 (isDisabledTomahawkFacesContextWrapper &&
99 !(requestInterceptedByFilter && extensionsFilterInitialized)))
100 {
101 if (log.isWarnEnabled())
102 {
103 log.warn("t:inputFileUpload requires ExtensionsFilter or TomahawkFacesContextFactory configured to handle multipart file upload, and any of " +
104 "them has been detected. Please read the instructions on http://myfaces.apache.org/tomahawk/extensionsFilter.html " +
105 "for more information about how to setup your environment correctly. Please be sure ExtensionsFilter is the top most " +
106 "filter if you are using multiple jsf libraries.");
107 if (extensionsFilterInitialized && !requestInterceptedByFilter)
108 {
109 log.warn("t:inputFileUpload requires the current request be intercepted by the filter in order to handle forms with multipart encode type. " +
110 "ExtensionsFilter was initialized but the current request was not intercepted. " +
111 "Please add a filter-mapping entry to intercept jsf page requests.");
112 }
113 }
114 }
115 }
116
117 ResponseWriter writer = facesContext.getResponseWriter();
118
119 Map<String, List<ClientBehavior>> behaviors = null;
120 if (uiComponent instanceof ClientBehaviorHolder)
121 {
122 behaviors = ((ClientBehaviorHolder) uiComponent).getClientBehaviors();
123 if (!behaviors.isEmpty())
124 {
125 ResourceUtils.renderDefaultJsfJsInlineIfNecessary(facesContext, facesContext.getResponseWriter());
126 }
127 }
128
129 writer.startElement(HTML.INPUT_ELEM, uiComponent);
130 writer.writeAttribute(HTML.TYPE_ATTR, HTML.FILE_ATTR, null);
131 String clientId = uiComponent.getClientId(facesContext);
132 if (behaviors != null && !behaviors.isEmpty())
133 {
134 writer.writeAttribute(HTML.ID_ATTR, clientId,null);
135 }
136 else
137 {
138 renderId(facesContext, uiComponent);
139 }
140 writer.writeAttribute(HTML.NAME_ATTR, clientId, null);
141 UploadedFile value = (UploadedFile)((HtmlInputFileUpload)uiComponent).getValue();
142 if (value != null)
143 {
144 if( value.getName() != null )
145 {
146 writer.writeAttribute(HTML.VALUE_ATTR, value.getName(), null);
147 }
148 }
149
150 if (behaviors != null && !behaviors.isEmpty())
151 {
152 HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent, HTML.INPUT_FILE_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_EVENTS);
153 HtmlRendererUtils.renderBehaviorizedEventHandlers(facesContext, writer, uiComponent, behaviors);
154 HtmlRendererUtils.renderBehaviorizedFieldEventHandlersWithoutOnchange(facesContext, writer, uiComponent, behaviors);
155 HtmlRendererUtils.renderBehaviorizedOnchangeEventHandler(facesContext, writer, uiComponent, behaviors);
156 }
157 else
158 {
159 HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent, HTML.INPUT_FILE_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED);
160 }
161
162 if (isDisabled(facesContext, uiComponent))
163 {
164 writer.writeAttribute(HTML.DISABLED_ATTR, Boolean.TRUE, null);
165 }
166
167 writer.endElement(HTML.INPUT_ELEM);
168 }
169
170 protected boolean isDisabled(FacesContext facesContext, UIComponent uiComponent)
171 {
172 if (!UserRoleUtils.isEnabledOnUserRole(uiComponent))
173 {
174
175
176 return true;
177 }
178 else
179 {
180 if (uiComponent instanceof HtmlInputFileUpload)
181 {
182 return ((HtmlInputFileUpload)uiComponent).isDisabled();
183 }
184 else
185 {
186 return RendererUtils.getBooleanAttribute(uiComponent, HTML.DISABLED_ATTR, false);
187 }
188 }
189 }
190
191 private void setSubmittedValueForImplementation(
192 FacesContext facesContext, UIComponent uiComponent, FileItem fileItem)
193 {
194 try
195 {
196 UploadedFile upFile;
197 String implementation =
198 ((HtmlInputFileUpload)uiComponent).getStorage();
199 if (implementation == null || implementation.length() == 0)
200 {
201 implementation = "default";
202 }
203 if (("memory").equals(implementation))
204 {
205 upFile = new UploadedFileDefaultMemoryImpl(fileItem);
206 }
207 else if (("default").equals(implementation))
208 {
209 if (fileItem.isInMemory())
210 {
211 upFile = new UploadedFileDefaultMemoryImpl(fileItem);
212 }
213 else
214 {
215 upFile = new UploadedFileDefaultFileImpl(fileItem);
216 }
217 }
218 else
219 {
220 upFile = new UploadedFileDefaultFileImpl(fileItem);
221 }
222
223 ((HtmlInputFileUpload)uiComponent).setSubmittedValue(upFile);
224 ((HtmlInputFileUpload)uiComponent).setValid(true);
225 }
226 catch (IOException ioe)
227 {
228 throw new FacesException(
229 "Exception while processing file upload for file-input : "
230 + uiComponent.getClientId(facesContext), ioe);
231 }
232 }
233
234
235
236
237
238
239
240
241
242
243 public void decode(FacesContext facesContext, UIComponent uiComponent)
244 {
245 super.decode(facesContext, uiComponent);
246
247 HtmlRendererUtils.decodeClientBehaviors(facesContext, uiComponent);
248
249
250
251
252 Object request = facesContext.getExternalContext().getRequest();
253 if (!(request instanceof ServletRequest)) {
254 ExternalContext externalContext = facesContext.getExternalContext();
255 Map fileItems = (Map)externalContext.getRequestMap().
256 get(MultipartRequestWrapper.UPLOADED_FILES_ATTRIBUTE);
257 FileItem fileItem = null;
258 if (fileItems != null) {
259 String paramName = uiComponent.getClientId(facesContext);
260 fileItem = (FileItem) fileItems.get(paramName);
261 }
262 if (fileItem != null)
263 {
264 setSubmittedValueForImplementation(facesContext, uiComponent, fileItem);
265 }
266 return;
267 }
268 if(facesContext.getExternalContext().getRequest() instanceof ServletRequest)
269 {
270 ServletRequest multipartRequest = (ServletRequest)facesContext.getExternalContext().getRequest();
271 while (multipartRequest != null &&
272 !(multipartRequest instanceof MultipartRequestWrapper))
273 {
274 if (multipartRequest instanceof HttpServletRequestWrapper)
275 {
276 multipartRequest = ((HttpServletRequestWrapper)multipartRequest).getRequest();
277 }
278 else
279 {
280 multipartRequest = null;
281 }
282 }
283
284 if (multipartRequest != null)
285 {
286 MultipartRequestWrapper mpReq = (MultipartRequestWrapper)multipartRequest;
287
288 String paramName = uiComponent.getClientId(facesContext);
289 FileItem fileItem = mpReq.getFileItem(paramName);
290 if (fileItem != null)
291 {
292 setSubmittedValueForImplementation(facesContext, uiComponent, fileItem);
293 }
294 }
295 }
296 }
297
298 public Object getConvertedValue(FacesContext context, UIComponent component, Object submittedValue) throws ConverterException
299 {
300 if(submittedValue instanceof UploadedFile)
301 {
302 UploadedFile file = (UploadedFile) submittedValue;
303
304 if(file.getSize()>0 && file.getName()!=null && file.getName().length()>0)
305 {
306 return file;
307 }
308 }
309
310 return null;
311 }
312 }