1 2 3 4 Previous Next 56 Replies Latest reply on Sep 19, 2013 9:57 AM by haseeb Go to original post
      • 30. Re: workaround for multipleUpload capability in <rich:fileUpload>
        simone.83

        I've been updated the fileupload.js . Read the revisions comments for more infos about changes here https://gist.github.com/simone83/5728231.

        I'd to investigate about the particular case of mixed type files uploaded (accepted and not): in this case there's something in the code that not works as i expect, 'cause it will load all the files (accepted or not) at bean-side but in the history lists, correctly discards all the files of rejected types. I need to accurately examine the code...

        sorry, I hope to close this Jira as soon as possibile.

        For the onsizeexceeded event issue, I've not yet implemented this functionality. I think i'll do after I resolve the mixed types issue.

         

        Thank you Lukas.

        • 31. Re: workaround for multipleUpload capability in <rich:fileUpload>
          lfryc

          Hey Simone,

           

          I guess that's because you are reacting on the 'files' property value correctly but you don't modify it - it doesn't remove rejected files.

          I'm not sure whether we can modify this 'files' list from JavaScript (due to security concerns).

           

           

          To the previous question - how to retrieve the data from event callback?

           

          ontyperejected="alert('File selected: ' + event.rf.data)";
          
          • 32. Re: workaround for multipleUpload capability in <rich:fileUpload>
            simone.83

            Thank you!

            The event.rf.data works correctly (I've verified the files list returned).

             

            And I've an idea for the uploaded rejected files issue: I can use the removeItem code for removing them, it should work (even if I don't find a better way to do that).

            Ok, i'd investigated and seems there's only a way to do the things works:

            using the accept attribute for <input type="file">.

            accept takes a list of MIME TYPES http://www.w3.org/TR/html-markup/input.file.html

            So we need to change <input type="file"> of class "rf-fu-inp" at runtime with javascript (inside the fileupload.js) adding an attribute "accept= <LIST OF MIME TYPES>". It's the only way. Obviously this will impact only the multi-upload implementation when it's supported by the client. In the single upload case, it will preserve the oldest behaviour.

            I think I can't do better of that...but if anyone can please help us!!!!

             

            Lukas, to proceed I need to convert the acceptedTypes list (a string of comma-separated file extensions from <rich:fileUpload> acceptedTypes attribute)

            in a mime type comma-separated list.

            jQuery supports that feature only inside the sdk library (jQuery.mime()), but it's not supported in jQuery library.

            I know all browsers except IE supports navigator.mimeTypes: a mimeTypes array with related suffixes,

            but these mimes are too few for our proposals, it not contains the "image" mime type for example... so I can't use it for the conversion.

            Suggestions? I need to manually create an enormous Map <mimeType,suffix> for ALL THE IANA MIME TYPES http://www.iana.org/assignments/media-types to resolve this problem? Or does richfaces have something like that inside the libraries??


            Bad news: even if we use the accept property (however, not supported by all the browsers) , the browsers implementation will differ from that we expect: it also allow to select files with suffix that will differ from the specified accepted types. In other words, ther user can pick whatever he/she wants.

             

            So that's not the right way (umph!!!), cause this badly browser's <input type="file"> implementation.

             

            I think we have two ways, in case of one or more files in the "files" array are not of allowed type, we can:

             

              1) allow uploading these files, and finally fire the "ontyperejected" event (this is the current implementations, so we leave it as it is). So at bean side the user will have all files, and we leave the user to do the type-checking of the uploaded files inside the listener.

                      --> this is the better solution, because however the user will adviced with the ontyperejected,

                           and at server-side he can even discards all the undesired files...you agree??


              2) discard the upload of entere block, firing the "ontyperejected" listing the files not allowed...

            --> but this is frustrating for the user, that will do repeat...until all the files are of allowed type!

             

             

            That's all I can do.

            Otherwise, we have to modify the implemention at server side and I've not idea how to do that now ...

            • 33. Re: workaround for multipleUpload capability in <rich:fileUpload>
              lfryc


              Simone Cinti wrote:

               

                1) allow uploading these files, and finally fire the "ontyperejected" event (this is the current implementations, so we leave it as it is). So at bean side the user will have all files, and we leave the user to do the type-checking of the uploaded files inside the listener.

              We should definitely do double checking on a server-side and dropping those files if we decide to go this way.

               

               

              Bad news: even if we use the accept property (however, not supported by all the browsers) , the browsers implementation will differ from that we expect: it also allow to select files with suffix that will differ from the specified accepted types. In other words, ther user can pick whatever he/she wants.

               

              So that's not the right way (umph!!!), cause this badly browser's <input type="file"> implementation.

               

              I think we have two ways, in case of one or more files in the "files" array are not of allowed type, we can:

               

                1) allow uploading these files, and finally fire the "ontyperejected" event (this is the current implementations, so we leave it as it is). So at bean side the user will have all files, and we leave the user to do the type-checking of the uploaded files inside the listener.

                        --> this is the better solution, because however the user will adviced with the ontyperejected,

                             and at server-side he can even discards all the undesired files...you agree??


                2) discard the upload of entere block, firing the "ontyperejected" listing the files not allowed...

              --> but this is frustrating for the user, that will do repeat...until all the files are of allowed type!

               

               

              That's all I can do.

              Otherwise, we have to modify the implemention at server side and I've not idea how to do that now ...

              I would incline to support both, mime-types and file-extension checking together with server-side dropping of wrong extensions.

              Additionally, I would enable support for multiple only when it will be specifically enabled by @multiple attribute.

               

              It's little bit hairy but probably the best what we can get out of it as for now:

               

              - support for multiple selection

              - allow to display just files by given mime-types (e.g. image/jpeg,image/png)

              - filter by file-extensions (on client-side and for multiple files on server-side)

              • 34. Re: workaround for multipleUpload capability in <rich:fileUpload>
                lfryc

                Simone Cinti wrote:

                 

                 

                Lukas, to proceed I need to convert the acceptedTypes list (a string of comma-separated file extensions from <rich:fileUpload> acceptedTypes attribute)

                in a mime type comma-separated list.

                jQuery supports that feature only inside the sdk library (jQuery.mime()), but it's not supported in jQuery library.

                I know all browsers except IE supports navigator.mimeTypes: a mimeTypes array with related suffixes,

                but these mimes are too few for our proposals, it not contains the "image" mime type for example... so I can't use it for the conversion.

                Suggestions? I need to manually create an enormous Map <mimeType,suffix> for ALL THE IANA MIME TYPES http://www.iana.org/assignments/media-types to resolve this problem? Or does richfaces have something like that inside the libraries??

                Btw we have a list of mime.types stored at server-side, we can transfer it to a client if necessary.

                • 35. Re: workaround for multipleUpload capability in <rich:fileUpload>
                  simone.83

                  Lukáš Fryč ha scritto:

                   


                  Simone Cinti wrote:

                   

                    1) allow uploading these files, and finally fire the "ontyperejected" event (this is the current implementations, so we leave it as it is). So at bean side the user will have all files, and we leave the user to do the type-checking of the uploaded files inside the listener.

                  We should definitely do double checking on a server-side and dropping those files if we decide to go this way.

                  Ok, I agree, by the client way the browsers implementation will differ from that we expect. If you specify the accept="<LIST OF MIME TYPES>" it will not do the same as for the .swf component of RF3.x. It will append on list the single extensions filter, the only selected type filter and the all Files filter. So this is not what we really want ...

                   

                  Lukáš Fryč ha scritto:

                   

                  Btw we have a list of mime.types stored at server-side, we can transfer it to a client if necessary.

                   

                  ...even with the mime.type list the problem still remain...we cannot rely by all the various/bogus browsers implementations, they'll ever differ each other .

                   

                   

                  Lukáš Fryč ha scritto:


                  I would incline to support both, mime-types and file-extension checking together with server-side dropping of wrong extensions.

                  Additionally, I would enable support for multiple only when it will be specifically enabled by @multiple attribute.

                   

                  It's little bit hairy but probably the best what we can get out of it as for now:

                   

                  - support for multiple selection

                  - allow to display just files by given mime-types (e.g. image/jpeg,image/png)

                  - filter by file-extensions (on client-side and for multiple files on server-side)

                  - support for multiple selection : ok we're doing it...

                   

                  - allow to display just files by given mime-types (e.g. image/jpeg,image/png)

                  - filter by file-extensions (on client-side and for multiple files on server-side).


                  unfortunatley, we have the browser's rendering problems reported above. We can even insert the accept="<LIST OF MIME TYPES"> attribute inside the <input type="file"/> element, but I think it can introduce a sort of disorientation by the end users because they can select too many filters inside the list and the "all files" filter is ever included when you specify the mime types...I've just done that  so If you prefer I would add it in fileupload.js...let me know what do you prefer to do for that point.

                   

                  For the last point (filter by file-extension) by server-side we can implement the rejection inside the FileUploadRendererBase class. In the for loop we can introduce an extension type check of each

                  UploadedFile item.

                  Ok, I'm going to discover how can I pick in the FileUploadRenedererBase the list of file extesions specified by the user inside the <rich:fileUpload> element ...if you have any suggestions I'll appreciate

                   

                  Thank you Lukáš. I'm sure we can solve this issue as soon...

                  Bye.

                   

                  Simone

                  • 36. Re: workaround for multipleUpload capability in <rich:fileUpload>
                    simone.83

                    Ok, i've found the way at server-side to pick the list of extensions specified in acceptedTypes attribute.

                    I'll add this method inside the FileUploadRendererBase. It will return a comma separated list of acceptedTypes.

                     

                    Then in "for" loop we filter each UploadedFile file extensions and if they're not included in that comma-separated list of acceptedTypes, the related FileUploadEvent will not fired.

                     

                    Agree??

                     

                    Here's the code

                     

                    private static String getAcceptedTypes(FacesContext context, UIComponent component) {

                    Attributes _acceptedTypesAttr = attributes().generic("acceptedTypes","acceptedTypes");

                    ComponentAttribute compAttr = null;   

                    try {

                           compAttr = _acceptedTypesAttr.first();

                    }catch (java.util.NoSuchElementException e) {

                    ;

                    }

                        if (compAttr==null) return "";

                        String componentAttributeName = compAttr.getComponentAttributeName();

                        Object attributeValue = component.getAttributes().get(componentAttributeName);

                        return attributeValue.toString();

                    }

                    • 37. Re: workaround for multipleUpload capability in <rich:fileUpload>
                      lfryc

                      I agree with suggested concepts,

                      I just have few comments to a code:

                       

                      I would not use generics: you can cast UIComponent to AbstractFileUpload which has getter getAcceptedTypes().

                      • 38. Re: workaround for multipleUpload capability in <rich:fileUpload>
                        simone.83

                        Ok Lukáš, as you suggests it's better to cast the UIComponent with AbstractFileUpload...I'm applying changes and testing the whole block ...

                        I'll refresh you soon

                        • 39. Re: workaround for multipleUpload capability in <rich:fileUpload>
                          simone.83

                          Ok, WDYT ? Now we can add the support either for maxFilesQuantity server-side, Agree?

                          If you have suggestions about the getFileNameSuffix(String name) I'll appreciate.

                           

                           

                          private static List<String> toAcceptedTypesList(String acceptedTypes) {

                           

                               List<String> result = new ArrayList<String>();

                               if (acceptedTypes == null) return result;

                               acceptedTypes.trim();

                               if (acceptedTypes.length() == 0) return result;

                               String types[] = acceptedTypes.split(",");

                               for (int i = 0 ; i < types.length; i++) {

                                  result.add((types[i].trim()).toLowerCase());

                               }

                               return result;

                              }

                           

                              private static String getFileNameSuffix(String fileName) {

                           

                                  String result="";

                                  if (fileName != null) {

                                     int i = fileName.lastIndexOf('.');

                                     if (fileName.lastIndexOf('.') > 0) result = fileName.substring(i+1);

                                  }

                                  return result;

                              }

                           

                          protected void doDecode(FacesContext context, UIComponent component) {

                                  ExternalContext externalContext = context.getExternalContext();

                                  MultipartRequest multipartRequest = (MultipartRequest) externalContext.getRequestMap().get(

                                      MultipartRequest.REQUEST_ATTRIBUTE_NAME);

                                  if (multipartRequest != null) {

                                      String clientId = component.getClientId(context);

                                      AbstractFileUpload abstractFileUpload = (AbstractFileUpload) component;

                                      List<String> acceptedTypes = toAcceptedTypesList(abstractFileUpload.getAcceptedTypes());

                           

                                      for (UploadedFile file : multipartRequest.getUploadedFiles()) {

                           

                                          if (clientId.equals(file.getParameterName())) {

                           

                                              if (acceptedTypes.isEmpty() || (!acceptedTypes.isEmpty() && acceptedTypes.contains(getFileNameSuffix(file.getName()).toLowerCase()))) {

                                                   component.queueEvent(new FileUploadEvent(component, file));

                                                   //    break;

                                              }

                                          }

                           

                                      }

                                  }

                              }

                           

                          P.S: now we are co-authors of these changes

                          • 40. Re: workaround for multipleUpload capability in <rich:fileUpload>
                            lfryc

                            Seems good, Simone.

                            • 41. Re: workaround for multipleUpload capability in <rich:fileUpload>
                              simone.83

                              ok, now I'm working at maxFilesQuantity issue on server-side.

                              The code is that (I'm just verifying if it is correct as it seems):

                               

                                         int maxFilesQuantity = parseMaxFilesQuantity(abstractFileUpload.getMaxFilesQuantity());

                               

                                          List<String> acceptedTypes = toAcceptedTypesList(abstractFileUpload.getAcceptedTypes());

                               

                                         int enqueuedEvents = 0;

                               

                                          for (UploadedFile file : multipartRequest.getUploadedFiles()) {

                                              if ((maxFilesQuantity > 0) && (enqueuedEvents == maxFilesQuantity)) break;      

                                              if (clientId.equals(file.getParameterName())) {

                               

                                                  if (acceptedTypes.isEmpty() || (!acceptedTypes.isEmpty() && acceptedTypes.contains(getFileNameSuffix(file.getName()).toLowerCase()))) {

                                                       component.queueEvent(new FileUploadEvent(component, file));

                                                       enqueuedEvents ++;

                                                  }

                                              }

                               

                                          }

                               

                               

                              Now we just add a new event on fileupload.js for user warning of that the maxFilesQuantity limit has exceeded...I'm investigating how to do that...if you have a ready suggestions (as you usually had ) ...

                              ... or we can just rely on the disabled Add button? We have already the __updateButtons in fileupload.js that does that! WDYT?

                              • 42. Re: workaround for multipleUpload capability in <rich:fileUpload>
                                simone.83

                                I've been pulled the new FileUploadRendererBase code here: https://github.com/richfaces4/components/pull/77

                                And I've decided to add your name in the @author , because we've worked togheter here ok?. If not agree, please reply and I'll do the changes.

                                 

                                I still waiting your confirm/verifications to close this Jira (that we need for going in production, we're in late...so in case of other related issue we can ever open a new Jira...agree?)

                                 

                                --> DAMN: I've made an error in class name!!! sorry!!!

                                 

                                I cannot modify the class name now because i've already pulled it. How can I do? Now the name is MyFileUploadRendererBase instead of FileUploadRendererBase ...

                                 

                                Thanks Lukas.

                                Simone

                                • 43. Re: workaround for multipleUpload capability in <rich:fileUpload>
                                  lfryc

                                  Hey Simone, I' currently opening new branch with a modifications you have did, I will let you know once it is created

                                  • 44. Re: workaround for multipleUpload capability in <rich:fileUpload>
                                    lfryc