1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.myfaces.tobago.renderkit.html.scarborough.standard.tag;
21
22 import org.apache.commons.fileupload.FileItem;
23 import org.apache.myfaces.tobago.context.ClientProperties;
24 import org.apache.myfaces.tobago.internal.component.AbstractUIFile;
25 import org.apache.myfaces.tobago.internal.util.FacesContextUtils;
26 import org.apache.myfaces.tobago.internal.webapp.TobagoMultipartFormdataRequest;
27 import org.apache.myfaces.tobago.layout.Measure;
28 import org.apache.myfaces.tobago.renderkit.InputRendererBase;
29 import org.apache.myfaces.tobago.renderkit.css.Classes;
30 import org.apache.myfaces.tobago.renderkit.css.Style;
31 import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
32 import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
33 import org.apache.myfaces.tobago.renderkit.html.HtmlInputTypes;
34 import org.apache.myfaces.tobago.renderkit.html.util.HtmlRendererUtils;
35 import org.apache.myfaces.tobago.util.ComponentUtils;
36 import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39
40 import javax.faces.component.UIComponent;
41 import javax.faces.context.FacesContext;
42 import javax.servlet.ServletRequest;
43 import javax.servlet.http.HttpServletRequestWrapper;
44 import java.io.IOException;
45
46 public class FileRenderer extends InputRendererBase {
47
48 private static final Logger LOG = LoggerFactory.getLogger(FileRenderer.class);
49
50 public void prepareRender(FacesContext facesContext, UIComponent component) throws IOException {
51 super.prepareRender(facesContext, component);
52 FacesContextUtils.setEnctype(facesContext, "multipart/form-data");
53 }
54
55 public boolean getRendersChildren() {
56 return true;
57 }
58
59 public void decode(FacesContext facesContext, UIComponent component) {
60 if (ComponentUtils.isOutputOnly(component)) {
61 return;
62 }
63
64 AbstractUIFile input = (AbstractUIFile) component;
65
66 TobagoMultipartFormdataRequest request = null;
67 Object requestObject = facesContext.getExternalContext().getRequest();
68 if (requestObject instanceof TobagoMultipartFormdataRequest) {
69 request = (TobagoMultipartFormdataRequest) requestObject;
70 } else if (requestObject instanceof HttpServletRequestWrapper) {
71 ServletRequest wrappedRequest
72 = ((HttpServletRequestWrapper) requestObject).getRequest();
73 if (wrappedRequest instanceof TobagoMultipartFormdataRequest) {
74 request = (TobagoMultipartFormdataRequest) wrappedRequest;
75 }
76 }
77
78 if (request == null) {
79
80 LOG.error("Can't process multipart/form-data without TobagoRequest. "
81 + "Please check the web.xml and define a TobagoMultipartFormdataFilter. "
82 + "See documentation for <tc:file>");
83 } else {
84
85 FileItem item = request.getFileItem(input.getClientId(facesContext));
86
87 if (LOG.isDebugEnabled()) {
88 LOG.debug("Uploaded file name : \"" + item.getName()
89 + "\" size = " + item.getSize());
90 }
91 input.setSubmittedValue(item);
92
93 input.setValid(true);
94 }
95 }
96
97 public void encodeEnd(FacesContext facesContext, UIComponent component) throws IOException {
98
99 final AbstractUIFile file = (AbstractUIFile) component;
100 final String clientId = file.getClientId(facesContext);
101 final Style style = new Style(facesContext, file);
102
103 final TobagoResponseWriter writer = HtmlRendererUtils.getTobagoResponseWriter(facesContext);
104
105 writer.startElement(HtmlElements.DIV, file);
106 writer.writeIdAttribute(clientId);
107 writer.writeClassAttribute(Classes.create(file));
108 HtmlRendererUtils.writeDataAttributes(facesContext, writer, file);
109 writer.writeStyleAttribute(style);
110
111
112 final Style inputStyle = new Style();
113 final Measure prettyWidthSub = getResourceManager().getThemeMeasure(facesContext, file, "prettyWidthSub");
114 inputStyle.setWidth(style.getWidth().subtract(prettyWidthSub));
115 writer.startElement(HtmlElements.INPUT, file);
116 writer.writeIdAttribute(clientId + ComponentUtils.SUB_SEPARATOR + "pretty");
117 writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.TEXT, false);
118 writer.writeClassAttribute(Classes.create(file, "pretty"));
119 writer.writeStyleAttribute(inputStyle);
120 writer.writeAttribute(HtmlAttributes.DISABLED, true);
121
122
123 writer.endElement(HtmlElements.INPUT);
124
125
126 writer.startElement(HtmlElements.INPUT, file);
127 writer.writeIdAttribute(clientId + ComponentUtils.SUB_SEPARATOR + "real");
128 writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.FILE, false);
129 writer.writeClassAttribute(Classes.create(file, "real"));
130 writer.writeNameAttribute(clientId);
131
132 writer.writeAttribute(HtmlAttributes.DISABLED, file.isDisabled() || file.isReadonly());
133 writer.writeAttribute(HtmlAttributes.READONLY, file.isReadonly());
134 writer.writeAttribute(HtmlAttributes.REQUIRED, file.isRequired());
135 writer.writeAttribute(HtmlAttributes.SIZE, "1024", false);
136 final Integer tabIndex = file.getTabIndex();
137 if (tabIndex != null) {
138 writer.writeAttribute(HtmlAttributes.TABINDEX, tabIndex);
139 }
140 final String title = HtmlRendererUtils.getTitleFromTipAndMessages(facesContext, file);
141 if (title != null) {
142 writer.writeAttribute(HtmlAttributes.TITLE, title, true);
143 }
144 if (ClientProperties.getInstance(facesContext).getUserAgent().isMsie6()) {
145 writer.writeAttribute(HtmlAttributes.ONKEYDOWN, "this.blur();return false;", false);
146 writer.writeAttribute("oncontextmenu", "return false;", false);
147 }
148 writer.endElement(HtmlElements.INPUT);
149
150 writer.endElement(HtmlElements.DIV);
151 }
152 }