You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lo...@apache.org on 2016/03/03 18:46:04 UTC

svn commit: r1733503 - in /myfaces/tobago/branches/tobago-3.0.x: ./ tobago-assembly/ tobago-core/ tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/ tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/ tob...

Author: lofwyr
Date: Thu Mar  3 17:46:03 2016
New Revision: 1733503

URL: http://svn.apache.org/viewvc?rev=1733503&view=rev
Log:
TOBAGO-1539: Summary: Using Servelt 3.0 for uploading files with <tc:file>

Added:
    myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/PartUtils.java
    myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/util/PartUtilsUnitTest.java
Removed:
    myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/webapp/TobagoMultipartFormdataRequest.java
    myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/webapp/TobagoMultipartFormdataFilter.java
    myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/test/java/org/apache/myfaces/tobago/webapp/TobagoMultipartFormdataRequestUnitTest.java
    myfaces/tobago/branches/tobago-3.0.x/tobago-extension/tobago-fileupload/
Modified:
    myfaces/tobago/branches/tobago-3.0.x/pom.xml
    myfaces/tobago/branches/tobago-3.0.x/tobago-assembly/pom.xml
    myfaces/tobago/branches/tobago-3.0.x/tobago-core/pom.xml
    myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIFile.java
    myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIPage.java
    myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/FileTagDeclaration.java
    myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/validator/FileItemValidator.java
    myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-addressbook/pom.xml
    myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-addressbook/src/main/java/org/apache/myfaces/tobago/example/addressbook/Picture.java
    myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-addressbook/src/main/java/org/apache/myfaces/tobago/example/addressbook/web/Controller.java
    myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-addressbook/src/main/webapp/WEB-INF/web.xml
    myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-blank/src/main/webapp/WEB-INF/web.xml
    myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-demo/pom.xml
    myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/Upload.java
    myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/UploadItem.java
    myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-demo/src/main/webapp/WEB-INF/web.xml
    myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-demo/src/main/webapp/content/40-upload/upload.xhtml
    myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-portlet/src/main/webapp/WEB-INF/web.xml
    myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-security/src/main/webapp/WEB-INF/web.xml
    myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-test/src/main/java/org/apache/myfaces/tobago/example/test/Upload.java
    myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-test/src/main/webapp/WEB-INF/web.xml
    myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-test/src/main/webapp/test/file/file.xhtml
    myfaces/tobago/branches/tobago-3.0.x/tobago-extension/pom.xml
    myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/FileRenderer.java

Modified: myfaces/tobago/branches/tobago-3.0.x/pom.xml
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-3.0.x/pom.xml?rev=1733503&r1=1733502&r2=1733503&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-3.0.x/pom.xml (original)
+++ myfaces/tobago/branches/tobago-3.0.x/pom.xml Thu Mar  3 17:46:03 2016
@@ -198,7 +198,6 @@
             <link>http://docs.oracle.com/javase/6/docs/api/</link>
             <link>http://docs.oracle.com/javaee/6/api/</link>
             <link>http://jakarta.apache.org/commons/collections/api-${commons-collection.version}/</link>
-            <link>http://jakarta.apache.org/commons/fileupload/apidocs</link>
             <link>http://www.slf4j.org/apidocs</link>
             <link>http://junit.sourceforge.net/javadoc/</link>
             <link>http://logback.qos.ch/apidocs/</link>
@@ -464,11 +463,6 @@
         <version>${commons-collection.version}</version>
       </dependency>
       <dependency>
-        <groupId>commons-fileupload</groupId>
-        <artifactId>commons-fileupload</artifactId>
-        <version>1.3.1</version>
-      </dependency>
-      <dependency>
         <groupId>commons-codec</groupId>
         <artifactId>commons-codec</artifactId>
         <version>1.10</version>

Modified: myfaces/tobago/branches/tobago-3.0.x/tobago-assembly/pom.xml
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-3.0.x/tobago-assembly/pom.xml?rev=1733503&r1=1733502&r2=1733503&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-3.0.x/tobago-assembly/pom.xml (original)
+++ myfaces/tobago/branches/tobago-3.0.x/tobago-assembly/pom.xml Thu Mar  3 17:46:03 2016
@@ -58,11 +58,6 @@
       <scope>provided</scope>
     </dependency>
     <dependency>
-      <groupId>${project.groupId}</groupId>
-      <artifactId>tobago-fileupload</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
       <groupId>org.apache.geronimo.specs</groupId>
       <artifactId>geronimo-servlet_3.0_spec</artifactId>
       <scope>provided</scope>
@@ -237,12 +232,6 @@
                       <version>${project.version}</version>
                       <classifier>sources</classifier>
                     </artifactItem>
-                    <artifactItem>
-                      <groupId>${project.groupId}</groupId>
-                      <artifactId>tobago-fileupload</artifactId>
-                      <version>${project.version}</version>
-                      <classifier>sources</classifier>
-                    </artifactItem>
 
                   </artifactItems>
                   <outputDirectory>${project.build.directory}/src

Modified: myfaces/tobago/branches/tobago-3.0.x/tobago-core/pom.xml
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-3.0.x/tobago-core/pom.xml?rev=1733503&r1=1733502&r2=1733503&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-3.0.x/tobago-core/pom.xml (original)
+++ myfaces/tobago/branches/tobago-3.0.x/tobago-core/pom.xml Thu Mar  3 17:46:03 2016
@@ -160,10 +160,6 @@
       <scope>provided</scope>
     </dependency>
     <dependency>
-      <groupId>commons-fileupload</groupId>
-      <artifactId>commons-fileupload</artifactId>
-    </dependency>
-    <dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-api</artifactId>
     </dependency>

Modified: myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIFile.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIFile.java?rev=1733503&r1=1733502&r2=1733503&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIFile.java (original)
+++ myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIFile.java Thu Mar  3 17:46:03 2016
@@ -19,7 +19,6 @@
 
 package org.apache.myfaces.tobago.internal.component;
 
-import org.apache.commons.fileupload.FileItem;
 import org.apache.myfaces.tobago.component.SupportsLabelLayout;
 import org.apache.myfaces.tobago.component.Visual;
 import org.apache.myfaces.tobago.util.MessageUtils;
@@ -27,13 +26,14 @@ import org.apache.myfaces.tobago.util.Me
 import javax.faces.application.FacesMessage;
 import javax.faces.component.UIInput;
 import javax.faces.context.FacesContext;
+import javax.servlet.http.Part;
 
 public abstract class AbstractUIFile extends UIInput implements SupportsLabelLayout, Visual {
 
   public void validate(final FacesContext facesContext) {
     if (isRequired()) {
-      if (getSubmittedValue() instanceof FileItem) {
-        final FileItem file = (FileItem) getSubmittedValue();
+      if (getSubmittedValue() instanceof Part) {
+        final Part file = (Part) getSubmittedValue();
         if (file == null || file.getName().length() == 0) {
           addErrorMessage(facesContext);
           setValid(false);

Modified: myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIPage.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIPage.java?rev=1733503&r1=1733502&r2=1733503&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIPage.java (original)
+++ myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIPage.java Thu Mar  3 17:46:03 2016
@@ -25,7 +25,6 @@ import org.apache.myfaces.tobago.interna
 import org.apache.myfaces.tobago.internal.ajax.AjaxResponseRenderer;
 import org.apache.myfaces.tobago.internal.layout.LayoutUtils;
 import org.apache.myfaces.tobago.internal.util.FacesContextUtils;
-import org.apache.myfaces.tobago.internal.webapp.TobagoMultipartFormdataRequest;
 import org.apache.myfaces.tobago.util.ApplyRequestValuesCallback;
 import org.apache.myfaces.tobago.util.ComponentUtils;
 import org.apache.myfaces.tobago.util.DebugUtils;
@@ -36,13 +35,10 @@ import org.apache.myfaces.tobago.util.Up
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import javax.faces.application.FacesMessage;
 import javax.faces.component.ContextCallback;
 import javax.faces.component.UIComponent;
 import javax.faces.component.UIViewRoot;
 import javax.faces.context.FacesContext;
-import javax.servlet.ServletRequest;
-import javax.servlet.http.HttpServletRequestWrapper;
 import java.io.IOException;
 import java.util.Iterator;
 import java.util.Map;
@@ -114,8 +110,6 @@ public abstract class AbstractUIPage ext
 
   private void processDecodes0(final FacesContext facesContext) {
 
-    checkTobagoRequest(facesContext);
-
     decode(facesContext);
 
     markSubmittedForm(facesContext);
@@ -272,30 +266,6 @@ public abstract class AbstractUIPage ext
     }
   }
 
-  private void checkTobagoRequest(final FacesContext facesContext) {
-    // multipart/form-data must use TobagoMultipartFormdataRequest
-    final String contentType = facesContext.getExternalContext().getRequestHeaderMap().get("content-type");
-    if (contentType != null && contentType.startsWith("multipart/form-data")) {
-      final Object request = facesContext.getExternalContext().getRequest();
-      boolean okay = false;
-      if (request instanceof TobagoMultipartFormdataRequest) {
-        okay = true;
-      } else if (request instanceof HttpServletRequestWrapper) {
-        final ServletRequest wrappedRequest = ((HttpServletRequestWrapper) request).getRequest();
-        if (wrappedRequest instanceof TobagoMultipartFormdataRequest) {
-          okay = true;
-        }
-      }
-      // TODO PortletRequest ??
-      if (!okay) {
-        LOG.error("Can't process multipart/form-data without TobagoRequest. "
-            + "Please check the web.xml and define a TobagoMultipartFormdataFilter. "
-            + "See documentation for <tc:file>");
-        facesContext.addMessage(null, new FacesMessage("An error has occurred!"));
-      }
-    }
-  }
-
   /** @deprecated XXX delete me */
   @Deprecated
   private String getActionId() {

Modified: myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/FileTagDeclaration.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/FileTagDeclaration.java?rev=1733503&r1=1733502&r2=1733503&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/FileTagDeclaration.java (original)
+++ myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/FileTagDeclaration.java Thu Mar  3 17:46:03 2016
@@ -45,10 +45,6 @@ import javax.faces.component.UIInput;
 
 /**
  * Renders a file input field.
- * You need to define an org.apache.myfaces.tobago.webapp.TobagoMultipartFormdataFilter in your web.xml or
- * add the tobago-fileupload.jar to your project.
- * The tobago-fileupload.jar contains a FacesContextFactory that wraps the
- * multipart-formdata request inside the facesContext.
  * <p />
  * For content constraints please use <a href="validateFileItem.html">tc:validateFileItem</a>.
  */
@@ -67,12 +63,12 @@ public interface FileTagDeclaration
 
   /**
    * Value binding expression pointing to a
-   * <code>org.apache.commons.fileupload.FileItem</code> property to store the
+   * {@link javax.servlet.http.Part} property to store the
    * uploaded file.
    */
   @TagAttribute()
   @UIComponentTagAttribute(
-      type = { "org.apache.commons.fileupload.FileItem" },
+      type = { "javax.servlet.http.Part" },
       expression = DynamicExpression.VALUE_EXPRESSION_REQUIRED)
   void setValue(String value);
 }

Added: myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/PartUtils.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/PartUtils.java?rev=1733503&view=auto
==============================================================================
--- myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/PartUtils.java (added)
+++ myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/PartUtils.java Thu Mar  3 17:46:03 2016
@@ -0,0 +1,331 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.myfaces.tobago.internal.util;
+
+import org.apache.commons.beanutils.PropertyUtils;
+
+import javax.servlet.http.Part;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ * Only needed for Servlet 3.0. Not needed for Servlet 3.1 or higher.
+ *
+ * Basically taken from Apache Tomcat 8
+ */
+public final class PartUtils {
+
+  private PartUtils() {
+  }
+
+  /**
+   * This is a helper method, to get the original file name of the upload.
+   * If you have at least Servlet 3.1, you wouldn't need this function.
+   *
+   * @since Tobago 3.0.0
+   */
+  public static String getSubmittedFileName(Part part) {
+
+    try { // try to call the Servlet 3.1 function
+      return (String) PropertyUtils.getProperty(part, "submittedFileName");
+    } catch (Exception e) {
+      // ignore
+    }
+
+    String fileName = null;
+    String cd = part.getHeader("Content-Disposition");
+    if (cd != null) {
+      String cdl = cd.toLowerCase(Locale.ENGLISH);
+      if (cdl.startsWith("form-data") || cdl.startsWith("attachment")) {
+        ParameterParser paramParser = new ParameterParser();
+        paramParser.setLowerCaseNames(true);
+        // Parameter parser can handle null input
+        Map<String, String> params =
+            paramParser.parse(cd, ';');
+        if (params.containsKey("filename")) {
+          fileName = params.get("filename");
+          if (fileName != null) {
+            fileName = fileName.trim();
+            // XXX seems to be wrong in the code?
+            fileName = fileName.replaceAll("\\\\\\\"", "\""); // replaces \" with "
+          } else {
+            // Even if there is no value, the parameter is present,
+            // so we return an empty file name rather than no file
+            // name.
+            fileName = "";
+          }
+        }
+      }
+    }
+    return fileName;
+  }
+
+  private static class ParameterParser {
+
+    /**
+     * String to be parsed.
+     */
+    private char[] chars = null;
+
+    /**
+     * Current position in the string.
+     */
+    private int pos = 0;
+
+    /**
+     * Maximum position in the string.
+     */
+    private int len = 0;
+
+    /**
+     * Start of a token.
+     */
+    private int i1 = 0;
+
+    /**
+     * End of a token.
+     */
+    private int i2 = 0;
+
+    /**
+     * Whether names stored in the map should be converted to lower case.
+     */
+    private boolean lowerCaseNames = false;
+
+    /**
+     * Default ParameterParser constructor.
+     */
+    public ParameterParser() {
+      super();
+    }
+
+    /**
+     * Are there any characters left to parse?
+     *
+     * @return {@code true} if there are unparsed characters,
+     * {@code false} otherwise.
+     */
+    private boolean hasChar() {
+      return this.pos < this.len;
+    }
+
+    /**
+     * A helper method to process the parsed token. This method removes
+     * leading and trailing blanks as well as enclosing quotation marks,
+     * when necessary.
+     *
+     * @param quoted {@code true} if quotation marks are expected,
+     *               {@code false} otherwise.
+     * @return the token
+     */
+    private String getToken(boolean quoted) {
+      // Trim leading white spaces
+      while ((i1 < i2) && (Character.isWhitespace(chars[i1]))) {
+        i1++;
+      }
+      // Trim trailing white spaces
+      while ((i2 > i1) && (Character.isWhitespace(chars[i2 - 1]))) {
+        i2--;
+      }
+      // Strip away quotation marks if necessary
+      if (quoted
+          && ((i2 - i1) >= 2)
+          && (chars[i1] == '"')
+          && (chars[i2 - 1] == '"')) {
+        i1++;
+        i2--;
+      }
+      String result = null;
+      if (i2 > i1) {
+        result = new String(chars, i1, i2 - i1);
+      }
+      return result;
+    }
+
+    /**
+     * Tests if the given character is present in the array of characters.
+     *
+     * @param ch      the character to test for presense in the array of characters
+     * @param charray the array of characters to test against
+     * @return {@code true} if the character is present in the array of
+     * characters, {@code false} otherwise.
+     */
+    private boolean isOneOf(char ch, final char[] charray) {
+      boolean result = false;
+      for (char element : charray) {
+        if (ch == element) {
+          result = true;
+          break;
+        }
+      }
+      return result;
+    }
+
+    /**
+     * Parses out a token until any of the given terminators
+     * is encountered.
+     *
+     * @param terminators the array of terminating characters. Any of these
+     *                    characters when encountered signify the end of the token
+     * @return the token
+     */
+    private String parseToken(final char[] terminators) {
+      char ch;
+      i1 = pos;
+      i2 = pos;
+      while (hasChar()) {
+        ch = chars[pos];
+        if (isOneOf(ch, terminators)) {
+          break;
+        }
+        i2++;
+        pos++;
+      }
+      return getToken(false);
+    }
+
+    /**
+     * Parses out a token until any of the given terminators
+     * is encountered outside the quotation marks.
+     *
+     * @param terminators the array of terminating characters. Any of these
+     *                    characters when encountered outside the quotation marks signify the end
+     *                    of the token
+     * @return the token
+     */
+    private String parseQuotedToken(final char[] terminators) {
+      char ch;
+      i1 = pos;
+      i2 = pos;
+      boolean quoted = false;
+      boolean charEscaped = false;
+      while (hasChar()) {
+        ch = chars[pos];
+        if (!quoted && isOneOf(ch, terminators)) {
+          break;
+        }
+        if (!charEscaped && ch == '"') {
+          quoted = !quoted;
+        }
+        charEscaped = (!charEscaped && ch == '\\');
+        i2++;
+        pos++;
+
+      }
+      return getToken(true);
+    }
+
+    /**
+     * Sets the flag if parameter names are to be converted to lower case when
+     * name/value pairs are parsed.
+     *
+     * @param b {@code true} if parameter names are to be
+     *          converted to lower case when name/value pairs are parsed.
+     *          {@code false} otherwise.
+     */
+    public void setLowerCaseNames(boolean b) {
+      this.lowerCaseNames = b;
+    }
+
+    /**
+     * Extracts a map of name/value pairs from the given string. Names are
+     * expected to be unique.
+     *
+     * @param str       the string that contains a sequence of name/value pairs
+     * @param separator the name/value pairs separator
+     * @return a map of name/value pairs
+     */
+    public Map<String, String> parse(final String str, char separator) {
+      if (str == null) {
+        return new HashMap<String, String>();
+      }
+      return parse(str.toCharArray(), separator);
+    }
+
+    /**
+     * Extracts a map of name/value pairs from the given array of
+     * characters. Names are expected to be unique.
+     *
+     * @param charArray the array of characters that contains a sequence of
+     *                  name/value pairs
+     * @param separator the name/value pairs separator
+     * @return a map of name/value pairs
+     */
+    public Map<String, String> parse(final char[] charArray, char separator) {
+      if (charArray == null) {
+        return new HashMap<String, String>();
+      }
+      return parse(charArray, 0, charArray.length, separator);
+    }
+
+    /**
+     * Extracts a map of name/value pairs from the given array of
+     * characters. Names are expected to be unique.
+     *
+     * @param charArray the array of characters that contains a sequence of
+     *                  name/value pairs
+     * @param offset    - the initial offset.
+     * @param length    - the length.
+     * @param separator the name/value pairs separator
+     * @return a map of name/value pairs
+     */
+    public Map<String, String> parse(
+        final char[] charArray,
+        int offset,
+        int length,
+        char separator) {
+
+      if (charArray == null) {
+        return new HashMap<String, String>();
+      }
+      HashMap<String, String> params = new HashMap<String, String>();
+      this.chars = charArray;
+      this.pos = offset;
+      this.len = length;
+
+      String paramName;
+      String paramValue;
+      while (hasChar()) {
+        paramName = parseToken(new char[]{
+            '=', separator
+        });
+        paramValue = null;
+        if (hasChar() && (charArray[pos] == '=')) {
+          pos++; // skip '='
+          paramValue = parseQuotedToken(new char[]{
+              separator
+          });
+        }
+        if (hasChar() && (charArray[pos] == separator)) {
+          pos++; // skip separator
+        }
+        if ((paramName != null) && (paramName.length() > 0)) {
+          if (this.lowerCaseNames) {
+            paramName = paramName.toLowerCase(Locale.ENGLISH);
+          }
+
+          params.put(paramName, paramValue);
+        }
+      }
+      return params;
+    }
+  }
+}

Modified: myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/validator/FileItemValidator.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/validator/FileItemValidator.java?rev=1733503&r1=1733502&r2=1733503&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/validator/FileItemValidator.java (original)
+++ myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/main/java/org/apache/myfaces/tobago/validator/FileItemValidator.java Thu Mar  3 17:46:03 2016
@@ -19,7 +19,6 @@
 
 package org.apache.myfaces.tobago.validator;
 
-import org.apache.commons.fileupload.FileItem;
 import org.apache.myfaces.tobago.internal.component.AbstractUIFile;
 import org.apache.myfaces.tobago.internal.util.ContentType;
 import org.apache.myfaces.tobago.util.MessageUtils;
@@ -30,6 +29,7 @@ import javax.faces.component.UIComponent
 import javax.faces.context.FacesContext;
 import javax.faces.validator.Validator;
 import javax.faces.validator.ValidatorException;
+import javax.servlet.http.Part;
 import java.util.Arrays;
 
 /**
@@ -54,7 +54,7 @@ public class FileItemValidator implement
   public void validate(final FacesContext facesContext, final UIComponent component, final Object value)
       throws ValidatorException {
     if (value != null && component instanceof AbstractUIFile) {
-      final FileItem file = (FileItem) value;
+      final Part file = (Part) value;
       if (maxSize != null && file.getSize() > maxSize) {
         final FacesMessage facesMessage = MessageUtils.getMessage(
             facesContext, facesContext.getViewRoot().getLocale(), FacesMessage.SEVERITY_ERROR,

Added: myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/util/PartUtilsUnitTest.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/util/PartUtilsUnitTest.java?rev=1733503&view=auto
==============================================================================
--- myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/util/PartUtilsUnitTest.java (added)
+++ myfaces/tobago/branches/tobago-3.0.x/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/util/PartUtilsUnitTest.java Thu Mar  3 17:46:03 2016
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.myfaces.tobago.internal.util;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import javax.servlet.http.Part;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collection;
+
+public class PartUtilsUnitTest {
+
+  @Test
+  public void testGetSubmittedFileName() throws Exception {
+
+    final String dc0 = "form-data; name=\"page:file\"; filename=\"foo.jpg\"";
+    Assert.assertEquals("foo.jpg", PartUtils.getSubmittedFileName(new PartMock(dc0)));
+
+    final String dc1 = "form-data; name=\"page:file\"; filename=\"foo;bar=\\\"boo\\\"-bar.jpg\"";
+    Assert.assertEquals("foo;bar=\"boo\"-bar.jpg", PartUtils.getSubmittedFileName(new PartMock(dc1)));
+  }
+
+  private static final class PartMock implements Part {
+
+    private String contentDisposition;
+
+    public PartMock(String contentDisposition) {
+      this.contentDisposition = contentDisposition;
+    }
+
+    @Override
+    public void delete() throws IOException {
+
+    }
+
+    @Override
+    public String getContentType() {
+      return null;
+    }
+
+    @Override
+    public String getHeader(String headerName) {
+      if (headerName.equals("Content-Disposition")) {
+        return contentDisposition;
+      } else {
+        return null;
+      }
+    }
+
+    @Override
+    public Collection<String> getHeaderNames() {
+      return null;
+    }
+
+    @Override
+    public Collection<String> getHeaders(String headerName) {
+      return null;
+    }
+
+    @Override
+    public InputStream getInputStream() throws IOException {
+      return null;
+    }
+
+    @Override
+    public String getName() {
+      return null;
+    }
+
+    @Override
+    public long getSize() {
+      return 0;
+    }
+
+    @Override
+    public void write(String fileName) throws IOException {
+
+    }
+  }
+}
\ No newline at end of file

Modified: myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-addressbook/pom.xml
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-addressbook/pom.xml?rev=1733503&r1=1733502&r2=1733503&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-addressbook/pom.xml (original)
+++ myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-addressbook/pom.xml Thu Mar  3 17:46:03 2016
@@ -249,11 +249,6 @@
     </dependency-->
     <dependency>
       <groupId>org.apache.myfaces.tobago</groupId>
-      <artifactId>tobago-fileupload</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.myfaces.tobago</groupId>
       <artifactId>tobago-security</artifactId>
       <version>${project.version}</version>
     </dependency>

Modified: myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-addressbook/src/main/java/org/apache/myfaces/tobago/example/addressbook/Picture.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-addressbook/src/main/java/org/apache/myfaces/tobago/example/addressbook/Picture.java?rev=1733503&r1=1733502&r2=1733503&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-addressbook/src/main/java/org/apache/myfaces/tobago/example/addressbook/Picture.java (original)
+++ myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-addressbook/src/main/java/org/apache/myfaces/tobago/example/addressbook/Picture.java Thu Mar  3 17:46:03 2016
@@ -19,6 +19,8 @@
 
 package org.apache.myfaces.tobago.example.addressbook;
 
+import org.apache.commons.io.IOUtils;
+
 import javax.persistence.Basic;
 import javax.persistence.Entity;
 import javax.persistence.FetchType;
@@ -26,6 +28,8 @@ import javax.persistence.GeneratedValue;
 import javax.persistence.GenerationType;
 import javax.persistence.Id;
 import javax.persistence.Lob;
+import java.io.IOException;
+import java.io.InputStream;
 import java.io.Serializable;
 
 @Entity
@@ -43,9 +47,9 @@ public class Picture implements Serializ
   public Picture() {
   }
 
-  public Picture(final String contentType, final byte[] content) {
+  public Picture(final String contentType, final InputStream inputStream) throws IOException {
     this.contentType = contentType;
-    this.content = content;
+    this.content = IOUtils.toByteArray(inputStream);
   }
 
   public Integer getId() {

Modified: myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-addressbook/src/main/java/org/apache/myfaces/tobago/example/addressbook/web/Controller.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-addressbook/src/main/java/org/apache/myfaces/tobago/example/addressbook/web/Controller.java?rev=1733503&r1=1733502&r2=1733503&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-addressbook/src/main/java/org/apache/myfaces/tobago/example/addressbook/web/Controller.java (original)
+++ myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-addressbook/src/main/java/org/apache/myfaces/tobago/example/addressbook/web/Controller.java Thu Mar  3 17:46:03 2016
@@ -19,7 +19,6 @@
 
 package org.apache.myfaces.tobago.example.addressbook.web;
 
-import org.apache.commons.fileupload.FileItem;
 import org.apache.deltaspike.core.api.scope.WindowScoped;
 import org.apache.myfaces.tobago.component.UIColumn;
 import org.apache.myfaces.tobago.component.UISheet;
@@ -45,6 +44,7 @@ import javax.faces.validator.ValidatorEx
 import javax.inject.Inject;
 import javax.inject.Named;
 import javax.servlet.http.HttpSession;
+import javax.servlet.http.Part;
 import java.io.IOException;
 import java.io.Serializable;
 import java.util.ArrayList;
@@ -93,7 +93,7 @@ public class Controller implements Seria
   @Inject
   private AddressDao addressDao;
 
-  private FileItem uploadedFile;
+  private Part part;
   private boolean renderFileUploadPopup;
 
   static {
@@ -282,9 +282,9 @@ public class Controller implements Seria
     return OUTCOME_LIST;
   }
 
-  public String okFileUpload() {
+  public String okFileUpload() throws IOException {
     setRenderFileUploadPopup(false);
-    final Picture picture = new Picture(uploadedFile.getContentType(), uploadedFile.get());
+    final Picture picture = new Picture(part.getContentType(), part.getInputStream());
     currentAddress.setPicture(picture);
     return null;
   }
@@ -380,12 +380,12 @@ public class Controller implements Seria
     this.renderDayOfBirth = renderDayOfBirth;
   }
 
-  public FileItem getUploadedFile() {
-    return uploadedFile;
+  public Part getPart() {
+    return part;
   }
 
-  public void setUploadedFile(final FileItem uploadedFile) {
-    this.uploadedFile = uploadedFile;
+  public void setPart(final Part part) {
+    this.part = part;
   }
 
   public String getSearchCriterion() {

Modified: myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-addressbook/src/main/webapp/WEB-INF/web.xml
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-addressbook/src/main/webapp/WEB-INF/web.xml?rev=1733503&r1=1733502&r2=1733503&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-addressbook/src/main/webapp/WEB-INF/web.xml (original)
+++ myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-addressbook/src/main/webapp/WEB-INF/web.xml Thu Mar  3 17:46:03 2016
@@ -65,6 +65,8 @@
     <servlet-name>FacesServlet</servlet-name>
     <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
     <load-on-startup>1</load-on-startup>
+    <!-- This is needed, for file upload e.g. <tc:file> with JSF 2.0 or 2.1, JSF 2.2 doesn't need it. -->
+    <multipart-config/>
   </servlet>
 
   <servlet>

Modified: myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-blank/src/main/webapp/WEB-INF/web.xml
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-blank/src/main/webapp/WEB-INF/web.xml?rev=1733503&r1=1733502&r2=1733503&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-blank/src/main/webapp/WEB-INF/web.xml (original)
+++ myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-blank/src/main/webapp/WEB-INF/web.xml Thu Mar  3 17:46:03 2016
@@ -25,20 +25,13 @@
 
   <display-name>Blank Tobago Application</display-name>
 
-  <filter>
-    <filter-name>multipartFormdataFilter</filter-name>
-    <filter-class>org.apache.myfaces.tobago.webapp.TobagoMultipartFormdataFilter</filter-class>
-  </filter>
-  <filter-mapping>
-    <filter-name>multipartFormdataFilter</filter-name>
-    <url-pattern>/faces/*</url-pattern>
-  </filter-mapping>
-
   <!-- servlet -->
   <servlet>
     <servlet-name>FacesServlet</servlet-name>
     <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
     <load-on-startup>3</load-on-startup>
+    <!-- This is needed, for file upload e.g. <tc:file> with JSF 2.0 or 2.1, JSF 2.2 doesn't need it. -->
+    <multipart-config/>
   </servlet>
 
   <servlet>

Modified: myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-demo/pom.xml
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-demo/pom.xml?rev=1733503&r1=1733502&r2=1733503&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-demo/pom.xml (original)
+++ myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-demo/pom.xml Thu Mar  3 17:46:03 2016
@@ -80,11 +80,6 @@
       <version>${project.version}</version>
     </dependency>
     <dependency>
-      <groupId>org.apache.myfaces.tobago</groupId>
-      <artifactId>tobago-fileupload</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
       <groupId>oro</groupId>
       <artifactId>oro</artifactId>
       <version>2.0.8</version>

Modified: myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/Upload.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/Upload.java?rev=1733503&r1=1733502&r2=1733503&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/Upload.java (original)
+++ myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/Upload.java Thu Mar  3 17:46:03 2016
@@ -19,12 +19,15 @@
 
 package org.apache.myfaces.tobago.example.demo;
 
-import org.apache.commons.fileupload.FileItem;
+import org.apache.myfaces.tobago.internal.util.PartUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import javax.enterprise.context.SessionScoped;
+import javax.faces.application.FacesMessage;
+import javax.faces.context.FacesContext;
 import javax.inject.Named;
+import javax.servlet.http.Part;
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.List;
@@ -35,8 +38,8 @@ public class Upload implements Serializa
 
   private static final Logger LOG = LoggerFactory.getLogger(Upload.class);
 
-  private FileItem file1;
-  private FileItem file2;
+  private Part file1;
+  private Part file2;
 
   private List<UploadItem> list = new ArrayList<UploadItem>();
 
@@ -46,37 +49,34 @@ public class Upload implements Serializa
     return null;
   }
 
-  public void upload(FileItem file) {
+  public void upload(Part part) {
     LOG.info("checking file item");
-    if (file == null || file.get().length == 0) {
+    if (part == null || part.getSize() == 0) {
       return;
     }
-    LOG.info("type=" + file.getContentType());
-    LOG.info("size=" + file.get().length);
-    String name = file.getName();
-    final int pos = Math.max(name.lastIndexOf('/'), name.lastIndexOf('\\'));
-    if (pos >= 0) {
-      // some old browsers send the name with path.
-      // modern browsers doesn't because of security reasons.
-      name = name.substring(pos + 1);
-    }
-    LOG.info("name=" + name);
-    list.add(new UploadItem(name, file.get().length, file.getContentType()));
+    LOG.info("type=" + part.getContentType());
+    LOG.info("size=" + part.getSize());
+    final String submittedFileName = PartUtils.getSubmittedFileName(part);
+    LOG.info("name=" + submittedFileName);
+    list.add(new UploadItem(submittedFileName, part.getSize(), part.getContentType()));
+    FacesContext.getCurrentInstance().addMessage(
+        null, new FacesMessage(FacesMessage.SEVERITY_INFO, "File was uploaded: " + submittedFileName, null));
+
   }
 
-  public FileItem getFile1() {
+  public Part getFile1() {
     return file1;
   }
 
-  public void setFile1(FileItem file1) {
+  public void setFile1(Part file1) {
     this.file1 = file1;
   }
 
-  public FileItem getFile2() {
+  public Part getFile2() {
     return file2;
   }
 
-  public void setFile2(FileItem file2) {
+  public void setFile2(Part file2) {
     this.file2 = file2;
   }
 

Modified: myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/UploadItem.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/UploadItem.java?rev=1733503&r1=1733502&r2=1733503&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/UploadItem.java (original)
+++ myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/UploadItem.java Thu Mar  3 17:46:03 2016
@@ -29,10 +29,10 @@ public class UploadItem implements Seria
   private static final Logger LOG = LoggerFactory.getLogger(UploadItem.class);
 
   private String name;
-  private int size;
+  private long size;
   private String type;
 
-  public UploadItem(final String name, final int size, final String type) {
+  public UploadItem(final String name, final long size, final String type) {
     this.name = name;
     this.size = size;
     this.type = type;
@@ -46,11 +46,11 @@ public class UploadItem implements Seria
     this.name = name;
   }
 
-  public int getSize() {
+  public long getSize() {
     return size;
   }
 
-  public void setSize(final int size) {
+  public void setSize(final long size) {
     this.size = size;
   }
 

Modified: myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-demo/src/main/webapp/WEB-INF/web.xml
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-demo/src/main/webapp/WEB-INF/web.xml?rev=1733503&r1=1733502&r2=1733503&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-demo/src/main/webapp/WEB-INF/web.xml (original)
+++ myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-demo/src/main/webapp/WEB-INF/web.xml Thu Mar  3 17:46:03 2016
@@ -68,30 +68,6 @@
     <param-value>true</param-value>
   </context-param>
 
-  <filter>
-    <filter-name>multipartFormdataFilter</filter-name>
-    <filter-class>org.apache.myfaces.tobago.webapp.TobagoMultipartFormdataFilter</filter-class>
-    <init-param>
-      <description>Set the size limit for uploaded files. Default value is 1 MB.
-        Format: 10 = 10 bytes
-        10k = 10 KB
-        10m = 10 MB
-        1g = 1 GB
-      </description>
-      <param-name>uploadMaxFileSize</param-name>
-      <param-value>20m</param-value>
-    </init-param>
-    <!--<init-param>
-      <description>Set the upload repository path for uploaded files. Default value is java.io.tmpdir.</description>
-      <param-name>uploadRepositoryPath</param-name>
-      <param-value>/tmp</param-value>
-    </init-param>-->
-  </filter>
-  <filter-mapping>
-    <filter-name>multipartFormdataFilter</filter-name>
-    <url-pattern>/faces/*</url-pattern>
-  </filter-mapping>
-
   <listener>
     <listener-class>org.apache.myfaces.tobago.example.demo.info.ActivitySessionListener</listener-class>
   </listener>
@@ -144,6 +120,8 @@
     <servlet-name>FacesServlet</servlet-name>
     <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
     <load-on-startup>3</load-on-startup>
+    <!-- This is needed, for file upload e.g. <tc:file> with JSF 2.0 or 2.1, JSF 2.2 doesn't need it. -->
+    <multipart-config/>
   </servlet>
 
   <servlet-mapping>

Modified: myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-demo/src/main/webapp/content/40-upload/upload.xhtml
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-demo/src/main/webapp/content/40-upload/upload.xhtml?rev=1733503&r1=1733502&r2=1733503&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-demo/src/main/webapp/content/40-upload/upload.xhtml (original)
+++ myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-demo/src/main/webapp/content/40-upload/upload.xhtml Thu Mar  3 17:46:03 2016
@@ -20,15 +20,39 @@
 <ui:composition template="/main.xhtml"
                 xmlns:tc="http://myfaces.apache.org/tobago/component"
                 xmlns:ui="http://java.sun.com/jsf/facelets"
-                xmlns:f="http://java.sun.com/jsf/core">
+                xmlns="http://www.w3.org/1999/xhtml">
   <ui:param name="title" value="File Upload"/>
   <tc:panel>
 
+    <p>
+      To load up files to the server for JSF 2.0 and 2.1 you will need to
+      add an multipart-config entry to the FacesServlet in the <code>web.xml</code> file.
+      Since JSF 2.2 this is not required.
+    </p>
+
+    <p>
+      Here you can configure some more general information.
+    </p>
+
+    <pre><code class="language-markup">
+      &lt;multipart-config>
+        &lt;location>/tmp&lt;/location>
+        &lt;max-file-size>20848820&lt;/max-file-size>
+        &lt;max-request-size>418018841&lt;/max-request-size>
+        &lt;file-size-threshold>1048576&lt;/file-size-threshold>
+      &lt;/multipart-config>
+    </code></pre>
+
+    The first example loads up an arbitrary file. The second example contains a <code>&lt;tc:validateFileItem></code>
+    tag with restrict the content type.
+
     <tc:file label="Upload file:" value="#{upload.file1}" tip="without extra validation" id="file1"/>
+
     <tc:file label="Upload image:" value="#{upload.file2}" id="file2"
              tip="with a validator for file items - types: gif, jpg, png">
       <tc:validateFileItem contentType="image/*"/>
     </tc:file>
+
     <tc:button label="Submit" defaultCommand="true" action="#{upload.upload}"/>
 
     <tc:sheet var="entry" value="#{upload.list}" columns="*;*;*">

Modified: myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-portlet/src/main/webapp/WEB-INF/web.xml
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-portlet/src/main/webapp/WEB-INF/web.xml?rev=1733503&r1=1733502&r2=1733503&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-portlet/src/main/webapp/WEB-INF/web.xml (original)
+++ myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-portlet/src/main/webapp/WEB-INF/web.xml Thu Mar  3 17:46:03 2016
@@ -26,6 +26,8 @@
   <servlet>
     <servlet-name>FacesServlet</servlet-name>
     <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
+    <!-- This is needed, for file upload e.g. <tc:file> with JSF 2.0 or 2.1, JSF 2.2 doesn't need it. -->
+    <multipart-config/>
   </servlet>
   <servlet-mapping>
     <servlet-name>FacesServlet</servlet-name>

Modified: myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-security/src/main/webapp/WEB-INF/web.xml
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-security/src/main/webapp/WEB-INF/web.xml?rev=1733503&r1=1733502&r2=1733503&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-security/src/main/webapp/WEB-INF/web.xml (original)
+++ myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-security/src/main/webapp/WEB-INF/web.xml Thu Mar  3 17:46:03 2016
@@ -31,6 +31,8 @@
     <servlet-name>FacesServlet</servlet-name>
     <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
     <load-on-startup>1</load-on-startup>
+    <!-- This is needed, for file upload e.g. <tc:file> with JSF 2.0 or 2.1, JSF 2.2 doesn't need it. -->
+    <multipart-config/>
   </servlet>
 
   <servlet>

Modified: myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-test/src/main/java/org/apache/myfaces/tobago/example/test/Upload.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-test/src/main/java/org/apache/myfaces/tobago/example/test/Upload.java?rev=1733503&r1=1733502&r2=1733503&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-test/src/main/java/org/apache/myfaces/tobago/example/test/Upload.java (original)
+++ myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-test/src/main/java/org/apache/myfaces/tobago/example/test/Upload.java Thu Mar  3 17:46:03 2016
@@ -19,37 +19,42 @@
 
 package org.apache.myfaces.tobago.example.test;
 
-import org.apache.commons.fileupload.FileItem;
+import org.apache.myfaces.tobago.internal.util.PartUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import javax.faces.application.FacesMessage;
 import javax.faces.context.FacesContext;
+import javax.servlet.http.Part;
 import java.io.Serializable;
 
 public class Upload implements Serializable {
 
   private static final Logger LOG = LoggerFactory.getLogger(Upload.class);
 
-  private FileItem file;
+  private Part part;
 
   public String upload() {
-    if (file == null) {
+    if (part == null) {
       FacesContext.getCurrentInstance().addMessage(
           null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "No UploadItem found!", null));
       return null;
     }
-    LOG.info("type=" + file.getContentType());
-    LOG.info("size=" + file.get().length);
-    LOG.info("name=" + file.getName());
+    LOG.info("type=" + part.getContentType());
+    LOG.info("size=" + part.getSize());
+    final String name = PartUtils.getSubmittedFileName(part);
+    LOG.info("name=" + name);
+    FacesContext.getCurrentInstance().addMessage(
+        null, new FacesMessage(FacesMessage.SEVERITY_INFO, "File was uploaded: " + name, null));
+
     return "/test/file/file.xhtml";
   }
   
-  public FileItem getFile() {
-    return file;
+  public Part getFile() {
+    return part;
   }
 
-  public void setFile(final FileItem file) {
-    this.file = file;
+  public void setFile(final Part file) {
+    this.part = file;
   }
 }

Modified: myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-test/src/main/webapp/WEB-INF/web.xml
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-test/src/main/webapp/WEB-INF/web.xml?rev=1733503&r1=1733502&r2=1733503&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-test/src/main/webapp/WEB-INF/web.xml (original)
+++ myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-test/src/main/webapp/WEB-INF/web.xml Thu Mar  3 17:46:03 2016
@@ -65,6 +65,8 @@
     <servlet-name>FacesServlet</servlet-name>
     <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
     <load-on-startup>3</load-on-startup>
+    <!-- This is needed, for file upload e.g. <tc:file> with JSF 2.0 or 2.1, JSF 2.2 doesn't need it. -->
+    <multipart-config/>
   </servlet>
   <servlet-mapping>
     <servlet-name>FacesServlet</servlet-name>
@@ -163,30 +165,6 @@
       <url-pattern>/image/wait/*</url-pattern>
   </filter-mapping>
 
-  <filter>
-    <filter-name>multipartFormdataFilter</filter-name>
-    <filter-class>org.apache.myfaces.tobago.webapp.TobagoMultipartFormdataFilter</filter-class>
-    <init-param>
-      <description>Set the size limit for uploaded files. Default value is 1 MB.
-        Format: 10 = 10 bytes
-        10k = 10 KB
-        10m = 10 MB
-        1g = 1 GB
-      </description>
-      <param-name>uploadMaxFileSize</param-name>
-      <param-value>20m</param-value>
-    </init-param>
-    <!--<init-param>
-      <description>Set the upload repository path for uploaded files. Default value is java.io.tmpdir.</description>
-      <param-name>uploadRepositoryPath</param-name>
-      <param-value>/tmp</param-value>
-    </init-param>-->
-  </filter>
-  <filter-mapping>
-    <filter-name>multipartFormdataFilter</filter-name>
-    <url-pattern>/faces/*</url-pattern>
-  </filter-mapping>
-
   <session-config>
     <cookie-config>
       <http-only>true</http-only>

Modified: myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-test/src/main/webapp/test/file/file.xhtml
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-test/src/main/webapp/test/file/file.xhtml?rev=1733503&r1=1733502&r2=1733503&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-test/src/main/webapp/test/file/file.xhtml (original)
+++ myfaces/tobago/branches/tobago-3.0.x/tobago-example/tobago-example-test/src/main/webapp/test/file/file.xhtml Thu Mar  3 17:46:03 2016
@@ -21,10 +21,8 @@
     xmlns:f="http://java.sun.com/jsf/core">
 
   <tc:page>
-    <f:facet name="layout">
-      <tc:gridLayout rows="auto;auto"/>
-    </f:facet>
-    <tc:gridLayoutConstraint width="600px" height="300px"/>
+
+    <tc:messages/>
 
     <tc:file value="#{upload.file}" required="true"/>
     <tc:button label="OK" action="#{upload.upload}"/>

Modified: myfaces/tobago/branches/tobago-3.0.x/tobago-extension/pom.xml
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-3.0.x/tobago-extension/pom.xml?rev=1733503&r1=1733502&r2=1733503&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-3.0.x/tobago-extension/pom.xml (original)
+++ myfaces/tobago/branches/tobago-3.0.x/tobago-extension/pom.xml Thu Mar  3 17:46:03 2016
@@ -28,7 +28,6 @@
 
   <modules>
     <module>tobago-deprecation</module>
-    <module>tobago-fileupload</module>
     <module>tobago-sandbox</module>
     <module>tobago-security</module>
   </modules>

Modified: myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/FileRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/FileRenderer.java?rev=1733503&r1=1733502&r2=1733503&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/FileRenderer.java (original)
+++ myfaces/tobago/branches/tobago-3.0.x/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/html/standard/standard/tag/FileRenderer.java Thu Mar  3 17:46:03 2016
@@ -19,10 +19,9 @@
 
 package org.apache.myfaces.tobago.renderkit.html.standard.standard.tag;
 
-import org.apache.commons.fileupload.FileItem;
 import org.apache.myfaces.tobago.internal.component.AbstractUIFile;
 import org.apache.myfaces.tobago.internal.util.FacesContextUtils;
-import org.apache.myfaces.tobago.internal.webapp.TobagoMultipartFormdataRequest;
+import org.apache.myfaces.tobago.internal.util.PartUtils;
 import org.apache.myfaces.tobago.renderkit.css.Classes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
@@ -39,8 +38,8 @@ import javax.faces.event.ComponentSystem
 import javax.faces.event.ComponentSystemEventListener;
 import javax.faces.event.ListenerFor;
 import javax.faces.event.PostAddToViewEvent;
-import javax.servlet.ServletRequest;
-import javax.servlet.http.HttpServletRequestWrapper;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.Part;
 import java.io.IOException;
 
 @ListenerFor(systemEventClass = PostAddToViewEvent.class)
@@ -64,48 +63,22 @@ public class FileRenderer extends InputR
     }
 
     final AbstractUIFile input = (AbstractUIFile) component;
-
-    TobagoMultipartFormdataRequest request = null;
-    final Object requestObject = facesContext.getExternalContext().getRequest();
-    if (requestObject instanceof TobagoMultipartFormdataRequest) {
-      request = (TobagoMultipartFormdataRequest) requestObject;
-    } else if (requestObject instanceof HttpServletRequestWrapper) {
-      final ServletRequest wrappedRequest
-          = ((HttpServletRequestWrapper) requestObject).getRequest();
-      if (wrappedRequest instanceof TobagoMultipartFormdataRequest) {
-        request = (TobagoMultipartFormdataRequest) wrappedRequest;
-      }
-    }
-    // TODO PortletRequest ??
-    if (request == null) {
-      // should not be possible, because of the check in UIPage
-      LOG.error("Can't process multipart/form-data without TobagoRequest. "
-          + "Please check the web.xml and define a TobagoMultipartFormdataFilter. "
-          + "See documentation for <tc:file>");
-    } else {
-
-      final FileItem item = request.getFileItem(input.getClientId(facesContext));
-/*
-TODO: Using Servlet 3.0 file upload...
+    final Object request = facesContext.getExternalContext().getRequest();
+    if (request instanceof HttpServletRequest) {
       try {
-        final Part part = request.getPart(input.getClientId(facesContext));
-        LOG.info("content type: " + part.getContentType());
-        LOG.info("name:         " + part.getName());
-        LOG.info("size:         " + part.getSize());
-      } catch (IOException e) {
-        e.printStackTrace();
-      } catch (ServletException e) {
-        e.printStackTrace();
-      }
-*/
-
-      if (LOG.isDebugEnabled()) {
-        LOG.debug("Uploaded file name : \"" + item.getName()
-            + "\"  size = " + item.getSize());
+        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
+        final Part part = httpServletRequest.getPart(input.getClientId(facesContext));
+        if (LOG.isDebugEnabled()) {
+          LOG.debug("Uploaded file '{}', size={}, type='{}'",
+              PartUtils.getSubmittedFileName(part), part.getSize(), part.getContentType());
+        }
+        input.setSubmittedValue(part);
+      } catch (Exception e) {
+        LOG.error("", e);
+        input.setValid(false);
       }
-      input.setSubmittedValue(item);
-      //TODO remove this
-      input.setValid(true);
+    } else { // todo: PortletRequest
+      LOG.warn("Unsupported request type: " + request.getClass().getName());
     }
   }