001 package org.apache.myfaces.tobago.renderkit.html.scarborough.standard.tag;
002
003 /*
004 * Licensed to the Apache Software Foundation (ASF) under one or more
005 * contributor license agreements. See the NOTICE file distributed with
006 * this work for additional information regarding copyright ownership.
007 * The ASF licenses this file to You under the Apache License, Version 2.0
008 * (the "License"); you may not use this file except in compliance with
009 * the License. You may obtain a copy of the License at
010 *
011 * http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing, software
014 * distributed under the License is distributed on an "AS IS" BASIS,
015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016 * See the License for the specific language governing permissions and
017 * limitations under the License.
018 */
019
020 /*
021 * Created 07.02.2003 16:00:00.
022 * $Id: FileRenderer.java 652070 2008-04-28 06:38:01Z bommel $
023 */
024
025 import org.apache.commons.fileupload.FileItem;
026 import org.apache.commons.logging.Log;
027 import org.apache.commons.logging.LogFactory;
028 import static org.apache.myfaces.tobago.TobagoConstants.ATTR_DISABLED;
029 import static org.apache.myfaces.tobago.TobagoConstants.FACET_LABEL;
030 import org.apache.myfaces.tobago.util.ComponentUtil;
031 import org.apache.myfaces.tobago.component.UIFileInput;
032 import org.apache.myfaces.tobago.context.ClientProperties;
033 import org.apache.myfaces.tobago.context.TobagoFacesContext;
034 import org.apache.myfaces.tobago.renderkit.InputRendererBase;
035 import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
036 import org.apache.myfaces.tobago.renderkit.html.HtmlConstants;
037 import org.apache.myfaces.tobago.renderkit.html.util.HtmlRendererUtil;
038 import org.apache.myfaces.tobago.util.LayoutUtil;
039 import org.apache.myfaces.tobago.webapp.TobagoMultipartFormdataRequest;
040 import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
041
042 import javax.faces.component.UIComponent;
043 import javax.faces.context.FacesContext;
044 import javax.servlet.ServletRequest;
045 import javax.servlet.http.HttpServletRequestWrapper;
046 import java.io.IOException;
047
048 public class FileRenderer extends InputRendererBase {
049
050 private static final Log LOG = LogFactory.getLog(FileRenderer.class);
051
052 public void prepareRender(FacesContext facesContext, UIComponent component) throws IOException {
053 super.prepareRender(facesContext, component);
054 if (facesContext instanceof TobagoFacesContext) {
055 ((TobagoFacesContext) facesContext).setEnctype("multipart/form-data");
056 }
057 }
058
059 public boolean getRendersChildren() {
060 return true;
061 }
062
063 public int getComponentExtraWidth(
064 FacesContext facesContext, UIComponent component) {
065 int space = 0;
066
067 if (component.getFacet(FACET_LABEL) != null) {
068 int labelWidht = LayoutUtil.getLabelWidth(component);
069 space += labelWidht != 0
070 ? labelWidht : getLabelWidth(facesContext, component);
071 }
072
073 return space;
074 }
075
076 public void decode(FacesContext facesContext, UIComponent component) {
077 if (!(component instanceof UIFileInput)) {
078 LOG.error("Wrong type: Need " + UIFileInput.class.getName() + ", but was " + component.getClass().getName());
079 return;
080 }
081
082 if (ComponentUtil.isOutputOnly(component)) {
083 return;
084 }
085
086 UIFileInput input = (UIFileInput) component;
087
088 TobagoMultipartFormdataRequest request = null;
089 Object requestObject = facesContext.getExternalContext().getRequest();
090 if (requestObject instanceof TobagoMultipartFormdataRequest) {
091 request = (TobagoMultipartFormdataRequest) requestObject;
092 } else if (requestObject instanceof HttpServletRequestWrapper) {
093 ServletRequest wrappedRequest
094 = ((HttpServletRequestWrapper) requestObject).getRequest();
095 if (wrappedRequest instanceof TobagoMultipartFormdataRequest) {
096 request = (TobagoMultipartFormdataRequest) wrappedRequest;
097 }
098 }
099 // TODO PortletRequest ??
100 if (request == null) {
101 // should not be possible, because of the check in UIPage
102 LOG.error("Can't process multipart/form-data without TobagoRequest. "
103 + "Please check the web.xml and define a TobagoMultipartFormdataFilter. "
104 + "See documentation for <tc:file>");
105 } else {
106
107 FileItem item = request.getFileItem(input.getClientId(facesContext));
108
109 if (LOG.isDebugEnabled()) {
110 LOG.debug("Uploaded file name : \"" + item.getName()
111 + "\" size = " + item.getSize());
112 }
113 input.setSubmittedValue(item);
114 //TODO remove this
115 input.setValid(true);
116 }
117 }
118
119 public void encodeEnd(FacesContext facesContext, UIComponent component) throws IOException {
120 if (!(component instanceof UIFileInput)) {
121 LOG.error("Wrong type: Need " + UIFileInput.class.getName() + ", but was " + component.getClass().getName());
122 return;
123 }
124
125 UIFileInput input = (UIFileInput) component;
126 String clientId = input.getClientId(facesContext);
127
128 TobagoResponseWriter writer = HtmlRendererUtil.getTobagoResponseWriter(facesContext);
129
130 writer.startElement(HtmlConstants.INPUT, input);
131 writer.writeAttribute(HtmlAttributes.TYPE, "file", false);
132 writer.writeClassAttribute();
133 if (!ClientProperties.getInstance(facesContext).getUserAgent().isMozilla()) {
134 writer.writeStyleAttribute();
135 }
136 writer.writeNameAttribute(clientId);
137 writer.writeIdAttribute(clientId);
138 writer.writeAttribute(HtmlAttributes.READONLY, ComponentUtil.getBooleanAttribute(input, ATTR_DISABLED));
139 Integer tabIndex = input.getTabIndex();
140 if (tabIndex != null) {
141 writer.writeAttribute(HtmlAttributes.TABINDEX, tabIndex);
142 }
143 HtmlRendererUtil.renderTip(input, writer);
144 writer.endElement(HtmlConstants.INPUT);
145 }
146 }
147