package uws.service.request; /* * This file is part of UWSLibrary. * * UWSLibrary is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * UWSLibrary is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with UWSLibrary. If not, see <http://www.gnu.org/licenses/>. * * Copyright 2014 - Astronomisches Rechen Institut (ARI) */ import java.io.IOException; import java.io.InputStream; import uws.job.UWSJob; import uws.job.parameters.UWSParameters; import uws.service.file.UWSFileManager; /** * <p>This class lets represent a file submitted inline in an HTTP request.</p> * * <p> * To read this special kind of parameter, an {@link InputStream} must be open. This class lets do it * by its function {@link #open()}. * </p> * * <p> * When not used any more this file should be deleted, in order to save server disk space. * This can be easily done thanks to {@link #deleteFile()}. This function actually just call the corresponding function * of the file manager, which is the only one to known how to deal with this file on the server. Indeed, even if most * of the time this file is stored on the local file system, it could also be stored on a distant server by a VOSpace. * In this case, the way to proceed is different, hence the use of the file manager. * </p> * * @author Grégory Mantelet (ARI) * @version 4.1 (11/2014) * * @see UWSParameters * @see MultipartParser */ public class UploadFile { /** Name of the parameter in which the file was submitted. */ public final String paramName; /** File name. It is the name provided in the HTTP request. */ public final String fileName; /** Location at which the content of this upload has been stored. * It can be a local file path, but also any other path or ID allowing * the {@link UWSFileManager} to access its content. */ protected String location; /** Jobs that owns this uploaded file. */ protected UWSJob owner = null; /** Indicate whether this file has been or is used by a UWSJob. * In other words, it is <i>true</i> when an open, move or delete operation has been performed. * An unused {@link UploadFile} instance shall be physically deleted from the file system. */ protected boolean used = false; /** MIME type of the file. */ public String mimeType = null; /** Length in bytes of the file. * If negative, the length should be considered as unknown. */ public long length = -1; /** File manager to use in order to open, move or delete this uploaded file. */ protected final UWSFileManager fileManager; /** * Build the description of an uploaded file. * * @param paramName Name of the HTTP request parameter in which the uploaded content was stored. <b>MUST NOT be NULL</b> * @param location Location of the file on the server. This String is then used by the given file manager in order to open, * move or delete the uploaded file. Thus, it can be a path, an ID or any other String meaningful to the file manager. * @param fileManager File manager to use in order to open, move or delete this uploaded file from the server. */ public UploadFile(final String paramName, final String location, final UWSFileManager fileManager){ this(paramName, null, location, fileManager); } /** * Build the description of an uploaded file. * * @param paramName Name of the HTTP request parameter in which the uploaded content was stored. <b>MUST NOT be NULL</b> * @param fileName Filename as provided by the HTTP request. <i>MAY be NULL</i> * @param location Location of the file on the server. This String is then used by the given file manager in order to open, * move or delete the uploaded file. Thus, it can be a path, an ID or any other String meaningful to the file manager. * @param fileManager File manager to use in order to open, move or delete this uploaded file from the server. */ public UploadFile(final String paramName, final String fileName, final String location, final UWSFileManager fileManager){ if (paramName == null) throw new NullPointerException("Missing name of the parameter in which the uploaded file content was => can not create UploadFile!"); else if (location == null) throw new NullPointerException("Missing server location of the uploaded file => can not create UploadFile!"); else if (fileManager == null) throw new NullPointerException("Missing file manager => can not create the UploadFile!"); this.paramName = paramName; this.fileName = (fileName == null) ? "" : fileName; this.location = location; this.fileManager = fileManager; } /** * <p>Get the location (e.g. URI, file path) of this file on the server.</p> * * <p><i>Important note: * This function SHOULD be used only by the {@link UWSFileManager} when open, move and delete operations are executed. * The {@link RequestParser} provided by the library set this location to the file URI (i.e. "file://{local-file-path}") * since the default behavior is to store uploaded file on the system temporary directory. * </i></p> * * @return Location (e.g. URI) or ID or any other meaningful String used by the file manager to access to the uploaded file. */ public String getLocation(){ return location; } /** * Get the job that uses this uploaded file. * * @return The owner of this file. */ public UWSJob getOwner(){ return owner; } /** * <p>Tell whether this uploaded file has been or will be used. * That's to say, whether an open, delete or move operation has been executed (even if it failed) on this {@link UploadFile} instance.</p> * * @return <i>true</i> if the file must be preserved, <i>false</i> otherwise. */ public final boolean isUsed(){ return used; } /** * Open a stream toward this uploaded file. * * @return Stream toward this upload content. * * @throws IOException If an error occurs while opening the stream. * * @see UWSFileManager#getUploadInput(UploadFile) */ public InputStream open() throws IOException{ used = true; return fileManager.getUploadInput(this); } /** * Delete definitely this uploaded file from the server. * * @throws IOException If the delete operation can not be performed. * * @see UWSFileManager#deleteUpload(UploadFile) */ public void deleteFile() throws IOException{ fileManager.deleteUpload(this); used = true; } /** * <p>Move this uploaded file in a location related to the given {@link UWSJob}. * It is particularly useful if at reception of an HTTP request uploaded files are stored in a temporary * directory (e.g. /tmp on Unix/Linux systems).</p> * * <p> * This function calls {@link UWSFileManager#moveUpload(UploadFile, UWSJob)} to process to the physical * moving of the file, but it then, it updates its location in this {@link UploadFile} instance. * <b>The file manager does NOT update this location! That's why it must not be called directly, but * through {@link #move(UWSJob)}.</b> * </p> * * @param destination The job by which this uploaded file will be exclusively used. * * @throws IOException If the move operation can not be performed. * * @see UWSFileManager#moveUpload(UploadFile, UWSJob) */ public void move(final UWSJob destination) throws IOException{ if (destination == null) throw new NullPointerException("Missing move destination (i.e. the job in which the uploaded file must be stored)!"); location = fileManager.moveUpload(this, destination); used = true; owner = destination; } @Override public String toString(){ return (owner != null && owner.getJobList() != null && owner.getUrl() != null) ? owner.getUrl().jobParameter(owner.getJobList().getName(), owner.getJobId(), paramName).toString() : fileName; } }