001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041: package com.sun.rave.web.ui.component;
042:
043: import java.io.IOException;
044: import javax.faces.component.UIComponent;
045: import javax.faces.context.FacesContext;
046: import javax.faces.el.MethodBinding;
047: import javax.faces.el.ValueBinding;
048:
049: /**
050: * <p>Use the ui:upload tag to create a component that can be used to
051: * browse the local file system for a file, and upload a copy of the
052: * file's contents to the web application.</p>
053: *
054: *
055: * <h3>HTML Elements and Layout</h3>
056: *
057: * <p>The Upload component produces an XHTML <input type="file">
058: * element, which displays a text input field with an adjacent Browse button.
059: * The user can type a file name or click the Browse button to select
060: * a file. When the form is submitted, the file is uploaded. Note
061: * that this tag requires the use of a filter.</p>
062: *
063: *
064: * <h3>Configuring the UploadFilter</h3>
065: *
066: * <p>In order for the <code>ui:upload</code> tag to work, you must
067: * configure the web application to use the
068: * <code>com.sun.rave.web.ui.util.UploadFilter</code>.
069: * Configure the filter by declaring a filter element in the web application's
070: * deployment descriptor, <code>web.xml</code>.</p>
071: * <pre>
072: * <filter>
073: * <filter-name>UploadFilter</filter-name>
074: * <filter-class>com.sun.rave.web.ui.util.UploadFilter</filter-class>
075: * </filter>
076: * </pre>
077: * <p>Map the filter to the FacesServlet by adding the following filter
078: * mapping in the same file, for example</p>
079: * <pre>
080: * <filter-mapping>
081: * <filter-name>UploadFilter</filter-name>
082: * <servlet-name>FacesServlet</servlet-name>
083: * </filter-mapping>
084: * </pre>
085: * <p>The UploadFilter uses the Apache commons fileupload package. You
086: * can optionally configure the parameters of the DiskFileUpload
087: * class by specifying init parameters on the UploadFilter. The
088: * following parameters are available:
089: * <ul>
090: * <li><code>maxSize</code> The maximum allowed upload size in bytes.
091: * If negative, there is no maximum. The default value is 1,000,000.</li>
092: *
093: * <li><code>sizeThreshold</code>The implementation of the uploading
094: * functionality uses temporary storage of the file contents before the
095: * Upload component stores them per its configuration. In the temporary
096: * storage, smaller files are stored in memory while larger files are
097: * written directly to disk . Use this parameter
098: * to specify an integer value of the cut-off where files should be
099: * written to disk. The default value is 4096 bytes.</li>
100: * <li><code>tmpDir</code> Use this directory to specify the directory to
101: * be used for temporary storage of files. The default behaviour is to use
102: * the directory specified in the system property "java.io.tmpdir". </li>
103: * </ul>
104: *
105: * <h3>The <code>UploadedFile</code> model object</h3>
106: *
107: * <p>The contents of the uploaded file, together with some information
108: * about it are stored in an instance of
109: * <code>com.sun.rave.web.ui.model.UploadedFile</code>. Using this object you
110: * can get the content of the file as a String or write the contents to
111: * disk, as well as get properties such as the name and the size of the
112: * file. In the interest of conserving memory, the contents and file data
113: * are only available during the HTTP request in which the file was
114: * uploaded.</p>
115: *
116: * <TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
117: * <TR BGCOLOR="#CCCCFF">
118: * <TH ALIGN="left" COLSPAN="2">
119: * <B>UploadedFile Method Summary</B></TH>
120: * </TR>
121: * <TR BGCOLOR="white">
122: * <TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
123: * <CODE> void</CODE></FONT></TD>
124: * <TD><CODE><B><code>dispose</code></B>()</CODE>
125: *
126: * <BR>
127: * Dispose of the resources associated with the file upload (this will
128: * happen automatically when the resource is garbage collected).</TD>
129: * </TR>
130: * <TR BGCOLOR="white">
131: * <TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
132: * <CODE> java.lang.String</CODE></FONT></TD>
133: * <TD><CODE><B><code>getAsString</code></B>()</CODE>
134: *
135: * <BR>
136: * Use this method to retrieve the contents of the file as a String</TD>
137: * </TR>
138: * <TR BGCOLOR="white">
139: * <TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
140: * <CODE> byte[]</CODE></FONT></TD>
141: * <TD><CODE><B><code>getBytes</code></B>()</CODE>
142: *
143: * <BR>
144: * Use this method to retrieve the contents of the file as an array of bytes.</TD>
145: * </TR>
146: * <TR BGCOLOR="white">
147: * <TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
148: * <CODE> java.lang.String</CODE></FONT></TD>
149: * <TD><CODE><B><code>getContentType</code></B>()</CODE>
150: *
151: * <BR>
152: * Get the content-type that the browser communicated with the request
153: * that included the uploaded file.</TD>
154: * </TR>
155: * <TR BGCOLOR="white">
156: * <TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
157: * <CODE> java.io.InputStream</CODE></FONT></TD>
158: * <TD><CODE><B><code>getInputStream</code></B>()</CODE>
159: *
160: * <BR>
161: * Returns a <CODE>InputStream</CODE> for reading the file.</TD>
162: * </TR>
163: * <TR BGCOLOR="white">
164: * <TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
165: * <CODE> java.lang.String</CODE></FONT></TD>
166: * <TD><CODE><B><code>getOriginalName</code></B>()</CODE>
167: *
168: * <BR>
169: * Use this method to retrieve the name that the file has on the web
170: * application user's local system.</TD>
171: * </TR>
172: * <TR BGCOLOR="white">
173: * <TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
174: * <CODE> long</CODE></FONT></TD>
175: * <TD><CODE><B><code>getSize</code></B>()</CODE>
176: *
177: * <BR>
178: * The size of the file in bytes</TD>
179: * </TR>
180: * <TR BGCOLOR="white">
181: * <TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
182: * <CODE> void</CODE></FONT></TD>
183: * <TD><CODE><B><code>write</code></B>(java.io.File file)</CODE>
184: *
185: * <BR>
186: * Write the contents of the uploaded file to a file on the server host.</TD>
187: * </TR>
188: * </TABLE>
189: *
190: * <P>
191: *
192: * <h3>Configuring the <code>ui:upload</code> tag</h3>
193: *
194: *
195: * <p>To access the contents of the uploaded file from the
196: * <code>ui:upload</code> tag you have two
197: * options:</p>
198: * <ul>
199: * <li>Bind the <code>uploadedFile</code> attribute to managed bean
200: * property of type <code>com.sun.rave.web.ui.model.UploadedFile</code>.
201: * Have the setter or an action method process the file.</li>
202: * <li>Specify a valueChangeListener on the Upload component.
203: * The method invoked by the value change listener has access to the
204: * new value of the component.</code>
205: * method. </li>
206: * </ul>
207: *
208: * <p>To optionally specify a label for the component, use the
209: * <code>label</code> attribute, or specify a label facet. </p>
210: *
211: * <h3>Client Side Javascript Functions</h3>
212: *
213: * <p>In all the functions below, <code><id></code> should be
214: * the generated id of the Upload component.
215: *
216: * <table cellpadding="2" cellspacing="2" border="1"
217: * style="text-align: left; width: 100%;">
218: * <tbody>
219: * <tr>
220: * <td style="vertical-align">
221: * <code>field_setDisabled(<id>, <disabled>)</code>
222: * </td>
223: * <td style="vertical-align: top">
224: * Enable/disable the field. Set <code><disabled></code>
225: * to true to disable the component, or false to enable it.
226: * </td>
227: * </tr>
228: * <tr>
229: * <td style="vertical-align: top">
230: * <code>field_setValue(<id>, <newValue>)</code>
231: * </td>
232: * <td style="vertical-align: top">
233: * Set the value of the field to <code><newValue></code>.
234: * </td>
235: * </tr>
236: * <tr>
237: * <td style="vertical-align: top">
238: * <code>field_getValue(<id>)</code>
239: * </td>
240: * <td style="vertical-align: top">Get the value of the field.</td>
241: * </tr>
242: * <tr>
243: * <td style="vertical-align: top">
244: * <code>field_getInputElement(<id>)</code></td>
245: * <td style="vertical-align: top">
246: * Get hold of a reference to the input element rendered by this
247: * component.
248: * </td>
249: * </tr>
250: * <tr>
251: * <td style="vertical-align: top">
252: * <code>component_setVisible(<id>)</code>
253: * </td>
254: * <td style="vertical-align: top">Hide or show this component.
255: * </td>
256: * </tr>
257: * </tbody>
258: * </table>
259: *
260: *
261: * <h3>Examples</h3>
262: *
263: * <h4>Get the contents of the file as a String (using a managed bean)</h4>
264: *
265: * <p>On the form that controls the upload:</p>
266: * <pre>
267: * <ui:upload id="upload2"
268: * uploadedFile = "#{FileUploadBean.uploadedFile}"
269: * label="Choose a file: "
270: * required="true"/>
271: * </pre>
272: *
273: * <p>On the page that displays the results of the upload:</p>
274: * <pre>
275: * <ui:staticText id="text"
276: * text ="File contents are bound to string: " >
277: * <ui:staticText id="text"
278: * text ="#{FileUploadBean.stringContent}"/>
279: *
280: * </pre>
281: * <p> The managed bean looks like this:</p>
282: * <pre>
283: * import java.io.Serializable;
284: * import com.sun.rave.web.ui.model.UploadedFile;
285: *
286: * public class FileUploadBean implements Serializable {
287: * //
288: * // Holds value of property uploadedFile.
289: * //
290: * transient private UploadedFile uploadedFile;
291: *
292: * //
293: * // Getter for property stringContent.
294: * // @return Value of property stringContent.
295: * //
296: * public String getStringContent() {
297: * return uploadedFile.getAsString();
298: * }
299: *
300: * //
301: * // Getter for property uploadedFile.
302: * // @return Value of property uploadedFile.
303: * //
304: * public UploadedFile getUploadedFile() {
305: * return this.uploadedFile;
306: * }
307: *
308: * //
309: * // Setter for property uploadedFile.
310: * // @param uploadedFile New value of property uploadedFile.
311: * //
312: * public void setUploadedFile(UploadedFile uploadedFile) {
313: * this.uploadedFile = uploadedFile;
314: * }
315: * }
316: * </pre>
317: *
318: * <h4>Write the contents of the file to disk (using a ValueChangeListener)</h4>
319: *
320: * <p>On the form that controls the upload:</p>
321: * <pre>
322: * <ui:upload id="upload1"
323: * label="Choose a file: "
324: * valueChangeListener="#{FileUploadedListener.processValueChange}"/>
325: * </pre>
326: *
327: * <p>Code for the ValueChangeListener</p>
328: * <pre>
329: * import java.io.File;
330: * import java.io.Serializable;
331: * import javax.faces.event.AbortProcessingException;
332: * import javax.faces.event.ValueChangeEvent;
333: * import com.sun.rave.web.ui.model.UploadedFile;
334: *
335: * public class FileUploadedListener implements ValueChangeListener, Serializable {
336: * public void processValueChange(ValueChangeEvent event)
337: * throws AbortProcessingException { Object value = event.getNewValue();
338: * if(value != null && value instanceof UploadedFile) {
339: * UploadedFile uploadedFile = (UploadedFile)value;
340: * String name = uploadedFile.getOriginalName();
341: * if(name == null || name.length() == 0) {
342: * name = "tmp.tmp";
343: * }
344: * String suffix = name.substring(name.indexOf("."));
345: * if(suffix.length() == 0) {
346: * suffix = ".tmp";
347: * }
348: * String prefix = name.substring(0, name.indexOf("."));
349: * try {
350: * File tmpFile = File.createTempFile(prefix, suffix);
351: * uploadedFile.write(tmpFile);
352: * } catch(Exception ex) {
353: * // report the problem
354: * }
355: * }
356: * }
357: * }
358: * </pre>
359: * <p>Auto-generated component class.
360: * Do <strong>NOT</strong> modify; all changes
361: * <strong>will</strong> be lost!</p>
362: */
363:
364: public abstract class UploadBase extends
365: com.sun.rave.web.ui.component.Field {
366:
367: /**
368: * <p>Construct a new <code>UploadBase</code>.</p>
369: */
370: public UploadBase() {
371: super ();
372: setRendererType("com.sun.rave.web.ui.Upload");
373: }
374:
375: /**
376: * <p>Return the identifier of the component family to which this
377: * component belongs. This identifier, in conjunction with the value
378: * of the <code>rendererType</code> property, may be used to select
379: * the appropriate {@link Renderer} for this component instance.</p>
380: */
381: public String getFamily() {
382: return "com.sun.rave.web.ui.Upload";
383: }
384:
385: /**
386: * <p>Return the <code>ValueBinding</code> stored for the
387: * specified name (if any), respecting any property aliases.</p>
388: *
389: * @param name Name of value binding to retrieve
390: */
391: public ValueBinding getValueBinding(String name) {
392: if (name.equals("uploadedFile")) {
393: return super .getValueBinding("value");
394: }
395: return super .getValueBinding(name);
396: }
397:
398: /**
399: * <p>Set the <code>ValueBinding</code> stored for the
400: * specified name (if any), respecting any property
401: * aliases.</p>
402: *
403: * @param name Name of value binding to set
404: * @param binding ValueBinding to set, or null to remove
405: */
406: public void setValueBinding(String name, ValueBinding binding) {
407: if (name.equals("uploadedFile")) {
408: super .setValueBinding("value", binding);
409: return;
410: }
411: super .setValueBinding(name, binding);
412: }
413:
414: // columns
415: private int columns = Integer.MIN_VALUE;
416: private boolean columns_set = false;
417:
418: /**
419: * <p>Number of character columns used to render this field.</p>
420: */
421: public int getColumns() {
422: if (this .columns_set) {
423: return this .columns;
424: }
425: ValueBinding _vb = getValueBinding("columns");
426: if (_vb != null) {
427: Object _result = _vb.getValue(getFacesContext());
428: if (_result == null) {
429: return Integer.MIN_VALUE;
430: } else {
431: return ((Integer) _result).intValue();
432: }
433: }
434: return 40;
435: }
436:
437: /**
438: * <p>Number of character columns used to render this field.</p>
439: * @see #getColumns()
440: */
441: public void setColumns(int columns) {
442: this .columns = columns;
443: this .columns_set = true;
444: }
445:
446: // uploadedFile
447: /**
448: * <p>The value of this attribute must be a JSF EL expression, and
449: * it must resolve to an object of type
450: * <code>com.sun.rave.web.ui.model.UploadedFile</code>. See the JavaDoc for
451: * this class for details.</p>
452: */
453: public com.sun.rave.web.ui.model.UploadedFile getUploadedFile() {
454: return (com.sun.rave.web.ui.model.UploadedFile) getValue();
455: }
456:
457: /**
458: * <p>The value of this attribute must be a JSF EL expression, and
459: * it must resolve to an object of type
460: * <code>com.sun.rave.web.ui.model.UploadedFile</code>. See the JavaDoc for
461: * this class for details.</p>
462: * @see #getUploadedFile()
463: */
464: public void setUploadedFile(
465: com.sun.rave.web.ui.model.UploadedFile uploadedFile) {
466: setValue((Object) uploadedFile);
467: }
468:
469: /**
470: * <p>Restore the state of this component.</p>
471: */
472: public void restoreState(FacesContext _context, Object _state) {
473: Object _values[] = (Object[]) _state;
474: super .restoreState(_context, _values[0]);
475: this .columns = ((Integer) _values[1]).intValue();
476: this .columns_set = ((Boolean) _values[2]).booleanValue();
477: }
478:
479: /**
480: * <p>Save the state of this component.</p>
481: */
482: public Object saveState(FacesContext _context) {
483: Object _values[] = new Object[3];
484: _values[0] = super .saveState(_context);
485: _values[1] = new Integer(this .columns);
486: _values[2] = this.columns_set ? Boolean.TRUE : Boolean.FALSE;
487: return _values;
488: }
489:
490: }
|