//
// $Id: DefaultUploadPolicy.java 289 2007-06-19 10:04:46 +0000 (mar., 19 juin
// 2007) etienne_sf $
//
// jupload - A file upload applet.
// Copyright 2007 The JUpload Team
//
// Created: 2006-05-04
// Creator: etienne_sf
// Last modified: $Date: 2008-06-05 06:06:40 -0700 (Thu, 05 Jun 2008) $
//
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free Software
// Foundation; either version 2 of the License, or (at your option) any later
// version. This program 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 General Public License for more
// details. You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation, Inc.,
// 675 Mass Ave, Cambridge, MA 02139, USA.
package wjhk.jupload2.policies;
import java.awt.BorderLayout;
import java.awt.Cursor;
import java.awt.GridLayout;
import java.awt.SystemColor;
import java.awt.dnd.DropTargetDropEvent;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.UIManager;
import javax.swing.border.BevelBorder;
import javax.swing.text.BadLocationException;
import netscape.javascript.JSException;
import netscape.javascript.JSObject;
import wjhk.jupload2.JUploadApplet;
import wjhk.jupload2.exception.JUploadException;
import wjhk.jupload2.exception.JUploadExceptionStopAddingFiles;
import wjhk.jupload2.exception.JUploadExceptionUploadFailed;
import wjhk.jupload2.exception.JUploadIOException;
import wjhk.jupload2.filedata.DefaultFileData;
import wjhk.jupload2.filedata.FileData;
import wjhk.jupload2.gui.JUploadFileChooser;
import wjhk.jupload2.gui.JUploadFileFilter;
import wjhk.jupload2.gui.JUploadPanel;
import wjhk.jupload2.gui.JUploadTextArea;
import wjhk.jupload2.upload.HttpConnect;
import wjhk.jupload2.upload.InteractiveTrustManager;
import wjhk.jupload2.upload.helper.ByteArrayEncoderHTTP;
import wjhk.jupload2.upload.helper.ByteArrayEncoder;
/**
* This class implements all {@link wjhk.jupload2.policies.UploadPolicy}
* methods. Its way of working is he same as the JUpload version 1. <BR>
* The simplest way to use this policy is given in the presentation of
* {@link UploadPolicy}. The DefaultUploadPolicy is used when no
* <I>uploadPolicy</I> parameter is given to the applet, or this parameter has
* 'DefaultUploadPolicy' as a value. <BR>
* <P>
* The <U>default behavior</U> is representated below. It can be overrided by
* adding parameters to the applet. All available parameters are shown in the
* presentation of {@link UploadPolicy}.
* </P>
* <UL>
* <LI>Default implementation for all
* {@link wjhk.jupload2.policies.UploadPolicy} methods.
* <LI>Files are uploaded all in one HTTP request.
* <LI>No handling for particular kind of files: files are transmitted without
* any transformation.
* <LI>The file are transmitted to the server with the navigator cookies,
* userAgent and Protocol. This make upload occurs within the current user
* session on the server. So, it allows right management and context during the
* management of uploaded files, on the server.
* </UL>
*
* @author etienne_sf
* @version $Revision: 477 $
*/
public class DefaultUploadPolicy implements UploadPolicy {
// //////////////////////////////////////////////////////////////////////////////////////////////
// /////////////////// APPLET PARAMETERS
// ///////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////////////////////////////////
/**
* applet contains the reference of the Applet. It's useful to interact with
* it. <BR>
* It also allows access to the navigator properties, if the html tag
* MAYSCRIPT is put in the APPLET tag. This allows this class to get the
* cookie, userAgent and protocol, to upload files in the current user
* session on the server. <BR>
* Default : no default value
*/
private JUploadApplet applet = null;
/**
* Contains the applet parameter of the same name. If a valid URL is given
* here, the navigator will get redirected to this page, after a successful
* upload.
*/
private String afterUploadURL = UploadPolicy.DEFAULT_AFTER_UPLOAD_URL;
/**
* Contains the allowedFileExtensions applet parameter.
*/
private boolean allowHttpPersistent = UploadPolicy.DEFAULT_ALLOW_HTTP_PERSISTENT;
/**
* Contains the allowedFileExtensions applet parameter.
*/
private String allowedFileExtensions = UploadPolicy.DEFAULT_ALLOWED_FILE_EXTENSIONS;
/**
* Contains the allowedFileExtensions applet parameter.
*/
private String ignoredDirectoryRegex = UploadPolicy.DEFAULT_IGNORED_DIRECTORY_REGEX;
/**
* Contains the ignoedFileRegex applet parameter.
*/
private String ignoredFileRegex = UploadPolicy.DEFAULT_IGNORED_FILE_REGEX;
/**
* Indicate whether the log window is shown or not to the user. In all cases
* it remains in memory, and stores all debug information. This allows a log
* information, in case of an error occurs.
*
* @see #urlToSendErrorTo
*/
private boolean showLogWindow = UploadPolicy.DEFAULT_SHOW_LOGWINDOW;
private boolean showStatusbar = UploadPolicy.DEFAULT_SHOW_STATUSBAR;
private String specificHeaders = null;
/**
* The current debug level.
*/
private int debugLevel = UploadPolicy.DEFAULT_DEBUG_LEVEL;
/**
* Stored value for the fileChooserIconFromFileContent applet property.
*
* @see UploadPolicy#PROP_FILE_CHOOSER_ICON_FROM_FILE_CONTENT
*/
private int fileChooserIconFromFileContent = UploadPolicy.DEFAULT_FILE_CHOOSER_ICON_FROM_FILE_CONTENT;
/**
* Stored value for the fileChooserIconSize applet property.
*
* @see UploadPolicy#PROP_FILE_CHOOSER_ICON_SIZE
*/
private int fileChooserIconSize = UploadPolicy.DEFAULT_FILE_CHOOSER_ICON_SIZE;
private String fileUploadLoadedCallback = null;
private String formvarPrefix = null;
private boolean suppress = false;
private String filenamePrefix = null;
/**
* This String contains the filenameEncoding parameter. All details about
* the available applet parameters are displayed in the <a
* href="UploadPolicy.html@parameters">Upload Policy javadoc page</a>.
*/
private String filenameEncoding = UploadPolicy.DEFAULT_FILENAME_ENCODING;
/**
* The lang parameter, given to the applet.
*/
private String lang = UploadPolicy.DEFAULT_LANG;
/**
* The look and feel is used as a parameter of the
* UIManager.setLookAndFeel(String) method. See the parameters list on the
* {@link UploadPolicy} page.
*/
private String lookAndFeel = UploadPolicy.DEFAULT_LOOK_AND_FEEL;
/**
* The applet will do as may HTTP requests to upload all files, with the
* number as a maximum number of files for each HTTP request. <BR>
* Default : -1
*/
private int nbFilesPerRequest = UploadPolicy.DEFAULT_NB_FILES_PER_REQUEST;
/**
* if this is set, we'll only upload one file from the queue per press of the button
*/
private boolean oneFilePerStart = UploadPolicy.DEFAULT_ONE_FILE_PER_START;
/**
* Current value (or default value) of the maxChunkSize applet parameter.
* <BR>
* Default : Long.MAX_VALUE
*/
private long maxChunkSize = UploadPolicy.DEFAULT_MAX_CHUNK_SIZE;
/**
* Current value (or default value) of the maxFileSize applet parameter.
* <BR>
* Default : Long.MAX_VALUE
*/
private long maxFileSize = UploadPolicy.DEFAULT_MAX_FILE_SIZE;
/**
* The URL where files should be posted. <BR>
* Default : no default value. (mandatory)
*/
private String postURL = UploadPolicy.DEFAULT_POST_URL;
/**
* @see UploadPolicy#getServerProtocol()
*/
private String serverProtocol = UploadPolicy.DEFAULT_SERVER_PROTOCOL;
/**
* @see UploadPolicy#getStringUploadError()
*/
private String stringUploadError = UploadPolicy.DEFAULT_STRING_UPLOAD_ERROR;
/**
* @see UploadPolicy#getStringUploadSuccess()
*/
private String stringUploadSuccess = UploadPolicy.DEFAULT_STRING_UPLOAD_SUCCESS;
/**
* If an error occurs during upload, and this attribute is not null, the
* applet asks the user if wants to send the debug ouput to the
* administrator. If yes, the full debug information is POSTed to this URL.
* It's a little development on the server side to send a mail to the
* webmaster, or just log this error into a log file.
*
* @see UploadPolicy#sendDebugInformation(String)
*/
private String urlToSendErrorTo = UploadPolicy.DEFAULT_URL_TO_SEND_ERROR_TO;
/**
* Optional name of a form (in the same document like the applet) which is
* used to populate POST parameters.
*/
private String formData = UploadPolicy.DEFAULT_FORMDATA;
private String afterUploadTarget = UploadPolicy.DEFAULT_AFTER_UPLOAD_TARGET;
private String lastResponseBody = null;
private String lastResponseMessage = null;
private int sslVerifyCert = InteractiveTrustManager.NONE;
private final static String CRLF = System.getProperty("line.separator");
/* a Stats object */
private boolean in_progress = false; // t or f indicating if a file upload is currently in progress
private int files_queued=0; // The number of files currently in the queue
private int successful_uploads=0; // The number of files that have uploaded successfully (caused uploadSuccess to be fired)
private int upload_errors=0; // The number of files that have had errors (excluding cancelled files)
private int upload_cancelled=0; // The number of files that have been cancelled
private int queue_errors=0; // The number of files that caused fileQueueError to be fired
private String javascriptInstancePrefix = "JUpload.instances"; //
// //////////////////////////////////////////////////////////////////////////////////////////////
// /////////////////// INTERNAL ATTRIBUTE
// ///////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////////////////////////////////
/**
* This Vector contains headers that will be added for each upload. It may
* contains specific cookies, for instance.
*
* @see #onAppendHeader(ByteArrayEncoder)
*/
private Vector<String> headers = new Vector<String>();
/**
* The text area, where message are to be displayed.
*
* @see #displayMsg(String, String)
*/
private JUploadTextArea logWindow = null;
/**
* The resourceBundle contains all localized String (and others ??)
*/
private ResourceBundle resourceBundle = null;
/**
* This stream is used to store all information that could be useful, in
* case a problem occurs. Is content can then be sent to the webmaster.
*/
protected PrintStream debugOut = null;
/**
* The actual file, used for the debug log.
*/
protected File debugFile = null;
/**
* This flag prevents endless repeats of opening the debug log, if that
* failed for some reason.
*/
protected boolean debugOk = true;
/** cookie is the value of the javascript <I>document.cookie</I> property. */
protected String cookie = null;
/**
* userAgent is the value of the javascript <I>navigator.userAgent</I>
* property.
* Protected as there is no setter for it, and no other way to update it.
*/
protected String userAgent = null;
/**
* This constant defines the upper limit of lines, kept in the log window.
*/
private final static int MAX_DEBUG_LINES = 10000;
/**
* The regexp pattern that is used to find the success string in the HTTP
* response. If found, the upload is considered to be a success: it has been
* accepted by the remote server and the remote application.
*/
protected Pattern patternSuccess = Pattern
.compile(UploadPolicy.DEFAULT_STRING_UPLOAD_SUCCESS);
/**
* Same as {@link #patternSuccess}, but for the error message. If found,
* then the upload was accepted by the remote HTTP server, but rejected by
* the remote application. This pattern should also find the error message
* in the first matching string.
*/
protected Pattern patternError = Pattern
.compile(UploadPolicy.DEFAULT_STRING_UPLOAD_ERROR);
// //////////////////////////////////////////////////////////////////////////////////////////////
// /////////////////// CONSTRUCTORS
// //////////////////////////////////////////////////////////////////////////////////////////////
/**
* The main constructor : use default values, and the given postURL.
*
* @param theApplet The current applet. As the reference to the current
* upload policy exists almost everywhere, this parameter allows
* any access to anyone on the applet... including reading the
* applet parameters.
* @throws JUploadException If an applet parameter is invalid
*/
public DefaultUploadPolicy(JUploadApplet theApplet) throws JUploadException {
// Call default constructor for all default initialization;.
this.applet = theApplet;
this.logWindow = theApplet.getLogWindow();
// get the debug level. This control the level of debug messages that
// are written in the log window (see displayDebugMessage). In all
// cases, the full output is written in the debugBufferString (see also
// urlToSendErrorTo)
setDebugLevel(UploadPolicyFactory.getParameter(theApplet,
PROP_DEBUG_LEVEL, DEFAULT_DEBUG_LEVEL, this), false);
// Get resource file. This must be the very first parameter to be set,
// because during initialization, translations may be needed.
setLang(UploadPolicyFactory.getParameter(theApplet, PROP_LANG,
DEFAULT_LANG, this));
// Force the look and feel of the current system. This must be the
// second
// first parameter to be set, because during initialization, dialogs can
// appear.
setLookAndFeel(UploadPolicyFactory.getParameter(theApplet,
PROP_LOOK_AND_FEEL, DEFAULT_LOOK_AND_FEEL, this));
// This must be set before any URL's because these might trigger an
// connection attempt.
setSslVerifyCert(UploadPolicyFactory.getParameter(theApplet,
PROP_SSL_VERIFY_CERT, DEFAULT_SSL_VERIFY_CERT, this));
// get the afterUploadURL applet parameter.
setAfterUploadURL(UploadPolicyFactory.getParameter(theApplet,
PROP_AFTER_UPLOAD_URL, DEFAULT_AFTER_UPLOAD_URL, this));
// get the allowedFileExtensions applet parameter
setAllowedFileExtensions(UploadPolicyFactory.getParameter(theApplet,
PROP_ALLOWED_FILE_EXTENSIONS, DEFAULT_ALLOWED_FILE_EXTENSIONS,
this));
setAllowHttpPersistent(UploadPolicyFactory
.getParameter(theApplet, PROP_ALLOW_HTTP_PERSISTENT,
DEFAULT_ALLOW_HTTP_PERSISTENT, this));
setShowStatusbar(UploadPolicyFactory.getParameter(theApplet,
PROP_SHOW_STATUSBAR, DEFAULT_SHOW_STATUSBAR, this));
setShowLogWindow(UploadPolicyFactory.getParameter(theApplet,
PROP_SHOW_LOGWINDOW, DEFAULT_SHOW_LOGWINDOW, this));
// get the fileChooserIconFromFileContent.
setFileChooserIconFromFileContent(UploadPolicyFactory.getParameter(
theApplet, PROP_FILE_CHOOSER_ICON_FROM_FILE_CONTENT,
DEFAULT_FILE_CHOOSER_ICON_FROM_FILE_CONTENT, this));
// get the fileChooserIconSize.
setFileChooserIconSize(UploadPolicyFactory.getParameter(theApplet,
PROP_FILE_CHOOSER_ICON_SIZE, DEFAULT_FILE_CHOOSER_ICON_SIZE,
this));
// get the callbacks..
setCallBackString(PROP_CALLBACK_FILE_UPLOAD_LOADED,UploadPolicyFactory.getParameter(theApplet,
PROP_CALLBACK_FILE_UPLOAD_LOADED,"juploadReady",
this));
setCallBackString(PROP_CALLBACK_FILE_DIALOG_START,UploadPolicyFactory.getParameter(theApplet,
PROP_CALLBACK_FILE_DIALOG_START, "fileDialogStart",
this));
setCallBackString(PROP_CALLBACK_FILE_QUEUED,UploadPolicyFactory.getParameter(theApplet,
PROP_CALLBACK_FILE_QUEUED, "fileQueued",
this));
setCallBackString(PROP_CALLBACK_FILE_QUEUE_ERROR,UploadPolicyFactory.getParameter(theApplet,
PROP_CALLBACK_FILE_QUEUE_ERROR, "fileQueueError",
this));
setCallBackString(PROP_CALLBACK_FILE_DIALOG_COMPLETE,UploadPolicyFactory.getParameter(theApplet,
PROP_CALLBACK_FILE_DIALOG_COMPLETE, "fileDialogComplete",
this));
setCallBackString(PROP_CALLBACK_FILE_UPLOAD_START,UploadPolicyFactory.getParameter(theApplet,
PROP_CALLBACK_FILE_UPLOAD_START, "uploadStart",
this));
setCallBackString(PROP_CALLBACK_FILE_UPLOAD_PROGRESS,UploadPolicyFactory.getParameter(theApplet,
PROP_CALLBACK_FILE_UPLOAD_PROGRESS, "uploadProgress",
this));
setCallBackString(PROP_CALLBACK_FILE_UPLOAD_ERROR,UploadPolicyFactory.getParameter(theApplet,
PROP_CALLBACK_FILE_UPLOAD_ERROR, "uploadError",
this));
setCallBackString(PROP_CALLBACK_FILE_UPLOAD_SUCCESS,UploadPolicyFactory.getParameter(theApplet,
PROP_CALLBACK_FILE_UPLOAD_SUCCESS, "uploadSuccess",
this));
setCallBackString(PROP_CALLBACK_FILE_UPLOAD_COMPLETE,UploadPolicyFactory.getParameter(theApplet,
PROP_CALLBACK_FILE_UPLOAD_COMPLETE, "uploadComplete",
this));
//setCallBackString(PROP_CALLBACK_FILE_)
setFilenamePrefix(UploadPolicyFactory.getParameter(theApplet,PROP_FILENAME_PREFIX, null,
this));
setFilenameSuppressSuffix(UploadPolicyFactory.getParameter(theApplet,PROP_FILENAME_SUPPRESS_SUFFIX, false,
this));
setFilenameFormvarName(UploadPolicyFactory.getParameter(theApplet,PROP_FORM_VAR_NAME, null,
this));
setIgnoreDirectoryRegex(UploadPolicyFactory.getParameter(theApplet, PROP_IGNORE_DIRECTORY_REGEX, null,
this));
setIgnoreFileRegex(UploadPolicyFactory.getParameter(theApplet, PROP_IGNORE_FILE_REGEX, null,
this));
// get the filenameEncoding. If not null, it should be a valid argument
// for the URLEncoder.encode method.
setFilenameEncoding(UploadPolicyFactory.getParameter(theApplet,
PROP_FILENAME_ENCODING, DEFAULT_FILENAME_ENCODING, this));
// get the maximum number of files to upload in one HTTP request.
setNbFilesPerRequest(UploadPolicyFactory.getParameter(theApplet,
PROP_NB_FILES_PER_REQUEST, DEFAULT_NB_FILES_PER_REQUEST, this));
// get the flag for whether or not we're only doing one file upload per press or javascript command.
setOneFilePerStart(UploadPolicyFactory.getParameter(theApplet,
PROP_ONE_FILE_PER_START, DEFAULT_ONE_FILE_PER_START, this));
// get the maximum size of a file on one HTTP request (indicate if the
// file must be splitted before upload, see UploadPolicy comment).
setMaxChunkSize(UploadPolicyFactory.getParameter(theApplet,
PROP_MAX_CHUNK_SIZE, DEFAULT_MAX_CHUNK_SIZE, this));
// get the maximum size of an uploaded file.
setMaxFileSize(UploadPolicyFactory.getParameter(theApplet,
PROP_MAX_FILE_SIZE, DEFAULT_MAX_FILE_SIZE, this));
// get the URL where files must be posted.
setPostURL(UploadPolicyFactory.getParameter(theApplet, PROP_POST_URL,
DEFAULT_POST_URL, this));
// get any additional headers.
setSpecificHeaders(UploadPolicyFactory.getParameter(theApplet,
PROP_SPECIFIC_HEADERS, DEFAULT_SPECIFIC_HEADERS, this));
setServerProtocol(UploadPolicyFactory.getParameter(theApplet,
PROP_SERVER_PROTOCOL, DEFAULT_SERVER_PROTOCOL, this));
setStringUploadError(UploadPolicyFactory.getParameter(theApplet,
PROP_STRING_UPLOAD_ERROR, DEFAULT_STRING_UPLOAD_ERROR, this));
setStringUploadSuccess(UploadPolicyFactory
.getParameter(theApplet, PROP_STRING_UPLOAD_SUCCESS,
DEFAULT_STRING_UPLOAD_SUCCESS, this));
// get the URL where the full debug output can be sent when an error
// occurs.
setUrlToSendErrorTo(UploadPolicyFactory.getParameter(theApplet,
PROP_URL_TO_SEND_ERROR_TO, DEFAULT_URL_TO_SEND_ERROR_TO, this));
this.formData = UploadPolicyFactory.getParameter(theApplet,
PROP_FORMDATA, DEFAULT_FORMDATA, this);
this.afterUploadTarget = UploadPolicyFactory.getParameter(theApplet,
PROP_AFTER_UPLOAD_TARGET, DEFAULT_AFTER_UPLOAD_TARGET, this);
// /////////////////////////////////////////////////////////////////////////////
// Load session data read from the navigator:
// - cookies.
// - User-Agent : useful, as the server will then see a post request
// coming from the same navigator.
//
try {
// Test, to avoid a crash under linux
JSObject awin = JSObject.getWindow(getApplet());
JSObject doc = (JSObject) awin.getMember("document");
this.cookie = (String) doc.getMember("cookie");
JSObject nav = (JSObject) awin.getMember("navigator");
this.userAgent = (String) nav.getMember("userAgent");
displayDebug("cookie: " + this.cookie, 10);
displayDebug("userAgent: " + this.userAgent, 10);
} catch (JSException e) {
displayWarn("JSException (" + e.getClass() + ": " + e.getMessage()
+ ") in DefaultUploadPolicy, trying default values.");
// If we can't have access to the JS objects, we're in development :
// Let's put some 'hard value', to test the applet from the
// development tool (mine is eclipse).
// felfert: I need different values so let's make that
// configurable...
this.cookie = System.getProperty("debug_cookie");
this.userAgent = System.getProperty("debug_agent");
displayDebug(
" no navigator found, reading 'debug_cookie' from system properties ("
+ this.cookie + ")", 10);
displayDebug(
" no navigator found, reading 'debug_agent' from system properties ("
+ this.userAgent + ")", 10);
/*
* Exemple of parameter when calling the JVM:
* -Ddebug_cookie="Cookie:
* cpg146_data=YTo0OntzOjI6IklEIjtzOjMyOiJhZGU3MWIxZmU4OTZjNThhZjQ5N2FiY2ZiNmFlZTUzOCI7czoyOiJhbSI7aToxO3M6NDoibGFuZyI7czo2OiJmcmVuY2giO3M6MzoibGl2IjthOjI6e2k6MDtOO2k6MTtzOjQ6IjE0ODgiO319;
* cpg143_data=YTozOntzOjI6IklEIjtzOjMyOiI4NjhhNmQ4ZmNlY2IwMTc5YTJiNmZlMGY3YWQzNThkNSI7czoyOiJhbSI7aToxO3M6NDoibGFuZyI7czo2OiJmcmVuY2giO30%3D;
* 8387c97d1f683b758a67a0473b586126=5ed998846fec70d6d2f73971b9cbbf0b;
* b1d7468cf1b317c97c7c284f6bb14ff8=587b82a7abb3d2aca134742b1df9acf7"
* -Ddebug_agent="userAgent: Mozilla/5.0 (Windows; U; Windows NT
* 5.0; fr; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3"
*/
}
// The cookies and user-agent will be added to the header sent by the
// applet:
if (this.cookie != null)
addHeader("Cookie: " + this.cookie);
if (this.userAgent != null)
addHeader("User-Agent: " + this.userAgent);
// We let the UploadPolicyFactory call the displayParameterStatus
// method, so that the initialization is finished, including for classes
// which inherit from DefaultUploadPolicy.
}
// //////////////////////////////////////////////////////////////////////////////////////////////
// /////////////////// UploadPolicy methods
// //////////////////////////////////////////////////////////////////////////////////////////////
// getters and setters are sorted below
/**
* @see wjhk.jupload2.policies.UploadPolicy#addHeader(java.lang.String)
*/
public void addHeader(String header) {
this.headers.add(header);
}
/**
* @see wjhk.jupload2.policies.UploadPolicy#beforeUpload()
*/
public void beforeUpload() {
// Default: no special action.
setStatInProgress(true); //
}
/**
* The default behaviour (see {@link DefaultUploadPolicy}) is to check that
* the stringUploadSuccess applet parameter is present in the response from
* the server. The return is tested, in the order below: <DIR>
* <LI>True, if the stringUploadSuccess was not given as an applet
* parameter (no test at all).
* <LI>True, if the stringUploadSuccess string is present in the
* serverOutputBody.
* <LI>True, If previous condition is not filled, but the HTTP header
* "HTTP(.*)200OK$" is present: the test is currently non blocking, because
* I can not test all possible HTTP configurations.<BR>
* <LI>False if the previous conditions are not fullfilled. </DIR>
*
* @param status The HTTP response code
* @param msg The full HTTP response message (e.g. "404 Not found").
* @param body The body of the HTTP answer.
* @return True or False, indicating if the upload is a success or not.
* @see UploadPolicy#checkUploadSuccess(int, String, String)
*/
public boolean checkUploadSuccess(int status, String msg, String body)
throws JUploadException {
this.lastResponseBody = body;
this.lastResponseMessage = msg;
displayDebug("HTTP status: " + msg, 40);
// HTTP-100 correction, thanks to Marc Reidy
if ((status != 200) && (status != 100))
throw new JUploadExceptionUploadFailed("Received HTTP status "
+ msg);
// Let's analyze the body returned, line by line.
StringTokenizer st = new StringTokenizer(body, "\n\r");
Matcher matcherError;
String line;
while (st.hasMoreTokens()) {
line = (String) st.nextToken();
// Check if this is a success
// The success string should be in the http body
if (getStringUploadSuccess() != null
&& !getStringUploadSuccess().equals("")) {
if (this.patternSuccess.matcher(line).matches()) {
//incrementStatSuccessfulUploads();
return true;
}
}
// Check if this is an error
if (getStringUploadError() != null
&& !getStringUploadError().equals("")) {
matcherError = this.patternError.matcher(line);
if (matcherError.matches()) {
String errmsg = "An error occurs during upload (but the applet couldn't find the error message)";
if (matcherError.groupCount() > 0) {
errmsg = matcherError.group(1);
if (errmsg.equals("")) {
errmsg = "An unknown error occurs during upload.";
}
}
this.lastResponseMessage = errmsg;
//incrementStatUploadErrors();
throw new JUploadExceptionUploadFailed(errmsg);
}
}
}
// We found no stringUploadSuccess nor stringUploadError
if (getStringUploadSuccess() == null
|| getStringUploadSuccess().equals("")) {
// No chance to check the correctness of this upload. -> Assume Ok
//incrementStatSuccessfulUploads();
return true;
}
// stringUploadSuccess was defined but we did not find it.
// This is most certainly an error as http-status 200 does *not* refer
// to the correctness of the content. It merely means that the protocol
// handling was ok. -> throw an exception
incrementStatUploadErrors();
throw new JUploadExceptionUploadFailed(getClass().getName()
+ ".checkUploadSuccess(): The string \""
+ this.stringUploadSuccess
+ "\" was not found in the response body");
} // checkUploadSuccess
private String jsString(String s) {
return "'" + s.replaceAll("'", "\\'") + "'";
}
// JUpload.JUploadReady.apply(JUpload.instances['jupload_0'],null) -
public Object performCallback(String function, String[] args, boolean use_instance) throws JUploadException {
Object return_val;
if (function != null) {
try {
String instanced_function = function;
String s_args="";
Integer i;
if (null != args) {
for (i = 0; i < args.length; i++) {
if (s_args.length() > 0) s_args += ",";
if (null != args[i]) {
s_args = s_args + args[i];
} else
s_args = s_args + "null";
}
}
if (use_instance && (null!=this.applet.getParameter("NAME"))){ // Do instance call, JUpload.instances['jupload_0'].function.apply(JUpload.instances['jupload_0'],args)
instanced_function = this.javascriptInstancePrefix+"[\""+this.applet.getParameter("NAME")+"\"]."+function+"("+s_args+")";
// turn into function.apply(JUpload['jupload_0'],(args))
} else { // do a class call, like JUpload.JUploadReady.apply(JUpload.instances['jupload_0'],null)
//instanced_function = function+".apply("+this.javascriptInstanceName+","+s_args+")";
instanced_function = function+"("+s_args+")";
}
// A JavaScript expression was specified. Execute it.
displayDebug("performCallback with "+instanced_function,20);
if (this.applet.jsOutcaller != null) {
this.applet.jsOutcaller.queue_callback(instanced_function); // do with a queued callback...
return null;
} else {
return_val = JSObject.getWindow(getApplet()).eval(instanced_function);
return return_val;
}
} catch (Exception ee) {
// Oops, no navigator. We are probably in debug mode, within
// eclipse for instance.
displayErr(ee);
}
}
return null;
}
/**
* @see wjhk.jupload2.policies.UploadPolicy#afterUpload(Exception, String)
*/
public void afterUpload(Exception e, @SuppressWarnings("unused")
String serverOutput) throws JUploadException {
// If there was no error, and afterUploadURL is defined, let's try to go
// to this URL.
String url = getAfterUploadURL();
setStatInProgress(false); // keep stats up to date
this.files_queued-=1;
if (this.files_queued<0)
this.files_queued = 0;
if (null == e) { // update stats..
this.successful_uploads++;
} else {
this.upload_errors++;
}
if (url != null) {
try {
if (url.toLowerCase().startsWith("javascript:")) {
// A JavaScript expression was specified. Execute it.
String expr = url.substring(11);
if (expr.contains("%msg%"))
// FIX given by Jon Gjengset, to be able to replace $
// characters.
expr = expr.replaceAll("%msg%", jsString(
getLastResponseMessage()).replaceAll("\\$",
"\\\\\\$"));
if (expr.contains("%body%"))
// FIX given by Jon Gjengset, to be able to replace $
// characters.
expr = expr.replaceAll("%body%", jsString(
getLastResponseBody()).replaceAll("\\$",
"\\\\\\$"));
if (expr.contains("%success%"))
expr = expr.replaceAll("%success%",
(null == e) ? "true" : "false");
JSObject.getWindow(getApplet()).eval(expr);
} else if (null == e) {
// This is not a javascript URL: we change the current page
// only if no error occured.
String target = getAfterUploadTarget();
if (getDebugLevel() >= 100) {
alertStr("No switch to getAfterUploadURL, because debug level is "
+ getDebugLevel() + " (>=100)");
} else {
// Let's change the current URL to edit names and
// comments, for the selected album. Ok, let's go and
// add names and comments to the newly updated pictures.
getApplet().getAppletContext().showDocument(
new URL(url),
(null == target) ? "_self" : target);
}
}
} catch (Exception ee) {
// Oops, no navigator. We are probably in debug mode, within
// eclipse for instance.
displayErr(ee);
}
}
}
/** @see UploadPolicy#alertStr(String) */
public void alertStr(String str) {
if (false) { JOptionPane.showMessageDialog(null, str, "Alert",
JOptionPane.WARNING_MESSAGE);
}
}
/** @see UploadPolicy#alert(String) */
public void alert(String key) {
alertStr(getString(key));
}
public void setStatFilesQueued(int nfiles) {
files_queued = nfiles;
}
public void setStatInProgress(boolean n_progress) {
in_progress = n_progress;
}
public void setStatSuccessfulUploads(int nfiles) {
successful_uploads = nfiles;
}
public void incrementStatSuccessfulUploads() {
successful_uploads+=1;
}
public int getStatSuccessfulUploads() {
return successful_uploads;
}
public void setStatUploadErrors(int nfiles) {
upload_errors = nfiles;
}
public void incrementStatUploadErrors() {
upload_errors+=1;
}
public void setStatUploadCancelleds(int nfiles) {
upload_cancelled = nfiles;
}
public void setStatQueueErrors(int nfiles) {
queue_errors = nfiles;
}
/**
* The DefaultUpload accepts all file types: we just return an instance of
* FileData, without any test.
*
* @see UploadPolicy#createFileData(File, File)
*/
public FileData createFileData(File file, File root)
throws JUploadExceptionStopAddingFiles {
this.files_queued+=1;
return new DefaultFileData(file, root, this);
}
/**
* Default implementation of
* {@link wjhk.jupload2.policies.UploadPolicy#createTopPanel(JButton, JButton, JButton, JUploadPanel)}.
* IT creates a JPanel, containing the three given JButton. It creates the
* same panel as the original JUpload.
*
* @see wjhk.jupload2.policies.UploadPolicy#createTopPanel(JButton, JButton,
* JButton, JUploadPanel)
*/
public JPanel createTopPanel(JButton browse, JButton remove,
JButton removeAll, @SuppressWarnings("unused")
JUploadPanel jUploadPanel) {
JPanel jPanel = new JPanel();
jPanel.setLayout(new GridLayout(1, 3, 10, 5));
jPanel.setBorder(BorderFactory.createEmptyBorder(5, 10, 5, 10));
jPanel.add(browse);
jPanel.add(removeAll);
jPanel.add(remove);
jUploadPanel.setBorder(BorderFactory
.createLineBorder(SystemColor.controlDkShadow));
return jPanel;
}
/**
* @see wjhk.jupload2.policies.UploadPolicy#createProgressPanel(javax.swing.JProgressBar,
* javax.swing.JButton, javax.swing.JButton, javax.swing.JPanel)
*/
public JPanel createProgressPanel(JProgressBar progressBar,
JButton uploadButton, JButton stopButton,
@SuppressWarnings("unused")
JPanel mainPanel) {
JPanel jPanel = new JPanel();
jPanel.setLayout(new BorderLayout(10, 0));
jPanel.setBorder(BorderFactory.createEmptyBorder(5, 10, 5, 10));
jPanel.add(uploadButton, BorderLayout.LINE_START);
if (null!= progressBar) jPanel.add(progressBar, BorderLayout.CENTER);
jPanel.add(stopButton, BorderLayout.LINE_END);
return jPanel;
}
/**
* @see wjhk.jupload2.policies.UploadPolicy#createStatusBar(javax.swing.JLabel,
* javax.swing.JPanel)
*/
public JPanel createStatusBar(JLabel content, @SuppressWarnings("unused")
JPanel mainPanel) {
if (this.showStatusbar) {
JPanel pstatus = new JPanel();
pstatus.setLayout(new BorderLayout());
pstatus.add(content, BorderLayout.CENTER);
pstatus.setBorder(new BevelBorder(BevelBorder.LOWERED));
return pstatus;
}
return null;
}
/**
* This methods allow the upload policy to override the default disposition
* of the components on the applet.
*
* @see UploadPolicy#addComponentsToJUploadPanel(JUploadPanel)
*/
public void addComponentsToJUploadPanel(JUploadPanel jUploadPanel) {
// Set the global layout of the panel.
jUploadPanel.setLayout(new BoxLayout(jUploadPanel, BoxLayout.Y_AXIS));
// The top panel is the upper part of the applet: above the file list.
// JPanel topPanel = new JPanel();
JPanel topPanel = createTopPanel(jUploadPanel.getBrowseButton(),
jUploadPanel.getRemoveButton(), jUploadPanel
.getRemoveAllButton(), jUploadPanel);
if (topPanel != null) {
jUploadPanel.add(topPanel);
topPanel.addMouseListener(jUploadPanel);
}
// Then, we add the file list.
jUploadPanel.add(jUploadPanel.getFilePanel().getDropComponent());
// The progress panel contains the progress bar, and the upload and stop
// buttons.
JPanel progressPanel = createProgressPanel(jUploadPanel
.getProgressBar(), jUploadPanel.getUploadButton(), jUploadPanel
.getStopButton(), jUploadPanel);
jUploadPanel.add(progressPanel);
jUploadPanel.addMouseListener(jUploadPanel);
// Now, we add the log window.
jUploadPanel.showOrHideLogWindow();
jUploadPanel.add(jUploadPanel.getJLogWindowPane());
// And, to finish with: the status bar.
JPanel p = createStatusBar(jUploadPanel.getStatusLabel(), jUploadPanel);
if (null != p) {
jUploadPanel.add(p);
p.addMouseListener(jUploadPanel);
}
}
/** @see UploadPolicy#displayErr(Exception) */
public void displayErr(Exception e) {
displayErr(e.getMessage(), e);
}
/** @see UploadPolicy#displayErr(String) */
public void displayErr(String err) {
displayErr(err, null);
}
/**
* If debug is off, the log window may not be visible. We switch the debug
* to on, to be sure that some information will be displayed to the user.
* <BR>
* If debug is -1, the log window remains hidden.
*
* @see wjhk.jupload2.policies.UploadPolicy#displayErr(java.lang.String,
* java.lang.Exception)
*/
public void displayErr(String errorText, Exception exception) {
// Default behavior: if debugLevel is 0, and an error occurs, we force
// the debug level to 1: this makes the log window become visible, if it
// was hidden.
if (getDebugLevel() == 0)
setDebugLevel(1);
String exceptionMsg = null;
String exceptionClassName = null;
String alertMsg = errorText;
String logMsg = errorText;
Exception justToPrintAStackTrace = exception;
// First, we construct the exception class name.
if (exception == null) {
justToPrintAStackTrace = new Exception();
exceptionClassName = "";
} else if (exception instanceof JUploadException) {
exceptionClassName = "["
+ ((JUploadException) exception).getClassNameAndClause()
+ "] ";
} else {
exceptionClassName = "[" + exception.getClass().getName() + "] ";
}
// Then, the message body can be completed by the exception message.
if (exception != null) {
// Ok, we have an exception.
if (exception.getCause() != null) {
exceptionMsg = exception.getCause().getMessage();
} else {
exceptionMsg = exception.getMessage();
}
if (errorText == null || errorText.equals("")) {
alertMsg = "Unknown error (" + exceptionMsg + ")";
}
logMsg = exceptionMsg + " (" + errorText + ")";
}
// Display the message to the user.
if (getDebugLevel() > 1) {
// Debug has been put on, by the user.
alertStr(exceptionClassName + logMsg);
} else {
// Debug level may be set to 1, when an error occurs, even if debug
// was not put on by the user.
alertStr(alertMsg);
}
// Add the message to the log window
displayMsg("[ERROR] ", exceptionClassName + logMsg);
// Let's display the stack trace, if relevant.
if (exception != null) {
ByteArrayOutputStream bs = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(bs);
justToPrintAStackTrace.printStackTrace(ps);
ps.close();
displayMsg("", bs.toString());
}
}
/**
* @see UploadPolicy#displayInfo(String)
*/
public void displayInfo(String info) {
displayMsg("[INFO] ", info);
}
/**
* @see UploadPolicy#displayWarn(String)
*/
public void displayWarn(String warn) {
displayMsg("[WARN] ", warn);
}
/**
* @see UploadPolicy#displayDebug(String, int)
*/
public void displayDebug(String debug, int minDebugLevel) {
final String tag = "[DEBUG] ";
if (this.debugLevel >= minDebugLevel) {
// displayMsg will add the message to the debugStrignBuffer.
displayMsg(tag, debug);
} else {
// Let's store all text in the debug BufferString
addMsgToDebugLog(timestamp(tag, debug));
}
}
/** @see UploadPolicy#getString(String) */
public String getString(String key) {
String ret = this.resourceBundle.getString(key);
return ret;
}
/**
* @see UploadPolicy#getUploadFilename(FileData, int)
*/
public String getUploadFilename(FileData fileData,
@SuppressWarnings("unused")
int index) throws JUploadException {
if (this.filenameEncoding == null || this.filenameEncoding.equals(""))
return fileData.getFileName();
try {
return URLEncoder.encode(fileData.getFileName(),
this.filenameEncoding);
} catch (UnsupportedEncodingException e) {
throw new JUploadException(e);
}
}
/** @see UploadPolicy#getUploadName(FileData, int) */
public String getUploadName(@SuppressWarnings("unused")
FileData fileData, int index) {
// This is the original way of working of JUpload.
// It can easily be modified, by using another UploadPolicy.
if (this.nbFilesPerRequest == 1)
return "uploaded_data";
return "File" + index;
}
/** @see wjhk.jupload2.policies.UploadPolicy#isUploadReady() */
public boolean isUploadReady() {
// Default : nothing to do before upload, so we're ready.
return true;
}
/** @see UploadPolicy#onAppendHeader(ByteArrayEncoder) */
public ByteArrayEncoder onAppendHeader(ByteArrayEncoder bae)
throws JUploadIOException {
Iterator<String> it = this.headers.iterator();
String header;
while (it.hasNext()) {
header = it.next();
displayDebug(header, 90);
bae.append(header).append("\r\n");
}
return bae;
}// appendHeader
/**
* Default implementation of the
* {@link wjhk.jupload2.policies.UploadPolicy#onFileSelected(wjhk.jupload2.filedata.FileData)}.
* Nothing's done.
*/
public void onFileSelected(@SuppressWarnings("unused")
FileData fileData) {
// Default implementation : no action
}
/**
* Default implementation of the
* {@link wjhk.jupload2.policies.UploadPolicy#onFileDoubleClicked(FileData)}.
* Nothing's done.
*/
public void onFileDoubleClicked(FileData fileData) {
// Default implementation : no action
}
/** @see UploadPolicy#sendDebugInformation(String) */
public void sendDebugInformation(String description) {
try {
ByteArrayEncoder request = new ByteArrayEncoderHTTP(this, null);
if (null != this.urlToSendErrorTo) {
if (JOptionPane.showConfirmDialog(null,
getString("questionSendMailOnError"),
getString("Confirm"), JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) {
displayDebug("Within response == true", 60);
// The message is written in english, as it is not sure that
// the
// webmaster speaks the same language as the current user.
String query = null;
String action = null;
Socket sock = null;
DataOutputStream dataout = null;
BufferedReader datain = null;
StringBuffer sbHttpResponseBody = null;
String line;
// During debug output, we need to make sure that the debug
// log is not changed, so we set debugOk to false
// temporarily. -> Everything goes to stdout.
boolean localDebugOk = this.debugOk;
this.debugOk = false;
try {
this.debugOut.flush();
// First, calculate the size of the strings we will
// send.
BufferedReader debugIn = new BufferedReader(
new FileReader(this.debugFile));
int contentLength = 0;
while ((line = debugIn.readLine()) != null) {
contentLength += URLEncoder.encode(line + "\n",
request.getEncoding()).length();
}
debugIn.close();
debugIn = new BufferedReader(new FileReader(
this.debugFile));
query = "description="
+ URLEncoder.encode(description, request
.getEncoding())
+ "&log="
+ URLEncoder
.encode(
"\n\nAn error occured during upload, in JUpload\n"
+ "All debug information is available below\n\n\n\n",
request.getEncoding());
contentLength += query.length();
URL url = new URL(this.urlToSendErrorTo);
request
.append("POST ")
.append(url.toString())
.append(" ")
.append(getServerProtocol())
.append("\r\n")
.append("Host: ")
.append(url.getHost())
.append("\r\n")
.append("Accept: */*\r\n")
.append(
"Content-type: application/x-www-form-urlencoded\r\n")
.append("Connection: close\r\n").append(
"Content-length: ").append(
String.valueOf(contentLength)).append(
"\r\n");
// Get specific headers for this upload.
onAppendHeader(request);
// Blank line (end of header)
request.append("\r\n").append(query);
sock = new HttpConnect(this).Connect(url);
dataout = new DataOutputStream(
new BufferedOutputStream(sock.getOutputStream()));
datain = new BufferedReader(new InputStreamReader(sock
.getInputStream()));
// Send http request to server
action = "send bytes (1)";
dataout.writeBytes(request.toString());
dataout.writeBytes(query);
while ((line = debugIn.readLine()) != null) {
dataout.writeBytes(URLEncoder.encode(line + "\n",
request.getEncoding()));
}
debugIn.close();
// We are done with the debug log, so re-enable it.
this.debugOk = localDebugOk;
action = "flush";
dataout.flush();
action = "wait for server answer";
String strUploadSuccess = getStringUploadSuccess();
boolean uploadSuccess = false;
boolean readingHttpBody = false;
sbHttpResponseBody = new StringBuffer();
// Now, we wait for the full answer (which should mean
// that
// the uploaded message has been treated on the server).
while ((line = datain.readLine()) != null) {
// Is this upload a success ?
action = "test success";
if (line.matches(strUploadSuccess)) {
uploadSuccess = true;
}
// Store the http body
if (readingHttpBody) {
action = "sbHttpResponseBody";
sbHttpResponseBody.append(line).append("\n");
}
if (line.length() == 0) {
// Next lines will be the http body (or perhaps
// we
// already are in the body, but it's Ok anyway)
action = "readingHttpBody";
readingHttpBody = true;
}
}
// Is our upload a success ?
if (!uploadSuccess) {
throw new JUploadExceptionUploadFailed(
getString("errHttpResponse"));
}
} catch (Exception e) {
this.debugOk = localDebugOk;
displayErr(getString("errDuringLogManagement") + " ("
+ action + ")", e);
} finally {
this.debugOk = localDebugOk;
try {
dataout.close();
} catch (Exception e) {
displayErr(getString("errDuringLogManagement")
+ " (dataout.close)", e);
}
dataout = null;
try {
// Throws java.io.IOException
datain.close();
} catch (Exception e) {
// Nothing to do.
}
datain = null;
try {
// Throws java.io.IOException
sock.close();
} catch (Exception e) {
displayErr(getString("errDuringLogManagement")
+ " (sock.close)", e);
}
sock = null;
displayDebug("Sent to server: " + request.getString(),
100);
displayDebug("Body received: "
+ sbHttpResponseBody.toString(), 100);
}
}
}
} catch (JUploadIOException e) {
displayErr("Could not send debug information", e);
}
}// sendDebugInformation
/**
* This method manages all applet parameters. It allows javascript to update
* their value, for instance after the user chooses a value in a list ...
*
* @throws JUploadException
* @see wjhk.jupload2.policies.UploadPolicy#setProperty(java.lang.String,
* java.lang.String)
*/
public void setProperty(String prop, String value) throws JUploadException {
displayDebug("[DefaultUploadPolicy] Call from setProperty: " + prop
+ " => " + value, 60);
if (prop.equals(PROP_CALLBACK_FILE_UPLOAD_LOADED) ||
prop.equals(PROP_CALLBACK_FILE_DIALOG_START) ||
prop.equals(PROP_CALLBACK_FILE_QUEUED) ||
prop.equals(PROP_CALLBACK_FILE_QUEUE_ERROR) ||
prop.equals(PROP_CALLBACK_FILE_DIALOG_COMPLETE) ||
prop.equals(PROP_CALLBACK_FILE_UPLOAD_START) ||
prop.equals(PROP_CALLBACK_FILE_UPLOAD_PROGRESS) ||
prop.equals(PROP_CALLBACK_FILE_UPLOAD_SUCCESS) ||
prop.equals(PROP_CALLBACK_FILE_UPLOAD_COMPLETE)) {
//setCallBackString(prop,value);
}
else if (prop.equals(PROP_AFTER_UPLOAD_URL)) {
setAfterUploadURL(value);
} else if (prop.equals(PROP_ALLOW_HTTP_PERSISTENT)) {
setAllowHttpPersistent(Boolean.parseBoolean(value));
} else if (prop.equals(PROP_ALLOWED_FILE_EXTENSIONS)) {
setAllowedFileExtensions(value);
} else if (prop.equals(PROP_DEBUG_LEVEL)) {
setDebugLevel(UploadPolicyFactory.parseInt(value, this.debugLevel,
this));
} else if (prop.equals(PROP_FILE_CHOOSER_ICON_FROM_FILE_CONTENT)) {
setFileChooserIconFromFileContent(UploadPolicyFactory.parseInt(
value, getFileChooserIconFromFileContent(), this));
} else if (prop.equals(PROP_FILE_CHOOSER_ICON_SIZE)) {
setFileChooserIconSize(UploadPolicyFactory.parseInt(value,
getFileChooserIconSize(), this));
} else if (prop.equals(PROP_LANG)) {
setLang(value);
} else if (prop.equals(PROP_FILENAME_ENCODING)) {
setFilenameEncoding(value);
} else if (prop.equals(PROP_LOOK_AND_FEEL)) {
setLookAndFeel(value);
} else if (prop.equals(PROP_MAX_CHUNK_SIZE)) {
setMaxChunkSize(UploadPolicyFactory.parseLong(value,
this.maxChunkSize, this));
} else if (prop.equals(PROP_MAX_FILE_SIZE)) {
setMaxFileSize(UploadPolicyFactory.parseLong(value,
this.maxFileSize, this));
} else if (prop.equals(PROP_NB_FILES_PER_REQUEST)) {
setNbFilesPerRequest(UploadPolicyFactory.parseInt(value,
this.nbFilesPerRequest, this));
} else if (prop.equals(PROP_ONE_FILE_PER_START)) {
setOneFilePerStart(Boolean.parseBoolean(value));
} else if (prop.equals(PROP_POST_URL)) {
setPostURL(value);
} else if (prop.equals(PROP_SERVER_PROTOCOL)) {
setServerProtocol(value);
} else if (prop.equals(PROP_STRING_UPLOAD_SUCCESS)) {
setStringUploadSuccess(value);
} else if (prop.equals(PROP_SSL_VERIFY_CERT)) {
setSslVerifyCert(value);
} else if (prop.equals(PROP_URL_TO_SEND_ERROR_TO)) {
setUrlToSendErrorTo(value);
} else {
displayWarn("Unknown applet parameter: " + prop
+ " (in DefaultUploadPolicy.setProperty)");
}
}
/**
* This method displays the applet parameter list, according to the current
* debugLevel. It is called by the {@link #setDebugLevel(int)} method. It
* should be override by any subclasses, that should display its own
* parameters, then call <I>super.displayParameterStatus()</I>.
*
* @see UploadPolicy#displayParameterStatus()
*/
public void displayParameterStatus() {
displayDebug(
"=======================================================================",
20);
displayDebug("======= Parameters managed by DefaultUploadPolicy", 20);
// /////////////////////////////////////////////////////////////////////////////
// Let's display some information to the user, about the received
// parameters.
displayInfo("JUpload applet *modified*, version " + JUploadApplet.VERSION
+ " (compiled: " + JUploadApplet.BUILD_DATE
+ "), available at http://jupload.sourceforge.net/");
displayDebug("Java version: " + System.getProperty("java.version"), 20);
displayDebug("Cookie: " + this.cookie, 20);
displayDebug("userAgent: " + this.userAgent, 20);
displayDebug("List of all applet parameters:", 20);
displayDebug(" language: "
+ this.resourceBundle.getLocale().getLanguage(), 20);
displayDebug(" country: "
+ this.resourceBundle.getLocale().getCountry(), 20);
displayDebug(PROP_AFTER_UPLOAD_URL + ": " + getAfterUploadURL(), 20);
displayDebug(PROP_ALLOW_HTTP_PERSISTENT + ": "
+ getAllowHttpPersistent(), 20);
displayDebug(PROP_ALLOWED_FILE_EXTENSIONS + ": "
+ getAllowedFileExtensions(), 20);
displayDebug(PROP_IGNORE_DIRECTORY_REGEX + ": "
+ getIgnoreDirectoryRegex(), 20);
displayDebug(PROP_IGNORE_FILE_REGEX + ": "
+ getIgnoreFileRegex(), 20);
displayDebug(PROP_DEBUG_LEVEL + ": " + this.debugLevel
+ " (debugfile: " + debugFile.getAbsolutePath() + ")", 1);
displayDebug(PROP_FILE_CHOOSER_ICON_FROM_FILE_CONTENT + ": "
+ getFileChooserIconFromFileContent(), 20);
displayDebug(PROP_FILE_CHOOSER_ICON_SIZE + ": "
+ getFileChooserIconSize(), 20);
displayDebug(PROP_CALLBACK_FILE_UPLOAD_LOADED + ": "
+ getCallBackString(PROP_CALLBACK_FILE_UPLOAD_LOADED), 20);
displayDebug(PROP_CALLBACK_FILE_UPLOAD_LOADED + ": "
+ getCallBackString(PROP_CALLBACK_FILE_UPLOAD_LOADED), 20);
displayDebug(PROP_FILENAME_ENCODING + ": " + getFilenameEncoding(), 20);
displayDebug("lang: " + this.lang, 20);
displayDebug(PROP_MAX_CHUNK_SIZE + ": " + getMaxChunkSize(), 20);
if (this.maxFileSize == Long.MAX_VALUE) {
// If the maxFileSize was not given, we display its value only
// in debug mode.
displayDebug(PROP_MAX_FILE_SIZE + ": " + getMaxFileSize(), 20);
} else {
// If the maxFileSize was given, we always inform the user.
displayInfo(PROP_MAX_FILE_SIZE + ": " + getMaxFileSize());
}
displayDebug(PROP_NB_FILES_PER_REQUEST + ": " + getNbFilesPerRequest(),
20);
displayDebug(PROP_ONE_FILE_PER_START+ ": " + getOneFilePerStart(),
20);
displayDebug(PROP_POST_URL + ": " + this.postURL, 20);
displayDebug(PROP_SERVER_PROTOCOL + ": " + getServerProtocol(), 20);
displayDebug(PROP_SHOW_LOGWINDOW + ": " + getShowLogWindow(), 20);
displayDebug(PROP_SHOW_STATUSBAR + ": " + showStatusbar, 20);
displayDebug(PROP_SPECIFIC_HEADERS + ": " + getSpecificHeaders(), 20);
displayDebug(PROP_STRING_UPLOAD_SUCCESS + ": "
+ getStringUploadSuccess(), 20);
displayDebug(PROP_STRING_UPLOAD_ERROR + ": " + getStringUploadError(),
20);
displayDebug(PROP_URL_TO_SEND_ERROR_TO + ": " + getUrlToSendErrorTo(),
20);
displayDebug("", 20);
}
private final String normalizeURL(String url) throws JUploadException {
if (null == url || url.length() == 0)
return getApplet().getDocumentBase().toString();
URI uri = null;
try {
uri = new URI(url);
if (null == uri.getScheme())
uri = getApplet().getDocumentBase().toURI().resolve(url);
if (!uri.getScheme().equals("http")
&& !uri.getScheme().equals("https")
&& !uri.getScheme().equals("ftp")) {
throw new JUploadException("URI scheme " + uri.getScheme()
+ " not supported.");
}
} catch (URISyntaxException e) {
throw new JUploadException(e);
}
return uri.toString();
}
// //////////////////////////////////////////////////////////////////////////////////////////////
// /////////////////// getters / setters
// ///////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////////////////////////////////
/** @see UploadPolicy#getAfterUploadURL() */
public String getAfterUploadURL() {
return this.afterUploadURL;
}
/**
* Set the {@link #afterUploadURL}
*
* @param afterUploadURL The URL to use.
* @throws JUploadException
*/
protected void setAfterUploadURL(String afterUploadURL)
throws JUploadException {
if (null == afterUploadURL)
return;
if (afterUploadURL.toLowerCase().startsWith("javascript:")) {
this.afterUploadURL = afterUploadURL;
} else
this.afterUploadURL = normalizeURL(afterUploadURL);
}
private Hashtable s_callbacks = new Hashtable();
protected void setCallBackString(String property_name, String new_value) {
if (null == new_value)
return;
displayInfo("Callback [" + property_name + "] set to " + new_value);
s_callbacks.put(property_name, new_value);
}
public String getCallBackString(String property_name) {
// will return null if the propertyname is not there...
return (String) s_callbacks.get(property_name);
}
public String getJavascriptInstanceName() {
return this.applet.getParameter("NAME");
}
public void setFilenamePrefix(String prefix){
this.filenamePrefix = prefix;
}
public String getFilenamePrefix() {
return this.filenamePrefix;
}
public void setFilenameSuppressSuffix(boolean suppress) {
this.suppress = suppress;
}
public boolean getFilenameSuppressSuffix() {
return this.suppress;
}
public void setFilenameFormvarName(String formvar){
this.formvarPrefix = formvar;
}
public String getFilenameFormvarName() {
return this.formvarPrefix;
}
/**
* @see wjhk.jupload2.policies.UploadPolicy#getAllowHttpPersistent()
*/
public boolean getAllowHttpPersistent() {
return this.allowHttpPersistent;
}
protected void setIgnoreDirectoryRegex(String ignoreDirectoryRegex) {
this.ignoredDirectoryRegex=ignoreDirectoryRegex;
}
protected String getIgnoreDirectoryRegex() {
return this.ignoredDirectoryRegex;
}
protected void setIgnoreFileRegex(String ignoreFileRegex) {
this.ignoredFileRegex=ignoreFileRegex;
}
protected String getIgnoreFileRegex() {
return this.ignoredFileRegex;
}
/** @see UploadPolicy#getAllowedFileExtensions() */
public String getAllowedFileExtensions() {
return this.allowedFileExtensions;
}
/** @param allowedFileExtensions the allowedFileExtensions to set */
protected void setAllowedFileExtensions(String allowedFileExtensions) {
if (allowedFileExtensions == null || allowedFileExtensions.equals("")) {
this.allowedFileExtensions = null;
} else {
this.allowedFileExtensions = (allowedFileExtensions.startsWith("/") ? ""
: "/")
+ allowedFileExtensions.toLowerCase()
+ (allowedFileExtensions.endsWith("/") ? "" : "/");
}
}
protected void setAllowHttpPersistent(boolean value) {
this.allowHttpPersistent = value;
}
/** @see UploadPolicy#getApplet() */
public JUploadApplet getApplet() {
return this.applet;
}
/** @see UploadPolicy#getDateFormat() */
public String getDateFormat() {
return UploadPolicy.DEFAULT_DATE_FORMAT;
}
/** @see UploadPolicy#getDebugLevel() */
public int getDebugLevel() {
return this.debugLevel;
}
/** @see UploadPolicy#setDebugLevel(int) */
public void setDebugLevel(int debugLevel) {
setDebugLevel(debugLevel, true);
}
/**
* Set the debug level.
*
* @param debugLevel The new debuglevel.
* @param displayAppletParameterList Flag. If set to true, the applet's
* parameters are shown.
*/
public void setDebugLevel(int debugLevel, boolean displayAppletParameterList) {
// If the debugLevel was previously set, we inform the user of this
// change.
if (this.debugLevel >= 0) {
displayInfo("Debug level set to " + debugLevel);
displayInfo("Current debug output file: "
+ debugFile.getAbsolutePath());
}
this.debugLevel = debugLevel;
// The log window may become visible or hidden, depending on the current
// debug level.
if (getApplet().getUploadPanel() != null) {
getApplet().getUploadPanel().showOrHideLogWindow();
// Let's display the current applet parameters.
if (displayAppletParameterList) {
displayParameterStatus();
}
}
}
/**
* Getter for fileChooserIconFromFileContent.
*
* @return Current value for fileChooserIconFromFileContent
* @see UploadPolicy#PROP_FILE_CHOOSER_ICON_FROM_FILE_CONTENT
*/
public int getFileChooserIconFromFileContent() {
return fileChooserIconFromFileContent;
}
/**
* Setter for fileChooserIconFromFileContent. Current allowed values are:
* -1, 0, 1. Default value is 0.
*
* @param fileChooserIconFromFileContent Value to be set. If the value is
* not allowed (not -1, 0 or 1), the current value is unchangeed.
* @see UploadPolicy#PROP_FILE_CHOOSER_ICON_FROM_FILE_CONTENT
*/
public void setFileChooserIconFromFileContent(
int fileChooserIconFromFileContent) {
this.fileChooserIconFromFileContent = fileChooserIconFromFileContent;
}
/**
* Getter for fileChooserIconSize.
*
* @return Current value for fileChooserIconSize
* @see UploadPolicy#PROP_FILE_CHOOSER_ICON_SIZE
*/
public int getFileChooserIconSize() {
return this.fileChooserIconSize;
}
/**
* Setter for fileChooserIconSize.
*
* @param fileChooserIconSize Value to be set.
* @see UploadPolicy#PROP_FILE_CHOOSER_ICON_SIZE
*/
public void setFileChooserIconSize(int fileChooserIconSize) {
this.fileChooserIconSize = fileChooserIconSize;
}
/** @see wjhk.jupload2.policies.UploadPolicy#setLang(String) */
public void setLang(String lang) {
Locale locale;
this.lang = lang;
if (lang == null) {
displayInfo("lang = null, taking default language");
locale = Locale.getDefault();
} else {
// If we have a 5 characters lang string, then it should look like
// ll_CC, where ll is the language code
// and CC is the Country code.
if (lang.length() == 5
&& (lang.substring(2, 3).equals("_") || lang
.substring(2, 3).equals("-"))) {
String language = lang.substring(0, 2);
String country = lang.substring(3, 5);
displayDebug("setLang - language read: " + language, 50);
displayDebug("setLang - country read: " + country, 50);
locale = new Locale(language, country.toUpperCase());
} else {
locale = new Locale(lang);
displayDebug("setLang - language read (no country): " + lang,
50);
}
}
/*
* Patch given by Patrick
*
* Use of a specific classloader. The standard ResourceBundle checks
* first for a class that has the name of the resource bundle. Since
* there is no such class in the jar file, the AppletClassLoader makes a
* http request to the server, which will end with a 404 since there is
* no such class either. To avoid this unneccessary lookup we use a
* clasloader that throws directly a ClassNotFoundException. After
* looking for a class (which is unsuccessful) ResourceBundle looks
* finally for a properties file. Herefore we delegate that lookup to
* the original classloader since this is in the jar file.
*/
this.resourceBundle = ResourceBundle.getBundle(
"wjhk.jupload2.lang.lang", locale,
// Special classloader, see description above
new ClassLoader(this.getClass().getClassLoader()) {
/** {@inheritDoc} */
@Override
public Class<?> loadClass(String name)
throws ClassNotFoundException {
throw new ClassNotFoundException();
}
/** {@inheritDoc} */
@Override
public InputStream getResourceAsStream(String name) {
return this.getClass().getClassLoader()
.getResourceAsStream(name);
}
});
}
/*
* protected void setLang2(String lang) { Locale locale; this.lang = lang;
* if (lang == null) { displayInfo("lang = null, taking default language");
* locale = Locale.getDefault(); } else { // If we have a 5 characters lang
* string, then it should look like // ll_CC, where ll is the language code //
* and CC is the Contry code. if (lang.length() == 5 && (lang.substring(2,
* 3).equals("_") || lang .substring(2, 3).equals("-"))) { String language =
* lang.substring(0, 2); String country = lang.substring(3, 5);
* displayDebug("setLang - language read: " + language, 50);
* displayDebug("setLang - country read: " + country, 50); locale = new
* Locale(language, country.toUpperCase()); } else { locale = new
* Locale(lang); } } this.resourceBundle = ResourceBundle.getBundle(
* "wjhk.jupload2.lang.lang", locale, // our special classloader, see
* description above new ClassLoader(this.getClass().getClassLoader()) { /**
* {@inheritDoc} * @Override public Class<?> loadClass(String name) throws
* ClassNotFoundException { throw new ClassNotFoundException(); }
*
* /** {@inheritDoc} * @Override public InputStream
* getResourceAsStream(String name) { return
* this.getClass().getClassLoader() .getResourceAsStream(name); } }); }
*/
protected String getLookAndFeel() {
return this.lookAndFeel;
}
/** @param lookAndFeel the lookAndFeel to set */
protected void setLookAndFeel(String lookAndFeel) {
this.lookAndFeel = lookAndFeel;
if (lookAndFeel != null && !lookAndFeel.equals("")
&& !lookAndFeel.equals("java")) {
// We try to call the UIManager.setLookAndFeel() method. We catch
// all possible exceptions, to prevent
// that the applet is blocked.
try {
if (!lookAndFeel.equals("system")) {
// Correction given by Fritz. Thanks to him.
UIManager.setLookAndFeel(lookAndFeel);
} else {
UIManager.setLookAndFeel(UIManager
.getSystemLookAndFeelClassName());
}
} catch (Exception e) {
displayErr(e);
}
}
}
/** @see wjhk.jupload2.policies.UploadPolicy#getMaxChunkSize() */
public long getMaxChunkSize() {
return this.maxChunkSize;
}
/** @param maxChunkSize the maxChunkSize to set */
protected void setMaxChunkSize(long maxChunkSize) {
if (maxChunkSize <= 0) {
displayDebug(
"maxChunkSize<=0 which is invalid. Switched to the default value (Long.MAX_VALUE)",
1);
maxChunkSize = Long.MAX_VALUE;
}
this.maxChunkSize = maxChunkSize;
}
/** @see wjhk.jupload2.policies.UploadPolicy#getMaxFileSize() */
public long getMaxFileSize() {
return this.maxFileSize;
}
/** @param maxFileSize the maxFileSize to set */
protected void setMaxFileSize(long maxFileSize) {
if (maxFileSize < 0) {
displayDebug(
"maxFileSize<0 which is invalid. Switched to the default value (Long.MAX_VALUE)",
1);
maxFileSize = Long.MAX_VALUE;
}
this.maxFileSize = maxFileSize;
}
/** @see wjhk.jupload2.policies.UploadPolicy#getNbFilesPerRequest() */
public int getNbFilesPerRequest() {
return this.nbFilesPerRequest;
}
/** @see wjhk.jupload2.policies.UploadPolicy#getOneFilePerStart() */
public boolean getOneFilePerStart() {
return this.oneFilePerStart;
}
/** @param nbFilesPerRequest the nbFilesPerRequest to set */
protected void setNbFilesPerRequest(int nbFilesPerRequest) {
if (nbFilesPerRequest < 0) {
displayDebug(
"nbFilesPerRequest<0 which is invalid. Switched to the default value (Integer.MAX_VALUE)",
1);
nbFilesPerRequest = Integer.MAX_VALUE;
}
this.nbFilesPerRequest = nbFilesPerRequest;
}
/** @param oneFilePerStart set */
protected void setOneFilePerStart(boolean oneFilePerStart) {
this.oneFilePerStart = oneFilePerStart;
}
/** @see UploadPolicy#getFilenameEncoding() */
public String getFilenameEncoding() {
return this.filenameEncoding;
}
/** @param filenameEncoding the filenameEncoding to set */
protected void setFilenameEncoding(String filenameEncoding) {
this.filenameEncoding = filenameEncoding;
}
/** @see wjhk.jupload2.policies.UploadPolicy#getPostURL() */
public String getPostURL() {
return this.postURL;
}
/**
* @throws JUploadException
* @see wjhk.jupload2.policies.UploadPolicy#setPostURL(String)
*/
public void setPostURL(String postURL) throws JUploadException {
// Be more forgiving about postURL:
// - If none is specified, use the original DocumentBase of the applet.
// - If a non-absolute URI (an URI without protocol and server) is
// specified,
// prefix it with "http://servername"
// - If a relative URI is specified, prefix it with the DocumentBase's
// parent
this.postURL = normalizeURL(postURL);
}
/** @see wjhk.jupload2.policies.UploadPolicy#getServerProtocol() */
public String getServerProtocol() {
return this.serverProtocol;
}
/**
* @param value the serverProtocol to set
* @throws JUploadException
*/
protected void setServerProtocol(String value) throws JUploadException {
if (null == value || value.equals("")) {
if (null == this.postURL || this.postURL.equals("")) {
displayErr("postURL not set");
value = UploadPolicy.DEFAULT_SERVER_PROTOCOL;
} else if (this.postURL.substring(0, 3).equals("ftp")) {
value = "ftp";
} else {
try {
value = new HttpConnect(this).getProtocol();
} catch (Exception e) {
// If we throw an error here, we prevent the applet to
// start. So we just log it, and try the default protocol
displayErr("Unable to access to the postURL: '"
+ getPostURL() + "'", e);
// Let's try with default value.
value = UploadPolicy.DEFAULT_SERVER_PROTOCOL;
}
}
} else if (value.startsWith("HTTP")) {
// In HTTP mode, we always give a try to HTTPConnect, to check if
// the page has moved, and other stuff.
// But we keep the given parameter.
try {
new HttpConnect(this).getProtocol();
} catch (Exception e) {
// If we throw an error here, we prevent the applet to
// start. So we just log it, and try the default protocol
displayErr("Unable to access to the postURL: '" + getPostURL()
+ "'", e);
}
}
this.serverProtocol = value;
}
/** @see wjhk.jupload2.policies.UploadPolicy#getShowLogWindow() */
public boolean getShowLogWindow() {
return this.showLogWindow;
}
/** @param showLogWindow the new showLogWindow value */
protected void setShowLogWindow(boolean showLogWindow) {
this.showLogWindow = showLogWindow;
// The log window may become visible or hidden, depending on this
// parameter.
if (getApplet().getUploadPanel() != null) {
getApplet().getUploadPanel().showOrHideLogWindow();
}
}
/** @see wjhk.jupload2.policies.UploadPolicy#getSpecificHeaders() */
public String getSpecificHeaders() {
return specificHeaders;
}
/**
* Set all specific headers defined in the specificHeaders applet parameter.
* This string is splitted, so that each header is added to the headers
* Vector. These headers are added to the headers list during applet
* initialization. There is currently no automatic way to remove the headers
* coming from specificHeaders, after initialization.
*
* @param specificHeaders
*/
protected void setSpecificHeaders(String specificHeaders) {
this.specificHeaders = specificHeaders;
if (specificHeaders != null) {
// Let's add each header in specificHeaders to the headers list. In
// specificHeaders, each header is separated by the \n string (two
// characters: \ then n, not the \n character).
// The regexp to find the \n string (not the \n character) is: \\n
// We then double each \ character:
String[] headerArray = specificHeaders.split("\\\\n");
for (int x = 0; x < headerArray.length; x++) {
addHeader(headerArray[x]);
}
}
}
/**
* @see wjhk.jupload2.policies.UploadPolicy#getSslVerifyCert()
*/
public int getSslVerifyCert() {
return this.sslVerifyCert;
}
protected void setSslVerifyCert(String mode) throws JUploadException {
int val = -1;
if (mode.toLowerCase().equals("none"))
val = InteractiveTrustManager.NONE;
if (mode.toLowerCase().equals("server"))
val = InteractiveTrustManager.SERVER;
if (mode.toLowerCase().equals("client"))
val = InteractiveTrustManager.CLIENT;
if (mode.toLowerCase().equals("strict"))
val = InteractiveTrustManager.STRICT;
if (val == -1)
throw new JUploadException("Invalid parameter sslVerifyCert ("
+ mode + ")");
this.sslVerifyCert = val;
}
/** @param show the new showStatusbar value */
protected void setShowStatusbar(boolean show) {
this.showStatusbar = show;
}
/** @see wjhk.jupload2.policies.UploadPolicy#getStringUploadError() */
public String getStringUploadError() {
return this.stringUploadError;
}
/** @see wjhk.jupload2.policies.UploadPolicy#getStringUploadSuccess() */
public String getStringUploadSuccess() {
return this.stringUploadSuccess;
}
/**
* @param stringUploadError the stringUploadError to set
* @throws JUploadException
*/
protected void setStringUploadError(String stringUploadError)
throws JUploadException {
this.stringUploadError = stringUploadError;
if (stringUploadError != null) {
try {
this.patternError = Pattern.compile(stringUploadError);
} catch (PatternSyntaxException e) {
throw new JUploadException(
"Invalid regex in parameter stringUploadError");
}
}
}
/**
* @param stringUploadSuccess the stringUploadSuccess to set
* @throws JUploadException
*/
protected void setStringUploadSuccess(String stringUploadSuccess)
throws JUploadException {
this.stringUploadSuccess = stringUploadSuccess;
if (stringUploadSuccess != null) {
try {
this.patternSuccess = Pattern.compile(stringUploadSuccess);
} catch (PatternSyntaxException e) {
throw new JUploadException(
"Invalid regex in parameter stringUploadSuccess");
}
}
}
/** @see wjhk.jupload2.policies.UploadPolicy#getUrlToSendErrorTo() */
public String getUrlToSendErrorTo() {
return this.urlToSendErrorTo;
}
/** {@inheritDoc} */
public void setUrlToSendErrorTo(String urlToSendErrorTo)
throws JUploadException {
if (null == urlToSendErrorTo)
return;
String tmp = normalizeURL(urlToSendErrorTo);
if (tmp.startsWith("ftp://")) {
throw new JUploadException(
"urlToSendErrorTo: ftp scheme not supported.");
}
this.urlToSendErrorTo = tmp;
}
/** @see wjhk.jupload2.policies.UploadPolicy#getFormdata() */
public String getFormdata() {
return this.formData;
}
/** @see wjhk.jupload2.policies.UploadPolicy#getAfterUploadTarget() */
public String getAfterUploadTarget() {
return this.afterUploadTarget;
}
// //////////////////////////////////////////////////////////////////////////////////////////////
// /////////////////// Internal methods
// //////////////////////////////////////////////////////////////////////////////////////////////
/**
* @see UploadPolicy#setWaitCursor()
*/
public Cursor setWaitCursor() {
Cursor previousCursor = getApplet().getCursor();
getApplet().setCursor(new Cursor(Cursor.WAIT_CURSOR));
return previousCursor;
}
/**
* @see UploadPolicy#setCursor(Cursor)
*/
public void setCursor(Cursor cursor) {
getApplet().setCursor(cursor);
}
/**
* Delete the current log. (called upon applet termination)
*/
public void deleteLog() {
try {
if (null != this.debugOut) {
this.debugOut.close();
this.debugOut = null;
}
if (null != this.debugFile) {
this.debugFile.delete();
this.debugFile = null;
}
} catch (Exception e) {
// nothing to do
}
}
/**
* This methods allows the applet to store all messages (debug, warning,
* info, errors...) into a StringBuffer. If any problem occurs, the whole
* output (displayed or not by the displayDebug, for instance) can be stored
* in a file, or sent to the webmaster. This can help to identify and
* correct problems that can occurs on the various computer configurations.
*
* @param msg
*/
protected synchronized void addMsgToDebugLog(String msg) {
// If uploading lots of chunks, the buffer gets too large, resulting in
// a OutOfMemoryError on the heap so we now use a temporary file for the
// debug log.
if (this.debugOk) {
try {
if (null == this.debugOut) {
this.getApplet().registerUnload(this, "deleteLog");
this.debugFile = File
.createTempFile("jupload_", "_log.txt");
this.debugOut = new PrintStream(new FileOutputStream(
this.debugFile));
}
boolean endsLF = msg.endsWith("\n");
msg = msg.replaceAll("\n", CRLF);
if (endsLF) {
this.debugOut.print(msg);
} else {
this.debugOut.println(msg);
}
} catch (IOException e) {
this.debugOk = false;
System.err.println("IO error on debuglog "
+ this.debugFile.getPath()
+ "\nFallback to standard output.");
System.out.println(msg);
}
} else {
System.out.println(msg);
}
}
private final String timestamp(String tag, String s) {
final String stamp = new SimpleDateFormat("HH:mm:ss.SSS ")
.format(new Date())
+ tag;
final boolean endsLF = s.endsWith("\n");
if (endsLF)
s = s.substring(0, s.length() - 1);
return (stamp + s.replaceAll("\n", "\n" + stamp) + (endsLF ? "\n" : ""));
}
/**
* Displays a message. If the logWindow panel is set, the message is
* displayed on it. If not, the System.out.println function is used.
*
* @param msg The message to display.
*/
private synchronized void displayMsg(String tag, String msg) {
msg = timestamp(tag, msg);
if (this.logWindow == null) {
System.out.println(msg);
} else {
this.logWindow.append(msg);
if (!msg.endsWith("\n"))
this.logWindow.append("\n");
int lc = this.logWindow.getLineCount();
if (lc > MAX_DEBUG_LINES) {
int end;
try {
end = this.logWindow.getLineEndOffset(lc - MAX_DEBUG_LINES);
this.logWindow.replaceRange("", 0, end);
} catch (BadLocationException e) {
e.printStackTrace();
}
}
}
// Let's store all text in the debug logfile
addMsgToDebugLog(msg);
}
/**
* Default reaction after a successful drop operation: no action.
*
* @see UploadPolicy#afterFileDropped(DropTargetDropEvent)
*/
public void afterFileDropped(DropTargetDropEvent dropEvent) {
// Default: no action.
}
/**
* Default implementation for {@link UploadPolicy#createFileChooser()}:
* just a creation of a {@link JUploadFileChooser}.
*
* @see UploadPolicy#createFileChooser()
*/
public JUploadFileChooser createFileChooser() {
return new JUploadFileChooser(this);
}
/**
* This method returns the response for the
* {@link JUploadFileFilter#accept(File)} which just calls this method. This
* method checks that the file isn't excluded by the ignoreDirectoryRegex
* applet parameter.
*
* @see UploadPolicy#fileFilterAccept(File)
*/
public boolean directoryFilterAccept(File file) {
if (file.isDirectory()) {
//
displayDebug("Directory filter directory: " + file.getName()+"\n regex: "+this.ignoredDirectoryRegex, 10);
if (this.ignoredDirectoryRegex.length()>0 && file.getName().matches(this.ignoredDirectoryRegex)){
displayDebug("Ignored", 10);
return false;
}
}
return true;
}
/**
* This method returns the response for the
* {@link JUploadFileFilter#accept(File)} which just calls this method. This
* method checks that the file extension corresponds to the
* allowedFileExtensions applet parameter.
*
* @see UploadPolicy#fileFilterAccept(File)
*/
public boolean fileFilterAccept(File file) {
if (file.isDirectory()) {
return directoryFilterAccept(file);
}
else {
this.displayDebug("File filter ignore: testing " + file.getName()+"\n regex: "+this.ignoredFileRegex, 70);
if (this.ignoredFileRegex!=null && (this.ignoredFileRegex.length()>0 && file.getName().matches(this.ignoredFileRegex))){
displayDebug("Ignored!", 70);
return false;
}
else if (this.allowedFileExtensions == null
|| this.allowedFileExtensions.equals("")) {
return true;
}
// Get the file extension
String extension = DefaultFileData.getExtension(file).toLowerCase();
// allowedFileExtensions is :
// - a list of file extensions,
// - in lower case,
// - separated by slash
// - A slash has been added at the beginning in
// setAllowedFileExtensions
// - A slash has been added at the end in setAllowedFileExtensions
// So, we just look for the /ext/ string in the stored
// allowedFileExtensions.
return (this.allowedFileExtensions.indexOf("/" + extension + "/")) >= 0;
}
}
/** @see UploadPolicy#fileFilterGetDescription() */
public String fileFilterGetDescription() {
String fileFilterDesc =
(this.allowedFileExtensions == null
|| this.allowedFileExtensions.equals("") ? "" : "JUpload file filter (" + this.allowedFileExtensions + ")");
String directoryFilterDesc = (this.ignoredDirectoryRegex == null
|| this.ignoredDirectoryRegex.equals("") ? "" : "JUpload directory filter ignore (" + this.ignoredDirectoryRegex + ")");
return fileFilterDesc+" "+directoryFilterDesc;
}
/**
* Returns null: the default icon is used.
*
* @see UploadPolicy#fileViewGetIcon(File)
*/
public Icon fileViewGetIcon(@SuppressWarnings("unused")
File file) {
return null;
}
/**
* @see wjhk.jupload2.policies.UploadPolicy#getLastResponseBody()
*/
public String getLastResponseBody() {
return (null != this.lastResponseBody) ? this.lastResponseBody : "";
}
/**
* @see wjhk.jupload2.policies.UploadPolicy#getLastResponseMessage()
*/
public String getLastResponseMessage() {
return (null != this.lastResponseMessage) ? this.lastResponseMessage
: "";
}
}