View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.myfaces.custom.fileupload;
20  
21  import javax.faces.application.FacesMessage;
22  import javax.faces.component.html.HtmlInputText;
23  import javax.faces.context.FacesContext;
24  
25  import org.apache.myfaces.component.AlignProperty;
26  import org.apache.myfaces.component.UserRoleAware;
27  import org.apache.myfaces.component.UserRoleUtils;
28  import org.apache.myfaces.shared_tomahawk.util.MessageUtils;
29  import org.apache.myfaces.tomahawk.util.Constants;
30  
31  /**
32   * Creates a file-selection widget in the rendered page which allows a user to select
33   * a file for uploading to the server.
34   * <p>
35   * When the page is selected (using a command component such as commandButton), the
36   * currently selected file contents are included in the data posted to the server.
37   * The contents are cached somewhere, and an object of type UploadedFile will then
38   * be assigned to the property pointed to by the "value" expression of this component.
39   * </p>
40   * <p>
41   * You must enable the Tomahawk ExtensionsFilter to make this component work (see web.xml).
42   * </p> 
43   * <p>
44   * Also, don't forget to set the form's attribute "enctype" to "multipart/form-data". 
45   * See "examples/web/fileupload.jsp" for an example!
46   * </p> 
47   * <p>
48   * Unless otherwise specified, all attributes accept static values or EL expressions.
49   * </p>
50   * 
51   * @JSFComponent
52   *   name = "t:inputFileUpload"
53   *   class = "org.apache.myfaces.custom.fileupload.HtmlInputFileUpload"
54   *   tagClass = "org.apache.myfaces.custom.fileupload.HtmlInputFileUploadTag"
55   * @since 1.1.7
56   * @author Manfred Geiler (latest modification by $Author: lu4242 $)
57   * @version $Revision: 1146523 $ $Date: 2011-07-13 19:20:18 -0500 (Wed, 13 Jul 2011) $
58   */
59  public abstract class AbstractHtmlInputFileUpload
60          extends HtmlInputText
61          implements UserRoleAware, AlignProperty
62  {
63      private static final String SIZE_LIMIT_EXCEEDED = "sizeLimitExceeded";
64      private static final String FILE_SIZE_LIMIT_EXCEEDED = "fileSizeLimitExceeded";
65      private static final String FILEUPLOAD_MAX_SIZE = "org.apache.myfaces.custom.fileupload.maxSize";
66      private static final String FILEUPLOAD_EXCEPTION = "org.apache.myfaces.custom.fileupload.exception";
67      public static final String COMPONENT_TYPE = "org.apache.myfaces.HtmlInputFileUpload";
68      public static final String DEFAULT_RENDERER_TYPE = "org.apache.myfaces.FileUpload";
69      public static final String SIZE_LIMIT_MESSAGE_ID = "org.apache.myfaces.FileUpload.SIZE_LIMIT";
70  
71      public AbstractHtmlInputFileUpload()
72      {
73          setRendererType(DEFAULT_RENDERER_TYPE);
74      }
75  
76      public void setUploadedFile(UploadedFile upFile)
77      {
78          setValue(upFile);
79      }
80  
81      public UploadedFile getUploadedFile()
82      {
83          return (UploadedFile)getValue();
84      }
85      
86      /**
87       * This setting was intended to allow control over how the contents of the
88       * file get temporarily stored during processing.
89       * <p> It allows three options</p>
90       * <ul>
91       * <li>"default": The file is handled on memory while the file size is below 
92       * uploadThresholdSize value, otherwise is handled on disk or file storage when
93       * decode occur (set submitted value)</li>
94       * <li>"memory": The file is loaded to memory when decode occur 
95       * (set submitted value). In other words, before set the uploaded file as 
96       * submitted value it is loaded to memory. Use with caution, because it
97       * could cause OutOfMemory exceptions when the uploaded files are too big. </li>
98       * <li>"file": The file is handled on disk or file storage.</li>
99       * </ul>
100      * 
101      * @JSFProperty
102      */
103     public abstract String getStorage();
104 
105     /**
106      * This attribute specifies a comma-separated list of content types that 
107      * a server processing this form will handle correctly. User agents may 
108      * use this information to filter out non-conforming files when prompting 
109      * a user to select files to be sent to the server 
110      * (cf. the INPUT element when type="file")."
111      * 
112      * @JSFProperty
113      */
114     public abstract String getAccept();
115 
116     /**
117      * An EL expression to which an UploadedFile object will be assigned on postback
118      * if the user specified a file to upload to the server.
119      * 
120      * @JSFProperty
121      */
122     public Object getValue()
123     {
124         return super.getValue();
125     }
126 
127     public boolean isRendered()
128     {
129         if (!UserRoleUtils.isVisibleOnUserRole(this)) return false;
130         return super.isRendered();
131     }
132     
133     protected void validateValue(FacesContext context, Object convertedValue)
134     {
135         super.validateValue(context, convertedValue);
136         
137         if (isValid())
138         {
139               String exception =
140                 (String) context.getExternalContext().getRequestMap().get(FILEUPLOAD_EXCEPTION);
141               
142               if(exception != null )
143               {
144                 if(exception.equals(SIZE_LIMIT_EXCEEDED))
145                 {
146                   Integer maxSize =
147                     (Integer) context.getExternalContext().getRequestMap().get(FILEUPLOAD_MAX_SIZE);
148                   MessageUtils.addMessage(Constants.TOMAHAWK_DEFAULT_BUNDLE, FacesMessage.SEVERITY_ERROR,
149                               SIZE_LIMIT_MESSAGE_ID, new Object[] { getId(),
150                                       maxSize},
151                               getClientId(context), context);
152                   setValid(false);
153                 }
154                 else if (FILE_SIZE_LIMIT_EXCEEDED.equals(exception))
155                 {
156                     Integer maxSize =
157                         (Integer) context.getExternalContext().getRequestMap().get(FILEUPLOAD_MAX_SIZE);
158                     if (maxSize != null)
159                     {
160                         MessageUtils.addMessage(Constants.TOMAHAWK_DEFAULT_BUNDLE, FacesMessage.SEVERITY_ERROR,
161                                 SIZE_LIMIT_MESSAGE_ID, new Object[] { getId(),
162                                         maxSize},
163                                 getClientId(context), context);
164                     }
165                     else
166                     {
167                         maxSize = (Integer) context.getExternalContext().getRequestMap().get(
168                                 "org.apache.myfaces.custom.fileupload."+this.getClientId(context)+".maxSize");
169                         if (maxSize != null)
170                         {
171                             MessageUtils.addMessage(Constants.TOMAHAWK_DEFAULT_BUNDLE, FacesMessage.SEVERITY_ERROR,
172                                     SIZE_LIMIT_MESSAGE_ID, new Object[] { getId(),
173                                             maxSize},
174                                     getClientId(context), context);
175                         }
176                         //else
177                         //{
178                             //Ignore because this exception belongs to other component
179                         //}
180                     }
181                     setValid(false);
182                 }
183                 else 
184                 {
185                   throw new IllegalStateException("other exceptions not handled yet, exception : "+exception);
186                 }
187              }
188          }
189      }
190     
191 }