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 java.io.Serializable;
045:
046: import javax.faces.FacesException;
047: import javax.faces.component.UIComponent;
048: import javax.faces.context.FacesContext;
049:
050: import org.apache.commons.fileupload.FileItem;
051:
052: import com.sun.rave.web.ui.model.UploadedFile;
053: import com.sun.rave.web.ui.util.ComponentUtilities;
054: import com.sun.rave.web.ui.util.ThemeUtilities;
055:
056: /**
057: * Use this component to allow web application users to upload a file.
058: * If a web application uses this component, it must be configured to use
059: * {@link com.sun.rave.web.ui.util.UploadFilter }
060: * @author avk
061: */
062: public class Upload extends UploadBase implements Serializable {
063:
064: /**
065: * A string concatenated with the component ID to form the ID and
066: * name of the HTML input element.
067: */
068: public static final String INPUT_ID = "_com.sun.rave.web.ui.upload"; //NOI18N
069: public static final String INPUT_PARAM_ID = "_com.sun.rave.web.ui.uploadParam"; //NOI18N
070: public static final String SCRIPT_ID = "_script";
071: public static final String SCRIPT_FACET = "script";
072: public static final String TEXT_ID = "_text";
073: public static final String UPLOAD_ERROR_KEY = "upload_error_key";
074: public static final String FILE_SIZE_KEY = "file_size_key";
075:
076: private static final boolean DEBUG = false;
077:
078: /** Creates a new instance of Upload */
079: public Upload() {
080: }
081:
082: /**
083: * Log an error - only used during development time.
084: */
085: protected void log(String s) {
086: System.out.println(this .getClass().getName() + "::" + s); //NOI18N
087: }
088:
089: /**
090: * <p>Converts the submitted value. Returns an object of type
091: * UploadedFile.</p>
092: * @param context The FacesContext
093: * @param value An object representing the submitted value
094: * @return An Object representation of the value (a
095: * java.lang.String or a java.io.File, depending on how the
096: * component is configured
097: */
098: public Object getConvertedValue(FacesContext context, Object value) {
099:
100: if (DEBUG)
101: log("getConvertedValue");
102: UploadedFileImpl uf = new UploadedFileImpl();
103: uf.setAttribute(value);
104: if (DEBUG) {
105: log("\tSize is " + String.valueOf(uf.getSize()));
106: log("\tName is " + uf.getOriginalName());
107: log("\tValue is required " + String.valueOf(isRequired()));
108: }
109: if (isRequired() && uf.getSize() == 0) {
110: String name = uf.getOriginalName();
111: if (name == null || name.trim().length() == 0) {
112: if (DEBUG)
113: log("No file specified");
114: setValue("");
115: if (DEBUG)
116: log("Set value to empty string");
117: return "";
118: //FacesMessage msg = new FacesMessage("Enter a file to upload");
119: //throw new ConverterException(msg);
120: }
121: }
122: return uf;
123: }
124:
125: /**
126: * <p>Return the value to be rendered, as a String (converted
127: * if necessary), or <code>null</code> if the value is null.</p>
128: * @param context FacesContext for the current request
129: * @return A String value of the component
130: */
131: public String getValueAsString(FacesContext context) {
132: String valueString = null;
133: Object value = getValue();
134: if (value instanceof UploadedFile) {
135: valueString = ((UploadedFile) value).getOriginalName();
136: }
137: if (valueString == null) {
138: valueString = ThemeUtilities.getTheme(context).getMessage(
139: "FileUpload.noFile");
140: }
141: return valueString;
142: }
143:
144: /**
145: * Overrides getType in the FileInput class, to always return
146: * "file"
147: * @return "file"
148: */
149: public String getType() {
150: return "file";
151: }
152:
153: /**
154: * This method overrides getText() in Field. It always returns null.
155: */
156: public Object getText() {
157: return null;
158: }
159:
160: /**
161: * This method overrides setText() in Field. It is a noop.
162: */
163: public void setText(Object text) {
164: // do nothing
165: }
166:
167: public int getColumns() {
168:
169: int columns = super .getColumns();
170: if (columns < 1) {
171: columns = 40;
172: super .setColumns(40);
173: }
174: return columns;
175: }
176:
177: // <RAVE>
178: // Merged INF http://inf.central/inf/integrationReport.jsp?id=82661 from braveheart.
179: // It fixes bug 6349156: File upload label's "for" attribute value is incorrect
180:
181: /**
182: * Retrieves the DOM ID for the HTML input element. To be used by
183: * Label component as a value for the "for" attribute.
184: */
185: // Overrides the method in Field.java as a workaround for an
186: // apparent compiler problem (?). The renderer (for Upload as well
187: // as TextField etc) casts the component to Field. It invokes
188: // Field.getPrimaryElementID, and even though this.getClass()
189: // returns Upload, this.INPUT_ID returns Field.INPUT_ID and
190: // not Upload.INPUT_ID.
191: public String getPrimaryElementID(FacesContext context) {
192:
193: // Check for a public facet
194: String clntId = this .getClientId(context);
195: UIComponent facet = getFacet(LABEL_FACET);
196: if (facet != null) {
197: return clntId.concat(this .INPUT_ID);
198: }
199: // Need to check for the private facet as well. Note that
200: // this is not ideal - unless getLabelComponent has been invoked
201: // first, the private facet will be null. (Is there a reason
202: // we can't just invoke getLabelComponent instead of getFacet?).
203:
204: // Pass "false" since we don't want to get null if the id's
205: // don't match. We don't care at this point, in fact they
206: // should match because getLabelComponent must have been
207: // called in order for this to even work.
208: //
209: facet = ComponentUtilities.getPrivateFacet(this , LABEL_FACET,
210: false);
211: if (facet == null) {
212: return getClientId(context);
213: }
214: return this .getClientId(context).concat(this .INPUT_ID);
215: }
216:
217: // <RAVE>
218:
219: class UploadedFileImpl implements UploadedFile {
220:
221: transient Object attribute = null;
222:
223: /** Creates a new instance of UploadedFileImpl */
224: UploadedFileImpl() {
225: }
226:
227: void setAttribute(Object attribute) {
228: this .attribute = attribute;
229: }
230:
231: private FileItem getFileItemObject() {
232:
233: FacesContext context = FacesContext.getCurrentInstance();
234: Object fileItemObject = context.getExternalContext()
235: .getRequestMap().get(attribute);
236:
237: // <RAVE>
238: if (fileItemObject == null)
239: return null;
240: // <RAVE>
241:
242: if (!(fileItemObject instanceof FileItem)) {
243: String message = "Did you install the upload filter?";
244: throw new FacesException(message);
245: }
246: return (FileItem) fileItemObject;
247: }
248:
249: /**
250: * Write the contents of the uploaded file to a file on the
251: * server host. Note that writing files outside of the web
252: * server's tmp directory must be explicitly permitted through
253: * configuration of the server's security policy.
254: *
255: * This method is not guaranteed to succeed if called more
256: * than once for the same item.
257: * @param file The <code>File</code> where the contents should
258: * be written
259: *
260: * @exception Exception the
261: */
262: public void write(java.io.File file) throws Exception {
263: // <RAVE>
264: //getFileItemObject().write(file);
265: if (getFileItemObject() != null)
266: getFileItemObject().write(file);
267: // <RAVE>
268: }
269:
270: /**
271: * The size of the file in bytes
272: *
273: * @return The size of the file in bytes.
274: */
275: public long getSize() {
276: // <RAVE>
277: //return getFileItemObject().getSize();return getFileItemObject().getSize();
278: if (getFileItemObject() != null)
279: return getFileItemObject().getSize();
280: else
281: return 0;
282: // <RAVE>
283: }
284:
285: /**
286: * Use this method to retrieve the name that the file has on the web
287: * application user's local system.
288: *
289: * @return the name of the file on the web app user's system
290: */
291: public String getOriginalName() {
292: // <RAVE>
293: //return getFileItemObject().getName();
294: if (getFileItemObject() != null)
295: return getFileItemObject().getName();
296: else
297: return null;
298: // <RAVE>
299: }
300:
301: /**
302: * Returns a {@link java.io.InputStream InputStream} for
303: * reading the file.
304: *
305: * @return An {@link java.io.InputStream InputStream} for
306: * reading the file.
307: *
308: * @exception IOException if there is a problem while reading
309: * the file
310: */
311: public java.io.InputStream getInputStream()
312: throws java.io.IOException {
313: // <RAVE>
314: //return getFileItemObject().getInputStream();
315: if (getFileItemObject() != null)
316: return getFileItemObject().getInputStream();
317: else
318: return null;
319: // <RAVE>
320: }
321:
322: /**
323: * Get the content-type that the browser communicated with the
324: * request that included the uploaded file. If the browser did
325: * not specify a content-type, this method returns null.
326: *
327: * @return the content-type that the browser communicated
328: * with the request that included the uploaded file
329: */
330: public String getContentType() {
331: // <RAVE>
332: //return getFileItemObject().getContentType();
333: if (getFileItemObject() != null)
334: return getFileItemObject().getContentType();
335: else
336: return null;
337: // <RAVE>
338: }
339:
340: /**
341: * Use this method to retrieve the contents of the file as an
342: * array of bytes.
343: * @return The contents of the file as a byte array
344: */
345: public byte[] getBytes() {
346: // <RAVE>
347: //return getFileItemObject().get();
348: if (getFileItemObject() != null)
349: return getFileItemObject().get();
350: else
351: return null;
352: // <RAVE>
353: }
354:
355: /**
356: * Use this method to retrieve the contents of the file as a
357: * String
358: *
359: * @return the contents of the file as a String
360: */
361: public String getAsString() {
362: // <RAVE>
363: //return getFileItemObject().getString();
364: if (getFileItemObject() != null)
365: return getFileItemObject().getString();
366: else
367: return null;
368: // <RAVE>
369: }
370:
371: /**
372: * Dispose of the resources associated with the file upload
373: * (this will happen automatically when the resource is
374: * garbage collected).
375: */
376: public void dispose() {
377: // <RAVE>
378: //getFileItemObject().delete();
379: if (getFileItemObject() != null)
380: getFileItemObject().delete();
381: // <RAVE>
382: }
383: }
384: }
|