001    package org.apache.myfaces.tobago.webapp;
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    import org.slf4j.Logger;
021    import org.slf4j.LoggerFactory;
022    import org.apache.myfaces.tobago.internal.webapp.TobagoMultipartFormdataRequest;
023    
024    import javax.servlet.Filter;
025    import javax.servlet.FilterChain;
026    import javax.servlet.FilterConfig;
027    import javax.servlet.ServletException;
028    import javax.servlet.ServletRequest;
029    import javax.servlet.ServletResponse;
030    import javax.servlet.http.HttpServletRequest;
031    import java.io.File;
032    import java.io.IOException;
033    import java.util.Locale;
034    
035    
036    /**
037     * This filter handles multipart request. It must be enabled in the web.xml of your web application.
038     * Usage:
039     * <p/>
040     * <p><blockquote><pre>
041     * &lt;filter&gt;
042     * &lt;filter-name&gt;multipartFormdataFilter&lt;/filter-name&gt;
043     * &lt;filter-class&gt;org.apache.myfaces.tobago.webapp.TobagoMultipartFormdataFilter&lt;/filter-class&gt;
044     * &lt;init-param&gt;
045     * &lt;description&gt;Set the size limit for uploaded files. Default value is 1 MB.
046     * Format: 10 = 10 bytes
047     * 10k = 10 KB
048     * 10m = 10 MB
049     * 1g = 1 GB
050     * &lt;/description&gt;
051     * &lt;param-name&gt;uploadMaxFileSize&lt;/param-name&gt;
052     * &lt;param-value&gt;20m&lt;/param-value&gt;
053     * &lt;/init-param&gt;
054     * &lt;init-param&gt;
055     * &lt;description&gt;Set the upload repository path for uploaded files.
056     * Default value is java.io.tmpdir.&lt;/description&gt;
057     * &lt;param-name&gt;uploadRepositoryPath&lt;/param-name&gt;
058     * &lt;param-value&gt;/tmp&lt;/param-value&gt;
059     * &lt;/init-param&gt;
060     * &lt;/filter&gt;
061     * &lt;filter-mapping&gt;
062     * &lt;filter-name&gt;multipartFormdataFilter&lt;/filter-name&gt;
063     * &lt;url-pattern&gt;/faces/*&lt;/url-pattern&gt;
064     * &lt;/filter-mapping&gt;
065     * </pre></blockquote><p>
066     */
067    public class TobagoMultipartFormdataFilter implements Filter {
068    
069      private static final Logger LOG = LoggerFactory.getLogger(TobagoMultipartFormdataFilter.class);
070    
071      private String repositoryPath = System.getProperty("java.io.tmpdir");
072      private long maxSize = TobagoMultipartFormdataRequest.ONE_MB;
073    
074      public void init(FilterConfig filterConfig) throws ServletException {
075        String repositoryPath = filterConfig.getInitParameter("uploadRepositoryPath");
076        if (repositoryPath != null) {
077          File file = new File(repositoryPath);
078          if (!file.exists()) {
079            LOG.error("Given repository Path for " + getClass().getName() + " " + repositoryPath + " doesn't exists");
080          } else if (!file.isDirectory()) {
081            LOG.error("Given repository Path for " + getClass().getName() + " " + repositoryPath + " is not a directory");
082          } else {
083            this.repositoryPath = repositoryPath;
084          }
085        }
086    
087    
088        maxSize = TobagoMultipartFormdataRequest.getMaxSize(filterConfig.getInitParameter("uploadMaxFileSize"));
089        if (LOG.isInfoEnabled()) {
090          LOG.info("Configure uploadRepositryPath for " + getClass().getName() + " to " + this.repositoryPath);
091          LOG.info("Configure uploadMaxFileSize for " + getClass().getName() + " to " + this.maxSize);
092        }
093    
094      }
095    
096      public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
097          throws IOException, ServletException {
098        ServletRequest wrapper;
099        if (request instanceof HttpServletRequest) {
100          if (request instanceof TobagoMultipartFormdataRequest) {
101            wrapper = request;
102          } else {
103            String contentType = request.getContentType();
104            if (contentType != null
105                && contentType.toLowerCase(Locale.ENGLISH).startsWith("multipart/form-data")) {
106              if (LOG.isDebugEnabled()) {
107                LOG.debug("Wrapping " + request.getClass().getName()
108                    + " with ContentType=\"" + contentType + "\" "
109                    + "into TobagoMultipartFormdataRequest");
110              }
111              wrapper = new TobagoMultipartFormdataRequest(
112                  (HttpServletRequest) request, repositoryPath, maxSize);
113            } else {
114              wrapper = request;
115            }
116          }
117        } else {
118          LOG.error("Not implemented for non HttpServletRequest");
119          wrapper = request;
120        }
121    
122        chain.doFilter(wrapper, response);
123      }
124    
125      public void destroy() {
126      }
127    
128    }