Coverage Report - wjhk.jupload2.policies.DefaultUploadPolicy
 
Classes in this File Line Coverage Branch Coverage Complexity
DefaultUploadPolicy
0 %
0/844
0 %
0/370
3,056
DefaultUploadPolicy$1
100 %
3/3
N/A
3,056
 
 1  
 //
 2  
 // $Id: DefaultUploadPolicy.java 289 2007-06-19 10:04:46 +0000 (mar., 19 juin
 3  
 // 2007) etienne_sf $
 4  
 //
 5  
 // jupload - A file upload juploadContext.
 6  
 // Copyright 2007 The JUpload Team
 7  
 //
 8  
 // Created: 2006-05-04
 9  
 // Creator: etienne_sf
 10  
 // Last modified: $Date: 2015-03-14 15:13:43 +0100 (sam., 14 mars 2015) $
 11  
 //
 12  
 // This program is free software; you can redistribute it and/or modify it under
 13  
 // the terms of the GNU General Public License as published by the Free Software
 14  
 // Foundation; either version 2 of the License, or (at your option) any later
 15  
 // version. This program is distributed in the hope that it will be useful, but
 16  
 // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 17  
 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 18  
 // details. You should have received a copy of the GNU General Public License
 19  
 // along with this program; if not, write to the Free Software Foundation, Inc.,
 20  
 // 675 Mass Ave, Cambridge, MA 02139, USA.
 21  
 
 22  
 package wjhk.jupload2.policies;
 23  
 
 24  
 import java.awt.BorderLayout;
 25  
 import java.awt.Cursor;
 26  
 import java.awt.GridLayout;
 27  
 import java.awt.SystemColor;
 28  
 import java.awt.dnd.DropTargetDropEvent;
 29  
 import java.io.BufferedReader;
 30  
 import java.io.ByteArrayOutputStream;
 31  
 import java.io.File;
 32  
 import java.io.FileOutputStream;
 33  
 import java.io.FileReader;
 34  
 import java.io.IOException;
 35  
 import java.io.InputStream;
 36  
 import java.io.PrintStream;
 37  
 import java.io.UnsupportedEncodingException;
 38  
 import java.net.MalformedURLException;
 39  
 import java.net.URL;
 40  
 import java.net.URLEncoder;
 41  
 import java.nio.charset.Charset;
 42  
 import java.nio.charset.UnsupportedCharsetException;
 43  
 import java.util.IllegalFormatException;
 44  
 import java.util.Iterator;
 45  
 import java.util.Locale;
 46  
 import java.util.ResourceBundle;
 47  
 import java.util.Vector;
 48  
 import java.util.regex.Matcher;
 49  
 import java.util.regex.Pattern;
 50  
 import java.util.regex.PatternSyntaxException;
 51  
 
 52  
 import javax.swing.BorderFactory;
 53  
 import javax.swing.BoxLayout;
 54  
 import javax.swing.Icon;
 55  
 import javax.swing.JButton;
 56  
 import javax.swing.JLabel;
 57  
 import javax.swing.JOptionPane;
 58  
 import javax.swing.JPanel;
 59  
 import javax.swing.JProgressBar;
 60  
 import javax.swing.UIManager;
 61  
 import javax.swing.UnsupportedLookAndFeelException;
 62  
 import javax.swing.border.BevelBorder;
 63  
 
 64  
 import wjhk.jupload2.context.JUploadContext;
 65  
 import wjhk.jupload2.exception.JUploadException;
 66  
 import wjhk.jupload2.exception.JUploadExceptionStopAddingFiles;
 67  
 import wjhk.jupload2.exception.JUploadExceptionUploadFailed;
 68  
 import wjhk.jupload2.exception.JUploadExceptionUploadFailedSuccessNotFound;
 69  
 import wjhk.jupload2.exception.JUploadIOException;
 70  
 import wjhk.jupload2.filedata.DefaultFileData;
 71  
 import wjhk.jupload2.filedata.FileData;
 72  
 import wjhk.jupload2.gui.JUploadFileChooser;
 73  
 import wjhk.jupload2.gui.JUploadFileFilter;
 74  
 import wjhk.jupload2.gui.JUploadPanel;
 75  
 import wjhk.jupload2.gui.filepanel.FilePanel.FileListViewMode;
 76  
 import wjhk.jupload2.upload.helper.ByteArrayEncoder;
 77  
 import wjhk.jupload2.upload.helper.ByteArrayEncoderHTTP;
 78  
 import wjhk.jupload2.upload.helper.HTTPConnectionHelper;
 79  
 import wjhk.jupload2.upload.helper.HttpProtocolFinderThread;
 80  
 import wjhk.jupload2.upload.helper.InteractiveTrustManager;
 81  
 
 82  
 /**
 83  
  * This class implements all {@link wjhk.jupload2.policies.UploadPolicy} methods. Its way of working is he same as the
 84  
  * JUpload version 1. <BR>
 85  
  * The simplest way to use this policy is given in the presentation of {@link UploadPolicy}. The DefaultUploadPolicy is
 86  
  * used when no <I>uploadPolicy</I> parameter is given to the juploadContext, or this parameter has
 87  
  * 'DefaultUploadPolicy' as a value. <BR>
 88  
  * <P>
 89  
  * The <U>default behavior</U> is representated below. It can be overridden by adding parameters to the juploadContext.
 90  
  * All available parameters are shown in the presentation of {@link UploadPolicy}.
 91  
  * </P>
 92  
  * <UL>
 93  
  * <LI>Default implementation for all {@link wjhk.jupload2.policies.UploadPolicy} methods.
 94  
  * <LI>Files are uploaded all in one HTTP request.
 95  
  * <LI>No handling for particular kind of files: files are transmitted without any transformation.
 96  
  * <LI>The file are transmitted to the server with the navigator cookies, userAgent and Protocol (see also the
 97  
  * readCookieFromNavigator and serverProtocol juploadContext parameter). This make upload occurs within the current user
 98  
  * session on the server. So, it allows right management and context during the management of uploaded files, on the
 99  
  * server.
 100  
  * </UL>
 101  
  * 
 102  
  * @author etienne_sf
 103  
  * @version $Revision: 1718 $
 104  
  */
 105  
 
 106  
 public class DefaultUploadPolicy implements UploadPolicy {
 107  
 
 108  
     /**
 109  
      * Maximum number of characters allowed for a message that is displayed in a DialogBox
 110  
      */
 111  
     public final static int DIALOG_MESSAGE_MAX_LINE_LENGTH = 80;
 112  
 
 113  
     // //////////////////////////////////////////////////////////////////////////////////////////////
 114  
     // /////////////////// APPLET PARAMETERS
 115  
     // ///////////////////////////////////////////////////
 116  
     // //////////////////////////////////////////////////////////////////////////////////////////////
 117  
 
 118  
     /**
 119  
      * juploadContext contains the reference of the Applet. It's useful to interact with it. <BR>
 120  
      * It also allows access to the navigator properties, if the html tag MAYSCRIPT is put in the APPLET tag. This
 121  
      * allows this class to get the cookie, userAgent and protocol, to upload files in the current user session on the
 122  
      * server. <BR>
 123  
      * Default : no default value
 124  
      */
 125  0
     JUploadContext juploadContext = null;
 126  
 
 127  
     /**
 128  
      * Contains the applet parameter of the same name. If a valid URL is given here, the navigator will get redirected
 129  
      * to this page, after a successful upload.
 130  
      */
 131  0
     private String afterUploadURL = UploadPolicy.DEFAULT_AFTER_UPLOAD_URL;
 132  
 
 133  
     /**
 134  
      * Contains the allowedFileExtensions applet parameter.
 135  
      */
 136  0
     private boolean allowHttpPersistent = UploadPolicy.DEFAULT_ALLOW_HTTP_PERSISTENT;
 137  
 
 138  
     /**
 139  
      * Contains the allowedFileExtensions applet parameter.
 140  
      */
 141  0
     private String allowedFileExtensions = UploadPolicy.DEFAULT_ALLOWED_FILE_EXTENSIONS;
 142  
 
 143  
     /**
 144  
      * Indicate whether the log window is shown or not to the user. In all cases it remains in memory, and stores all
 145  
      * debug information. This allows a log information, in case of an error occurs.
 146  
      * 
 147  
      * @see #urlToSendErrorTo
 148  
      */
 149  0
     private String showLogWindow = UploadPolicy.DEFAULT_SHOW_LOGWINDOW;
 150  
 
 151  0
     private boolean showStatusbar = UploadPolicy.DEFAULT_SHOW_STATUSBAR;
 152  
 
 153  0
     private String specificHeaders = null;
 154  
 
 155  
     /** Indicates the directory in which the file chooser is to be opened */
 156  0
     private File currentBrowsingDirectory = null;
 157  
 
 158  
     /**
 159  
      * This parameter controls whether the applet generates a debug file or not. If true, this file contains the full
 160  
      * debug output, whatever the current debugLevel is.
 161  
      */
 162  0
     private boolean debugGenerateFile = true;
 163  
 
 164  
     /**
 165  
      * The current debug level. This control the details of information that is written in the log part of the applet.
 166  
      */
 167  0
     private int debugLevel = UploadPolicy.DEFAULT_DEBUG_LEVEL;
 168  
 
 169  
     /**
 170  
      * Stored value for the fileChooserIconFromFileContent applet property.
 171  
      * 
 172  
      * @see UploadPolicy#PROP_FILE_CHOOSER_ICON_FROM_FILE_CONTENT
 173  
      */
 174  0
     private int fileChooserIconFromFileContent = UploadPolicy.DEFAULT_FILE_CHOOSER_ICON_FROM_FILE_CONTENT;
 175  
 
 176  
     /**
 177  
      * Stored value for the fileChooserIconSize applet property.
 178  
      * 
 179  
      * @see UploadPolicy#PROP_FILE_CHOOSER_ICON_SIZE
 180  
      */
 181  0
     private int fileChooserIconSize = UploadPolicy.DEFAULT_FILE_CHOOSER_ICON_SIZE;
 182  
 
 183  
     /** Stored value for the {@link UploadPolicy#PROP_FILE_FILTER_NAME} */
 184  0
     private String fileFilterName = UploadPolicy.DEFAULT_FILE_FILTER_NAME;
 185  
 
 186  
     /** Stored value for the {@link UploadPolicy#PROP_FILE_LIST_VIEW_MODE} */
 187  0
     private FileListViewMode fileListViewMode = UploadPolicy.DEFAULT_FILE_LIST_VIEW_MODE;
 188  
 
 189  
     /**
 190  
      * This String contains the filenameEncoding parameter. All details about the available applet parameters are
 191  
      * displayed in the <a href="UploadPolicy.html@parameters">Upload Policy javadoc page</a>.
 192  
      */
 193  0
     private String filenameEncoding = UploadPolicy.DEFAULT_FILENAME_ENCODING;
 194  
 
 195  
     /**
 196  
      * Default value for the ftpCreateDirectoryStructure applet parameter
 197  
      */
 198  0
     private boolean ftpCreateDirectoryStructure = UploadPolicy.DEFAULT_FTP_CREATE_DIRECTORY_STRUCTURE;
 199  
 
 200  
     /**
 201  
      * Default value for the ftpCreateDirectoryStructure applet parameter
 202  
      */
 203  0
     private boolean ftpTransfertBinary = UploadPolicy.DEFAULT_FTP_TRANSFERT_BINARY;
 204  
 
 205  
     /**
 206  
      * Default value for the ftpCreateDirectoryStructure applet parameter
 207  
      */
 208  0
     private boolean ftpTransfertPassive = UploadPolicy.DEFAULT_FTP_TRANSFERT_PASSIVE;
 209  
 
 210  
     /** Default value for the httpUploadParameterName applet parameter */
 211  0
     protected String httpUploadParameterName = UploadPolicy.DEFAULT_HTTP_UPLOAD_PARAMETER_NAME;
 212  
 
 213  
     /** Default value for the httpUploadParameterType applet parameter */
 214  0
     protected String httpUploadParameterType = UploadPolicy.DEFAULT_HTTP_UPLOAD_PARAMETER_TYPE;
 215  
 
 216  
     /**
 217  
      * The lang parameter, given to the applet.
 218  
      */
 219  0
     private String lang = UploadPolicy.DEFAULT_LANG;
 220  
 
 221  
     /**
 222  
      * The current Locale. If the lang parameter is given and value, this supersede the default locale.
 223  
      */
 224  0
     private Locale locale = Locale.getDefault();
 225  
 
 226  
     /**
 227  
      * Contains the last exception that occurs in the applet.
 228  
      * 
 229  
      * @see #displayErr(String, Exception)
 230  
      */
 231  0
     private JUploadException lastException = null;
 232  
 
 233  
     /**
 234  
      * The look and feel is used as a parameter of the UIManager.setLookAndFeel(String) method. See the parameters list
 235  
      * on the {@link UploadPolicy} page.
 236  
      */
 237  0
     private String lookAndFeel = UploadPolicy.DEFAULT_LOOK_AND_FEEL;
 238  
 
 239  
     /**
 240  
      * The applet will do as may HTTP requests to upload all files, with the number as a maximum number of files for
 241  
      * each HTTP request. <BR>
 242  
      * Default : -1
 243  
      */
 244  0
     private int nbFilesPerRequest = UploadPolicy.DEFAULT_NB_FILES_PER_REQUEST;
 245  
 
 246  
     /**
 247  
      * Current value (or default value) of the maxChunkSize applet parameter. <BR>
 248  
      * Default : Long.MAX_VALUE
 249  
      */
 250  0
     private long maxChunkSize = UploadPolicy.DEFAULT_MAX_CHUNK_SIZE;
 251  
 
 252  
     /**
 253  
      * Current value (or default value) of the maxFileSize applet parameter. <BR>
 254  
      * Default : Long.MAX_VALUE
 255  
      */
 256  0
     private long maxFileSize = UploadPolicy.DEFAULT_MAX_FILE_SIZE;
 257  
 
 258  
     /**
 259  
      * The URL where files should be posted. <BR>
 260  
      * Default : no default value. (mandatory)
 261  
      */
 262  0
     private String postURL = UploadPolicy.DEFAULT_POST_URL;
 263  
 
 264  
     /** @see UploadPolicy#getReadCookieFromNavigator() */
 265  0
     private boolean readCookieFromNavigator = UploadPolicy.DEFAULT_READ_COOKIE_FROM_NAVIGATOR;
 266  
 
 267  
     /** @see UploadPolicy#getReadUserAgentFromNavigator() */
 268  0
     private boolean readUserAgentFromNavigator = UploadPolicy.DEFAULT_READ_USER_AGENT_FROM_NAVIGATOR;
 269  
 
 270  
     /** @see UploadPolicy#getRetryMaxNumberOf() */
 271  0
     private int retryMaxNumberOf = UploadPolicy.DEFAULT_RETRY_MAX_NUMBER_OF;
 272  
 
 273  
     /** @see UploadPolicy#getRetryNbSecondsBetween() */
 274  0
     private int retryNbSecondsBetween = UploadPolicy.DEFAULT_RETRY_NB_SECONDS_BETWEEN;
 275  
 
 276  
     /** @see UploadPolicy#getSendMD5Sum() */
 277  0
     private boolean sendMD5Sum = UploadPolicy.DEFAULT_SEND_MD5_SUM;
 278  
 
 279  
     /** @see UploadPolicy#getServerProtocol() */
 280  0
     private String serverProtocol = UploadPolicy.DEFAULT_SERVER_PROTOCOL;
 281  
 
 282  
     /**
 283  
      * @see UploadPolicy#getStringUploadError()
 284  
      */
 285  0
     private String stringUploadError = UploadPolicy.DEFAULT_STRING_UPLOAD_ERROR;
 286  
 
 287  
     /**
 288  
      * @see UploadPolicy#getStringUploadSuccess()
 289  
      */
 290  0
     private String stringUploadSuccess = UploadPolicy.DEFAULT_STRING_UPLOAD_SUCCESS;
 291  
 
 292  
     /**
 293  
      * @see UploadPolicy#getStringUploadWarning()
 294  
      */
 295  0
     private String stringUploadWarning = UploadPolicy.DEFAULT_STRING_UPLOAD_WARNING;
 296  
 
 297  
     /**
 298  
      * If an error occurs during upload, and this attribute is not null, the applet asks the user if wants to send the
 299  
      * debug ouput to the administrator. If yes, the full debug information is POSTed to this URL. It's a little
 300  
      * development on the server side to send a mail to the webmaster, or just log this error into a log file.
 301  
      * 
 302  
      * @see UploadPolicy#sendDebugInformation(String, Exception)
 303  
      */
 304  0
     private String urlToSendErrorTo = UploadPolicy.DEFAULT_URL_TO_SEND_ERROR_TO;
 305  
 
 306  
     /**
 307  
      * Optional name of a form (in the same document like the applet) which is used to populate POST parameters.
 308  
      */
 309  0
     private String formData = UploadPolicy.DEFAULT_FORMDATA;
 310  
 
 311  0
     private String afterUploadTarget = UploadPolicy.DEFAULT_AFTER_UPLOAD_TARGET;
 312  
 
 313  0
     private String lastResponseBody = null;
 314  
 
 315  0
     protected String lastResponseMessage = null;
 316  
 
 317  0
     private int sslVerifyCert = InteractiveTrustManager.NONE;
 318  
 
 319  0
     private final String CRLF = System.getProperty("line.separator");
 320  
 
 321  
     // //////////////////////////////////////////////////////////////////////////////////////////////
 322  
     // /////////////////// INTERNAL ATTRIBUTE
 323  
     // ///////////////////////////////////////////////////
 324  
     // //////////////////////////////////////////////////////////////////////////////////////////////
 325  
 
 326  
     /**
 327  
      * This Vector contains headers that will be added for each upload. It may contains specific cookies, for instance.
 328  
      * 
 329  
      * @see #onAppendHeader(ByteArrayEncoder)
 330  
      */
 331  0
     private Vector<String> headers = new Vector<String>();
 332  
 
 333  
     /**
 334  
      * The resourceBundle contains all localized String (and others ??)
 335  
      */
 336  0
     private ResourceBundle resourceBundle = null;
 337  
 
 338  
     /**
 339  
      * This stream is used to store all information that could be useful, in case a problem occurs. Is content can then
 340  
      * be sent to the webmaster.
 341  
      */
 342  0
     protected PrintStream debugOut = null;
 343  
 
 344  
     /**
 345  
      * The actual file, used for the debug log.
 346  
      * 
 347  
      * @see #debugGenerateFile
 348  
      */
 349  0
     protected File debugFile = null;
 350  
 
 351  
     /**
 352  
      * This flag prevents endless repeats of opening the debug log, if that failed for some reason.
 353  
      */
 354  0
     protected boolean debugOk = true;
 355  
 
 356  
     /**
 357  
      * Same as {@link #patternSuccess}, but for the error message. If found, then the upload was accepted by the remote
 358  
      * HTTP server, but rejected by the remote application. This pattern should also find the error message in the first
 359  
      * matching string.
 360  
      */
 361  0
     protected Pattern patternError = Pattern.compile(UploadPolicy.DEFAULT_STRING_UPLOAD_ERROR);
 362  
 
 363  
     /**
 364  
      * The regexp pattern that is used to find the success string in the HTTP response. If found, the upload is
 365  
      * considered to be a success: it has been accepted by the remote server and the remote application.
 366  
      */
 367  0
     protected Pattern patternSuccess = Pattern.compile(UploadPolicy.DEFAULT_STRING_UPLOAD_SUCCESS);
 368  
 
 369  
     /**
 370  
      * Same as {@link #patternSuccess}, but for the warning message. Each time it is found, a message is displayed to
 371  
      * the user.
 372  
      */
 373  0
     protected Pattern patternWarning = Pattern.compile(UploadPolicy.DEFAULT_STRING_UPLOAD_WARNING);
 374  
 
 375  
     // //////////////////////////////////////////////////////////////////////////////////////////////
 376  
     // /////////////////// CONSTRUCTORS
 377  
     // //////////////////////////////////////////////////////////////////////////////////////////////
 378  
 
 379  
     /**
 380  
      * The main constructor : use default values, and the given postURL.
 381  
      * 
 382  
      * @param juploadContext The current juploadContext. As the reference to the current upload policy exists almost
 383  
      *            everywhere, this parameter allows any access to anyone on the juploadContext... including reading the
 384  
      *            applet parameters.
 385  
      * @throws JUploadException If an applet parameter is invalid
 386  
      */
 387  0
     public DefaultUploadPolicy(JUploadContext juploadContext) throws JUploadException {
 388  
         // Call default constructor for all default initialization;.
 389  0
         this.juploadContext = juploadContext;
 390  0
         displayInfo("JUpload juploadContext started, with " + this.getClass().getName() + " upload policy");
 391  
 
 392  
         // get the debug level. This control the level of debug messages that
 393  
         // are written in the log window (see displayDebugMessage). In all
 394  
         // cases, the full output is written in the debugBufferString (see also
 395  
         // urlToSendErrorTo)
 396  0
         setDebugLevel(juploadContext.getParameter(PROP_DEBUG_LEVEL, DEFAULT_DEBUG_LEVEL), false);
 397  
 
 398  
         // Get resource file. This must be the very first parameter to be set,
 399  
         // because during initialization, translations may be needed.
 400  0
         setLang(juploadContext.getParameter(PROP_LANG, DEFAULT_LANG));
 401  
 
 402  
         // Force the look and feel of the current system. This must be the
 403  
         // second
 404  
         // first parameter to be set, because during initialization, dialogs can
 405  
         // appear.
 406  0
         setLookAndFeel(juploadContext.getParameter(PROP_LOOK_AND_FEEL, DEFAULT_LOOK_AND_FEEL));
 407  
 
 408  
         // This must be set before any URL's because these might trigger an
 409  
         // connection attempt.
 410  0
         setSslVerifyCert(juploadContext.getParameter(PROP_SSL_VERIFY_CERT, DEFAULT_SSL_VERIFY_CERT));
 411  
 
 412  
         // get the afterUploadURL juploadContext parameter.
 413  0
         setAfterUploadURL(juploadContext.getParameter(PROP_AFTER_UPLOAD_URL, DEFAULT_AFTER_UPLOAD_URL));
 414  
 
 415  
         // FTP: whether or not to create subfolders on the server side.
 416  0
         setFtpCreateDirectoryStructure(juploadContext.getParameter(PROP_FTP_CREATE_DIRECTORY_STRUCTURE,
 417  
                 DEFAULT_FTP_CREATE_DIRECTORY_STRUCTURE));
 418  
         // FTP transfert mode
 419  0
         setFtpTransfertBinary(juploadContext.getParameter(PROP_FTP_TRANSFERT_BINARY, DEFAULT_FTP_TRANSFERT_BINARY));
 420  
         // FTP connection mode
 421  0
         setFtpTransfertPassive(juploadContext.getParameter(PROP_FTP_TRANSFERT_PASSIVE, DEFAULT_FTP_TRANSFERT_PASSIVE));
 422  
 
 423  
         // get the fileChooser parameters
 424  0
         setAllowedFileExtensions(juploadContext.getParameter(PROP_ALLOWED_FILE_EXTENSIONS,
 425  
                 DEFAULT_ALLOWED_FILE_EXTENSIONS));
 426  0
         setFileFilterName(juploadContext.getParameter(PROP_FILE_FILTER_NAME, DEFAULT_FILE_FILTER_NAME));
 427  0
         setFileListViewMode(juploadContext.getParameter(PROP_FILE_LIST_VIEW_MODE, DEFAULT_FILE_LIST_VIEW_MODE));
 428  
 
 429  0
         setAllowHttpPersistent(juploadContext.getParameter(PROP_ALLOW_HTTP_PERSISTENT, DEFAULT_ALLOW_HTTP_PERSISTENT));
 430  
 
 431  0
         setShowStatusbar(juploadContext.getParameter(PROP_SHOW_STATUSBAR, DEFAULT_SHOW_STATUSBAR));
 432  
 
 433  0
         setShowLogWindow(juploadContext.getParameter(PROP_SHOW_LOGWINDOW, DEFAULT_SHOW_LOGWINDOW));
 434  
 
 435  
         // set the fileChooser relative stuff.
 436  0
         setFileChooserIconFromFileContent(juploadContext.getParameter(PROP_FILE_CHOOSER_ICON_FROM_FILE_CONTENT,
 437  
                 DEFAULT_FILE_CHOOSER_ICON_FROM_FILE_CONTENT));
 438  0
         setFileChooserIconSize(juploadContext.getParameter(PROP_FILE_CHOOSER_ICON_SIZE, DEFAULT_FILE_CHOOSER_ICON_SIZE));
 439  0
         setCurrentBrowsingDirectory(juploadContext.getParameter(PROP_BROWSING_DIRECTORY, DEFAULT_BROWSING_DIRECTORY));
 440  
         // get the filenameEncoding. If not null, it should be a valid argument for the URLEncoder.encode method.
 441  
         // DEPRECATED.
 442  0
         setFilenameEncoding(juploadContext.getParameter(PROP_FILENAME_ENCODING, DEFAULT_FILENAME_ENCODING));
 443  
 
 444  
         // Read parameters about the HTTP upload request.
 445  0
         setNbFilesPerRequest(juploadContext.getParameter(PROP_NB_FILES_PER_REQUEST, DEFAULT_NB_FILES_PER_REQUEST));
 446  0
         setHttpUploadParameterName(juploadContext.getParameter(PROP_HTTP_UPLOAD_PARAMETER_NAME,
 447  
                 DEFAULT_HTTP_UPLOAD_PARAMETER_NAME));
 448  0
         setHttpUploadParameterType(juploadContext.getParameter(PROP_HTTP_UPLOAD_PARAMETER_TYPE,
 449  
                 DEFAULT_HTTP_UPLOAD_PARAMETER_TYPE));
 450  
         // get the maximum size of a file on one HTTP request (indicates if the
 451  
         // file must be splitted before upload, see UploadPolicy comment).
 452  0
         setMaxChunkSize(juploadContext.getParameter(PROP_MAX_CHUNK_SIZE, DEFAULT_MAX_CHUNK_SIZE));
 453  
         // get the maximum size of an uploaded file.
 454  0
         setMaxFileSize(juploadContext.getParameter(PROP_MAX_FILE_SIZE, DEFAULT_MAX_FILE_SIZE));
 455  
         // retry management
 456  0
         setRetryMaxNumberOf(juploadContext.getParameter(PROP_RETRY_MAX_NUMBER_OF, DEFAULT_RETRY_MAX_NUMBER_OF));
 457  0
         setRetryNbSecondsBetween(juploadContext.getParameter(PROP_RETRY_NB_SECONDS_BETWEEN,
 458  
                 DEFAULT_RETRY_NB_SECONDS_BETWEEN));
 459  
 
 460  
         // get the URL where files must be posted.
 461  0
         setPostURL(juploadContext.getParameter(PROP_POST_URL, DEFAULT_POST_URL));
 462  
 
 463  
         // get any additional headers.
 464  0
         setReadCookieFromNavigator(juploadContext.getParameter(PROP_READ_COOKIE_FROM_NAVIGATOR,
 465  
                 DEFAULT_READ_COOKIE_FROM_NAVIGATOR));
 466  0
         setReadUserAgentFromNavigator(juploadContext.getParameter(PROP_READ_USER_AGENT_FROM_NAVIGATOR,
 467  
                 DEFAULT_READ_USER_AGENT_FROM_NAVIGATOR));
 468  0
         setSendMD5Sum(juploadContext.getParameter(PROP_SEND_MD5_SUM, DEFAULT_SEND_MD5_SUM));
 469  0
         setSpecificHeaders(juploadContext.getParameter(PROP_SPECIFIC_HEADERS, DEFAULT_SPECIFIC_HEADERS));
 470  0
         setStringUploadError(juploadContext.getParameter(PROP_STRING_UPLOAD_ERROR, DEFAULT_STRING_UPLOAD_ERROR));
 471  0
         setStringUploadSuccess(juploadContext.getParameter(PROP_STRING_UPLOAD_SUCCESS, DEFAULT_STRING_UPLOAD_SUCCESS));
 472  0
         setStringUploadWarning(juploadContext.getParameter(PROP_STRING_UPLOAD_WARNING, DEFAULT_STRING_UPLOAD_WARNING));
 473  
 
 474  
         // get the URL where the full debug output can be sent when an error
 475  
         // occurs.
 476  0
         setUrlToSendErrorTo(juploadContext.getParameter(PROP_URL_TO_SEND_ERROR_TO, DEFAULT_URL_TO_SEND_ERROR_TO));
 477  0
         this.formData = juploadContext.getParameter(PROP_FORMDATA, DEFAULT_FORMDATA);
 478  0
         this.afterUploadTarget = juploadContext.getParameter(PROP_AFTER_UPLOAD_TARGET, DEFAULT_AFTER_UPLOAD_TARGET);
 479  
 
 480  
         // We let the UploadPolicyFactory call the displayParameterStatus
 481  
         // method, so that the initialization is finished, including for classes
 482  
         // which inherit from DefaultUploadPolicy.
 483  0
         displayDebug("[DefaultUploadPolicy] end of constructor (serverProtocol has not been set)", 30);
 484  0
     }
 485  
 
 486  
     // //////////////////////////////////////////////////////////////////////////////////////////////
 487  
     // /////////////////// UploadPolicy methods
 488  
     // //////////////////////////////////////////////////////////////////////////////////////////////
 489  
 
 490  
     /** @see UploadPolicy#start() */
 491  
     public void start() {
 492  
         // The current context may add any specific headers.
 493  0
         if (getReadCookieFromNavigator()) {
 494  0
             this.juploadContext.readCookieFromNavigator(this.headers);
 495  
         }
 496  0
         if (getReadUserAgentFromNavigator()) {
 497  0
             this.juploadContext.readUserAgentFromNavigator(this.headers);
 498  
         }
 499  
 
 500  
         // Let's touch the server, to test that everything is Ok. Take care,
 501  
         // this is the only place where we override the default value, by null:
 502  
         // the default value will be used by the HttpConnect.getProtocol()
 503  
         // method.
 504  
         // Also, in FTP mode, there can be no default value.
 505  
         //
 506  
         // Must be done AFTER reading the cookie and the userAgent.
 507  
         //
 508  0
         HttpProtocolFinderThread.computeServerProtocol(this,
 509  0
                 juploadContext.getParameter(PROP_SERVER_PROTOCOL, (String) null));
 510  0
     }
 511  
 
 512  
     // getters and setters are sorted below
 513  
 
 514  
     /**
 515  
      * @see wjhk.jupload2.policies.UploadPolicy#addHeader(java.lang.String)
 516  
      */
 517  
     public void addHeader(String header) {
 518  0
         this.headers.add(header);
 519  0
     }
 520  
 
 521  
     /**
 522  
      * The default behavior (see {@link DefaultUploadPolicy}) is to check that the stringUploadSuccess applet parameter
 523  
      * is present in the response from the server. The return is tested, in the order below: <DIR> <LI>False, if the
 524  
      * stringUploadError is found. An error message is then displayed. <LI>True, if the stringUploadSuccess is null or
 525  
      * empty (no test at all). <LI>True, if the stringUploadSuccess string is present in the serverOutputBody. <LI>True,
 526  
      * If previous condition is not filled, but the HTTP header "HTTP(.*)200OK$" is present: the test is currently non
 527  
      * blocking, because I can not test all possible HTTP configurations.<BR> <LI>False if the previous conditions are
 528  
      * not fullfilled. </DIR> <BR>
 529  
      * This method also looks for the stringUploadWarning regular expression. Each time it is matched, the found message
 530  
      * is displayed to the user.
 531  
      * 
 532  
      * @param status The HTTP response code
 533  
      * @param msg The status message from the first line of the response (e.g. "200 OK").
 534  
      * @param body The body of the HTTP answer.
 535  
      * @return True or False, indicating if the upload is a success or not.
 536  
      * @see UploadPolicy#checkUploadSuccess(int, String, String)
 537  
      */
 538  
     public boolean checkUploadSuccess(int status, String msg, String body) throws JUploadException {
 539  0
         boolean bReturn = false;
 540  
 
 541  0
         if (getDebugLevel() > 100) {
 542  
             // Let's have a little time to check the upload messages written on
 543  
             // the progress bar.
 544  
             try {
 545  0
                 Thread.sleep(300);
 546  0
             } catch (InterruptedException e) {
 547  0
             }
 548  
         }
 549  
 
 550  0
         this.lastResponseBody = body;
 551  0
         this.lastResponseMessage = msg;
 552  0
         displayDebug("HTTP status: " + msg, 30);
 553  
         // HTTP-100 correction, thanks to Marc Reidy
 554  0
         if ((status != 200) && (status != 100))
 555  0
             throw new JUploadExceptionUploadFailed("Received HTTP status " + msg);
 556  
 
 557  
         // HTTP-100 "continue", in case we're uploading
 558  
         // to an ASP.NET development server. We should
 559  
         // continue sending...
 560  0
         if (status == 100)
 561  0
             return true;
 562  
 
 563  
         // Let's analyze the body returned, line by line. The end of line
 564  
         // character may be CR, LF, or CRLF. We navigate through the body, and
 565  
         // replace any end of line character by a uniform CRLF.
 566  
         Matcher matcherError, matcherWarning;
 567  
         String line;
 568  0
         Pattern p = Pattern.compile("[\\r\\n]", Pattern.MULTILINE);
 569  0
         String[] lines = p.split(body);
 570  0
         StringBuffer sbBodyWithUniformCRLF = new StringBuffer(body.length());
 571  0
         for (int i = 0; i < lines.length; i += 1) {
 572  0
             line = lines[i];
 573  0
             sbBodyWithUniformCRLF.append(line).append("\r\n");
 574  
 
 575  
             // FIXME some empty lines are given by the server
 576  
             // Let's remove the empty line: with the p pattern, a multiline is
 577  
             // generated each time a \r\n is received, that is: for each line.
 578  0
             if (line == null || line.equals("")) {
 579  
                 // An empty line. Let's go the next line.
 580  0
                 continue;
 581  
             }
 582  
 
 583  
             // Check if this is a success
 584  
             // The success string should be in the http body
 585  0
             if (getStringUploadSuccess() != null && !getStringUploadSuccess().equals("")) {
 586  0
                 if (this.patternSuccess.matcher(line).matches()) {
 587  
                     // We go on. There may be some WARNING message, hereafter.
 588  0
                     bReturn = true;
 589  
                 }
 590  
             }
 591  
 
 592  
             // Check if this is an error
 593  0
             if (getStringUploadError() != null && !getStringUploadError().equals("")) {
 594  0
                 matcherError = this.patternError.matcher(line);
 595  0
                 if (matcherError.matches()) {
 596  0
                     String errmsg = "An error occurs during upload (but the applet couldn't find the error message)";
 597  0
                     if (matcherError.groupCount() > 0) {
 598  0
                         if (!matcherError.group(1).equals("")) {
 599  
                             // Let's do a (very simple) formatting: one line to
 600  
                             // 100 characters
 601  0
                             errmsg = formatMessage(matcherError.group(1));
 602  
                         }
 603  
                     }
 604  0
                     this.lastResponseMessage = errmsg;
 605  0
                     throw new JUploadExceptionUploadFailed(errmsg);
 606  
                 }
 607  
             }// getStringUploadError
 608  
 
 609  
             // Check if this is an warning
 610  0
             if (getStringUploadWarning() != null && !getStringUploadWarning().equals("")) {
 611  0
                 matcherWarning = this.patternWarning.matcher(line);
 612  0
                 if (matcherWarning.matches()) {
 613  0
                     String warnmsg = "A warning occurs during upload (but the applet couldn't find the warning message)";
 614  0
                     if (matcherWarning.groupCount() > 0) {
 615  0
                         if (!matcherWarning.group(1).equals("")) {
 616  0
                             warnmsg = formatMessage(matcherWarning.group(1));
 617  
                         }
 618  
                     }
 619  0
                     this.lastResponseMessage = warnmsg;
 620  0
                     displayWarn(warnmsg);
 621  0
                     alertStr(warnmsg);
 622  
                 }
 623  
             }// getStringUploadWarning
 624  
 
 625  
         }// while(st.hasMoreTokens())
 626  
 
 627  0
         if (bReturn) {
 628  0
             return true;
 629  
         }
 630  
 
 631  
         // We found no stringUploadSuccess nor stringUploadError
 632  0
         if (getStringUploadSuccess() == null || getStringUploadSuccess().equals("")) {
 633  
             // No chance to check the correctness of this upload. -> Assume Ok
 634  0
             return true;
 635  
         }
 636  
 
 637  
         // stringUploadSuccess was defined but we did not find it.
 638  
         // This is most certainly an error as http-status 200 does *not* refer
 639  
         // to the correctness of the content. It merely means that the protocol
 640  
         // handling was ok. -> throw an exception
 641  0
         throw new JUploadExceptionUploadFailedSuccessNotFound(getClass().getName()
 642  0
                 + ".checkUploadSuccess(): The regexp string \"" + getStringUploadSuccess()
 643  
                 + "\" was not found in the response body");
 644  
     } // checkUploadSuccess
 645  
 
 646  
     /**
 647  
      * Generation of a formatted error message, so that it can be displayed in a DialogBox. That is: each line that
 648  
      * contains more than {@link #DIALOG_MESSAGE_MAX_LINE_LENGTH} is truncated to DIALOG_MESSAGE_MAX_LINE_LENGTH.
 649  
      * 
 650  
      * @param msg
 651  
      * @return
 652  
      */
 653  
     protected String formatMessage(String msg) {
 654  0
         StringBuffer sbMsg = new StringBuffer();
 655  0
         String[] lines = msg.split("\\\\n");
 656  0
         for (int i = 0; i < lines.length; i += 1) {
 657  
             // For each line, we truncate it, if it's too long.
 658  0
             String line = lines[i];
 659  0
             for (int j = 0, remaining = line.length(); remaining > 0; remaining -= DIALOG_MESSAGE_MAX_LINE_LENGTH, j += 1) {
 660  0
                 if (remaining <= DIALOG_MESSAGE_MAX_LINE_LENGTH) {
 661  
                     // It's the last loop.
 662  0
                     sbMsg.append(line.substring(j * DIALOG_MESSAGE_MAX_LINE_LENGTH));
 663  
                 } else {
 664  0
                     sbMsg.append(line.substring(j * DIALOG_MESSAGE_MAX_LINE_LENGTH, (j + 1)
 665  
                             * DIALOG_MESSAGE_MAX_LINE_LENGTH));
 666  0
                     sbMsg.append("\n");
 667  
                 }
 668  
             }
 669  
             // End we add the EOL characters, for all lines, but the last one.
 670  0
             if (i < lines.length - 1) {
 671  0
                 sbMsg.append("\n");
 672  
             }
 673  
         }
 674  
 
 675  0
         return sbMsg.toString();
 676  
     }
 677  
 
 678  
     /**
 679  
      * @see wjhk.jupload2.policies.UploadPolicy#afterUpload(Exception, String)
 680  
      */
 681  
     public void afterUpload(Exception e, String serverOutput) throws JUploadException {
 682  
         // If there was no error, and afterUploadURL is defined, let's try to go
 683  
         // to this URL.
 684  0
         String url = getAfterUploadURL();
 685  0
         if (url != null) {
 686  0
             this.juploadContext.displayURL(url, e == null);
 687  
         }
 688  0
     }
 689  
 
 690  
     /** @see UploadPolicy#alertStr(String) */
 691  
     public void alertStr(String str) {
 692  0
         String str2 = str.replaceAll("\\\\n", "\n");
 693  0
         JOptionPane.showMessageDialog(null, str2, "Alert", JOptionPane.WARNING_MESSAGE);
 694  0
     }
 695  
 
 696  
     /** @see UploadPolicy#confirmDialogStr(String, int) */
 697  
     public int confirmDialogStr(String str, int optionTypes) {
 698  0
         String str2 = str.replaceAll("\\\\n", "\n");
 699  0
         return JOptionPane.showConfirmDialog(getContext().getUploadPanel().getJComponent().getParent(), str2, "Alert",
 700  
                 optionTypes);
 701  
     }
 702  
 
 703  
     /** @see UploadPolicy#alert(String) */
 704  
     public void alert(String key) {
 705  0
         alertStr(getLocalizedString(key));
 706  0
     }
 707  
 
 708  
     /**
 709  
      * The DefaultUpload accepts all file types: we just return an instance of FileData, without any test.
 710  
      * 
 711  
      * @exception JUploadExceptionStopAddingFiles If the users choosed to stop adding. This occurs when the
 712  
      *                {@link #fileFilterAccept(File)} method returns false, and the user then choose to stop adding
 713  
      *                files.
 714  
      * @see UploadPolicy#createFileData(File, File)
 715  
      */
 716  
     public FileData createFileData(File file) throws JUploadExceptionStopAddingFiles {
 717  0
         if (!fileFilterAccept(file)) {
 718  0
             String msg = file.getName() + " : " + getLocalizedString("errForbiddenExtension");
 719  0
             displayWarn(msg);
 720  0
             if (confirmDialogStr(msg, JOptionPane.OK_CANCEL_OPTION) == JOptionPane.CANCEL_OPTION) {
 721  
                 // The user want to stop to add files to the list. For instance,
 722  
                 // when he/she added a whole directory, and it contains a lot of
 723  
                 // files that don't match the allowed file extension.
 724  0
                 throw new JUploadExceptionStopAddingFiles("Stopped by the user");
 725  
             }
 726  0
             return null;
 727  0
         } else if (!file.canRead()) {
 728  0
             displayInfo("Can't read file " + file.getName() + ". No DefaultFileData creation.");
 729  0
             return null;
 730  
         } else {
 731  0
             return new DefaultFileData(file, this);
 732  
         }
 733  
     }
 734  
 
 735  
     /**
 736  
      * Default implementation of
 737  
      * {@link wjhk.jupload2.policies.UploadPolicy#createTopPanel(JButton, JButton, JButton, JUploadPanel)} . IT creates
 738  
      * a JPanel, containing the three given JButton. It creates the same panel as the original JUpload.
 739  
      * 
 740  
      * @see wjhk.jupload2.policies.UploadPolicy#createTopPanel(JButton, JButton, JButton, JUploadPanel)
 741  
      */
 742  
     public JPanel createTopPanel(JButton browse, JButton remove, JButton removeAll, JUploadPanel jUploadPanel) {
 743  0
         JPanel jPanel = new JPanel();
 744  
 
 745  0
         jPanel.setLayout(new GridLayout(1, 3, 10, 5));
 746  0
         jPanel.setBorder(BorderFactory.createEmptyBorder(5, 10, 5, 10));
 747  0
         jPanel.add(browse);
 748  0
         jPanel.add(removeAll);
 749  0
         jPanel.add(remove);
 750  
 
 751  0
         jUploadPanel.getJComponent().setBorder(BorderFactory.createLineBorder(SystemColor.controlDkShadow));
 752  
 
 753  0
         return jPanel;
 754  
     }
 755  
 
 756  
     /**
 757  
      * @see wjhk.jupload2.policies.UploadPolicy#createProgressPanel(JProgressBar, JProgressBar, JButton, JButton,
 758  
      *      JUploadPanel)
 759  
      */
 760  
     public JPanel createProgressPanel(JProgressBar preparationProgressBar, JProgressBar uploadProgressBar,
 761  
             JButton uploadButton, JButton stopButton, JUploadPanel mainPanel) {
 762  
 
 763  
         // There may be two progress bar: one for preparation progress of files
 764  
         // (preparation before upload) and one to follow the actual upload.
 765  0
         JPanel jProgressBarPanel = new JPanel();
 766  0
         jProgressBarPanel.setLayout(new BorderLayout(10, 1));
 767  0
         jProgressBarPanel.add(preparationProgressBar, BorderLayout.NORTH);
 768  0
         jProgressBarPanel.add(uploadProgressBar, BorderLayout.SOUTH);
 769  
 
 770  0
         JPanel jProgressPanel = new JPanel();
 771  0
         jProgressPanel.setLayout(new BorderLayout(10, 0));
 772  0
         jProgressPanel.setBorder(BorderFactory.createEmptyBorder(5, 10, 5, 10));
 773  0
         jProgressPanel.add(uploadButton, BorderLayout.LINE_START);
 774  0
         jProgressPanel.add(jProgressBarPanel, BorderLayout.CENTER);
 775  0
         jProgressPanel.add(stopButton, BorderLayout.LINE_END);
 776  0
         return jProgressPanel;
 777  
     }
 778  
 
 779  
     /**
 780  
      * @see wjhk.jupload2.policies.UploadPolicy#createStatusBar(javax.swing.JLabel, JUploadPanel)
 781  
      */
 782  
     public JPanel createStatusBar(JLabel content, JUploadPanel mainPanel) {
 783  0
         if (this.showStatusbar) {
 784  0
             JPanel pstatus = new JPanel();
 785  0
             pstatus.setLayout(new BorderLayout());
 786  0
             pstatus.add(content, BorderLayout.CENTER);
 787  0
             pstatus.setBorder(new BevelBorder(BevelBorder.LOWERED));
 788  0
             return pstatus;
 789  
         }
 790  0
         return null;
 791  
     }
 792  
 
 793  
     /**
 794  
      * This methods allow the upload policy to override the default disposition of the components on the applet.
 795  
      * 
 796  
      * @see UploadPolicy#addComponentsToJUploadPanel(JUploadPanel)
 797  
      */
 798  
     public void addComponentsToJUploadPanel(JUploadPanel jUploadPanel) {
 799  
         // Set the global layout of the panel.
 800  0
         jUploadPanel.getJComponent().setLayout(new BoxLayout(jUploadPanel.getJComponent(), BoxLayout.Y_AXIS));
 801  
 
 802  
         // The top panel is the upper part of the applet: above the file
 803  
         // list.
 804  
         // JPanel topPanel = new JPanel();
 805  0
         JPanel topPanel = createTopPanel(jUploadPanel.getBrowseButton(), jUploadPanel.getRemoveButton(),
 806  0
                 jUploadPanel.getRemoveAllButton(), jUploadPanel);
 807  0
         if (topPanel != null) {
 808  0
             jUploadPanel.getJComponent().add(topPanel);
 809  0
             topPanel.addMouseListener(jUploadPanel.getMouseListener());
 810  
         }
 811  
 
 812  
         // Then, we add the file list.
 813  0
         jUploadPanel.getJComponent().add(jUploadPanel.getFilePanel().getDropComponent());
 814  
 
 815  
         // The progress panel contains the progress bar, and the upload and stop
 816  
         // buttons.
 817  0
         JPanel progressPanel = createProgressPanel(jUploadPanel.getPreparationProgressBar(),
 818  0
                 jUploadPanel.getUploadProgressBar(), jUploadPanel.getUploadButton(), jUploadPanel.getStopButton(),
 819  
                 jUploadPanel);
 820  0
         jUploadPanel.getJComponent().add(progressPanel);
 821  0
         jUploadPanel.getJComponent().addMouseListener(jUploadPanel.getMouseListener());
 822  
 
 823  
         // Now, we add the log window.
 824  0
         jUploadPanel.showOrHideLogWindow();
 825  0
         jUploadPanel.getJComponent().add(jUploadPanel.getJLogWindowPane());
 826  
 
 827  
         // And, to finish with: the status bar.
 828  0
         JPanel p = createStatusBar(jUploadPanel.getStatusLabel(), jUploadPanel);
 829  0
         if (null != p) {
 830  0
             jUploadPanel.getJComponent().add(p);
 831  0
             p.addMouseListener(jUploadPanel.getMouseListener());
 832  
         }
 833  0
     }
 834  
 
 835  
     /** {@inheritDoc} */
 836  
     public void updateButtonState(int executionStatus) {
 837  
         // First step: check the parameter.
 838  0
         if (executionStatus != UploadPolicy.EXEC_STATUS_READY && executionStatus != UploadPolicy.EXEC_STATUS_UPLOADING) {
 839  0
             throw new java.lang.IllegalArgumentException("Unknow value for executionStatus: " + executionStatus);
 840  
         }
 841  
 
 842  
         // Then ... nothing to do! This class has no specific GUI item.
 843  0
     }
 844  
 
 845  
     /** @see UploadPolicy#displayErr(Exception) */
 846  
     public void displayErr(Exception e) {
 847  0
         displayErr(e.getMessage(), e);
 848  0
     }
 849  
 
 850  
     /** @see UploadPolicy#displayErr(String) */
 851  
     public void displayErr(String err) {
 852  0
         displayErr(err, null);
 853  0
     }
 854  
 
 855  
     /**
 856  
      * Logs a stack trace for the given exception.
 857  
      * 
 858  
      * @param throwable
 859  
      */
 860  
     private void displayStackTrace(Throwable throwable) {
 861  0
         if (throwable != null) {
 862  0
             ByteArrayOutputStream bs = new ByteArrayOutputStream();
 863  0
             PrintStream ps = new PrintStream(bs);
 864  0
             throwable.printStackTrace(ps);
 865  0
             ps.close();
 866  0
             displayMsg("", bs.toString());
 867  
 
 868  
             // If there is a cause, let's be sure its stack trace is displayed.
 869  0
             if (throwable.getCause() != null) {
 870  0
                 displayMsg("", "Caused by:");
 871  0
                 displayStackTrace(throwable.getCause());
 872  
             }
 873  
         }
 874  0
     }
 875  
 
 876  
     /**
 877  
      * This method just logs an error.
 878  
      * 
 879  
      * @param errorText
 880  
      * @param exception
 881  
      */
 882  
     private void logErr(String errorText, Exception exception) {
 883  0
         if (exception == null) {
 884  0
             setLastException(new JUploadException("errorText"));
 885  0
         } else if (exception instanceof JUploadException) {
 886  0
             setLastException((JUploadException) exception);
 887  
         } else {
 888  0
             setLastException(new JUploadException(exception));
 889  
         }
 890  
 
 891  
         // Default behavior: if debugLevel is 0, and an error occurs, we force
 892  
         // the debug level to 1: this makes the log window become visible, if it
 893  
         // was hidden.
 894  0
         if (getDebugLevel() == 0)
 895  0
             setDebugLevel(1);
 896  
 
 897  0
         String exceptionMsg = null;
 898  0
         String exceptionClassName = null;
 899  0
         String logMsg = errorText;
 900  
 
 901  
         // First, we construct the exception class name.
 902  0
         if (exception == null) {
 903  0
             exceptionClassName = "";
 904  0
         } else if (exception instanceof JUploadException) {
 905  0
             exceptionClassName = "[" + ((JUploadException) exception).getClassNameAndClause() + "] ";
 906  
         } else {
 907  0
             exceptionClassName = "[" + exception.getClass().getName() + "] ";
 908  
         }
 909  
 
 910  
         // Then, the message body can be completed by the exception message.
 911  0
         if (exception != null) {
 912  
             // Ok, we have an exception.
 913  0
             if (exception.getCause() != null) {
 914  0
                 exceptionMsg = exception.getCause().getMessage();
 915  
             } else {
 916  0
                 exceptionMsg = exception.getMessage();
 917  
             }
 918  0
             logMsg = exceptionMsg + " (" + errorText + ")";
 919  
         }
 920  
 
 921  
         // Add the message to the log window
 922  0
         displayMsg("[ERROR]", exceptionClassName + logMsg);
 923  
         // Let's display the stack trace, if relevant.
 924  0
         displayStackTrace(exception);
 925  
 
 926  
         // Then we copy the debug output to the clipboard, and say it to the
 927  
         // current user.
 928  0
         if (this.juploadContext.getUploadPanel() != null && getDebugLevel() >= 99) {
 929  
             // Ok, the applet has been fully built.
 930  0
             this.juploadContext.getUploadPanel().copyLogWindow();
 931  0
             alert("messageLogWindowCopiedToClipboard");
 932  
         }
 933  
 
 934  0
     }
 935  
 
 936  
     /**
 937  
      * If debug is off, the log window may not be visible. We switch the debug to on, to be sure that some information
 938  
      * will be displayed to the user. <BR>
 939  
      * If debug is -1, the log window remains hidden.
 940  
      * 
 941  
      * @see wjhk.jupload2.policies.UploadPolicy#displayErr(java.lang.String, java.lang.Exception, int)
 942  
      */
 943  
     public int displayErr(String errorText, Exception exception, int optionTypes) {
 944  
         // Then, we display it to the user.
 945  0
         String alertMsg = errorText;
 946  
         // Then, the message body can be completed by the exception message.
 947  0
         if (exception != null && (errorText == null || errorText.equals(""))) {
 948  
             // Ok, we have an exception.
 949  0
             if (exception.getCause() != null) {
 950  0
                 alertMsg = exception.getCause().getMessage();
 951  
             } else {
 952  0
                 alertMsg = exception.getMessage();
 953  
             }
 954  
         }
 955  
 
 956  
         // The message displayed depend on the debug level:
 957  0
         if (getDebugLevel() >= 30 && exception != null) {
 958  0
             alertMsg = exception.getClass().getName() + ": " + alertMsg;
 959  
         }
 960  
 
 961  
         // Display the message to the user. The kind of alert box depends on the
 962  
         // given options:
 963  0
         int buttonClicked = 0;
 964  0
         switch (optionTypes) {
 965  
             case -1:
 966  
                 // Standard message box.
 967  0
                 alertStr(alertMsg);
 968  0
                 buttonClicked = JOptionPane.OK_OPTION;
 969  0
                 break;
 970  
             case JOptionPane.OK_CANCEL_OPTION:
 971  
             case JOptionPane.YES_NO_CANCEL_OPTION:
 972  
             case JOptionPane.YES_NO_OPTION:
 973  0
                 buttonClicked = confirmDialogStr(alertMsg, optionTypes);
 974  0
                 break;
 975  
             default:
 976  
                 // This is a problem. Let's display it to the user as a standard
 977  
                 // alert box.
 978  0
                 alertStr(alertMsg);
 979  0
                 buttonClicked = JOptionPane.OK_OPTION;
 980  
                 // Then, we log this new problem.
 981  0
                 String msg = "Unknown optionType in displayErr(String, Exception, int)";
 982  0
                 alertStr(msg);
 983  0
                 logErr(msg, null);
 984  
         }
 985  
 
 986  
         // First, we log the error.
 987  0
         logErr(errorText, exception);
 988  
 
 989  0
         return buttonClicked;
 990  
     }
 991  
 
 992  
     /**
 993  
      * If debug is off, the log window may not be visible. We switch the debug to on, to be sure that some information
 994  
      * will be displayed to the user. <BR>
 995  
      * If debug is -1, the log window remains hidden.
 996  
      * 
 997  
      * @see wjhk.jupload2.policies.UploadPolicy#displayErr(java.lang.String, java.lang.Exception)
 998  
      */
 999  
     public void displayErr(String errorText, Exception exception) {
 1000  0
         displayErr(errorText, exception, -1);
 1001  0
     }
 1002  
 
 1003  
     /**
 1004  
      * @see UploadPolicy#displayInfo(String)
 1005  
      */
 1006  
     public void displayInfo(String info) {
 1007  0
         displayMsg("[INFO]", info);
 1008  0
     }
 1009  
 
 1010  
     /**
 1011  
      * @see UploadPolicy#displayWarn(String)
 1012  
      */
 1013  
     public void displayWarn(String warn) {
 1014  0
         displayMsg("[WARN]", warn);
 1015  0
     }
 1016  
 
 1017  
     /**
 1018  
      * @see UploadPolicy#displayDebug(String, int)
 1019  
      */
 1020  
     public void displayDebug(String debug, int minDebugLevel) {
 1021  0
         final String tag = "[DEBUG]";
 1022  0
         if (this.debugLevel >= minDebugLevel) {
 1023  
             // displayMsg will add the message to the debugStrignBuffer.
 1024  0
             displayMsg(tag, debug);
 1025  0
         } else if (this.debugGenerateFile) {
 1026  
             // We have to write the message to the debug file, whatever the
 1027  
             // debugLevel is.
 1028  0
             addMsgToDebugLog(tag + debug);
 1029  
         }
 1030  0
     }
 1031  
 
 1032  
     /** @see UploadPolicy#getLocalizedString(String, Object...) */
 1033  
     public String getLocalizedString(String key, Object... args) {
 1034  0
         String ret = this.resourceBundle.getString(key);
 1035  
         try {
 1036  
             // We have to recreate the correct call to String.format
 1037  0
             switch (args.length) {
 1038  
                 case 0:
 1039  0
                     return String.format(ret);
 1040  
                 case 1:
 1041  0
                     return String.format(ret, args[0]);
 1042  
                 case 2:
 1043  0
                     return String.format(ret, args[0], args[1]);
 1044  
                 case 3:
 1045  0
                     return String.format(ret, args[0], args[1], args[2]);
 1046  
                 case 4:
 1047  0
                     return String.format(ret, args[0], args[1], args[2], args[3]);
 1048  
                 case 5:
 1049  0
                     return String.format(ret, args[0], args[1], args[2], args[3], args[4]);
 1050  
                 case 6:
 1051  0
                     return String.format(ret, args[0], args[1], args[2], args[3], args[4], args[5]);
 1052  
                 case 7:
 1053  0
                     return String.format(ret, args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
 1054  
                 default:
 1055  0
                     throw new IllegalArgumentException(
 1056  
                             "DefaultUploadPolicy.getLocalizedString accepts up to 7 variable parameters ("
 1057  
                                     + args.length + " values were given for the 'args' argument");
 1058  
             }
 1059  0
         } catch (IllegalFormatException ife) {
 1060  0
             displayErr(ife.getClass().getName() + " (" + ife.getMessage() + ")when managing this string: " + ret);
 1061  0
             throw ife;
 1062  
         }
 1063  
     }
 1064  
 
 1065  
     /**
 1066  
      * @see UploadPolicy#getUploadFilename(FileData, int)
 1067  
      */
 1068  
     public String getUploadFilename(FileData fileData, int index) throws JUploadException {
 1069  0
         return getEncodedFilename(fileData.getFileName());
 1070  
     }
 1071  
 
 1072  
     /**
 1073  
      * returns the filename and encodes it, if necessary
 1074  
      * 
 1075  
      * @param filename the original filename
 1076  
      * @return filename (encoded, if necessary)
 1077  
      * @throws JUploadException
 1078  
      */
 1079  
     protected final String getEncodedFilename(String filename) throws JUploadException {
 1080  0
         if (this.filenameEncoding == null || this.filenameEncoding.equals("")) {
 1081  0
             return filename;
 1082  
         }
 1083  
         try {
 1084  0
             return URLEncoder.encode(filename, this.filenameEncoding);
 1085  0
         } catch (UnsupportedEncodingException e) {
 1086  0
             throw new JUploadException(e);
 1087  
         }
 1088  
     }
 1089  
 
 1090  
     /** @see UploadPolicy#getUploadName(FileData, int) */
 1091  
     public String getUploadName(FileData fileData, int index) throws JUploadException {
 1092  0
         if (this.httpUploadParameterType.equals(UploadPolicy.HTTPUPLOADPARAMETERTYPE_ARRAY)) {
 1093  0
             return this.httpUploadParameterName + "[]";
 1094  0
         } else if (this.httpUploadParameterType.equals(UploadPolicy.HTTPUPLOADPARAMETERTYPE_ITERATION)) {
 1095  0
             return this.httpUploadParameterName + index;
 1096  0
         } else if (this.httpUploadParameterType.equals(UploadPolicy.HTTPUPLOADPARAMETERTYPE_ONE_FILE)) {
 1097  
             // Only valid if nbFilesPerRequest is 1. Let's check it.
 1098  0
             if (getNbFilesPerRequest() == 1) {
 1099  0
                 return this.httpUploadParameterName;
 1100  
             } else {
 1101  0
                 throw new JUploadException(UploadPolicy.PROP_HTTP_UPLOAD_PARAMETER_TYPE + " value '"
 1102  
                         + this.httpUploadParameterType + "' is only valid when '"
 1103  
                         + UploadPolicy.PROP_NB_FILES_PER_REQUEST + " is 1.");
 1104  
             }
 1105  
         } else {
 1106  0
             throw new JUploadException(UploadPolicy.PROP_HTTP_UPLOAD_PARAMETER_TYPE + " '"
 1107  
                     + this.httpUploadParameterType + "' is not implemented.");
 1108  
         }
 1109  
     }
 1110  
 
 1111  
     /** @see UploadPolicy#getHttpUploadParameterName() */
 1112  
     public String getHttpUploadParameterName() {
 1113  0
         return this.httpUploadParameterName;
 1114  
     }
 1115  
 
 1116  
     /**
 1117  
      * Setter for the {@link #httpUploadParameterName}. This value is used by the {@link #getUploadName(FileData, int)}
 1118  
      * method, to generate the name of the upload parameter that will contain the uploaded file.<BR>
 1119  
      * The name must begin by a letter, then contain letter or numbers
 1120  
      * 
 1121  
      * @throws JUploadException When the given value is invalid (null, empty string, or contains other characters than
 1122  
      *             letters and/or numbers)
 1123  
      */
 1124  
     protected void setHttpUploadParameterName(String httpUploadParameterName) throws JUploadException {
 1125  
         // Some useful checks.
 1126  0
         if (httpUploadParameterName == null || httpUploadParameterName.equals("")) {
 1127  0
             throw new JUploadException("httpUploadParameterName may not be null");
 1128  
         }
 1129  
         // Control the parameter name content.
 1130  0
         if (!httpUploadParameterName.matches("^[a-zA-Z0-9][a-zA-Z0-9_]*$")) {
 1131  0
             throw new JUploadException(
 1132  
                     "httpUploadParameterName may only contain letters (lowercase or uppercase) and numbers.");
 1133  
         }
 1134  
 
 1135  
         // Ok, we're happy with the given value. Let's store it.
 1136  0
         this.httpUploadParameterName = httpUploadParameterName;
 1137  0
     }
 1138  
 
 1139  
     /** @see UploadPolicy#getHttpUploadParameterType() */
 1140  
     public String getHttpUploadParameterType() {
 1141  0
         return this.httpUploadParameterType;
 1142  
     }
 1143  
 
 1144  
     /**
 1145  
      * Setter for the {@link #httpUploadParameterType}. This value is used by the {@link #getUploadName(FileData, int)}
 1146  
      * method, to generate the name of the upload parameter that will contain the uploaded file. Depending on this
 1147  
      * value, the parameter will be an iteration or an array.
 1148  
      * 
 1149  
      * @throws JUploadException
 1150  
      */
 1151  
     protected void setHttpUploadParameterType(String httpUploadParameterType) throws JUploadException {
 1152  
         // Some useful checks.
 1153  0
         if (httpUploadParameterType == null) {
 1154  0
             throw new JUploadException("httpUploadParameterType may not be null");
 1155  
         }
 1156  
 
 1157  
         // Check against the list of allowed values
 1158  0
         if (!httpUploadParameterType.equals(UploadPolicy.HTTPUPLOADPARAMETERTYPE_ARRAY)
 1159  0
                 && !httpUploadParameterType.equals(UploadPolicy.HTTPUPLOADPARAMETERTYPE_ITERATION)
 1160  0
                 && !httpUploadParameterType.equals(UploadPolicy.HTTPUPLOADPARAMETERTYPE_ONE_FILE)) {
 1161  0
             throw new JUploadException("'" + httpUploadParameterType
 1162  
                     + "' is not an allowed value for httpUploadParameterType.");
 1163  
         }
 1164  
 
 1165  
         // OneFile is only valid ... when we upload file per file !
 1166  0
         if (httpUploadParameterType.equals(UploadPolicy.HTTPUPLOADPARAMETERTYPE_ONE_FILE)) {
 1167  0
             if (getNbFilesPerRequest() != 1) {
 1168  0
                 throw new JUploadException("'" + httpUploadParameterType
 1169  
                         + "' is only valid when nbFilesPerRequest is 1.");
 1170  
             }
 1171  
         }
 1172  
 
 1173  
         // Ok, we're happy. Let's store the value !
 1174  0
         this.httpUploadParameterType = httpUploadParameterType;
 1175  0
     }
 1176  
 
 1177  
     /** @see wjhk.jupload2.policies.UploadPolicy#beforeUpload() */
 1178  
     public boolean beforeUpload() {
 1179  
         // Default : nothing to do before upload, so we're ready.
 1180  0
         return true;
 1181  
     }
 1182  
 
 1183  
     /** @see UploadPolicy#onAppendHeader(ByteArrayEncoder) */
 1184  
     public ByteArrayEncoder onAppendHeader(ByteArrayEncoder bae) throws JUploadIOException {
 1185  0
         Iterator<String> it = this.headers.iterator();
 1186  
         String header;
 1187  0
         displayDebug("[onAppendHeader] Start", 80);
 1188  0
         while (it.hasNext()) {
 1189  0
             header = it.next();
 1190  0
             if (header == null || header.equals("")) {
 1191  0
                 displayWarn("[onAppendHeader] Found one empty header. Ignoring it.");
 1192  
             } else {
 1193  0
                 bae.append(header).append("\r\n");
 1194  0
                 displayDebug("[onAppendHeader] Header appended; " + header, 80);
 1195  
             }
 1196  
         }
 1197  0
         displayDebug("[onAppendHeader] End", 80);
 1198  0
         return bae;
 1199  
     }// appendHeader
 1200  
 
 1201  
     /**
 1202  
      * Default implementation of the
 1203  
      * {@link wjhk.jupload2.policies.UploadPolicy#onFileSelected(wjhk.jupload2.filedata.FileData)} . Nothing's done.
 1204  
      */
 1205  
     public void onFileSelected(FileData fileData) {
 1206  
         // Default implementation : no action
 1207  0
     }
 1208  
 
 1209  
     /**
 1210  
      * Default implementation of the {@link wjhk.jupload2.policies.UploadPolicy#onFileDoubleClicked(FileData)} .
 1211  
      * Nothing's done.
 1212  
      */
 1213  
     public void onFileDoubleClicked(FileData fileData) {
 1214  
         // Default implementation : no action
 1215  0
     }
 1216  
 
 1217  
     /** @see UploadPolicy#sendDebugInformation(String, Exception) */
 1218  
     public void sendDebugInformation(String description, Exception exception) {
 1219  
         try {
 1220  0
             if (null == getUrlToSendErrorTo()) {
 1221  0
                 displayInfo("getUrlToSendErrorTo is null. No debug information is sent.");
 1222  0
                 if (exception == null) {
 1223  0
                     displayInfo("  No exception was stored!");
 1224  
                 } else {
 1225  0
                     displayInfo("  The exception was: " + exception.getClass().getName() + exception.getMessage());
 1226  
                 }
 1227  
             } else {
 1228  0
                 displayInfo("Sending debug information to " + getUrlToSendErrorTo());
 1229  0
                 if (JOptionPane.showConfirmDialog(null, getLocalizedString("questionSendMailOnError"),
 1230  0
                         getLocalizedString("Confirm"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) {
 1231  0
                     displayDebug("[sendDebugInformation] Within response == true", 30);
 1232  
 
 1233  0
                     String action = null;
 1234  
                     String line;
 1235  0
                     HTTPConnectionHelper connectionHelper = null;
 1236  0
                     boolean localDebugOk = this.debugOk;
 1237  
 
 1238  
                     try {
 1239  0
                         URL url = new URL(this.urlToSendErrorTo);
 1240  0
                         connectionHelper = new HTTPConnectionHelper(this);
 1241  0
                         connectionHelper.initRequest(url, "POST", false, true);
 1242  
 
 1243  0
                         ByteArrayEncoder baeContent = new ByteArrayEncoderHTTP(this, connectionHelper
 1244  0
                                 .getByteArrayEncoder().getBoundary(), connectionHelper.getByteArrayEncoder()
 1245  0
                                 .getEncoding());
 1246  
                         // The message is written in English, as it is not sure
 1247  
                         // that
 1248  
                         // the webmaster speaks the same language as the current
 1249  
                         // user.
 1250  0
                         baeContent.appendTextProperty("description", "An error occured during upload, in JUpload.", -1);
 1251  0
                         String exceptionClass = null;
 1252  0
                         String exceptionCause = null;
 1253  0
                         String exceptionStackTrace = null;
 1254  0
                         if (exception != null) {
 1255  0
                             exceptionClass = exception.getClass().getName();
 1256  0
                             if (exception.getCause() != null) {
 1257  0
                                 exceptionCause = exception.getCause().getClass().getName();
 1258  
                             }
 1259  0
                             StackTraceElement[] elements = exception.getStackTrace();
 1260  0
                             ByteArrayEncoderHTTP baeStackTrace = new ByteArrayEncoderHTTP(this, connectionHelper
 1261  0
                                     .getByteArrayEncoder().getBoundary(), connectionHelper.getByteArrayEncoder()
 1262  0
                                     .getEncoding());
 1263  0
                             for (int i = 0; i < elements.length; i += 1) {
 1264  0
                                 baeStackTrace.append(" at ");
 1265  0
                                 baeStackTrace.append(elements[i].getClassName());
 1266  0
                                 baeStackTrace.append(".");
 1267  0
                                 baeStackTrace.append(elements[i].getMethodName());
 1268  0
                                 baeStackTrace.append("() [line ");
 1269  0
                                 baeStackTrace.append(Integer.toString(elements[i].getLineNumber()));
 1270  0
                                 baeStackTrace.append("]\r\n");
 1271  
                             }
 1272  0
                             baeStackTrace.close();
 1273  0
                             exceptionStackTrace = baeStackTrace.getString();
 1274  
                         }
 1275  0
                         baeContent.appendTextProperty("exceptionClass", exceptionClass, -1);
 1276  0
                         baeContent.appendTextProperty("exceptionCause", exceptionCause, -1);
 1277  0
                         baeContent.appendTextProperty("exceptionStackTrace", exceptionStackTrace, -1);
 1278  
 
 1279  0
                         String baeBound = connectionHelper.getByteArrayEncoder().getBoundary();
 1280  0
                         String baeEncoding = connectionHelper.getByteArrayEncoder().getEncoding();
 1281  0
                         ByteArrayEncoder baeDebug = new ByteArrayEncoderHTTP(this, baeBound, baeEncoding);
 1282  0
                         if (this.debugGenerateFile) {
 1283  
                             // During debug output, we need to make sure that
 1284  
                             // the debug log is not changed, so we set debugOk
 1285  
                             // to false temporarily. -> Everything goes to
 1286  
                             // stdout.
 1287  0
                             action = "flush (debugGenerateFile=true)";
 1288  0
                             synchronized (this) {
 1289  0
                                 this.debugOut.flush();
 1290  0
                                 this.debugOk = false;
 1291  
                                 // First, calculate the size of the strings we
 1292  
                                 // will
 1293  
                                 // send.
 1294  0
                                 action = "read debug file (debugGenerateFile=true)";
 1295  0
                                 BufferedReader debugIn = new BufferedReader(new FileReader(this.debugFile));
 1296  0
                                 while ((line = debugIn.readLine()) != null) {
 1297  0
                                     baeDebug.append(line).append("\r\n");
 1298  
                                 }
 1299  0
                                 debugIn.close();
 1300  
 
 1301  
                                 // We are done with the debug log, so re-enable
 1302  
                                 // it.
 1303  0
                                 this.debugOk = localDebugOk;
 1304  0
                             }// synchronized(this)
 1305  
                         }// if (this.debugGenerateFile)
 1306  
                         else {
 1307  0
                             action = "read debug file (debugGenerateFile=false)";
 1308  0
                             baeDebug.append(this.juploadContext.getLogWindow().getText());
 1309  
                         }
 1310  0
                         action = "baeDebug.close()";
 1311  0
                         baeDebug.close();
 1312  
 
 1313  0
                         baeContent.appendTextProperty("debugOutput", baeDebug.getString(), -1);
 1314  0
                         baeContent.appendEndPropertyList();
 1315  
                         // The content has been built.
 1316  0
                         baeContent.close();
 1317  
 
 1318  
                         // byteArrayEncoder
 1319  
                         // .append("Content-type:
 1320  
                         // application/x-www-form-urlencoded\r\n");
 1321  0
                         action = "send request";
 1322  0
                         connectionHelper.append("Content-Type: multipart/form-data; boundary=")
 1323  0
                                 .append(connectionHelper.getBoundary().substring(2)).append("\r\n");
 1324  0
                         connectionHelper.append("Content-length: ")
 1325  0
                                 .append(String.valueOf(baeContent.getEncodedLength())).append("\r\n");
 1326  
 
 1327  
                         // Let's send the headers (without baeDescription) ...
 1328  0
                         connectionHelper.sendRequest();
 1329  
                         // Blank line (end of header)
 1330  0
                         connectionHelper.append("\r\n");
 1331  0
                         connectionHelper.append(baeContent);
 1332  
 
 1333  0
                         action = "connectionHelper.readHttpResponse()";
 1334  0
                         int status = connectionHelper.readHttpResponse();
 1335  
 
 1336  0
                         displayDebug(
 1337  
                                 "========================================================================================",
 1338  
                                 90);
 1339  0
                         displayDebug(
 1340  
                                 "==================      sendDebugInformation [start]   =================================",
 1341  
                                 90);
 1342  0
                         displayDebug(
 1343  
                                 "========================================================================================",
 1344  
                                 90);
 1345  0
                         displayDebug("[sendDebugInformation] Sent to server: \r\n"
 1346  0
                                 + connectionHelper.getByteArrayEncoder().getString(), 90);
 1347  0
                         displayDebug(
 1348  
                                 "========================================================================================",
 1349  
                                 90);
 1350  0
                         displayDebug("[sendDebugInformation] Body received: \r\n" + connectionHelper.getResponseBody(),
 1351  
                                 90);
 1352  0
                         displayDebug(
 1353  
                                 "========================================================================================",
 1354  
                                 90);
 1355  0
                         displayDebug(
 1356  
                                 "==================      sendDebugInformation [end]     =================================",
 1357  
                                 90);
 1358  0
                         displayDebug(
 1359  
                                 "========================================================================================",
 1360  
                                 90);
 1361  
 
 1362  
                         // Is our upload a success ?
 1363  0
                         if (!checkUploadSuccess(status, connectionHelper.getResponseMsg(),
 1364  0
                                 connectionHelper.getResponseBody())) {
 1365  0
                             throw new JUploadExceptionUploadFailed(getLocalizedString("errHttpResponse"));
 1366  
                         }
 1367  
 
 1368  0
                         displayInfo("debug information sent correctly");
 1369  0
                     } catch (MalformedURLException e) {
 1370  0
                         throw new JUploadIOException("Malformed URL Exception for " + this.urlToSendErrorTo, e);
 1371  0
                     } catch (Exception e) {
 1372  0
                         this.debugOk = localDebugOk;
 1373  0
                         displayErr(getLocalizedString("errDuringLogManagement") + " (" + action + ")", e);
 1374  0
                     } finally {
 1375  0
                         this.debugOk = localDebugOk;
 1376  0
                     }
 1377  
                 }
 1378  
             }
 1379  0
         } catch (JUploadIOException e) {
 1380  0
             displayErr("Could not send debug information", e);
 1381  0
         }
 1382  0
     }// sendDebugInformation
 1383  
 
 1384  
     /**
 1385  
      * This method manages all applet parameters. It allows javascript to update their value, for instance after the
 1386  
      * user chooses a value in a list ...
 1387  
      * 
 1388  
      * @throws JUploadException
 1389  
      * @see wjhk.jupload2.policies.UploadPolicy#setProperty(java.lang.String, java.lang.String)
 1390  
      */
 1391  
     public void setProperty(String prop, String value) throws JUploadException {
 1392  
 
 1393  0
         displayDebug("[DefaultUploadPolicy] Call of setProperty: " + prop + " => " + value, 30);
 1394  
 
 1395  0
         if (prop.equals(PROP_AFTER_UPLOAD_URL)) {
 1396  0
             setAfterUploadURL(value);
 1397  0
         } else if (prop.equals(PROP_ALLOW_HTTP_PERSISTENT)) {
 1398  0
             setAllowHttpPersistent(Boolean.parseBoolean(value));
 1399  0
         } else if (prop.equals(PROP_ALLOWED_FILE_EXTENSIONS)) {
 1400  0
             setAllowedFileExtensions(value);
 1401  0
         } else if (prop.equals(PROP_DEBUG_LEVEL)) {
 1402  0
             setDebugLevel(this.juploadContext.parseInt(value, this.debugLevel));
 1403  0
         } else if (prop.equals(PROP_FILE_CHOOSER_ICON_FROM_FILE_CONTENT)) {
 1404  0
             setFileChooserIconFromFileContent(this.juploadContext.parseInt(value, getFileChooserIconFromFileContent()));
 1405  0
         } else if (prop.equals(PROP_FILE_CHOOSER_ICON_SIZE)) {
 1406  0
             setFileChooserIconSize(this.juploadContext.parseInt(value, getFileChooserIconSize()));
 1407  0
         } else if (prop.equals(PROP_FILE_FILTER_NAME)) {
 1408  0
             setFileFilterName(value);
 1409  0
         } else if (prop.equals(PROP_FILENAME_ENCODING)) {
 1410  0
             setFilenameEncoding(value);
 1411  0
         } else if (prop.equals(PROP_LANG)) {
 1412  0
             setLang(value);
 1413  0
         } else if (prop.equals(PROP_LOOK_AND_FEEL)) {
 1414  0
             setLookAndFeel(value);
 1415  0
         } else if (prop.equals(PROP_MAX_CHUNK_SIZE)) {
 1416  0
             setMaxChunkSize(this.juploadContext.parseLong(value, this.maxChunkSize));
 1417  0
         } else if (prop.equals(PROP_MAX_FILE_SIZE)) {
 1418  0
             setMaxFileSize(this.juploadContext.parseLong(value, this.maxFileSize));
 1419  0
         } else if (prop.equals(PROP_NB_FILES_PER_REQUEST)) {
 1420  0
             setNbFilesPerRequest(this.juploadContext.parseInt(value, this.nbFilesPerRequest));
 1421  0
         } else if (prop.equals(PROP_POST_URL)) {
 1422  0
             setPostURL(value);
 1423  0
         } else if (prop.equals(PROP_SERVER_PROTOCOL)) {
 1424  
             // No specific action: the computeServerProtocol() is called once everything is initialized,
 1425  
             // and the applet is ready for the user. This allows to give the 'hand' to the user quicker.
 1426  
             // HttpProtocolFinderThread.computeServerProtocol(this, value);
 1427  0
         } else if (prop.equals(PROP_STRING_UPLOAD_SUCCESS)) {
 1428  0
             setStringUploadSuccess(value);
 1429  0
         } else if (prop.equals(PROP_SSL_VERIFY_CERT)) {
 1430  0
             setSslVerifyCert(value);
 1431  0
         } else if (prop.equals(PROP_URL_TO_SEND_ERROR_TO)) {
 1432  0
             setUrlToSendErrorTo(value);
 1433  
         } else {
 1434  0
             displayWarn("Unknown applet parameter: " + prop + " (in DefaultUploadPolicy.setProperty)");
 1435  
         }
 1436  0
     }
 1437  
 
 1438  
     /**
 1439  
      * This method displays the applet parameter list, according to the current debugLevel. It is called by the
 1440  
      * {@link #setDebugLevel(int)} method. It should be override by any subclasses, that should display its own
 1441  
      * parameters, then call <I>super.displayParameterStatus()</I>.
 1442  
      * 
 1443  
      * @see UploadPolicy#displayParameterStatus()
 1444  
      */
 1445  
     public void displayParameterStatus() {
 1446  0
         displayDebug("=======================================================================", 30);
 1447  0
         displayDebug("======= Parameters managed by DefaultUploadPolicy", 30);
 1448  
         // /////////////////////////////////////////////////////////////////////////////
 1449  
         // Let's display some information to the user, about the received
 1450  
         // parameters.
 1451  0
         displayInfo("JUpload applet, version " + this.juploadContext.getDetailedVersionMessage() + " (compiled: "
 1452  0
                 + this.juploadContext.getBuildDate() + "), available at http://jupload.sourceforge.net/");
 1453  0
         displayDebug("Java version: " + System.getProperty("java.version"), 30);
 1454  
 
 1455  0
         displayDebug("List of all applet parameters:", 30);
 1456  0
         displayDebug("  language: " + this.resourceBundle.getLocale().getLanguage(), 30);
 1457  0
         displayDebug("  country: " + this.resourceBundle.getLocale().getCountry(), 30);
 1458  
 
 1459  0
         displayDebug(PROP_AFTER_UPLOAD_URL + ": " + getAfterUploadURL(), 30);
 1460  0
         displayDebug(PROP_ALLOW_HTTP_PERSISTENT + ": " + getAllowHttpPersistent(), 30);
 1461  0
         displayDebug(PROP_ALLOWED_FILE_EXTENSIONS + ": " + getAllowedFileExtensions(), 30);
 1462  0
         displayDebug(PROP_BROWSING_DIRECTORY + " (current value): " + getCurrentBrowsingDirectory(), 30);
 1463  0
         displayDebug(PROP_DEBUG_LEVEL + ": " + this.debugLevel, 1);
 1464  0
         synchronized (this) {
 1465  0
             if (this.debugGenerateFile) {
 1466  0
                 displayDebug("  (debugfile: " + this.debugFile.getAbsolutePath() + ")", 1);
 1467  
             }
 1468  0
         }
 1469  0
         displayDebug(PROP_FILE_CHOOSER_ICON_FROM_FILE_CONTENT + ": " + getFileChooserIconFromFileContent(), 30);
 1470  0
         displayDebug(PROP_FILE_CHOOSER_ICON_SIZE + ": " + getFileChooserIconSize(), 30);
 1471  0
         displayDebug(PROP_FILE_FILTER_NAME + ": " + getFileFilterName(), 30);
 1472  0
         displayDebug(PROP_FILE_LIST_VIEW_MODE + ": " + getFileListViewMode(), 30);
 1473  0
         displayDebug(PROP_FILENAME_ENCODING + ": " + getFilenameEncoding(), 30);
 1474  0
         displayDebug(PROP_FORMDATA + ": " + getFormdata(), 30);
 1475  0
         displayDebug(PROP_FTP_CREATE_DIRECTORY_STRUCTURE + ": " + getFtpCreateDirectoryStructure(), 30);
 1476  0
         displayDebug(PROP_FTP_TRANSFERT_BINARY + ": " + getFtpTransfertBinary(), 30);
 1477  0
         displayDebug(PROP_FTP_TRANSFERT_PASSIVE + ": " + getFtpTransfertPassive(), 30);
 1478  0
         displayDebug(PROP_HTTP_UPLOAD_PARAMETER_NAME + ": " + getHttpUploadParameterName(), 30);
 1479  0
         displayDebug(PROP_HTTP_UPLOAD_PARAMETER_TYPE + ": " + getHttpUploadParameterType(), 30);
 1480  0
         displayDebug("lang: " + this.lang, 30);
 1481  0
         displayDebug(PROP_MAX_CHUNK_SIZE + ": " + getMaxChunkSize(), 30);
 1482  0
         if (this.maxFileSize == Long.MAX_VALUE) {
 1483  
             // If the maxFileSize was not given, we display its value only
 1484  
             // in debug mode.
 1485  0
             displayDebug(PROP_MAX_FILE_SIZE + ": " + getMaxFileSize(), 30);
 1486  
         } else {
 1487  
             // If the maxFileSize was given, we always inform the user.
 1488  0
             displayInfo(PROP_MAX_FILE_SIZE + ": " + getMaxFileSize());
 1489  
         }
 1490  0
         displayDebug(PROP_NB_FILES_PER_REQUEST + ": " + getNbFilesPerRequest(), 30);
 1491  0
         displayDebug(PROP_POST_URL + ": " + this.postURL, 30);
 1492  0
         displayDebug(PROP_READ_COOKIE_FROM_NAVIGATOR + ": " + this.readCookieFromNavigator, 30);
 1493  0
         displayDebug(PROP_READ_USER_AGENT_FROM_NAVIGATOR + ": " + this.readUserAgentFromNavigator, 30);
 1494  0
         displayDebug(PROP_RETRY_MAX_NUMBER_OF + ": " + this.retryMaxNumberOf, 30);
 1495  0
         displayDebug(PROP_RETRY_NB_SECONDS_BETWEEN + ": " + this.retryNbSecondsBetween, 30);
 1496  0
         displayDebug(PROP_SEND_MD5_SUM + ": " + getSendMD5Sum(), 30);
 1497  0
         displayDebug(PROP_SERVER_PROTOCOL + ": " + getServerProtocol(), 30);
 1498  0
         displayDebug(PROP_SHOW_LOGWINDOW + ": " + getShowLogWindow(), 30);
 1499  0
         displayDebug(PROP_SHOW_STATUSBAR + ": " + this.showStatusbar, 30);
 1500  0
         displayDebug(PROP_SPECIFIC_HEADERS + ": " + getSpecificHeaders(), 30);
 1501  
 
 1502  0
         displayDebug("Headers that will be added to the POST request: ", 30);
 1503  0
         for (Iterator<String> it = this.headers.iterator(); it.hasNext();) {
 1504  0
             displayDebug(it.next() + "\n", 30);
 1505  
         }
 1506  0
         displayDebug(PROP_STRING_UPLOAD_ERROR + ": " + getStringUploadError(), 30);
 1507  0
         displayDebug(PROP_STRING_UPLOAD_SUCCESS + ": " + getStringUploadSuccess(), 30);
 1508  0
         displayDebug(PROP_STRING_UPLOAD_WARNING + ": " + getStringUploadWarning(), 30);
 1509  0
         displayDebug(PROP_URL_TO_SEND_ERROR_TO + ": " + getUrlToSendErrorTo(), 30);
 1510  0
         displayDebug("", 30);
 1511  0
     }
 1512  
 
 1513  
     // //////////////////////////////////////////////////////////////////////////////////////////////
 1514  
     // /////////////////// getters / setters
 1515  
     // ///////////////////////////////////////////////////
 1516  
     // //////////////////////////////////////////////////////////////////////////////////////////////
 1517  
 
 1518  
     /** @see UploadPolicy#getAfterUploadURL() */
 1519  
     public String getAfterUploadURL() {
 1520  0
         return this.afterUploadURL;
 1521  
     }
 1522  
 
 1523  
     /**
 1524  
      * Set the {@link #afterUploadURL}
 1525  
      * 
 1526  
      * @param afterUploadURL The URL to use.
 1527  
      * @throws JUploadException
 1528  
      */
 1529  
     protected void setAfterUploadURL(String afterUploadURL) throws JUploadException {
 1530  0
         if (null == afterUploadURL)
 1531  0
             return;
 1532  0
         if (afterUploadURL.toLowerCase().startsWith("javascript:")) {
 1533  0
             this.afterUploadURL = afterUploadURL;
 1534  
         } else
 1535  0
             this.afterUploadURL = this.juploadContext.normalizeURL(afterUploadURL);
 1536  0
     }
 1537  
 
 1538  
     /**
 1539  
      * @see wjhk.jupload2.policies.UploadPolicy#getAllowHttpPersistent()
 1540  
      */
 1541  
     public boolean getAllowHttpPersistent() {
 1542  0
         return this.allowHttpPersistent;
 1543  
     }
 1544  
 
 1545  
     /** @see UploadPolicy#getAllowedFileExtensions() */
 1546  
     public String getAllowedFileExtensions() {
 1547  0
         return this.allowedFileExtensions;
 1548  
     }
 1549  
 
 1550  
     /**
 1551  
      * @param allowedFileExtensions the allowedFileExtensions to set
 1552  
      */
 1553  
     protected void setAllowedFileExtensions(String allowedFileExtensions) {
 1554  0
         if (allowedFileExtensions == null || allowedFileExtensions.equals("")) {
 1555  0
             this.allowedFileExtensions = null;
 1556  
         } else {
 1557  0
             this.allowedFileExtensions = (allowedFileExtensions.startsWith("/") ? "" : "/")
 1558  0
                     + allowedFileExtensions.toLowerCase() + (allowedFileExtensions.endsWith("/") ? "" : "/");
 1559  
         }
 1560  0
     }
 1561  
 
 1562  
     protected void setAllowHttpPersistent(boolean value) {
 1563  0
         this.allowHttpPersistent = value;
 1564  0
     }
 1565  
 
 1566  
     /** @see UploadPolicy#getContext() */
 1567  
     public JUploadContext getContext() {
 1568  0
         return this.juploadContext;
 1569  
     }
 1570  
 
 1571  
     /** {@inheritDoc} */
 1572  
     public void setCurrentBrowsingDirectory(File currentBrowsingDirectoryParam) {
 1573  
         try {
 1574  0
             if (currentBrowsingDirectoryParam.isDirectory()) {
 1575  0
                 this.currentBrowsingDirectory = currentBrowsingDirectoryParam;
 1576  
             } else {
 1577  0
                 displayWarn("DefaultUploadPolicy.setCurrentBrowsingDirectory(): " + currentBrowsingDirectoryParam
 1578  
                         + " doesn't exist.");
 1579  
             }
 1580  0
         } catch (SecurityException se) {
 1581  0
             displayWarn(se.getClass().getName() + " in DefaultUploadPolicy.setCurrentBrowsingDirectory(): "
 1582  
                     + currentBrowsingDirectoryParam + " is ignored.");
 1583  0
         }
 1584  0
     }
 1585  
 
 1586  
     /**
 1587  
      * @param currentBrowsingDirectoryParam The name of the directory that should be the current one.
 1588  
      * @see UploadPolicy#setCurrentBrowsingDirectory(String)
 1589  
      */
 1590  
     public void setCurrentBrowsingDirectory(String currentBrowsingDirectoryParam) {
 1591  
         try {
 1592  0
             if (currentBrowsingDirectoryParam == null) {
 1593  0
                 this.currentBrowsingDirectory = null;
 1594  
             } else {
 1595  
                 // Apparently, Java deosn't manage path beginning by ~. folder
 1596  
                 // is actually ... ~!
 1597  
                 // Let's manager this.
 1598  0
                 if (currentBrowsingDirectoryParam.startsWith("~")) {
 1599  
                     // Let's keep the part of this path that is after the ~
 1600  0
                     currentBrowsingDirectoryParam = System.getProperty("user.home")
 1601  0
                             + currentBrowsingDirectoryParam.substring(1);
 1602  
                 }
 1603  
 
 1604  0
                 this.currentBrowsingDirectory = new File(currentBrowsingDirectoryParam);
 1605  
 
 1606  
                 // Let's check that we have a folder.
 1607  0
                 if (this.currentBrowsingDirectory != null && !this.currentBrowsingDirectory.isDirectory()) {
 1608  0
                     displayWarn("DefaultUploadPolicy.setCurrentBrowsingDirectory(): <" + currentBrowsingDirectoryParam
 1609  
                             + "> doesn't exist or is not a directory.");
 1610  0
                     this.currentBrowsingDirectory = null;
 1611  
                 }
 1612  
             }
 1613  0
         } catch (SecurityException se) {
 1614  0
             displayWarn(se.getClass().getName() + " in DefaultUploadPolicy.setCurrentBrowsingDirectory(): "
 1615  
                     + currentBrowsingDirectoryParam + " is ignored.");
 1616  0
         }
 1617  0
     }
 1618  
 
 1619  
     /** @see UploadPolicy#getCurrentBrowsingDirectory() */
 1620  
     public File getCurrentBrowsingDirectory() {
 1621  0
         return this.currentBrowsingDirectory;
 1622  
     }
 1623  
 
 1624  
     /** @see UploadPolicy#getDateFormat() */
 1625  
     public String getDateFormat() {
 1626  0
         return UploadPolicy.DEFAULT_DATE_FORMAT;
 1627  
     }
 1628  
 
 1629  
     /** @see UploadPolicy#getDebugLevel() */
 1630  
     public int getDebugLevel() {
 1631  0
         return this.debugLevel;
 1632  
     }
 1633  
 
 1634  
     /** @see UploadPolicy#setDebugLevel(int) */
 1635  
     public void setDebugLevel(int debugLevel) {
 1636  0
         setDebugLevel(debugLevel, true);
 1637  0
     }
 1638  
 
 1639  
     /**
 1640  
      * Set the debug level.
 1641  
      * 
 1642  
      * @param debugLevel The new debuglevel.
 1643  
      * @param displayAppletParameterList Flag. If set to true, the applet's parameters are shown.
 1644  
      */
 1645  
     public synchronized void setDebugLevel(int debugLevel, boolean displayAppletParameterList) {
 1646  
         // If the debugLevel was previously set, we inform the user of this
 1647  
         // change.
 1648  0
         if (this.debugLevel >= 0) {
 1649  0
             displayInfo("Debug level set to " + debugLevel);
 1650  0
             if (this.debugGenerateFile) {
 1651  0
                 displayInfo("Current debug output file: " + this.debugFile.getAbsolutePath());
 1652  
             }
 1653  
         }
 1654  0
         this.debugLevel = debugLevel;
 1655  
 
 1656  
         // Let's display the current applet parameters.
 1657  0
         if (displayAppletParameterList) {
 1658  0
             displayParameterStatus();
 1659  
         }
 1660  0
     }
 1661  
 
 1662  
     /**
 1663  
      * Getter for fileChooserIconFromFileContent.
 1664  
      * 
 1665  
      * @return Current value for fileChooserIconFromFileContent
 1666  
      * @see UploadPolicy#PROP_FILE_CHOOSER_ICON_FROM_FILE_CONTENT
 1667  
      */
 1668  
     public int getFileChooserIconFromFileContent() {
 1669  0
         return this.fileChooserIconFromFileContent;
 1670  
     }
 1671  
 
 1672  
     /**
 1673  
      * Setter for fileChooserIconFromFileContent. Current allowed values are: -1, 0, 1. Default value is 0.
 1674  
      * 
 1675  
      * @param fileChooserIconFromFileContent Value to be set. If the value is not allowed (not -1, 0 or 1), the current
 1676  
      *            value is unchangeed.
 1677  
      * @exception java.lang.IllegalArgumentException When a value not in -1, 0 1 is given.
 1678  
      * @see UploadPolicy#PROP_FILE_CHOOSER_ICON_FROM_FILE_CONTENT
 1679  
      */
 1680  
     public void setFileChooserIconFromFileContent(int fileChooserIconFromFileContent) {
 1681  0
         if (fileChooserIconFromFileContent != -1 && fileChooserIconFromFileContent != 0
 1682  
                 && fileChooserIconFromFileContent != 1) {
 1683  0
             throw new java.lang.IllegalArgumentException("fileChooserIconFromFileContent must be one of -1, 0, 1");
 1684  
         }
 1685  0
         this.fileChooserIconFromFileContent = fileChooserIconFromFileContent;
 1686  0
     }
 1687  
 
 1688  
     /**
 1689  
      * Getter for fileChooserIconSize.
 1690  
      * 
 1691  
      * @return Current value for fileChooserIconSize
 1692  
      * @see UploadPolicy#PROP_FILE_CHOOSER_ICON_SIZE
 1693  
      */
 1694  
     public int getFileChooserIconSize() {
 1695  0
         return this.fileChooserIconSize;
 1696  
     }
 1697  
 
 1698  
     /**
 1699  
      * Setter for fileChooserIconSize.
 1700  
      * 
 1701  
      * @param fileChooserIconSize Value to be set.
 1702  
      * @exception java.lang.IllegalArgumentException When a negative value is given.
 1703  
      * @see UploadPolicy#PROP_FILE_CHOOSER_ICON_SIZE
 1704  
      */
 1705  
     public void setFileChooserIconSize(int fileChooserIconSize) {
 1706  0
         if (fileChooserIconSize <= 0) {
 1707  0
             throw new java.lang.IllegalArgumentException("fileChooserIconSize must be more than 0");
 1708  
         }
 1709  0
         this.fileChooserIconSize = fileChooserIconSize;
 1710  0
     }
 1711  
 
 1712  
     /** @see wjhk.jupload2.policies.UploadPolicy#setLang(String) */
 1713  
     public void setLang(String lang) {
 1714  0
         this.lang = lang;
 1715  0
         if (lang == null) {
 1716  0
             displayInfo("lang = null, taking default language");
 1717  0
             locale = Locale.getDefault();
 1718  
         } else {
 1719  
             // If we have a 5 characters lang string, then it should look like
 1720  
             // ll_CC, where ll is the language code
 1721  
             // and CC is the Country code.
 1722  0
             if (lang.length() == 5 && (lang.substring(2, 3).equals("_") || lang.substring(2, 3).equals("-"))) {
 1723  0
                 String language = lang.substring(0, 2);
 1724  0
                 String country = lang.substring(3, 5);
 1725  0
                 displayDebug("setLang - language read: " + language, 50);
 1726  0
                 displayDebug("setLang - country read: " + country, 50);
 1727  0
                 locale = new Locale(language, country.toUpperCase());
 1728  0
             } else {
 1729  0
                 locale = new Locale(lang);
 1730  0
                 displayDebug("setLang - language read (no country): " + lang, 50);
 1731  
             }
 1732  
         }
 1733  
 
 1734  
         /*
 1735  
          * Patch given by Patrick Use of a specific class loader. The standard ResourceBundle checks first for a class
 1736  
          * that has the name of the resource bundle. Since there is no such class in the jar file, the AppletClassLoader
 1737  
          * makes a http request to the server, which will end with a 404 since there is no such class either. To avoid
 1738  
          * this unnecessary lookup we use a class loader that throws directly a ClassNotFoundException. After looking
 1739  
          * for a class (which is unsuccessful) ResourceBundle looks finally for a properties file. Therefore we delegate
 1740  
          * that lookup to the original class loader since this is in the jar file.
 1741  
          */
 1742  0
         this.resourceBundle = ResourceBundle.getBundle("lang.lang", locale,
 1743  
         // Special class loader, see description above
 1744  66
                 new ClassLoader(this.getClass().getClassLoader()) {
 1745  
                     /** {@inheritDoc} */
 1746  
                     @Override
 1747  
                     public Class<?> loadClass(String name) throws ClassNotFoundException {
 1748  196
                         throw new ClassNotFoundException();
 1749  
                     }
 1750  
 
 1751  
                     /** {@inheritDoc} */
 1752  
                     @Override
 1753  
                     public InputStream getResourceAsStream(String name) {
 1754  196
                         return this.getClass().getClassLoader().getResourceAsStream(name);
 1755  
                     }
 1756  
                 });
 1757  0
     }
 1758  
 
 1759  
     /** {@inheritDoc} */
 1760  
     public Locale getLocale() {
 1761  0
         return this.locale;
 1762  
     }
 1763  
 
 1764  
     /**
 1765  
      */
 1766  
     protected String getLookAndFeel() {
 1767  0
         return this.lookAndFeel;
 1768  
     }
 1769  
 
 1770  
     /**
 1771  
      * @param lookAndFeel the lookAndFeel to set
 1772  
      */
 1773  
     protected void setLookAndFeel(String lookAndFeel) {
 1774  
         try {
 1775  0
             this.lookAndFeel = lookAndFeel;
 1776  0
             if (lookAndFeel != null && !lookAndFeel.equals("") && !lookAndFeel.equals("java")) {
 1777  
                 // We try to call the UIManager.setLookAndFeel() method. We
 1778  
                 // catch
 1779  
                 // all possible exceptions, to prevent
 1780  
                 // that the applet is blocked.
 1781  0
                 if (!lookAndFeel.equals("system")) {
 1782  
                     // Correction given by Fritz. Thanks to him.
 1783  0
                     UIManager.setLookAndFeel(lookAndFeel);
 1784  
                 } else {
 1785  0
                     UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
 1786  
                 }
 1787  
             } else {
 1788  0
                 this.lookAndFeel = "java";
 1789  0
                 UIManager.setLookAndFeel(new javax.swing.plaf.metal.MetalLookAndFeel());
 1790  
             }
 1791  0
         } catch (Exception e) {
 1792  0
             displayErr(e);
 1793  
             try {
 1794  0
                 this.lookAndFeel = "java";
 1795  0
                 UIManager.setLookAndFeel(new javax.swing.plaf.metal.MetalLookAndFeel());
 1796  0
             } catch (UnsupportedLookAndFeelException e1) {
 1797  0
                 displayErr(e1);
 1798  
                 // Hum, hum: we should not arrive here... We not a 'dummy' one.
 1799  0
                 this.lookAndFeel = null;
 1800  0
             }
 1801  0
         }
 1802  0
     }
 1803  
 
 1804  
     /** @see wjhk.jupload2.policies.UploadPolicy#getMaxChunkSize() */
 1805  
     public long getMaxChunkSize() {
 1806  0
         return this.maxChunkSize;
 1807  
     }
 1808  
 
 1809  
     /**
 1810  
      * If the given value is less or equals to 0, it is set back to Long_MAX_VALUE.
 1811  
      * 
 1812  
      * @param maxChunkSize the maxChunkSize to set
 1813  
      */
 1814  
     protected void setMaxChunkSize(long maxChunkSize) {
 1815  0
         if (maxChunkSize <= 0) {
 1816  0
             displayDebug("maxChunkSize<=0 which is invalid. Switched to the default value (Long.MAX_VALUE)", 1);
 1817  0
             maxChunkSize = Long.MAX_VALUE;
 1818  
         }
 1819  0
         this.maxChunkSize = maxChunkSize;
 1820  0
     }
 1821  
 
 1822  
     /** @see wjhk.jupload2.policies.UploadPolicy#getMaxFileSize() */
 1823  
     public long getMaxFileSize() {
 1824  0
         return this.maxFileSize;
 1825  
     }
 1826  
 
 1827  
     /**
 1828  
      * @param maxFileSize the maxFileSize to set
 1829  
      */
 1830  
     protected void setMaxFileSize(long maxFileSize) {
 1831  0
         if (maxFileSize <= 0) {
 1832  0
             displayDebug("maxFileSize<=0 which is invalid. Switched to the default value (Long.MAX_VALUE)", 1);
 1833  0
             maxFileSize = Long.MAX_VALUE;
 1834  
         }
 1835  0
         this.maxFileSize = maxFileSize;
 1836  0
     }
 1837  
 
 1838  
     /** @see wjhk.jupload2.policies.UploadPolicy#getNbFilesPerRequest() */
 1839  
     public int getNbFilesPerRequest() {
 1840  0
         return this.nbFilesPerRequest;
 1841  
     }
 1842  
 
 1843  
     /**
 1844  
      * @param nbFilesPerRequest the nbFilesPerRequest to set
 1845  
      * @throws JUploadException
 1846  
      */
 1847  
     protected void setNbFilesPerRequest(int nbFilesPerRequest) throws JUploadException {
 1848  
         // If httpUploadParameterType is oneFile,
 1849  0
         if (getHttpUploadParameterType().equals(UploadPolicy.HTTPUPLOADPARAMETERTYPE_ONE_FILE)
 1850  
                 && nbFilesPerRequest != 1) {
 1851  0
             throw new JUploadException("nbFilesPerRequest must be 1, when httpUploadParameterType is oneFile");
 1852  
         }
 1853  
 
 1854  0
         if (nbFilesPerRequest < 1) {
 1855  0
             displayDebug("nbFilesPerRequest <1 : switched to the 'unlimited' value (Integer.MAX_VALUE)", 1);
 1856  0
             this.nbFilesPerRequest = Integer.MAX_VALUE;
 1857  
         } else {
 1858  0
             this.nbFilesPerRequest = nbFilesPerRequest;
 1859  
         }
 1860  0
     }
 1861  
 
 1862  
     /** @see UploadPolicy#getFileListViewMode() */
 1863  
     public FileListViewMode getFileListViewMode() {
 1864  0
         return fileListViewMode;
 1865  
     }
 1866  
 
 1867  
     /** @see UploadPolicy#getFileListViewMode() */
 1868  
     public void setFileListViewMode(FileListViewMode fileListViewMode) {
 1869  0
         this.fileListViewMode = fileListViewMode;
 1870  0
     }
 1871  
 
 1872  
     /** @see UploadPolicy#getFilenameEncoding() */
 1873  
     @Deprecated
 1874  
     public String getFilenameEncoding() {
 1875  0
         return this.filenameEncoding;
 1876  
     }
 1877  
 
 1878  
     /** @see UploadPolicy#getFileFilterName() */
 1879  
     public String getFileFilterName() {
 1880  0
         return this.fileFilterName;
 1881  
     }
 1882  
 
 1883  
     /**
 1884  
      * @param fileFilterName The new name for the fileFilter
 1885  
      * @see UploadPolicy#PROP_FILE_FILTER_NAME
 1886  
      */
 1887  
     protected void setFileFilterName(String fileFilterName) {
 1888  0
         this.fileFilterName = fileFilterName;
 1889  0
     }
 1890  
 
 1891  
     /**
 1892  
      * @param filenameEncoding the filenameEncoding to set
 1893  
      */
 1894  
     protected void setFilenameEncoding(String filenameEncoding) {
 1895  0
         if (filenameEncoding != null && filenameEncoding.equals("")) {
 1896  0
             filenameEncoding = null;
 1897  
         }
 1898  0
         if (filenameEncoding != null && !Charset.isSupported(filenameEncoding)) {
 1899  0
             throw new UnsupportedCharsetException("non supported charset (" + filenameEncoding + ")");
 1900  
         }
 1901  0
         this.filenameEncoding = filenameEncoding;
 1902  0
     }
 1903  
 
 1904  
     /** @see UploadPolicy#getFtpCreateDirectoryStructure() */
 1905  
     public boolean getFtpCreateDirectoryStructure() {
 1906  0
         return this.ftpCreateDirectoryStructure;
 1907  
     }
 1908  
 
 1909  
     /**
 1910  
      * @param ftpCreateDirectoryStructure the ftpCreateDirectoryStructure to set
 1911  
      */
 1912  
     protected void setFtpCreateDirectoryStructure(boolean ftpCreateDirectoryStructure) {
 1913  0
         this.ftpCreateDirectoryStructure = ftpCreateDirectoryStructure;
 1914  0
     }
 1915  
 
 1916  
     /** @see UploadPolicy#getFtpTransfertBinary() */
 1917  
     public boolean getFtpTransfertBinary() {
 1918  0
         return this.ftpTransfertBinary;
 1919  
     }
 1920  
 
 1921  
     /**
 1922  
      * @param ftpTransfertBinary the ftpTransfertBinary to set
 1923  
      */
 1924  
     protected void setFtpTransfertBinary(boolean ftpTransfertBinary) {
 1925  0
         this.ftpTransfertBinary = ftpTransfertBinary;
 1926  0
     }
 1927  
 
 1928  
     /** @see UploadPolicy#getFtpTransfertPassive() */
 1929  
     public boolean getFtpTransfertPassive() {
 1930  0
         return this.ftpTransfertPassive;
 1931  
     }
 1932  
 
 1933  
     /**
 1934  
      * @param ftpTransfertPassive the ftpTransfertPassive to set
 1935  
      */
 1936  
     protected void setFtpTransfertPassive(boolean ftpTransfertPassive) {
 1937  0
         this.ftpTransfertPassive = ftpTransfertPassive;
 1938  0
     }
 1939  
 
 1940  
     /** @see wjhk.jupload2.policies.UploadPolicy#getPostURL() */
 1941  
     public String getPostURL() {
 1942  0
         return this.postURL;
 1943  
     }
 1944  
 
 1945  
     /**
 1946  
      * @throws JUploadException
 1947  
      * @see wjhk.jupload2.policies.UploadPolicy#setPostURL(String)
 1948  
      */
 1949  
     public void setPostURL(String postURL) throws JUploadException {
 1950  
         // Be more forgiving about postURL:
 1951  
         // - If none is specified, use the original DocumentBase of the
 1952  
         // applet.
 1953  
         // - If a non-absolute URI (an URI without protocol and server) is
 1954  
         // specified,
 1955  
         // prefix it with "http://servername"
 1956  
         // - If a relative URI is specified, prefix it with the DocumentBase's
 1957  
         // parent
 1958  0
         this.postURL = this.juploadContext.normalizeURL(postURL);
 1959  0
     }
 1960  
 
 1961  
     /** @see wjhk.jupload2.policies.UploadPolicy#getReadCookieFromNavigator() */
 1962  
     public boolean getReadCookieFromNavigator() {
 1963  0
         return this.readCookieFromNavigator;
 1964  
     }
 1965  
 
 1966  
     /** @see wjhk.jupload2.policies.UploadPolicy#getReadCookieFromNavigator() */
 1967  
     protected void setReadCookieFromNavigator(boolean readCookieFromNavigator) {
 1968  0
         this.readCookieFromNavigator = readCookieFromNavigator;
 1969  0
     }
 1970  
 
 1971  
     /** @see wjhk.jupload2.policies.UploadPolicy#getReadUserAgentFromNavigator() */
 1972  
     public boolean getReadUserAgentFromNavigator() {
 1973  0
         return this.readUserAgentFromNavigator;
 1974  
     }
 1975  
 
 1976  
     /** @see wjhk.jupload2.policies.UploadPolicy#getReadUserAgentFromNavigator() */
 1977  
     protected void setReadUserAgentFromNavigator(boolean readUserAgentFromNavigator) {
 1978  0
         this.readUserAgentFromNavigator = readUserAgentFromNavigator;
 1979  0
     }
 1980  
 
 1981  
     /** @see UploadPolicy#getRetryMaxNumberOf() */
 1982  
     public int getRetryMaxNumberOf() {
 1983  0
         return this.retryMaxNumberOf;
 1984  
     }
 1985  
 
 1986  
     /**
 1987  
      * @param retryMaxNumberOf New value to set for the retryMaxNumberOf applet parameter
 1988  
      * @exception IllegalArgumentException If retryMaxNumberOf is less than 0.
 1989  
      * @see UploadPolicy#getRetryMaxNumberOf()
 1990  
      */
 1991  
     public void setRetryMaxNumberOf(int retryMaxNumberOf) {
 1992  0
         if (retryMaxNumberOf < 0) {
 1993  0
             throw new IllegalArgumentException("retryMaxNumberOf must be 0 or more");
 1994  
         }
 1995  0
         this.retryMaxNumberOf = retryMaxNumberOf;
 1996  0
     }
 1997  
 
 1998  
     /** @see UploadPolicy#getRetryNbSecondsBetween() */
 1999  
     public int getRetryNbSecondsBetween() {
 2000  0
         return this.retryNbSecondsBetween;
 2001  
     }
 2002  
 
 2003  
     /**
 2004  
      * @param retryNbSecondsBetween New value to set for the retryNbSecondsBetween applet parameter
 2005  
      * @exception IllegalArgumentException If retryNbSecondsBetween is less than 0.
 2006  
      * @see UploadPolicy#getRetryNbSecondsBetween()
 2007  
      */
 2008  
     public void setRetryNbSecondsBetween(int retryNbSecondsBetween) {
 2009  0
         if (retryNbSecondsBetween < 0) {
 2010  0
             throw new IllegalArgumentException("retryNbSecondsBetween must be 0 or more");
 2011  
         }
 2012  0
         this.retryNbSecondsBetween = retryNbSecondsBetween;
 2013  0
     }
 2014  
 
 2015  
     /** @see wjhk.jupload2.policies.UploadPolicy#getServerProtocol() */
 2016  
     public String getServerProtocol() {
 2017  0
         if (this.serverProtocol == null) {
 2018  0
             return DEFAULT_SERVER_PROTOCOL;
 2019  
         } else {
 2020  0
             return this.serverProtocol;
 2021  
         }
 2022  
     }
 2023  
 
 2024  
     /** @see UploadPolicy#setServerProtocol(String) */
 2025  
     public void setServerProtocol(String serverProtocol) {
 2026  0
         this.serverProtocol = serverProtocol;
 2027  0
     }
 2028  
 
 2029  
     /** @see wjhk.jupload2.policies.UploadPolicy#getSendMD5Sum() */
 2030  
     public boolean getSendMD5Sum() {
 2031  0
         return this.sendMD5Sum;
 2032  
     }
 2033  
 
 2034  
     /** @see UploadPolicy#setSendMD5Sum(boolean) */
 2035  
     public void setSendMD5Sum(boolean sendMD5Sum) {
 2036  0
         this.sendMD5Sum = sendMD5Sum;
 2037  0
     }
 2038  
 
 2039  
     /** @see wjhk.jupload2.policies.UploadPolicy#getShowLogWindow() */
 2040  
     public String getShowLogWindow() {
 2041  0
         return this.showLogWindow;
 2042  
     }
 2043  
 
 2044  
     /** {@inheritDoc} */
 2045  
     public void setShowLogWindow(String showLogWindow) {
 2046  0
         if (showLogWindow.equals(SHOWLOGWINDOW_TRUE) || showLogWindow.equals(SHOWLOGWINDOW_FALSE)
 2047  0
                 || showLogWindow.equals(SHOWLOGWINDOW_ONERROR)) {
 2048  0
             this.showLogWindow = showLogWindow;
 2049  
             // The log window may become visible or hidden, depending on this
 2050  
             // parameter.
 2051  0
             if (this.juploadContext.getUploadPanel() != null) {
 2052  0
                 this.juploadContext.getUploadPanel().showOrHideLogWindow();
 2053  
             }
 2054  
         } else {
 2055  0
             displayWarn("[setShowLogWindow] Unallowed value: " + showLogWindow + " (showLogWindow is left unchanged)");
 2056  
         }
 2057  0
     }
 2058  
 
 2059  
     /** @see wjhk.jupload2.policies.UploadPolicy#getSpecificHeaders() */
 2060  
     public String getSpecificHeaders() {
 2061  0
         return this.specificHeaders;
 2062  
     }
 2063  
 
 2064  
     /**
 2065  
      * Set all specific headers defined in the specificHeaders applet parameter. This string is splitted, so that each
 2066  
      * header is added to the headers Vector. These headers are added to the headers list during applet initialization.
 2067  
      * There is currently no automatic way to remove the headers coming from specificHeaders, after initialization.
 2068  
      * 
 2069  
      * @param specificHeaders
 2070  
      */
 2071  
     protected void setSpecificHeaders(String specificHeaders) {
 2072  0
         this.specificHeaders = specificHeaders;
 2073  0
         if (specificHeaders != null) {
 2074  
             // Let's add each header in specificHeaders to the headers list. In
 2075  
             // specificHeaders, each header is separated by the \n string (two
 2076  
             // characters: \ then n, not the \n character).
 2077  
             // The regexp to find the \n string (not the \n character) is: \\n
 2078  
             // We then double each \ character:
 2079  0
             String[] headerArray = specificHeaders.split("\\\\n");
 2080  0
             for (int x = 0; x < headerArray.length; x++) {
 2081  0
                 addHeader(headerArray[x]);
 2082  
             }
 2083  
         }
 2084  0
     }
 2085  
 
 2086  
     /**
 2087  
      * @see wjhk.jupload2.policies.UploadPolicy#getSslVerifyCert()
 2088  
      */
 2089  
     public int getSslVerifyCert() {
 2090  0
         return this.sslVerifyCert;
 2091  
     }
 2092  
 
 2093  
     protected void setSslVerifyCert(String mode) throws JUploadException {
 2094  0
         int val = -1;
 2095  0
         if (mode.toLowerCase().equals("none"))
 2096  0
             val = InteractiveTrustManager.NONE;
 2097  0
         if (mode.toLowerCase().equals("server"))
 2098  0
             val = InteractiveTrustManager.SERVER;
 2099  0
         if (mode.toLowerCase().equals("client"))
 2100  0
             val = InteractiveTrustManager.CLIENT;
 2101  0
         if (mode.toLowerCase().equals("strict"))
 2102  0
             val = InteractiveTrustManager.STRICT;
 2103  0
         if (val == -1)
 2104  0
             throw new JUploadException("Invalid parameter sslVerifyCert (" + mode + ")");
 2105  0
         this.sslVerifyCert = val;
 2106  0
     }
 2107  
 
 2108  
     /**
 2109  
      * @param show the new showStatusbar value
 2110  
      */
 2111  
     protected void setShowStatusbar(boolean show) {
 2112  0
         this.showStatusbar = show;
 2113  0
     }
 2114  
 
 2115  
     /** @see wjhk.jupload2.policies.UploadPolicy#getStringUploadError() */
 2116  
     public String getStringUploadError() {
 2117  0
         return this.stringUploadError;
 2118  
     }
 2119  
 
 2120  
     /** @see wjhk.jupload2.policies.UploadPolicy#getStringUploadSuccess() */
 2121  
     public String getStringUploadSuccess() {
 2122  0
         return this.stringUploadSuccess;
 2123  
     }
 2124  
 
 2125  
     /** @see wjhk.jupload2.policies.UploadPolicy#getStringUploadWarning() */
 2126  
     public String getStringUploadWarning() {
 2127  0
         return this.stringUploadWarning;
 2128  
     }
 2129  
 
 2130  
     /**
 2131  
      * @param stringUploadError the stringUploadError to set
 2132  
      * @throws JUploadException
 2133  
      */
 2134  
     protected void setStringUploadError(String stringUploadError) throws JUploadException {
 2135  0
         this.stringUploadError = stringUploadError;
 2136  0
         if (stringUploadError != null) {
 2137  
             try {
 2138  0
                 this.patternError = Pattern.compile(stringUploadError);
 2139  0
             } catch (PatternSyntaxException e) {
 2140  0
                 throw new JUploadException("Invalid regex in parameter stringUploadError");
 2141  0
             }
 2142  
         }
 2143  0
     }
 2144  
 
 2145  
     /**
 2146  
      * @param stringUploadSuccess the stringUploadSuccess to set
 2147  
      * @throws JUploadException
 2148  
      */
 2149  
     protected void setStringUploadSuccess(String stringUploadSuccess) throws JUploadException {
 2150  0
         this.stringUploadSuccess = stringUploadSuccess;
 2151  0
         if (stringUploadSuccess != null) {
 2152  
             try {
 2153  0
                 this.patternSuccess = Pattern.compile(stringUploadSuccess);
 2154  0
             } catch (PatternSyntaxException e) {
 2155  0
                 throw new JUploadException("Invalid regex in parameter stringUploadSuccess");
 2156  0
             }
 2157  
         }
 2158  0
     }
 2159  
 
 2160  
     /**
 2161  
      * @param stringUploadWarning the stringUploadWarning to set
 2162  
      * @throws JUploadException
 2163  
      */
 2164  
     protected void setStringUploadWarning(String stringUploadWarning) throws JUploadException {
 2165  0
         this.stringUploadWarning = stringUploadWarning;
 2166  0
         if (stringUploadWarning != null) {
 2167  
             try {
 2168  0
                 this.patternWarning = Pattern.compile(stringUploadWarning);
 2169  0
             } catch (PatternSyntaxException e) {
 2170  0
                 throw new JUploadException("Invalid regex in parameter stringUploadWarning");
 2171  0
             }
 2172  
         }
 2173  0
     }
 2174  
 
 2175  
     /** @see wjhk.jupload2.policies.UploadPolicy#getUrlToSendErrorTo() */
 2176  
     public String getUrlToSendErrorTo() {
 2177  0
         return this.urlToSendErrorTo;
 2178  
     }
 2179  
 
 2180  
     /** {@inheritDoc} */
 2181  
     public void setUrlToSendErrorTo(String urlToSendErrorTo) throws JUploadException {
 2182  0
         if (null == urlToSendErrorTo)
 2183  0
             return;
 2184  0
         String tmp = this.juploadContext.normalizeURL(urlToSendErrorTo);
 2185  0
         if (tmp.startsWith("ftp://")) {
 2186  0
             throw new JUploadException("urlToSendErrorTo: ftp scheme not supported.");
 2187  
         }
 2188  0
         this.urlToSendErrorTo = tmp;
 2189  0
     }
 2190  
 
 2191  
     /** @see wjhk.jupload2.policies.UploadPolicy#getFormdata() */
 2192  
     public String getFormdata() {
 2193  0
         return this.formData;
 2194  
     }
 2195  
 
 2196  
     /** @see wjhk.jupload2.policies.UploadPolicy#getAfterUploadTarget() */
 2197  
     public String getAfterUploadTarget() {
 2198  0
         return this.afterUploadTarget;
 2199  
     }
 2200  
 
 2201  
     // //////////////////////////////////////////////////////////////////////////////////////////////
 2202  
     // /////////////////// Internal methods
 2203  
     // //////////////////////////////////////////////////////////////////////////////////////////////
 2204  
 
 2205  
     /**
 2206  
      * Delete the current log. (called upon applet termination)
 2207  
      */
 2208  
     public synchronized void deleteLog() {
 2209  0
         if (this.debugGenerateFile) {
 2210  
             try {
 2211  0
                 if (null != this.debugOut) {
 2212  0
                     this.debugOut.close();
 2213  0
                     this.debugOut = null;
 2214  
                 }
 2215  0
                 if (null != this.debugFile) {
 2216  0
                     if (!this.debugFile.delete()) {
 2217  0
                         displayWarn(this.debugFile.getName() + " was not correctly removed!");
 2218  
                     }
 2219  0
                     this.debugFile = null;
 2220  
                 }
 2221  0
             } catch (Exception e) {
 2222  
                 // nothing to do: we mask the exception.
 2223  0
                 displayWarn(e.getClass().getName() + " occured in deleteLog(). Exception ignored.");
 2224  0
             }
 2225  
         }
 2226  0
     }
 2227  
 
 2228  
     /**
 2229  
      * This methods allows the applet to store all messages (debug, warning, info, errors...) into a StringBuffer. If
 2230  
      * any problem occurs, the whole output (displayed or not by the displayDebug, for instance) can be stored in a
 2231  
      * file, or sent to the webmaster. This can help to identify and correct problems that can occurs on the various
 2232  
      * computer configurations.
 2233  
      * 
 2234  
      * @param msg
 2235  
      */
 2236  
     protected synchronized void addMsgToDebugLog(String msg) {
 2237  
         // If uploading lots of chunks, the buffer gets too large, resulting in
 2238  
         // a OutOfMemoryError on the heap so we now use a temporary file for the
 2239  
         // debug log.
 2240  0
         if (this.debugGenerateFile && this.debugOk) {
 2241  
             try {
 2242  0
                 if (null == this.debugOut) {
 2243  0
                     this.juploadContext.registerUnload(this, "deleteLog");
 2244  0
                     this.debugFile = File.createTempFile("jupload_", "_log.txt");
 2245  0
                     this.debugOut = new PrintStream(new FileOutputStream(this.debugFile));
 2246  
                 }
 2247  0
                 boolean endsLF = msg.endsWith("\n");
 2248  0
                 msg = msg.replaceAll("\n", this.CRLF);
 2249  0
                 if (endsLF) {
 2250  0
                     this.debugOut.print(msg);
 2251  
                 } else {
 2252  0
                     this.debugOut.println(msg);
 2253  
                 }
 2254  0
             } catch (IOException e) {
 2255  0
                 this.debugOk = false;
 2256  0
                 System.err.println("IO error on debuglog " + this.debugFile.getPath()
 2257  
                         + "\nFallback to standard output.");
 2258  0
                 System.out.println(msg);
 2259  0
             }
 2260  
         } else {
 2261  0
             System.out.println(msg);
 2262  
         }
 2263  0
     }
 2264  
 
 2265  
     /**
 2266  
      * Displays a message. If the logWindow panel is set, the message is displayed on it. If not, the System.out.println
 2267  
      * function is used.
 2268  
      * 
 2269  
      * @param msg The message to display.
 2270  
      */
 2271  
     private void displayMsg(String tag, String msg) {
 2272  
         String message;
 2273  
 
 2274  0
         if (this.juploadContext.getLogWindow() == null) {
 2275  0
             message = tag + " - " + msg;
 2276  0
             System.out.println(message);
 2277  
         } else {
 2278  0
             message = this.juploadContext.getLogWindow().displayMsg(tag, msg);
 2279  
         }
 2280  
         // Let's store all text in the debug logfile
 2281  0
         if (this.debugGenerateFile) {
 2282  0
             addMsgToDebugLog(message);
 2283  
         }
 2284  0
     }
 2285  
 
 2286  
     /**
 2287  
      * Default reaction after a successful drop operation: no action.
 2288  
      * 
 2289  
      * @see UploadPolicy#afterFileDropped(DropTargetDropEvent)
 2290  
      */
 2291  
     public void afterFileDropped(DropTargetDropEvent dropEvent) {
 2292  
         // Default: no action.
 2293  0
     }
 2294  
 
 2295  
     /**
 2296  
      * Default implementation for {@link UploadPolicy#createFileChooser()}: just a creation of a
 2297  
      * {@link JUploadFileChooser}.
 2298  
      * 
 2299  
      * @see UploadPolicy#createFileChooser()
 2300  
      */
 2301  
     public JUploadFileChooser createFileChooser() {
 2302  0
         return new JUploadFileChooser(this);
 2303  
     }
 2304  
 
 2305  
     /**
 2306  
      * This method returns the response for the {@link JUploadFileFilter#accept(File)} which just calls this method.
 2307  
      * This method checks that the file extension corresponds to the allowedFileExtensions applet parameter.
 2308  
      * 
 2309  
      * @see UploadPolicy#fileFilterAccept(File)
 2310  
      */
 2311  
     public boolean fileFilterAccept(File file) {
 2312  0
         if (file.isDirectory()) {
 2313  0
             return true;
 2314  0
         } else if (this.allowedFileExtensions == null || this.allowedFileExtensions.equals("")) {
 2315  0
             return true;
 2316  
         } else {
 2317  
             // Get the file extension
 2318  0
             String extension = DefaultFileData.getExtension(file.getName()).toLowerCase();
 2319  
             // allowedFileExtensions is :
 2320  
             // - a list of file extensions,
 2321  
             // - in lower case,
 2322  
             // - separated by slash
 2323  
             // - A slash has been added at the beginning in
 2324  
             // setAllowedFileExtensions
 2325  
             // - A slash has been added at the end in setAllowedFileExtensions
 2326  
             // So, we just look for the /ext/ string in the stored
 2327  
             // allowedFileExtensions.
 2328  0
             return (this.allowedFileExtensions.indexOf("/" + extension + "/")) >= 0;
 2329  
         }
 2330  
     }
 2331  
 
 2332  
     /** @see UploadPolicy#fileFilterGetDescription() */
 2333  
     public String fileFilterGetDescription() {
 2334  0
         if (this.allowedFileExtensions == null || this.allowedFileExtensions.equals("")) {
 2335  0
             return null;
 2336  0
         } else if (getFileFilterName() != null) {
 2337  0
             return getFileFilterName();
 2338  
         } else {
 2339  0
             return "JUpload file filter (" + this.allowedFileExtensions + ")";
 2340  
         }
 2341  
     }
 2342  
 
 2343  
     /**
 2344  
      * Returns null: the default icon is used.
 2345  
      * 
 2346  
      * @see UploadPolicy#fileViewGetIcon(File)
 2347  
      */
 2348  
     public Icon fileViewGetIcon(File file) {
 2349  0
         return null;
 2350  
     }
 2351  
 
 2352  
     /** @see wjhk.jupload2.policies.UploadPolicy#getLastException() */
 2353  
     public JUploadException getLastException() {
 2354  0
         return this.lastException;
 2355  
     }
 2356  
 
 2357  
     /**
 2358  
      * Set the last exception.
 2359  
      * 
 2360  
      * @param exception The last exception that occurs into the applet.
 2361  
      */
 2362  
     public void setLastException(JUploadException exception) {
 2363  0
         this.lastException = exception;
 2364  
 
 2365  
         // The log window may become visible.
 2366  0
         if (this.juploadContext.getUploadPanel() != null) {
 2367  0
             this.juploadContext.getUploadPanel().showOrHideLogWindow();
 2368  
         }
 2369  
 
 2370  0
     }
 2371  
 
 2372  
     /** @see wjhk.jupload2.policies.UploadPolicy#getLastResponseBody() */
 2373  
     public String getLastResponseBody() {
 2374  0
         return this.lastResponseBody;
 2375  
     }
 2376  
 
 2377  
     /** @see wjhk.jupload2.policies.UploadPolicy#getLastResponseMessage() */
 2378  
     public String getLastResponseMessage() {
 2379  0
         return (null != this.lastResponseMessage) ? this.lastResponseMessage : "";
 2380  
     }
 2381  
 
 2382  
     /**
 2383  
      * @return The cursor that was active before setting the new one. Can be used to restore its previous state.
 2384  
      * @see UploadPolicy#setCursor(Cursor)
 2385  
      */
 2386  
     public Cursor setCursor(Cursor cursor) {
 2387  0
         return this.juploadContext.setCursor(cursor);
 2388  
     }
 2389  
 
 2390  
     /**
 2391  
      * @return The cursor that was active before setting the new one. Can be used to restore its previous state.
 2392  
      * @see UploadPolicy#setWaitCursor()
 2393  
      */
 2394  
     public Cursor setWaitCursor() {
 2395  0
         return this.juploadContext.setWaitCursor();
 2396  
     }
 2397  
 
 2398  
 }