ICEfaces
  1. ICEfaces
  2. ICE-2198

Allow inputFile to save file to OutputStream

    Details

    • Type: New Feature New Feature
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 1.7DR#1
    • Fix Version/s: 1.8.2-EE-GA_P01, 1.8.3
    • Component/s: ICE-Components
    • Labels:
      None
    • Environment:
      All

      Description

      Users would prefer to have access to a stream for saving the uploaded file directly into a database, instead of to the filesystem.

      The way that the commons upload code works, is that we receive the file in chunks, and probably wouldn't want to expose those intricacies to the application layer. So if the application could provide the ice:inputFile component an OutputStream with which to write to, then that would be the simplest approach.

        Activity

        Hide
        Mark Collette added a comment -

        Compared various methods of providing file information, while skipping the filesystem:

        1. Writing to a byte[], which could then be set in the FileInfo structure, for the application to pickup in the actionListener. The main problem with this approach is the potentially large memory overhead on a user by user basis, which could easily blow the heap if there is a noticeable load of uploaders, particularly because of how the byte[] would have to be growable, and so the max memory usage could be several times larger than the number of users * max quota.

        2. The InputStream to the socket data is passed on to the application, so it can read it. This is fraught with too many things that could go wrong. First off, the reading of that InputStream is what pushes the progress notification system, which makes the lifecycles happen. But the application would have to be given the InputStream within a lifecycle, leading to the likelihood of nested lifecycles, or a much more complicated usage model. Also, the ending lifecycle, that causes the iframe result to be sent, has to be done in a timely manner. Putting this under application control increases the likelihood of this not being done when it has to be.

        3. The application provides an OutputStream, which could be a ByteArrayOutputStream, or one for a database BLOB/CLOB, or whatever it needs, to the InputFile component, via a ValueBinding attribute on the InputFile. The UploadServer would need to do an initial lifecycle to access this OutputStream, with progress=0. The existence of the OutputStream could be indicated, and accessed via the existing UploadConfig mechanism. Once the UploadServer has it, it would simply substitute that application OutputStream in place of whatever FileOutputStream it would have otherwise created. The quota mechanism would have to be rethought, since this currently relies on checking the written file size. Hopefully something could be done to not have actually written more than the quota to the application OutputStream or FileOutputStream, since that seems like a flaw in the quota that once can temporarily write more than the acceptable amount.

        Show
        Mark Collette added a comment - Compared various methods of providing file information, while skipping the filesystem: 1. Writing to a byte[], which could then be set in the FileInfo structure, for the application to pickup in the actionListener. The main problem with this approach is the potentially large memory overhead on a user by user basis, which could easily blow the heap if there is a noticeable load of uploaders, particularly because of how the byte[] would have to be growable, and so the max memory usage could be several times larger than the number of users * max quota. 2. The InputStream to the socket data is passed on to the application, so it can read it. This is fraught with too many things that could go wrong. First off, the reading of that InputStream is what pushes the progress notification system, which makes the lifecycles happen. But the application would have to be given the InputStream within a lifecycle, leading to the likelihood of nested lifecycles, or a much more complicated usage model. Also, the ending lifecycle, that causes the iframe result to be sent, has to be done in a timely manner. Putting this under application control increases the likelihood of this not being done when it has to be. 3. The application provides an OutputStream, which could be a ByteArrayOutputStream, or one for a database BLOB/CLOB, or whatever it needs, to the InputFile component, via a ValueBinding attribute on the InputFile. The UploadServer would need to do an initial lifecycle to access this OutputStream, with progress=0. The existence of the OutputStream could be indicated, and accessed via the existing UploadConfig mechanism. Once the UploadServer has it, it would simply substitute that application OutputStream in place of whatever FileOutputStream it would have otherwise created. The quota mechanism would have to be rethought, since this currently relies on checking the written file size. Hopefully something could be done to not have actually written more than the quota to the application OutputStream or FileOutputStream, since that seems like a flaw in the quota that once can temporarily write more than the acceptable amount.
        Hide
        Mark Collette added a comment - - edited

        Implemented #3, above. Committed to http://server.ice:8888/svn/ossrepo/icefaces/scratchpads/patches/ICE-2198 which is an svn copy of http://server.ice:8888/svn/ossrepo/icefaces/tags/icefaces-1.8.2a

        Subversion 20727
        icefaces\component-metadata\src\main\resources\conf\ice_cust_properties\cust-inputFile-props.xml
        icefaces\component\src\com\icesoft\faces\component\inputfile\InputFile.java
        icefaces\core\src\com\icesoft\faces\component\inputfile\FileInfo.java
        icefaces\core\src\com\icesoft\faces\component\inputfile\UploadConfig.java
        icefaces\core\src\com\icesoft\faces\component\inputfile\UploadStateHolder.java
        icefaces\core\src\com\icesoft\faces\webapp\http\core\UploadServer.java

        Subversion 20733
        icefaces\core\src\com\icesoft\faces\component\inputfile\FileUploadNullOutputStreamException.java

        Show
        Mark Collette added a comment - - edited Implemented #3, above. Committed to http://server.ice:8888/svn/ossrepo/icefaces/scratchpads/patches/ICE-2198 which is an svn copy of http://server.ice:8888/svn/ossrepo/icefaces/tags/icefaces-1.8.2a Subversion 20727 icefaces\component-metadata\src\main\resources\conf\ice_cust_properties\cust-inputFile-props.xml icefaces\component\src\com\icesoft\faces\component\inputfile\InputFile.java icefaces\core\src\com\icesoft\faces\component\inputfile\FileInfo.java icefaces\core\src\com\icesoft\faces\component\inputfile\UploadConfig.java icefaces\core\src\com\icesoft\faces\component\inputfile\UploadStateHolder.java icefaces\core\src\com\icesoft\faces\webapp\http\core\UploadServer.java Subversion 20733 icefaces\core\src\com\icesoft\faces\component\inputfile\FileUploadNullOutputStreamException.java
        Hide
        Mark Collette added a comment -

        Verified on JBoss 4.2.3 with JSF 1.2, in both Facelets and JSP environments. Also, verified on Tomcat 5.5.27, with JSF 1.1, with Facelets and JSP.

        Show
        Mark Collette added a comment - Verified on JBoss 4.2.3 with JSF 1.2, in both Facelets and JSP environments. Also, verified on Tomcat 5.5.27, with JSF 1.1, with Facelets and JSP.
        Hide
        Mark Collette added a comment -

        TRUNK
        Subversion 20769

        icefaces-ee-1.8.2
        Subversion 20779

        icefaces-ee\icefaces\component-metadata\src\main\resources\conf\ice_cust_properties\cust-inputFile-props.xml
        icefaces-ee\icefaces\component\src\com\icesoft\faces\component\inputfile\InputFile.java
        icefaces-ee\icefaces\core\src\com\icesoft\faces\component\inputfile\FileInfo.java
        icefaces-ee\icefaces\core\src\com\icesoft\faces\component\inputfile\UploadConfig.java
        icefaces-ee\icefaces\core\src\com\icesoft\faces\component\inputfile\UploadStateHolder.java
        icefaces-ee\icefaces\core\src\com\icesoft\faces\webapp\http\core\UploadServer.java
        icefaces-ee\icefaces\core\src\com\icesoft\faces\component\inputfile\FileUploadNullOutputStreamException.java

        Show
        Mark Collette added a comment - TRUNK Subversion 20769 icefaces-ee-1.8.2 Subversion 20779 icefaces-ee\icefaces\component-metadata\src\main\resources\conf\ice_cust_properties\cust-inputFile-props.xml icefaces-ee\icefaces\component\src\com\icesoft\faces\component\inputfile\InputFile.java icefaces-ee\icefaces\core\src\com\icesoft\faces\component\inputfile\FileInfo.java icefaces-ee\icefaces\core\src\com\icesoft\faces\component\inputfile\UploadConfig.java icefaces-ee\icefaces\core\src\com\icesoft\faces\component\inputfile\UploadStateHolder.java icefaces-ee\icefaces\core\src\com\icesoft\faces\webapp\http\core\UploadServer.java icefaces-ee\icefaces\core\src\com\icesoft\faces\component\inputfile\FileUploadNullOutputStreamException.java
        Hide
        Mark Collette added a comment -

        The code was failing a meta-data test, because by default propertise are read/write, and this property has no setter method, so needed to be marked read-only.

        TRUNK
        Subversion 20783

        icefaces-ee-1.8.2
        Subversion 20788

        http://server.ice:8888/svn/ossrepo/icefaces/scratchpads/patches/ICE-2198
        http://server.ice:8888/svn/ossrepo/icefaces/tags/icefaces-1.8.2a
        Subversion 20789

        icefaces\component-metadata\src\main\resources\conf\ice_cust_properties\cust-inputFile-props.xml
        icefaces\component\src\com\icesoft\faces\component\inputfile\InputFile.java

        Show
        Mark Collette added a comment - The code was failing a meta-data test, because by default propertise are read/write, and this property has no setter method, so needed to be marked read-only. TRUNK Subversion 20783 icefaces-ee-1.8.2 Subversion 20788 http://server.ice:8888/svn/ossrepo/icefaces/scratchpads/patches/ICE-2198 http://server.ice:8888/svn/ossrepo/icefaces/tags/icefaces-1.8.2a Subversion 20789 icefaces\component-metadata\src\main\resources\conf\ice_cust_properties\cust-inputFile-props.xml icefaces\component\src\com\icesoft\faces\component\inputfile\InputFile.java
        Hide
        Aaron Lucas added a comment -

        Do you have an example of how to use this new component?

        Show
        Aaron Lucas added a comment - Do you have an example of how to use this new component?
        Hide
        Mark Collette added a comment -

        It's the same ice:inputFile component, it just has a new "outputStream" property, which you can use to create a ValueBinding to your bean where your getter method will return a java.io.OutputStream object. In your actionListener method you would still do the same logic of seeing if the file upload was a success or failure, to then handle the data that was written to your OutputStream.

        Show
        Mark Collette added a comment - It's the same ice:inputFile component, it just has a new "outputStream" property, which you can use to create a ValueBinding to your bean where your getter method will return a java.io.OutputStream object. In your actionListener method you would still do the same logic of seeing if the file upload was a success or failure, to then handle the data that was written to your OutputStream.

          People

          • Assignee:
            Unassigned
            Reporter:
            Mark Collette
          • Votes:
            26 Vote for this issue
            Watchers:
            17 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: