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