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