Java tutorial
// // $Id: DefaultUploadPolicy.java 289 2007-06-19 10:04:46 +0000 (mar., 19 juin // 2007) etienne_sf $ // // jupload - A file upload juploadContext. // Copyright 2007 The JUpload Team // // Created: 2006-05-04 // Creator: etienne_sf // Last modified: $Date: 2011-10-13 22:29:13 +0200 (jeu., 13 oct. 2011) $ // // This program is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) any later // version. This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more // details. You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software Foundation, Inc., // 675 Mass Ave, Cambridge, MA 02139, USA. package wjhk.jupload2.policies; import java.awt.BorderLayout; import java.awt.Cursor; import java.awt.GridLayout; import java.awt.SystemColor; import java.awt.dnd.DropTargetDropEvent; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.PrintStream; import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; import java.net.URL; import java.net.URLEncoder; import java.nio.charset.Charset; import java.nio.charset.UnsupportedCharsetException; import java.util.ArrayList; import java.util.HashMap; import java.util.IllegalFormatException; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.ResourceBundle; import java.util.Vector; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; import javax.swing.BorderFactory; import javax.swing.BoxLayout; import javax.swing.Icon; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JProgressBar; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; import javax.swing.border.BevelBorder; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import wjhk.jupload2.context.JUploadContext; import wjhk.jupload2.exception.JUploadException; import wjhk.jupload2.exception.JUploadExceptionStopAddingFiles; import wjhk.jupload2.exception.JUploadExceptionUploadFailed; import wjhk.jupload2.exception.JUploadExceptionUploadFailedSuccessNotFound; import wjhk.jupload2.exception.JUploadIOException; import wjhk.jupload2.filedata.DefaultFileData; import wjhk.jupload2.filedata.FileData; import wjhk.jupload2.gui.JUploadFileChooser; import wjhk.jupload2.gui.JUploadFileFilter; import wjhk.jupload2.gui.JUploadPanel; import wjhk.jupload2.upload.helper.ByteArrayEncoder; import wjhk.jupload2.upload.helper.ByteArrayEncoderHTTP; import wjhk.jupload2.upload.helper.HTTPConnectionHelper; import wjhk.jupload2.upload.helper.HttpProtocolFinderThread; import wjhk.jupload2.upload.helper.InteractiveTrustManager; /** * This class implements all {@link wjhk.jupload2.policies.UploadPolicy} * methods. Its way of working is he same as the JUpload version 1. <BR> * The simplest way to use this policy is given in the presentation of * {@link UploadPolicy}. The DefaultUploadPolicy is used when no * <I>uploadPolicy</I> parameter is given to the juploadContext, or this * parameter has 'DefaultUploadPolicy' as a value. <BR> * <P> * The <U>default behavior</U> is representated below. It can be overridden by * adding parameters to the juploadContext. All available parameters are shown * in the presentation of {@link UploadPolicy}. * </P> * <UL> * <LI>Default implementation for all * {@link wjhk.jupload2.policies.UploadPolicy} methods. * <LI>Files are uploaded all in one HTTP request. * <LI>No handling for particular kind of files: files are transmitted without * any transformation. * <LI>The file are transmitted to the server with the navigator cookies, * userAgent and Protocol (see also the readCookieFromNavigator and * serverProtocol juploadContext parameter). This make upload occurs within the * current user session on the server. So, it allows right management and * context during the management of uploaded files, on the server. * </UL> * * @author etienne_sf * @version $Revision: 1581 $ */ public class DefaultUploadPolicy implements UploadPolicy { /** * Maximum number of characters allowed for a message that is displayed in a * DialogBox */ public final static int DIALOG_MESSAGE_MAX_LINE_LENGTH = 80; // ////////////////////////////////////////////////////////////////////////////////////////////// // /////////////////// APPLET PARAMETERS // /////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////////////////////////////////// /** * juploadContext contains the reference of the Applet. It's useful to * interact with it. <BR> * It also allows access to the navigator properties, if the html tag * MAYSCRIPT is put in the APPLET tag. This allows this class to get the * cookie, userAgent and protocol, to upload files in the current user * session on the server. <BR> * Default : no default value */ JUploadContext juploadContext = null; /** * Contains the applet parameter of the same name. If a valid URL is given * here, the navigator will get redirected to this page, after a successful * upload. */ private String afterUploadURL = UploadPolicy.DEFAULT_AFTER_UPLOAD_URL; /** * Contains the allowedFileExtensions applet parameter. */ private boolean allowHttpPersistent = UploadPolicy.DEFAULT_ALLOW_HTTP_PERSISTENT; /** * Contains the allowedFileExtensions applet parameter. */ private String allowedFileExtensions = UploadPolicy.DEFAULT_ALLOWED_FILE_EXTENSIONS; /** * Indicate whether the log window is shown or not to the user. In all cases * it remains in memory, and stores all debug information. This allows a log * information, in case of an error occurs. * * @see #urlToSendErrorTo */ private String showLogWindow = UploadPolicy.DEFAULT_SHOW_LOGWINDOW; private boolean showStatusbar = UploadPolicy.DEFAULT_SHOW_STATUSBAR; private String specificHeaders = null; /** Indicates the directory in which the file chooser is to be opened */ private File currentBrowsingDirectory = null; /** * This parameter controls whether the applet generates a debug file or not. * If true, this file contains the full debug output, whatever the current * debugLevel is. */ private boolean debugGenerateFile = true; /** * The current debug level. This control the details of information that is * written in the log part of the applet. */ private int debugLevel = UploadPolicy.DEFAULT_DEBUG_LEVEL; /** * Stored value for the fileChooserIconFromFileContent applet property. * * @see UploadPolicy#PROP_FILE_CHOOSER_ICON_FROM_FILE_CONTENT */ private int fileChooserIconFromFileContent = UploadPolicy.DEFAULT_FILE_CHOOSER_ICON_FROM_FILE_CONTENT; /** * Stored value for the fileChooserIconSize applet property. * * @see UploadPolicy#PROP_FILE_CHOOSER_ICON_SIZE */ private int fileChooserIconSize = UploadPolicy.DEFAULT_FILE_CHOOSER_ICON_SIZE; /** * Stored value for the {@link UploadPolicy#PROP_FILE_FILTER_NAME} */ private String fileFilterName = UploadPolicy.DEFAULT_FILE_FILTER_NAME; /** * This String contains the filenameEncoding parameter. All details about * the available applet parameters are displayed in the <a * href="UploadPolicy.html@parameters">Upload Policy javadoc page</a>. */ private String filenameEncoding = UploadPolicy.DEFAULT_FILENAME_ENCODING; /** * Default value for the ftpCreateDirectoryStructure applet parameter */ private boolean ftpCreateDirectoryStructure = UploadPolicy.DEFAULT_FTP_CREATE_DIRECTORY_STRUCTURE; /** * Default value for the ftpCreateDirectoryStructure applet parameter */ private boolean ftpTransfertBinary = UploadPolicy.DEFAULT_FTP_TRANSFERT_BINARY; /** * Default value for the ftpCreateDirectoryStructure applet parameter */ private boolean ftpTransfertPassive = UploadPolicy.DEFAULT_FTP_TRANSFERT_PASSIVE; /** Default value for the httpUploadParameterName applet parameter */ protected String httpUploadParameterName = UploadPolicy.DEFAULT_HTTP_UPLOAD_PARAMETER_NAME; /** Default value for the httpUploadParameterType applet parameter */ protected String httpUploadParameterType = UploadPolicy.DEFAULT_HTTP_UPLOAD_PARAMETER_TYPE; /** * The lang parameter, given to the applet. */ private String lang = UploadPolicy.DEFAULT_LANG; /** * The current Locale. If the lang parameter is given and value, this * supersede the default locale. */ private Locale locale = Locale.getDefault(); /** * Contains the last exception that occurs in the applet. * * @see #displayErr(String, Exception) */ private JUploadException lastException = null; /** * The look and feel is used as a parameter of the * UIManager.setLookAndFeel(String) method. See the parameters list on the * {@link UploadPolicy} page. */ private String lookAndFeel = UploadPolicy.DEFAULT_LOOK_AND_FEEL; /** * The applet will do as may HTTP requests to upload all files, with the * number as a maximum number of files for each HTTP request. <BR> * Default : -1 */ private int nbFilesPerRequest = UploadPolicy.DEFAULT_NB_FILES_PER_REQUEST; /** * Current value (or default value) of the maxChunkSize applet parameter. <BR> * Default : Long.MAX_VALUE */ private long maxChunkSize = UploadPolicy.DEFAULT_MAX_CHUNK_SIZE; /** * Current value (or default value) of the maxFileSize applet parameter. <BR> * Default : Long.MAX_VALUE */ private long maxFileSize = UploadPolicy.DEFAULT_MAX_FILE_SIZE; /** * The URL where files should be posted. <BR> * Default : no default value. (mandatory) */ private String postURL = UploadPolicy.DEFAULT_POST_URL; /** @see UploadPolicy#getReadCookieFromNavigator() */ private boolean readCookieFromNavigator = UploadPolicy.DEFAULT_READ_COOKIE_FROM_NAVIGATOR; /** @see UploadPolicy#getReadUserAgentFromNavigator() */ private boolean readUserAgentFromNavigator = UploadPolicy.DEFAULT_READ_USER_AGENT_FROM_NAVIGATOR; /** @see UploadPolicy#getRetryMaxNumberOf() */ private int retryMaxNumberOf = UploadPolicy.DEFAULT_RETRY_MAX_NUMBER_OF; /** @see UploadPolicy#getRetryNbSecondsBetween() */ private int retryNbSecondsBetween = UploadPolicy.DEFAULT_RETRY_NB_SECONDS_BETWEEN; /** @see UploadPolicy#getSendMD5Sum() */ private boolean sendMD5Sum = UploadPolicy.DEFAULT_SEND_MD5_SUM; /** @see UploadPolicy#getServerProtocol() */ private String serverProtocol = UploadPolicy.DEFAULT_SERVER_PROTOCOL; /** * @see UploadPolicy#getStringUploadError() */ private String stringUploadError = UploadPolicy.DEFAULT_STRING_UPLOAD_ERROR; /** * @see UploadPolicy#getStringUploadSuccess() */ private String stringUploadSuccess = UploadPolicy.DEFAULT_STRING_UPLOAD_SUCCESS; /** * @see UploadPolicy#getStringUploadWarning() */ private String stringUploadWarning = UploadPolicy.DEFAULT_STRING_UPLOAD_WARNING; /** * If an error occurs during upload, and this attribute is not null, the * applet asks the user if wants to send the debug ouput to the * administrator. If yes, the full debug information is POSTed to this URL. * It's a little development on the server side to send a mail to the * webmaster, or just log this error into a log file. * * @see UploadPolicy#sendDebugInformation(String, Exception) */ private String urlToSendErrorTo = UploadPolicy.DEFAULT_URL_TO_SEND_ERROR_TO; /** * Optional name of a form (in the same document like the applet) which is * used to populate POST parameters. */ private String formData = UploadPolicy.DEFAULT_FORMDATA; private String afterUploadTarget = UploadPolicy.DEFAULT_AFTER_UPLOAD_TARGET; private String lastResponseBody = null; protected String lastResponseMessage = null; private int sslVerifyCert = InteractiveTrustManager.NONE; private final String CRLF = System.getProperty("line.separator"); // ////////////////////////////////////////////////////////////////////////////////////////////// // /////////////////// INTERNAL ATTRIBUTE // /////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////////////////////////////////// /** * This Vector contains headers that will be added for each upload. It may * contains specific cookies, for instance. * * @see #onAppendHeader(ByteArrayEncoder) */ private Vector<String> headers = new Vector<String>(); /** * The resourceBundle contains all localized String (and others ??) */ private ResourceBundle resourceBundle = null; /** * This stream is used to store all information that could be useful, in * case a problem occurs. Is content can then be sent to the webmaster. */ protected PrintStream debugOut = null; /** * The actual file, used for the debug log. * * @see #debugGenerateFile */ protected File debugFile = null; /** * This flag prevents endless repeats of opening the debug log, if that * failed for some reason. */ protected boolean debugOk = true; /** * Same as {@link #patternSuccess}, but for the error message. If found, * then the upload was accepted by the remote HTTP server, but rejected by * the remote application. This pattern should also find the error message * in the first matching string. */ protected Pattern patternError = Pattern.compile(UploadPolicy.DEFAULT_STRING_UPLOAD_ERROR); /** * The regexp pattern that is used to find the success string in the HTTP * response. If found, the upload is considered to be a success: it has been * accepted by the remote server and the remote application. */ protected Pattern patternSuccess = Pattern.compile(UploadPolicy.DEFAULT_STRING_UPLOAD_SUCCESS); /** * Same as {@link #patternSuccess}, but for the warning message. Each time * it is found, a message is displayed to the user. */ protected Pattern patternWarning = Pattern.compile(UploadPolicy.DEFAULT_STRING_UPLOAD_WARNING); File currentDirectory; File[] selectedFiles; // ////////////////////////////////////////////////////////////////////////////////////////////// // /////////////////// CONSTRUCTORS // ////////////////////////////////////////////////////////////////////////////////////////////// /** * The main constructor : use default values, and the given postURL. * * @param juploadContext * The current juploadContext. As the reference to the current * upload policy exists almost everywhere, this parameter allows * any access to anyone on the juploadContext... including * reading the applet parameters. * @throws JUploadException * If an applet parameter is invalid */ public DefaultUploadPolicy(JUploadContext juploadContext) throws JUploadException { // Call default constructor for all default initialization;. this.juploadContext = juploadContext; displayInfo("JUpload juploadContext started, with " + this.getClass().getName() + " upload policy"); // get the debug level. This control the level of debug messages that // are written in the log window (see displayDebugMessage). In all // cases, the full output is written in the debugBufferString (see also // urlToSendErrorTo) setDebugLevel(juploadContext.getParameter(PROP_DEBUG_LEVEL, DEFAULT_DEBUG_LEVEL), false); // Get resource file. This must be the very first parameter to be set, // because during initialization, translations may be needed. setLang(juploadContext.getParameter(PROP_LANG, DEFAULT_LANG)); // Force the look and feel of the current system. This must be the // second // first parameter to be set, because during initialization, dialogs can // appear. setLookAndFeel(juploadContext.getParameter(PROP_LOOK_AND_FEEL, DEFAULT_LOOK_AND_FEEL)); // This must be set before any URL's because these might trigger an // connection attempt. setSslVerifyCert(juploadContext.getParameter(PROP_SSL_VERIFY_CERT, DEFAULT_SSL_VERIFY_CERT)); // get the afterUploadURL juploadContext parameter. setAfterUploadURL(juploadContext.getParameter(PROP_AFTER_UPLOAD_URL, DEFAULT_AFTER_UPLOAD_URL)); // FTP: whether or not to create subfolders on the server side. setFtpCreateDirectoryStructure(juploadContext.getParameter(PROP_FTP_CREATE_DIRECTORY_STRUCTURE, DEFAULT_FTP_CREATE_DIRECTORY_STRUCTURE)); // FTP transfert mode setFtpTransfertBinary(juploadContext.getParameter(PROP_FTP_TRANSFERT_BINARY, DEFAULT_FTP_TRANSFERT_BINARY)); // FTP connection mode setFtpTransfertPassive( juploadContext.getParameter(PROP_FTP_TRANSFERT_PASSIVE, DEFAULT_FTP_TRANSFERT_PASSIVE)); // get the fileChooser parameters setAllowedFileExtensions( juploadContext.getParameter(PROP_ALLOWED_FILE_EXTENSIONS, DEFAULT_ALLOWED_FILE_EXTENSIONS)); setFileFilterName(juploadContext.getParameter(PROP_FILE_FILTER_NAME, DEFAULT_FILE_FILTER_NAME)); setAllowHttpPersistent( juploadContext.getParameter(PROP_ALLOW_HTTP_PERSISTENT, DEFAULT_ALLOW_HTTP_PERSISTENT)); setShowStatusbar(juploadContext.getParameter(PROP_SHOW_STATUSBAR, DEFAULT_SHOW_STATUSBAR)); setShowLogWindow(juploadContext.getParameter(PROP_SHOW_LOGWINDOW, DEFAULT_SHOW_LOGWINDOW)); // set the fileChooser relative stuff. setFileChooserIconFromFileContent(juploadContext.getParameter(PROP_FILE_CHOOSER_ICON_FROM_FILE_CONTENT, DEFAULT_FILE_CHOOSER_ICON_FROM_FILE_CONTENT)); setFileChooserIconSize( juploadContext.getParameter(PROP_FILE_CHOOSER_ICON_SIZE, DEFAULT_FILE_CHOOSER_ICON_SIZE)); setCurrentBrowsingDirectory( juploadContext.getParameter(PROP_BROWSING_DIRECTORY, DEFAULT_BROWSING_DIRECTORY)); // get the filenameEncoding. If not null, it should be a valid argument // for the URLEncoder.encode method. // DEPRECATED. setFilenameEncoding(juploadContext.getParameter(PROP_FILENAME_ENCODING, DEFAULT_FILENAME_ENCODING)); // Read parameters about the HTTP upload request. setNbFilesPerRequest(juploadContext.getParameter(PROP_NB_FILES_PER_REQUEST, DEFAULT_NB_FILES_PER_REQUEST)); setHttpUploadParameterName( juploadContext.getParameter(PROP_HTTP_UPLOAD_PARAMETER_NAME, DEFAULT_HTTP_UPLOAD_PARAMETER_NAME)); setHttpUploadParameterType( juploadContext.getParameter(PROP_HTTP_UPLOAD_PARAMETER_TYPE, DEFAULT_HTTP_UPLOAD_PARAMETER_TYPE)); // get the maximum size of a file on one HTTP request (indicates if the // file must be splitted before upload, see UploadPolicy comment). setMaxChunkSize(juploadContext.getParameter(PROP_MAX_CHUNK_SIZE, DEFAULT_MAX_CHUNK_SIZE)); // get the maximum size of an uploaded file. setMaxFileSize(juploadContext.getParameter(PROP_MAX_FILE_SIZE, DEFAULT_MAX_FILE_SIZE)); // retry management setRetryMaxNumberOf(juploadContext.getParameter(PROP_RETRY_MAX_NUMBER_OF, DEFAULT_RETRY_MAX_NUMBER_OF)); setRetryNbSecondsBetween( juploadContext.getParameter(PROP_RETRY_NB_SECONDS_BETWEEN, DEFAULT_RETRY_NB_SECONDS_BETWEEN)); // get the URL where files must be posted. setPostURL(juploadContext.getParameter(PROP_POST_URL, DEFAULT_POST_URL)); // get any additional headers. setReadCookieFromNavigator( juploadContext.getParameter(PROP_READ_COOKIE_FROM_NAVIGATOR, DEFAULT_READ_COOKIE_FROM_NAVIGATOR)); setReadUserAgentFromNavigator(juploadContext.getParameter(PROP_READ_USER_AGENT_FROM_NAVIGATOR, DEFAULT_READ_USER_AGENT_FROM_NAVIGATOR)); setSendMD5Sum(juploadContext.getParameter(PROP_SEND_MD5_SUM, DEFAULT_SEND_MD5_SUM)); setSpecificHeaders(juploadContext.getParameter(PROP_SPECIFIC_HEADERS, DEFAULT_SPECIFIC_HEADERS)); setStringUploadError(juploadContext.getParameter(PROP_STRING_UPLOAD_ERROR, DEFAULT_STRING_UPLOAD_ERROR)); setStringUploadSuccess( juploadContext.getParameter(PROP_STRING_UPLOAD_SUCCESS, DEFAULT_STRING_UPLOAD_SUCCESS)); setStringUploadWarning( juploadContext.getParameter(PROP_STRING_UPLOAD_WARNING, DEFAULT_STRING_UPLOAD_WARNING)); // get the URL where the full debug output can be sent when an error // occurs. setUrlToSendErrorTo(juploadContext.getParameter(PROP_URL_TO_SEND_ERROR_TO, DEFAULT_URL_TO_SEND_ERROR_TO)); this.formData = juploadContext.getParameter(PROP_FORMDATA, DEFAULT_FORMDATA); this.afterUploadTarget = juploadContext.getParameter(PROP_AFTER_UPLOAD_TARGET, DEFAULT_AFTER_UPLOAD_TARGET); // We let the UploadPolicyFactory call the displayParameterStatus // method, so that the initialization is finished, including for classes // which inherit from DefaultUploadPolicy. displayDebug("[DefaultUploadPolicy] end of constructor (serverProtocol has not been set)", 30); } // ////////////////////////////////////////////////////////////////////////////////////////////// // /////////////////// UploadPolicy methods // ////////////////////////////////////////////////////////////////////////////////////////////// /** @see UploadPolicy#start() */ public void start() { // The current context may add any specific headers. if (getReadCookieFromNavigator()) { this.juploadContext.readCookieFromNavigator(this.headers); } if (getReadUserAgentFromNavigator()) { this.juploadContext.readUserAgentFromNavigator(this.headers); } // Let's touch the server, to test that everything is Ok. Take care, // this is the only place where we override the default value, by null: // the default value will be used by the HttpConnect.getProtocol() // method. // Also, in FTP mode, there can be no default value. // // Must be done AFTER reading the cookie and the userAgent. // HttpProtocolFinderThread.computeServerProtocol(this, juploadContext.getParameter(PROP_SERVER_PROTOCOL, null)); } // getters and setters are sorted below /** * @see wjhk.jupload2.policies.UploadPolicy#addHeader(java.lang.String) */ public void addHeader(String header) { this.headers.add(header); } /** * The default behavior (see {@link DefaultUploadPolicy}) is to check that * the stringUploadSuccess applet parameter is present in the response from * the server. The return is tested, in the order below: <DIR> <LI>False, if * the stringUploadError is found. An error message is then displayed. <LI> * True, if the stringUploadSuccess is null or empty (no test at all). <LI> * True, if the stringUploadSuccess string is present in the * serverOutputBody. <LI>True, If previous condition is not filled, but the * HTTP header "HTTP(.*)200OK$" is present: the test is currently non * blocking, because I can not test all possible HTTP configurations.<BR> * <LI>False if the previous conditions are not fullfilled. </DIR> <BR> * This method also looks for the stringUploadWarning regular expression. * Each time it is matched, the found message is displayed to the user. * * @param status * The HTTP response code * @param msg * The status message from the first line of the response (e.g. * "200 OK"). * @param body * The body of the HTTP answer. * @return True or False, indicating if the upload is a success or not. * @see UploadPolicy#checkUploadSuccess(int, String, String) */ public boolean checkUploadSuccess(int status, String msg, String body) throws JUploadException { boolean bReturn = false; if (getDebugLevel() > 100) { // Let's have a little time to check the upload messages written on // the progress bar. try { Thread.sleep(300); } catch (InterruptedException e) { } } this.lastResponseBody = body; this.lastResponseMessage = msg; displayDebug("HTTP status: " + msg, 30); // HTTP-100 correction, thanks to Marc Reidy if ((status != 200) && (status != 100)) throw new JUploadExceptionUploadFailed("Received HTTP status " + msg); // HTTP-100 "continue", in case we're uploading // to an ASP.NET development server. We should // continue sending... if (status == 100) return true; // Let's analyze the body returned, line by line. The end of line // character may be CR, LF, or CRLF. We navigate through the body, and // replace any end of line character by a uniform CRLF. Matcher matcherError, matcherWarning; String line; Pattern p = Pattern.compile("[\\r\\n]", Pattern.MULTILINE); String[] lines = p.split(body); StringBuffer sbBodyWithUniformCRLF = new StringBuffer(body.length()); for (int i = 0; i < lines.length; i += 1) { line = lines[i]; sbBodyWithUniformCRLF.append(line).append("\r\n"); boolean bStatus = true; List<Map<String, String>> uploads = null; try { JSONArray jsonArray = new JSONArray(line); uploads = new ArrayList<Map<String, String>>(jsonArray.length()); for (int j = 0; j < jsonArray.length(); j++) { JSONObject jsonObj = jsonArray.getJSONObject(j); Map<String, String> map = new HashMap<String, String>(); String[] names = JSONObject.getNames(jsonObj); for (String name : names) map.put(name, jsonObj.getString(name)); uploads.add(map); if (!"SUCCESS".equals(map.get("status"))) { bStatus = false; } else { System.out.println("Upload of " + map.get("name") + " completed successfully"); } } } catch (JSONException e) { e.printStackTrace(); } // FIXME some empty lines are given by the server // Let's remove the empty line: with the p pattern, a multiline is // generated each time a \r\n is received, that is: for each line. if (line == null || line.equals("")) { // An empty line. Let's go the next line. continue; } // Check if this is a success // The success string should be in the http body if (getStringUploadSuccess() != null && !getStringUploadSuccess().equals("")) { if (this.patternSuccess.matcher(line).matches()) { // We go on. There may be some WARNING message, hereafter. bReturn = true; } } if (bStatus) bReturn = true; // Check if this is an error if (getStringUploadError() != null && !getStringUploadError().equals("")) { matcherError = this.patternError.matcher(line); if (matcherError.matches()) { String errmsg = "An error occurs during upload (but the applet couldn't find the error message)"; if (matcherError.groupCount() > 0) { if (!matcherError.group(1).equals("")) { // Let's do a (very simple) formatting: one line to // 100 characters errmsg = formatMessage(matcherError.group(1)); } } this.lastResponseMessage = errmsg; throw new JUploadExceptionUploadFailed(errmsg); } } // getStringUploadError // Check if this is an warning if (getStringUploadWarning() != null && !getStringUploadWarning().equals("")) { matcherWarning = this.patternWarning.matcher(line); if (matcherWarning.matches()) { String warnmsg = "A warning occurs during upload (but the applet couldn't find the warning message)"; if (matcherWarning.groupCount() > 0) { if (!matcherWarning.group(1).equals("")) { warnmsg = formatMessage(matcherWarning.group(1)); } } this.lastResponseMessage = warnmsg; displayWarn(warnmsg); alertStr(warnmsg); } } // getStringUploadWarning } // while(st.hasMoreTokens()) if (bReturn) { return true; } // We found no stringUploadSuccess nor stringUploadError if (getStringUploadSuccess() == null || getStringUploadSuccess().equals("")) { // No chance to check the correctness of this upload. -> Assume Ok return true; } // stringUploadSuccess was defined but we did not find it. // This is most certainly an error as http-status 200 does *not* refer // to the correctness of the content. It merely means that the protocol // handling was ok. -> throw an exception throw new JUploadExceptionUploadFailedSuccessNotFound( getClass().getName() + ".checkUploadSuccess(): The regexp string \"" + getStringUploadSuccess() + "\" was not found in the response body"); } // checkUploadSuccess /** * Generation of a formatted error message, so that it can be displayed in a * DialogBox. That is: each line that contains more than * {@link #DIALOG_MESSAGE_MAX_LINE_LENGTH} is truncated to * DIALOG_MESSAGE_MAX_LINE_LENGTH. * * @param msg * @return */ protected String formatMessage(String msg) { StringBuffer sbMsg = new StringBuffer(); String[] lines = msg.split("\\\\n"); for (int i = 0; i < lines.length; i += 1) { // For each line, we truncate it, if it's too long. String line = lines[i]; for (int j = 0, remaining = line .length(); remaining > 0; remaining -= DIALOG_MESSAGE_MAX_LINE_LENGTH, j += 1) { if (remaining <= DIALOG_MESSAGE_MAX_LINE_LENGTH) { // It's the last loop. sbMsg.append(line.substring(j * DIALOG_MESSAGE_MAX_LINE_LENGTH)); } else { sbMsg.append(line.substring(j * DIALOG_MESSAGE_MAX_LINE_LENGTH, (j + 1) * DIALOG_MESSAGE_MAX_LINE_LENGTH)); sbMsg.append("\n"); } } // End we add the EOL characters, for all lines, but the last one. if (i < lines.length - 1) { sbMsg.append("\n"); } } return sbMsg.toString(); } /** * @see wjhk.jupload2.policies.UploadPolicy#afterUpload(Exception, String) */ public void afterUpload(Exception e, String serverOutput) throws JUploadException { // If there was no error, and afterUploadURL is defined, let's try to go // to this URL. String url = getAfterUploadURL(); if (url != null) { this.juploadContext.displayURL(url, e == null); } } /** @see UploadPolicy#alertStr(String) */ public void alertStr(String str) { String str2 = str.replaceAll("\\\\n", "\n"); JOptionPane.showMessageDialog(null, str2, "Alert", JOptionPane.WARNING_MESSAGE); } /** @see UploadPolicy#confirmDialogStr(String, int) */ public int confirmDialogStr(String str, int optionTypes) { String str2 = str.replaceAll("\\\\n", "\n"); return JOptionPane.showConfirmDialog(getContext().getUploadPanel().getJComponent().getParent(), str2, "Alert", optionTypes); } /** @see UploadPolicy#alert(String) */ public void alert(String key) { alertStr(getLocalizedString(key)); } /** * The DefaultUpload accepts all file types: we just return an instance of * FileData, without any test. * * @exception JUploadExceptionStopAddingFiles * If the users choosed to stop adding. This occurs when the * {@link #fileFilterAccept(File)} method returns false, and * the user then choose to stop adding files. * @see UploadPolicy#createFileData(File, File) */ public FileData createFileData(File file, File root) throws JUploadExceptionStopAddingFiles { if (!fileFilterAccept(file)) { String msg = file.getName() + " : " + getLocalizedString("errForbiddenExtension"); displayWarn(msg); if (confirmDialogStr(msg, JOptionPane.OK_CANCEL_OPTION) == JOptionPane.CANCEL_OPTION) { // The user want to stop to add files to the list. For instance, // when he/she added a whole directory, and it contains a lot of // files that don't match the allowed file extension. throw new JUploadExceptionStopAddingFiles("Stopped by the user"); } return null; } else if (!file.canRead()) { displayInfo("Can't read file " + file.getName() + ". No DefaultFileData creation."); return null; } else { return new DefaultFileData(file, root, this); } } /** * Default implementation of * {@link wjhk.jupload2.policies.UploadPolicy#createTopPanel(JButton, JButton, JButton, JUploadPanel)} * . IT creates a JPanel, containing the three given JButton. It creates the * same panel as the original JUpload. * * @see wjhk.jupload2.policies.UploadPolicy#createTopPanel(JButton, JButton, * JButton, JUploadPanel) */ public JPanel createTopPanel(JButton browse, JButton remove, JButton removeAll, JUploadPanel jUploadPanel) { JPanel jPanel = new JPanel(); jPanel.setLayout(new GridLayout(1, 3, 10, 5)); jPanel.setBorder(BorderFactory.createEmptyBorder(5, 10, 5, 10)); jPanel.add(browse); jPanel.add(removeAll); jPanel.add(remove); jUploadPanel.getJComponent().setBorder(BorderFactory.createLineBorder(SystemColor.controlDkShadow)); return jPanel; } /** * @see wjhk.jupload2.policies.UploadPolicy#createProgressPanel(JProgressBar, * JProgressBar, JButton, JButton, JUploadPanel) */ public JPanel createProgressPanel(JProgressBar preparationProgressBar, JProgressBar uploadProgressBar, JButton uploadButton, JButton stopButton, JUploadPanel mainPanel) { // There may be two progress bar: one for preparation progress of files // (preparation before upload) and one to follow the actual upload. JPanel jProgressBarPanel = new JPanel(); jProgressBarPanel.setLayout(new BorderLayout(10, 1)); jProgressBarPanel.add(preparationProgressBar, BorderLayout.NORTH); jProgressBarPanel.add(uploadProgressBar, BorderLayout.SOUTH); JPanel jProgressPanel = new JPanel(); jProgressPanel.setLayout(new BorderLayout(10, 0)); jProgressPanel.setBorder(BorderFactory.createEmptyBorder(5, 10, 5, 10)); jProgressPanel.add(uploadButton, BorderLayout.LINE_START); jProgressPanel.add(jProgressBarPanel, BorderLayout.CENTER); jProgressPanel.add(stopButton, BorderLayout.LINE_END); return jProgressPanel; } /** * @see wjhk.jupload2.policies.UploadPolicy#createStatusBar(javax.swing.JLabel, * JUploadPanel) */ public JPanel createStatusBar(JLabel content, JUploadPanel mainPanel) { if (this.showStatusbar) { JPanel pstatus = new JPanel(); pstatus.setLayout(new BorderLayout()); pstatus.add(content, BorderLayout.CENTER); pstatus.setBorder(new BevelBorder(BevelBorder.LOWERED)); return pstatus; } return null; } /** * This methods allow the upload policy to override the default disposition * of the components on the applet. * * @see UploadPolicy#addComponentsToJUploadPanel(JUploadPanel) */ public void addComponentsToJUploadPanel(JUploadPanel jUploadPanel) { // Set the global layout of the panel. jUploadPanel.getJComponent().setLayout(new BoxLayout(jUploadPanel.getJComponent(), BoxLayout.Y_AXIS)); // The top panel is the upper part of the applet: above the file // list. // JPanel topPanel = new JPanel(); JPanel topPanel = createTopPanel(jUploadPanel.getBrowseButton(), jUploadPanel.getRemoveButton(), jUploadPanel.getRemoveAllButton(), jUploadPanel); if (topPanel != null) { jUploadPanel.getJComponent().add(topPanel); topPanel.addMouseListener(jUploadPanel.getMouseListener()); } // Then, we add the file list. jUploadPanel.getJComponent().add(jUploadPanel.getFilePanel().getDropComponent()); // The progress panel contains the progress bar, and the upload and stop // buttons. JPanel progressPanel = createProgressPanel(jUploadPanel.getPreparationProgressBar(), jUploadPanel.getUploadProgressBar(), jUploadPanel.getUploadButton(), jUploadPanel.getStopButton(), jUploadPanel); jUploadPanel.getJComponent().add(progressPanel); jUploadPanel.getJComponent().addMouseListener(jUploadPanel.getMouseListener()); // Now, we add the log window. jUploadPanel.showOrHideLogWindow(); jUploadPanel.getJComponent().add(jUploadPanel.getJLogWindowPane()); // And, to finish with: the status bar. JPanel p = createStatusBar(jUploadPanel.getStatusLabel(), jUploadPanel); if (null != p) { jUploadPanel.getJComponent().add(p); p.addMouseListener(jUploadPanel.getMouseListener()); } } /** {@inheritDoc} */ public void updateButtonState(int executionStatus) { // First step: check the parameter. if (executionStatus != UploadPolicy.EXEC_STATUS_READY && executionStatus != UploadPolicy.EXEC_STATUS_UPLOADING) { throw new java.lang.IllegalArgumentException("Unknow value for executionStatus: " + executionStatus); } // Then ... nothing to do! This class has no specific GUI item. } /** @see UploadPolicy#displayErr(Exception) */ public void displayErr(Exception e) { displayErr(e.getMessage(), e); } /** @see UploadPolicy#displayErr(String) */ public void displayErr(String err) { displayErr(err, null); } /** * Logs a stack trace for the given exception. * * @param throwable */ private void displayStackTrace(Throwable throwable) { if (throwable != null) { ByteArrayOutputStream bs = new ByteArrayOutputStream(); PrintStream ps = new PrintStream(bs); throwable.printStackTrace(ps); ps.close(); displayMsg("", bs.toString()); // If there is a cause, let's be sure its stack trace is displayed. if (throwable.getCause() != null) { displayMsg("", "Caused by:"); displayStackTrace(throwable.getCause()); } } } /** * This method just logs an error. * * @param errorText * @param exception */ private void logErr(String errorText, Exception exception) { if (exception == null) { setLastException(new JUploadException("errorText")); } else if (exception instanceof JUploadException) { setLastException((JUploadException) exception); } else { setLastException(new JUploadException(exception)); } // Default behavior: if debugLevel is 0, and an error occurs, we force // the debug level to 1: this makes the log window become visible, if it // was hidden. if (getDebugLevel() == 0) setDebugLevel(1); String exceptionMsg = null; String exceptionClassName = null; String logMsg = errorText; // First, we construct the exception class name. if (exception == null) { exceptionClassName = ""; } else if (exception instanceof JUploadException) { exceptionClassName = "[" + ((JUploadException) exception).getClassNameAndClause() + "] "; } else { exceptionClassName = "[" + exception.getClass().getName() + "] "; } // Then, the message body can be completed by the exception message. if (exception != null) { // Ok, we have an exception. if (exception.getCause() != null) { exceptionMsg = exception.getCause().getMessage(); } else { exceptionMsg = exception.getMessage(); } logMsg = exceptionMsg + " (" + errorText + ")"; } // Add the message to the log window displayMsg("[ERROR]", exceptionClassName + logMsg); // Let's display the stack trace, if relevant. displayStackTrace(exception); // Then we copy the debug output to the clipboard, and say it to the // current user. if (this.juploadContext.getUploadPanel() != null && getDebugLevel() >= 99) { // Ok, the applet has been fully built. this.juploadContext.getUploadPanel().copyLogWindow(); alert("messageLogWindowCopiedToClipboard"); } } /** * If debug is off, the log window may not be visible. We switch the debug * to on, to be sure that some information will be displayed to the user. <BR> * If debug is -1, the log window remains hidden. * * @see wjhk.jupload2.policies.UploadPolicy#displayErr(java.lang.String, * java.lang.Exception, int) */ public int displayErr(String errorText, Exception exception, int optionTypes) { // Then, we display it to the user. String alertMsg = errorText; // Then, the message body can be completed by the exception message. if (exception != null && (errorText == null || errorText.equals(""))) { // Ok, we have an exception. if (exception.getCause() != null) { alertMsg = exception.getCause().getMessage(); } else { alertMsg = exception.getMessage(); } } // The message displayed depend on the debug level: if (getDebugLevel() >= 30 && exception != null) { alertMsg = exception.getClass().getName() + ": " + alertMsg; } // Display the message to the user. The kind of alert box depends on the // given options: int buttonClicked = 0; switch (optionTypes) { case -1: // Standard message box. alertStr(alertMsg); buttonClicked = JOptionPane.OK_OPTION; break; case JOptionPane.OK_CANCEL_OPTION: case JOptionPane.YES_NO_CANCEL_OPTION: case JOptionPane.YES_NO_OPTION: buttonClicked = confirmDialogStr(alertMsg, optionTypes); break; default: // This is a problem. Let's display it to the user as a standard // alert box. alertStr(alertMsg); buttonClicked = JOptionPane.OK_OPTION; // Then, we log this new problem. String msg = "Unknown optionType in displayErr(String, Exception, int)"; alertStr(msg); logErr(msg, null); } // First, we log the error. logErr(errorText, exception); return buttonClicked; } /** * If debug is off, the log window may not be visible. We switch the debug * to on, to be sure that some information will be displayed to the user. <BR> * If debug is -1, the log window remains hidden. * * @see wjhk.jupload2.policies.UploadPolicy#displayErr(java.lang.String, * java.lang.Exception) */ public void displayErr(String errorText, Exception exception) { displayErr(errorText, exception, -1); } /** * @see UploadPolicy#displayInfo(String) */ public void displayInfo(String info) { displayMsg("[INFO]", info); } /** * @see UploadPolicy#displayWarn(String) */ public void displayWarn(String warn) { displayMsg("[WARN]", warn); } /** * @see UploadPolicy#displayDebug(String, int) */ public void displayDebug(String debug, int minDebugLevel) { final String tag = "[DEBUG]"; if (this.debugLevel >= minDebugLevel) { // displayMsg will add the message to the debugStrignBuffer. displayMsg(tag, debug); } else if (this.debugGenerateFile) { // We have to write the message to the debug file, whatever the // debugLevel is. addMsgToDebugLog(tag + debug); } } /** @see UploadPolicy#getLocalizedString(String, Object...) */ public String getLocalizedString(String key, Object... args) { String ret = this.resourceBundle.getString(key); try { // We have to recreate the correct call to String.format switch (args.length) { case 0: return String.format(ret); case 1: return String.format(ret, args[0]); case 2: return String.format(ret, args[0], args[1]); case 3: return String.format(ret, args[0], args[1], args[2]); case 4: return String.format(ret, args[0], args[1], args[2], args[3]); case 5: return String.format(ret, args[0], args[1], args[2], args[3], args[4]); case 6: return String.format(ret, args[0], args[1], args[2], args[3], args[4], args[5]); case 7: return String.format(ret, args[0], args[1], args[2], args[3], args[4], args[5], args[6]); default: throw new IllegalArgumentException( "DefaultUploadPolicy.getLocalizedString accepts up to 7 variable parameters (" + args.length + " values were given for the 'args' argument"); } } catch (IllegalFormatException ife) { displayErr(ife.getClass().getName() + " (" + ife.getMessage() + ")when managing this string: " + ret); throw ife; } } /** * @see UploadPolicy#getUploadFilename(FileData, int) */ public String getUploadFilename(FileData fileData, int index) throws JUploadException { return getEncodedFilename(fileData.getFileName()); } /** * returns the filename and encodes it, if necessary * * @param filename * the original filename * @return filename (encoded, if necessary) * @throws JUploadException */ protected final String getEncodedFilename(String filename) throws JUploadException { if (this.filenameEncoding == null || this.filenameEncoding.equals("")) { return filename; } try { return URLEncoder.encode(filename, this.filenameEncoding); } catch (UnsupportedEncodingException e) { throw new JUploadException(e); } } /** @see UploadPolicy#getUploadName(FileData, int) */ public String getUploadName(FileData fileData, int index) throws JUploadException { if (this.httpUploadParameterType.equals(UploadPolicy.HTTPUPLOADPARAMETERTYPE_ARRAY)) { return this.httpUploadParameterName + "[]"; } else if (this.httpUploadParameterType.equals(UploadPolicy.HTTPUPLOADPARAMETERTYPE_ITERATION)) { return this.httpUploadParameterName + index; } else if (this.httpUploadParameterType.equals(UploadPolicy.HTTPUPLOADPARAMETERTYPE_ONE_FILE)) { // Only valid if nbFilesPerRequest is 1. Let's check it. if (getNbFilesPerRequest() == 1) { return this.httpUploadParameterName; } else { throw new JUploadException( UploadPolicy.PROP_HTTP_UPLOAD_PARAMETER_TYPE + " value '" + this.httpUploadParameterType + "' is only valid when '" + UploadPolicy.PROP_NB_FILES_PER_REQUEST + " is 1."); } } else { throw new JUploadException(UploadPolicy.PROP_HTTP_UPLOAD_PARAMETER_TYPE + " '" + this.httpUploadParameterType + "' is not implemented."); } } /** @see UploadPolicy#getHttpUploadParameterName() */ public String getHttpUploadParameterName() { return this.httpUploadParameterName; } /** * Setter for the {@link #httpUploadParameterName}. This value is used by * the {@link #getUploadName(FileData, int)} method, to generate the name of * the upload parameter that will contain the uploaded file.<BR> * The name must begin by a letter, then contain letter or numbers * * @throws JUploadException * When the given value is invalid (null, empty string, or * contains other characters than letters and/or numbers) */ protected void setHttpUploadParameterName(String httpUploadParameterName) throws JUploadException { // Some useful checks. if (httpUploadParameterName == null || httpUploadParameterName.equals("")) { throw new JUploadException("httpUploadParameterName may not be null"); } // Control the parameter name content. if (!httpUploadParameterName.matches("^[a-zA-Z0-9][a-zA-Z0-9_]*$")) { throw new JUploadException( "httpUploadParameterName may only contain letters (lowercase or uppercase) and numbers."); } // Ok, we're happy with the given value. Let's store it. this.httpUploadParameterName = httpUploadParameterName; } /** @see UploadPolicy#getHttpUploadParameterType() */ public String getHttpUploadParameterType() { return this.httpUploadParameterType; } /** * Setter for the {@link #httpUploadParameterType}. This value is used by * the {@link #getUploadName(FileData, int)} method, to generate the name of * the upload parameter that will contain the uploaded file. Depending on * this value, the parameter will be an iteration or an array. * * @throws JUploadException */ protected void setHttpUploadParameterType(String httpUploadParameterType) throws JUploadException { // Some useful checks. if (httpUploadParameterType == null) { throw new JUploadException("httpUploadParameterType may not be null"); } // Check against the list of allowed values if (!httpUploadParameterType.equals(UploadPolicy.HTTPUPLOADPARAMETERTYPE_ARRAY) && !httpUploadParameterType.equals(UploadPolicy.HTTPUPLOADPARAMETERTYPE_ITERATION) && !httpUploadParameterType.equals(UploadPolicy.HTTPUPLOADPARAMETERTYPE_ONE_FILE)) { throw new JUploadException( "'" + httpUploadParameterType + "' is not an allowed value for httpUploadParameterType."); } // OneFile is only valid ... when we upload file per file ! if (httpUploadParameterType.equals(UploadPolicy.HTTPUPLOADPARAMETERTYPE_ONE_FILE)) { if (getNbFilesPerRequest() != 1) { throw new JUploadException( "'" + httpUploadParameterType + "' is only valid when nbFilesPerRequest is 1."); } } // Ok, we're happy. Let's store the value ! this.httpUploadParameterType = httpUploadParameterType; } /** @see wjhk.jupload2.policies.UploadPolicy#beforeUpload() */ public boolean beforeUpload() { // Default : nothing to do before upload, so we're ready. return true; } /** @see UploadPolicy#onAppendHeader(ByteArrayEncoder) */ public ByteArrayEncoder onAppendHeader(ByteArrayEncoder bae) throws JUploadIOException { Iterator<String> it = this.headers.iterator(); String header; displayDebug("[onAppendHeader] Start", 80); while (it.hasNext()) { header = it.next(); if (header == null || header.equals("")) { displayWarn("[onAppendHeader] Found one empty header. Ignoring it."); } else { bae.append(header).append("\r\n"); displayDebug("[onAppendHeader] Header appended; " + header, 80); } } displayDebug("[onAppendHeader] End", 80); return bae; }// appendHeader /** * Default implementation of the * {@link wjhk.jupload2.policies.UploadPolicy#onFileSelected(wjhk.jupload2.filedata.FileData)} * . Nothing's done. */ public void onFileSelected(FileData fileData) { // Default implementation : no action } /** * Default implementation of the * {@link wjhk.jupload2.policies.UploadPolicy#onFileDoubleClicked(FileData)} * . Nothing's done. */ public void onFileDoubleClicked(FileData fileData) { // Default implementation : no action } /** @see UploadPolicy#sendDebugInformation(String, Exception) */ public void sendDebugInformation(String description, Exception exception) { try { if (null == getUrlToSendErrorTo()) { displayInfo("getUrlToSendErrorTo is null. No debug information is sent."); if (exception == null) { displayInfo(" No exception was stored!"); } else { displayInfo(" The exception was: " + exception.getClass().getName() + exception.getMessage()); } } else { displayInfo("Sending debug information to " + getUrlToSendErrorTo()); if (JOptionPane.showConfirmDialog(null, getLocalizedString("questionSendMailOnError"), getLocalizedString("Confirm"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) { displayDebug("[sendDebugInformation] Within response == true", 30); String action = null; String line; HTTPConnectionHelper connectionHelper = null; boolean localDebugOk = this.debugOk; try { URL url = new URL(this.urlToSendErrorTo); connectionHelper = new HTTPConnectionHelper(this); connectionHelper.initRequest(url, "POST", false, true); ByteArrayEncoder baeContent = new ByteArrayEncoderHTTP(this, connectionHelper.getByteArrayEncoder().getBoundary(), connectionHelper.getByteArrayEncoder().getEncoding()); // The message is written in English, as it is not sure // that // the webmaster speaks the same language as the current // user. baeContent.appendTextProperty("description", "An error occured during upload, in JUpload.", -1); String exceptionClass = null; String exceptionCause = null; String exceptionStackTrace = null; if (exception != null) { exceptionClass = exception.getClass().getName(); if (exception.getCause() != null) { exceptionCause = exception.getCause().getClass().getName(); } StackTraceElement[] elements = exception.getStackTrace(); ByteArrayEncoderHTTP baeStackTrace = new ByteArrayEncoderHTTP(this, connectionHelper.getByteArrayEncoder().getBoundary(), connectionHelper.getByteArrayEncoder().getEncoding()); for (int i = 0; i < elements.length; i += 1) { baeStackTrace.append(" at "); baeStackTrace.append(elements[i].getClassName()); baeStackTrace.append("."); baeStackTrace.append(elements[i].getMethodName()); baeStackTrace.append("() [line "); baeStackTrace.append(Integer.toString(elements[i].getLineNumber())); baeStackTrace.append("]\r\n"); } baeStackTrace.close(); exceptionStackTrace = baeStackTrace.getString(); } baeContent.appendTextProperty("exceptionClass", exceptionClass, -1); baeContent.appendTextProperty("exceptionCause", exceptionCause, -1); baeContent.appendTextProperty("exceptionStackTrace", exceptionStackTrace, -1); String baeBound = connectionHelper.getByteArrayEncoder().getBoundary(); String baeEncoding = connectionHelper.getByteArrayEncoder().getEncoding(); ByteArrayEncoder baeDebug = new ByteArrayEncoderHTTP(this, baeBound, baeEncoding); if (this.debugGenerateFile) { // During debug output, we need to make sure that // the debug log is not changed, so we set debugOk // to false temporarily. -> Everything goes to // stdout. action = "flush (debugGenerateFile=true)"; synchronized (this) { this.debugOut.flush(); this.debugOk = false; // First, calculate the size of the strings we // will // send. action = "read debug file (debugGenerateFile=true)"; BufferedReader debugIn = new BufferedReader(new FileReader(this.debugFile)); while ((line = debugIn.readLine()) != null) { baeDebug.append(line).append("\r\n"); } debugIn.close(); // We are done with the debug log, so re-enable // it. this.debugOk = localDebugOk; } // synchronized(this) } // if (this.debugGenerateFile) else { action = "read debug file (debugGenerateFile=false)"; baeDebug.append(this.juploadContext.getLogWindow().getText()); } action = "baeDebug.close()"; baeDebug.close(); baeContent.appendTextProperty("debugOutput", baeDebug.getString(), -1); baeContent.appendEndPropertyList(); // The content has been built. baeContent.close(); // byteArrayEncoder // .append("Content-type: // application/x-www-form-urlencoded\r\n"); action = "send request"; connectionHelper.append("Content-Type: multipart/form-data; boundary=") .append(connectionHelper.getBoundary().substring(2)).append("\r\n"); connectionHelper.append("Content-length: ") .append(String.valueOf(baeContent.getEncodedLength())).append("\r\n"); // Let's send the headers (without baeDescription) ... connectionHelper.sendRequest(); // Blank line (end of header) connectionHelper.append("\r\n"); connectionHelper.append(baeContent); action = "connectionHelper.readHttpResponse()"; int status = connectionHelper.readHttpResponse(); displayDebug( "========================================================================================", 90); displayDebug( "================== sendDebugInformation [start] =================================", 90); displayDebug( "========================================================================================", 90); displayDebug("[sendDebugInformation] Sent to server: \r\n" + connectionHelper.getByteArrayEncoder().getString(), 90); displayDebug( "========================================================================================", 90); displayDebug( "[sendDebugInformation] Body received: \r\n" + connectionHelper.getResponseBody(), 90); displayDebug( "========================================================================================", 90); displayDebug( "================== sendDebugInformation [end] =================================", 90); displayDebug( "========================================================================================", 90); // Is our upload a success ? if (!checkUploadSuccess(status, connectionHelper.getResponseMsg(), connectionHelper.getResponseBody())) { throw new JUploadExceptionUploadFailed(getLocalizedString("errHttpResponse")); } displayInfo("debug information sent correctly"); } catch (MalformedURLException e) { throw new JUploadIOException("Malformed URL Exception for " + this.urlToSendErrorTo, e); } catch (Exception e) { this.debugOk = localDebugOk; displayErr(getLocalizedString("errDuringLogManagement") + " (" + action + ")", e); } finally { this.debugOk = localDebugOk; } } } } catch (JUploadIOException e) { displayErr("Could not send debug information", e); } }// sendDebugInformation /** * This method manages all applet parameters. It allows javascript to update * their value, for instance after the user chooses a value in a list ... * * @throws JUploadException * @see wjhk.jupload2.policies.UploadPolicy#setProperty(java.lang.String, * java.lang.String) */ public void setProperty(String prop, String value) throws JUploadException { displayDebug("[DefaultUploadPolicy] Call of setProperty: " + prop + " => " + value, 30); if (prop.equals(PROP_AFTER_UPLOAD_URL)) { setAfterUploadURL(value); } else if (prop.equals(PROP_ALLOW_HTTP_PERSISTENT)) { setAllowHttpPersistent(Boolean.parseBoolean(value)); } else if (prop.equals(PROP_ALLOWED_FILE_EXTENSIONS)) { setAllowedFileExtensions(value); } else if (prop.equals(PROP_DEBUG_LEVEL)) { setDebugLevel(this.juploadContext.parseInt(value, this.debugLevel)); } else if (prop.equals(PROP_FILE_CHOOSER_ICON_FROM_FILE_CONTENT)) { setFileChooserIconFromFileContent( this.juploadContext.parseInt(value, getFileChooserIconFromFileContent())); } else if (prop.equals(PROP_FILE_CHOOSER_ICON_SIZE)) { setFileChooserIconSize(this.juploadContext.parseInt(value, getFileChooserIconSize())); } else if (prop.equals(PROP_FILE_FILTER_NAME)) { setFileFilterName(value); } else if (prop.equals(PROP_FILENAME_ENCODING)) { setFilenameEncoding(value); } else if (prop.equals(PROP_LANG)) { setLang(value); } else if (prop.equals(PROP_LOOK_AND_FEEL)) { setLookAndFeel(value); } else if (prop.equals(PROP_MAX_CHUNK_SIZE)) { setMaxChunkSize(this.juploadContext.parseLong(value, this.maxChunkSize)); } else if (prop.equals(PROP_MAX_FILE_SIZE)) { setMaxFileSize(this.juploadContext.parseLong(value, this.maxFileSize)); } else if (prop.equals(PROP_NB_FILES_PER_REQUEST)) { setNbFilesPerRequest(this.juploadContext.parseInt(value, this.nbFilesPerRequest)); } else if (prop.equals(PROP_POST_URL)) { setPostURL(value); } else if (prop.equals(PROP_SERVER_PROTOCOL)) { HttpProtocolFinderThread.computeServerProtocol(this, value); } else if (prop.equals(PROP_STRING_UPLOAD_SUCCESS)) { setStringUploadSuccess(value); } else if (prop.equals(PROP_SSL_VERIFY_CERT)) { setSslVerifyCert(value); } else if (prop.equals(PROP_URL_TO_SEND_ERROR_TO)) { setUrlToSendErrorTo(value); } else { displayWarn("Unknown applet parameter: " + prop + " (in DefaultUploadPolicy.setProperty)"); } } /** * This method displays the applet parameter list, according to the current * debugLevel. It is called by the {@link #setDebugLevel(int)} method. It * should be override by any subclasses, that should display its own * parameters, then call <I>super.displayParameterStatus()</I>. * * @see UploadPolicy#displayParameterStatus() */ public void displayParameterStatus() { displayDebug("=======================================================================", 30); displayDebug("======= Parameters managed by DefaultUploadPolicy", 30); // ///////////////////////////////////////////////////////////////////////////// // Let's display some information to the user, about the received // parameters. displayInfo("JUpload applet, version " + this.juploadContext.getDetailedVersionMessage() + " (compiled: " + this.juploadContext.getBuildDate() + "), available at http://jupload.sourceforge.net/"); displayDebug("Java version: " + System.getProperty("java.version"), 30); displayDebug("List of all applet parameters:", 30); displayDebug(" language: " + this.resourceBundle.getLocale().getLanguage(), 30); displayDebug(" country: " + this.resourceBundle.getLocale().getCountry(), 30); displayDebug(PROP_AFTER_UPLOAD_URL + ": " + getAfterUploadURL(), 30); displayDebug(PROP_ALLOW_HTTP_PERSISTENT + ": " + getAllowHttpPersistent(), 30); displayDebug(PROP_ALLOWED_FILE_EXTENSIONS + ": " + getAllowedFileExtensions(), 30); displayDebug(PROP_BROWSING_DIRECTORY + " (current value): " + getCurrentBrowsingDirectory(), 30); displayDebug(PROP_DEBUG_LEVEL + ": " + this.debugLevel, 1); synchronized (this) { if (this.debugGenerateFile) { displayDebug(" (debugfile: " + this.debugFile.getAbsolutePath() + ")", 1); } } displayDebug(PROP_FILE_CHOOSER_ICON_FROM_FILE_CONTENT + ": " + getFileChooserIconFromFileContent(), 30); displayDebug(PROP_FILE_CHOOSER_ICON_SIZE + ": " + getFileChooserIconSize(), 30); displayDebug(PROP_FILE_FILTER_NAME + ": " + getFileFilterName(), 30); displayDebug(PROP_FILENAME_ENCODING + ": " + getFilenameEncoding(), 30); displayDebug(PROP_FORMDATA + ": " + getFormdata(), 30); displayDebug(PROP_FTP_CREATE_DIRECTORY_STRUCTURE + ": " + getFtpCreateDirectoryStructure(), 30); displayDebug(PROP_FTP_TRANSFERT_BINARY + ": " + getFtpTransfertBinary(), 30); displayDebug(PROP_FTP_TRANSFERT_PASSIVE + ": " + getFtpTransfertPassive(), 30); displayDebug(PROP_HTTP_UPLOAD_PARAMETER_NAME + ": " + getHttpUploadParameterName(), 30); displayDebug(PROP_HTTP_UPLOAD_PARAMETER_TYPE + ": " + getHttpUploadParameterType(), 30); displayDebug("lang: " + this.lang, 30); displayDebug(PROP_MAX_CHUNK_SIZE + ": " + getMaxChunkSize(), 30); if (this.maxFileSize == Long.MAX_VALUE) { // If the maxFileSize was not given, we display its value only // in debug mode. displayDebug(PROP_MAX_FILE_SIZE + ": " + getMaxFileSize(), 30); } else { // If the maxFileSize was given, we always inform the user. displayInfo(PROP_MAX_FILE_SIZE + ": " + getMaxFileSize()); } displayDebug(PROP_NB_FILES_PER_REQUEST + ": " + getNbFilesPerRequest(), 30); displayDebug(PROP_POST_URL + ": " + this.postURL, 30); displayDebug(PROP_READ_COOKIE_FROM_NAVIGATOR + ": " + this.readCookieFromNavigator, 30); displayDebug(PROP_READ_USER_AGENT_FROM_NAVIGATOR + ": " + this.readUserAgentFromNavigator, 30); displayDebug(PROP_RETRY_MAX_NUMBER_OF + ": " + this.retryMaxNumberOf, 30); displayDebug(PROP_RETRY_NB_SECONDS_BETWEEN + ": " + this.retryNbSecondsBetween, 30); displayDebug(PROP_SEND_MD5_SUM + ": " + getSendMD5Sum(), 30); displayDebug(PROP_SERVER_PROTOCOL + ": " + getServerProtocol(), 30); displayDebug(PROP_SHOW_LOGWINDOW + ": " + getShowLogWindow(), 30); displayDebug(PROP_SHOW_STATUSBAR + ": " + this.showStatusbar, 30); displayDebug(PROP_SPECIFIC_HEADERS + ": " + getSpecificHeaders(), 30); displayDebug("Headers that will be added to the POST request: ", 30); for (Iterator<String> it = this.headers.iterator(); it.hasNext();) { displayDebug(it.next() + "\n", 30); } displayDebug(PROP_STRING_UPLOAD_ERROR + ": " + getStringUploadError(), 30); displayDebug(PROP_STRING_UPLOAD_SUCCESS + ": " + getStringUploadSuccess(), 30); displayDebug(PROP_STRING_UPLOAD_WARNING + ": " + getStringUploadWarning(), 30); displayDebug(PROP_URL_TO_SEND_ERROR_TO + ": " + getUrlToSendErrorTo(), 30); displayDebug("", 30); } // ////////////////////////////////////////////////////////////////////////////////////////////// // /////////////////// getters / setters // /////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////////////////////////////////// /** @see UploadPolicy#getAfterUploadURL() */ public String getAfterUploadURL() { return this.afterUploadURL; } /** * Set the {@link #afterUploadURL} * * @param afterUploadURL * The URL to use. * @throws JUploadException */ protected void setAfterUploadURL(String afterUploadURL) throws JUploadException { if (null == afterUploadURL) return; if (afterUploadURL.toLowerCase().startsWith("javascript:")) { this.afterUploadURL = afterUploadURL; } else this.afterUploadURL = this.juploadContext.normalizeURL(afterUploadURL); } /** * @see wjhk.jupload2.policies.UploadPolicy#getAllowHttpPersistent() */ public boolean getAllowHttpPersistent() { return this.allowHttpPersistent; } /** @see UploadPolicy#getAllowedFileExtensions() */ public String getAllowedFileExtensions() { return this.allowedFileExtensions; } /** * @param allowedFileExtensions * the allowedFileExtensions to set */ protected void setAllowedFileExtensions(String allowedFileExtensions) { if (allowedFileExtensions == null || allowedFileExtensions.equals("")) { this.allowedFileExtensions = null; } else { this.allowedFileExtensions = (allowedFileExtensions.startsWith("/") ? "" : "/") + allowedFileExtensions.toLowerCase() + (allowedFileExtensions.endsWith("/") ? "" : "/"); } } protected void setAllowHttpPersistent(boolean value) { this.allowHttpPersistent = value; } /** @see UploadPolicy#getContext() */ public JUploadContext getContext() { return this.juploadContext; } /** {@inheritDoc} */ public void setCurrentBrowsingDirectory(File currentBrowsingDirectoryParam) { try { if (currentBrowsingDirectoryParam.isDirectory()) { this.currentBrowsingDirectory = currentBrowsingDirectoryParam; } else { displayWarn("DefaultUploadPolicy.setCurrentBrowsingDirectory(): " + currentBrowsingDirectoryParam + " doesn't exist."); } } catch (SecurityException se) { displayWarn(se.getClass().getName() + " in DefaultUploadPolicy.setCurrentBrowsingDirectory(): " + currentBrowsingDirectoryParam + " is ignored."); } } /** * @param currentBrowsingDirectoryParam * The name of the directory that should be the current one. * @see UploadPolicy#setCurrentBrowsingDirectory(String) */ public void setCurrentBrowsingDirectory(String currentBrowsingDirectoryParam) { try { if (currentBrowsingDirectoryParam == null) { this.currentBrowsingDirectory = null; } else { // Apparently, Java deosn't manage path beginning by ~. folder // is actually ... ~! // Let's manager this. if (currentBrowsingDirectoryParam.startsWith("~")) { // Let's keep the part of this path that is after the ~ currentBrowsingDirectoryParam = System.getProperty("user.home") + currentBrowsingDirectoryParam.substring(1); } this.currentBrowsingDirectory = new File(currentBrowsingDirectoryParam); // Let's check that we have a folder. if (this.currentBrowsingDirectory != null && !this.currentBrowsingDirectory.isDirectory()) { displayWarn("DefaultUploadPolicy.setCurrentBrowsingDirectory(): <" + currentBrowsingDirectoryParam + "> doesn't exist or is not a directory."); this.currentBrowsingDirectory = null; } } } catch (SecurityException se) { displayWarn(se.getClass().getName() + " in DefaultUploadPolicy.setCurrentBrowsingDirectory(): " + currentBrowsingDirectoryParam + " is ignored."); } } /** @see UploadPolicy#getCurrentBrowsingDirectory() */ public File getCurrentBrowsingDirectory() { return this.currentBrowsingDirectory; } /** @see UploadPolicy#getDateFormat() */ public String getDateFormat() { return UploadPolicy.DEFAULT_DATE_FORMAT; } /** @see UploadPolicy#getDebugLevel() */ public int getDebugLevel() { return this.debugLevel; } /** @see UploadPolicy#setDebugLevel(int) */ public void setDebugLevel(int debugLevel) { setDebugLevel(debugLevel, true); } /** * Set the debug level. * * @param debugLevel * The new debuglevel. * @param displayAppletParameterList * Flag. If set to true, the applet's parameters are shown. */ public synchronized void setDebugLevel(int debugLevel, boolean displayAppletParameterList) { // If the debugLevel was previously set, we inform the user of this // change. if (this.debugLevel >= 0) { displayInfo("Debug level set to " + debugLevel); if (this.debugGenerateFile) { displayInfo("Current debug output file: " + this.debugFile.getAbsolutePath()); } } this.debugLevel = debugLevel; // Let's display the current applet parameters. if (displayAppletParameterList) { displayParameterStatus(); } } /** * Getter for fileChooserIconFromFileContent. * * @return Current value for fileChooserIconFromFileContent * @see UploadPolicy#PROP_FILE_CHOOSER_ICON_FROM_FILE_CONTENT */ public int getFileChooserIconFromFileContent() { return this.fileChooserIconFromFileContent; } /** * Setter for fileChooserIconFromFileContent. Current allowed values are: * -1, 0, 1. Default value is 0. * * @param fileChooserIconFromFileContent * Value to be set. If the value is not allowed (not -1, 0 or 1), * the current value is unchangeed. * @exception java.lang.IllegalArgumentException * When a value not in -1, 0 1 is given. * @see UploadPolicy#PROP_FILE_CHOOSER_ICON_FROM_FILE_CONTENT */ public void setFileChooserIconFromFileContent(int fileChooserIconFromFileContent) { if (fileChooserIconFromFileContent != -1 && fileChooserIconFromFileContent != 0 && fileChooserIconFromFileContent != 1) { throw new java.lang.IllegalArgumentException("fileChooserIconFromFileContent must be one of -1, 0, 1"); } this.fileChooserIconFromFileContent = fileChooserIconFromFileContent; } /** * Getter for fileChooserIconSize. * * @return Current value for fileChooserIconSize * @see UploadPolicy#PROP_FILE_CHOOSER_ICON_SIZE */ public int getFileChooserIconSize() { return this.fileChooserIconSize; } /** * Setter for fileChooserIconSize. * * @param fileChooserIconSize * Value to be set. * @exception java.lang.IllegalArgumentException * When a negative value is given. * @see UploadPolicy#PROP_FILE_CHOOSER_ICON_SIZE */ public void setFileChooserIconSize(int fileChooserIconSize) { if (fileChooserIconSize <= 0) { throw new java.lang.IllegalArgumentException("fileChooserIconSize must be more than 0"); } this.fileChooserIconSize = fileChooserIconSize; } /** @see wjhk.jupload2.policies.UploadPolicy#setLang(String) */ public void setLang(String lang) { this.lang = lang; if (lang == null) { displayInfo("lang = null, taking default language"); locale = Locale.getDefault(); } else { // If we have a 5 characters lang string, then it should look like // ll_CC, where ll is the language code // and CC is the Country code. if (lang.length() == 5 && (lang.substring(2, 3).equals("_") || lang.substring(2, 3).equals("-"))) { String language = lang.substring(0, 2); String country = lang.substring(3, 5); displayDebug("setLang - language read: " + language, 50); displayDebug("setLang - country read: " + country, 50); locale = new Locale(language, country.toUpperCase()); } else { locale = new Locale(lang); displayDebug("setLang - language read (no country): " + lang, 50); } } /* * Patch given by Patrick Use of a specific class loader. The standard * ResourceBundle checks first for a class that has the name of the * resource bundle. Since there is no such class in the jar file, the * AppletClassLoader makes a http request to the server, which will end * with a 404 since there is no such class either. To avoid this * unnecessary lookup we use a class loader that throws directly a * ClassNotFoundException. After looking for a class (which is * unsuccessful) ResourceBundle looks finally for a properties file. * Therefore we delegate that lookup to the original class loader since * this is in the jar file. */ this.resourceBundle = ResourceBundle.getBundle("lang.lang", locale, // Special class loader, see description above new ClassLoader(this.getClass().getClassLoader()) { /** {@inheritDoc} */ @Override public Class<?> loadClass(String name) throws ClassNotFoundException { throw new ClassNotFoundException(); } /** {@inheritDoc} */ @Override public InputStream getResourceAsStream(String name) { return this.getClass().getClassLoader().getResourceAsStream(name); } }); } /** {@inheritDoc} */ public Locale getLocale() { return this.locale; } /** */ protected String getLookAndFeel() { return this.lookAndFeel; } /** * @param lookAndFeel * the lookAndFeel to set */ protected void setLookAndFeel(String lookAndFeel) { try { this.lookAndFeel = lookAndFeel; if (lookAndFeel != null && !lookAndFeel.equals("") && !lookAndFeel.equals("java")) { // We try to call the UIManager.setLookAndFeel() method. We // catch // all possible exceptions, to prevent // that the applet is blocked. if (!lookAndFeel.equals("system")) { // Correction given by Fritz. Thanks to him. UIManager.setLookAndFeel(lookAndFeel); } else { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } } else { this.lookAndFeel = "java"; UIManager.setLookAndFeel(new javax.swing.plaf.metal.MetalLookAndFeel()); } } catch (Exception e) { displayErr(e); try { this.lookAndFeel = "java"; UIManager.setLookAndFeel(new javax.swing.plaf.metal.MetalLookAndFeel()); } catch (UnsupportedLookAndFeelException e1) { displayErr(e1); // Hum, hum: we should not arrive here... We not a 'dummy' one. this.lookAndFeel = null; } } } /** @see wjhk.jupload2.policies.UploadPolicy#getMaxChunkSize() */ public long getMaxChunkSize() { return this.maxChunkSize; } /** * If the given value is less or equals to 0, it is set back to * Long_MAX_VALUE. * * @param maxChunkSize * the maxChunkSize to set */ protected void setMaxChunkSize(long maxChunkSize) { if (maxChunkSize <= 0) { displayDebug("maxChunkSize<=0 which is invalid. Switched to the default value (Long.MAX_VALUE)", 1); maxChunkSize = Long.MAX_VALUE; } this.maxChunkSize = maxChunkSize; } /** @see wjhk.jupload2.policies.UploadPolicy#getMaxFileSize() */ public long getMaxFileSize() { return this.maxFileSize; } /** * @param maxFileSize * the maxFileSize to set */ protected void setMaxFileSize(long maxFileSize) { if (maxFileSize <= 0) { displayDebug("maxFileSize<=0 which is invalid. Switched to the default value (Long.MAX_VALUE)", 1); maxFileSize = Long.MAX_VALUE; } this.maxFileSize = maxFileSize; } /** @see wjhk.jupload2.policies.UploadPolicy#getNbFilesPerRequest() */ public int getNbFilesPerRequest() { return this.nbFilesPerRequest; } /** * @param nbFilesPerRequest * the nbFilesPerRequest to set * @throws JUploadException */ protected void setNbFilesPerRequest(int nbFilesPerRequest) throws JUploadException { // If httpUploadParameterType is oneFile, if (getHttpUploadParameterType().equals(UploadPolicy.HTTPUPLOADPARAMETERTYPE_ONE_FILE) && nbFilesPerRequest != 1) { throw new JUploadException("nbFilesPerRequest must be 1, when httpUploadParameterType is oneFile"); } if (nbFilesPerRequest < 1) { displayDebug("nbFilesPerRequest <1 : switched to the 'unlimited' value (Integer.MAX_VALUE)", 1); this.nbFilesPerRequest = Integer.MAX_VALUE; } else { this.nbFilesPerRequest = nbFilesPerRequest; } } /** @see UploadPolicy#getFilenameEncoding() */ public String getFilenameEncoding() { return this.filenameEncoding; } /** @see UploadPolicy#getFileFilterName() */ public String getFileFilterName() { return this.fileFilterName; } /** * @param fileFilterName * The new name for the fileFilter * @see UploadPolicy#PROP_FILE_FILTER_NAME */ protected void setFileFilterName(String fileFilterName) { this.fileFilterName = fileFilterName; } /** * @param filenameEncoding * the filenameEncoding to set */ protected void setFilenameEncoding(String filenameEncoding) { if (filenameEncoding != null && filenameEncoding.equals("")) { filenameEncoding = null; } if (filenameEncoding != null && !Charset.isSupported(filenameEncoding)) { throw new UnsupportedCharsetException("non supported charset (" + filenameEncoding + ")"); } this.filenameEncoding = filenameEncoding; } /** @see UploadPolicy#getFtpCreateDirectoryStructure() */ public boolean getFtpCreateDirectoryStructure() { return this.ftpCreateDirectoryStructure; } /** * @param ftpCreateDirectoryStructure * the ftpCreateDirectoryStructure to set */ protected void setFtpCreateDirectoryStructure(boolean ftpCreateDirectoryStructure) { this.ftpCreateDirectoryStructure = ftpCreateDirectoryStructure; } /** @see UploadPolicy#getFtpTransfertBinary() */ public boolean getFtpTransfertBinary() { return this.ftpTransfertBinary; } /** * @param ftpTransfertBinary * the ftpTransfertBinary to set */ protected void setFtpTransfertBinary(boolean ftpTransfertBinary) { this.ftpTransfertBinary = ftpTransfertBinary; } /** @see UploadPolicy#getFtpTransfertPassive() */ public boolean getFtpTransfertPassive() { return this.ftpTransfertPassive; } /** * @param ftpTransfertPassive * the ftpTransfertPassive to set */ protected void setFtpTransfertPassive(boolean ftpTransfertPassive) { this.ftpTransfertPassive = ftpTransfertPassive; } /** @see wjhk.jupload2.policies.UploadPolicy#getPostURL() */ public String getPostURL() { return this.postURL; } /** * @throws JUploadException * @see wjhk.jupload2.policies.UploadPolicy#setPostURL(String) */ public void setPostURL(String postURL) throws JUploadException { // Be more forgiving about postURL: // - If none is specified, use the original DocumentBase of the // applet. // - If a non-absolute URI (an URI without protocol and server) is // specified, // prefix it with "http://servername" // - If a relative URI is specified, prefix it with the DocumentBase's // parent this.postURL = this.juploadContext.normalizeURL(postURL); } /** @see wjhk.jupload2.policies.UploadPolicy#getReadCookieFromNavigator() */ public boolean getReadCookieFromNavigator() { return this.readCookieFromNavigator; } /** @see wjhk.jupload2.policies.UploadPolicy#getReadCookieFromNavigator() */ protected void setReadCookieFromNavigator(boolean readCookieFromNavigator) { this.readCookieFromNavigator = readCookieFromNavigator; } /** @see wjhk.jupload2.policies.UploadPolicy#getReadUserAgentFromNavigator() */ public boolean getReadUserAgentFromNavigator() { return this.readUserAgentFromNavigator; } /** @see wjhk.jupload2.policies.UploadPolicy#getReadUserAgentFromNavigator() */ protected void setReadUserAgentFromNavigator(boolean readUserAgentFromNavigator) { this.readUserAgentFromNavigator = readUserAgentFromNavigator; } /** @see UploadPolicy#getRetryMaxNumberOf() */ public int getRetryMaxNumberOf() { return this.retryMaxNumberOf; } /** * @param retryMaxNumberOf * New value to set for the retryMaxNumberOf applet parameter * @exception IllegalArgumentException * If retryMaxNumberOf is less than 0. * @see UploadPolicy#getRetryMaxNumberOf() */ public void setRetryMaxNumberOf(int retryMaxNumberOf) { if (retryMaxNumberOf < 0) { throw new IllegalArgumentException("retryMaxNumberOf must be 0 or more"); } this.retryMaxNumberOf = retryMaxNumberOf; } /** @see UploadPolicy#getRetryNbSecondsBetween() */ public int getRetryNbSecondsBetween() { return this.retryNbSecondsBetween; } /** * @param retryNbSecondsBetween * New value to set for the retryNbSecondsBetween applet * parameter * @exception IllegalArgumentException * If retryNbSecondsBetween is less than 0. * @see UploadPolicy#getRetryNbSecondsBetween() */ public void setRetryNbSecondsBetween(int retryNbSecondsBetween) { if (retryNbSecondsBetween < 0) { throw new IllegalArgumentException("retryNbSecondsBetween must be 0 or more"); } this.retryNbSecondsBetween = retryNbSecondsBetween; } /** @see wjhk.jupload2.policies.UploadPolicy#getServerProtocol() */ public String getServerProtocol() { if (this.serverProtocol == null) { return DEFAULT_SERVER_PROTOCOL; } else { return this.serverProtocol; } } /** @see UploadPolicy#setServerProtocol(String) */ public void setServerProtocol(String serverProtocol) { this.serverProtocol = serverProtocol; } /** @see wjhk.jupload2.policies.UploadPolicy#getSendMD5Sum() */ public boolean getSendMD5Sum() { return this.sendMD5Sum; } /** @see UploadPolicy#setSendMD5Sum(boolean) */ public void setSendMD5Sum(boolean sendMD5Sum) { this.sendMD5Sum = sendMD5Sum; } /** @see wjhk.jupload2.policies.UploadPolicy#getShowLogWindow() */ public String getShowLogWindow() { return this.showLogWindow; } /** {@inheritDoc} */ public void setShowLogWindow(String showLogWindow) { if (showLogWindow.equals(SHOWLOGWINDOW_TRUE) || showLogWindow.equals(SHOWLOGWINDOW_FALSE) || showLogWindow.equals(SHOWLOGWINDOW_ONERROR)) { this.showLogWindow = showLogWindow; // The log window may become visible or hidden, depending on this // parameter. if (this.juploadContext.getUploadPanel() != null) { this.juploadContext.getUploadPanel().showOrHideLogWindow(); } } else { displayWarn( "[setShowLogWindow] Unallowed value: " + showLogWindow + " (showLogWindow is left unchanged)"); } } /** @see wjhk.jupload2.policies.UploadPolicy#getSpecificHeaders() */ public String getSpecificHeaders() { return this.specificHeaders; } /** * Set all specific headers defined in the specificHeaders applet parameter. * This string is splitted, so that each header is added to the headers * Vector. These headers are added to the headers list during applet * initialization. There is currently no automatic way to remove the headers * coming from specificHeaders, after initialization. * * @param specificHeaders */ protected void setSpecificHeaders(String specificHeaders) { this.specificHeaders = specificHeaders; if (specificHeaders != null) { // Let's add each header in specificHeaders to the headers list. In // specificHeaders, each header is separated by the \n string (two // characters: \ then n, not the \n character). // The regexp to find the \n string (not the \n character) is: \\n // We then double each \ character: String[] headerArray = specificHeaders.split("\\\\n"); for (int x = 0; x < headerArray.length; x++) { addHeader(headerArray[x]); } } } /** * @see wjhk.jupload2.policies.UploadPolicy#getSslVerifyCert() */ public int getSslVerifyCert() { return this.sslVerifyCert; } protected void setSslVerifyCert(String mode) throws JUploadException { int val = -1; if (mode.toLowerCase().equals("none")) val = InteractiveTrustManager.NONE; if (mode.toLowerCase().equals("server")) val = InteractiveTrustManager.SERVER; if (mode.toLowerCase().equals("client")) val = InteractiveTrustManager.CLIENT; if (mode.toLowerCase().equals("strict")) val = InteractiveTrustManager.STRICT; if (val == -1) throw new JUploadException("Invalid parameter sslVerifyCert (" + mode + ")"); this.sslVerifyCert = val; } /** * @param show * the new showStatusbar value */ protected void setShowStatusbar(boolean show) { this.showStatusbar = show; } /** @see wjhk.jupload2.policies.UploadPolicy#getStringUploadError() */ public String getStringUploadError() { return this.stringUploadError; } /** @see wjhk.jupload2.policies.UploadPolicy#getStringUploadSuccess() */ public String getStringUploadSuccess() { return this.stringUploadSuccess; } /** @see wjhk.jupload2.policies.UploadPolicy#getStringUploadWarning() */ public String getStringUploadWarning() { return this.stringUploadWarning; } /** * @param stringUploadError * the stringUploadError to set * @throws JUploadException */ protected void setStringUploadError(String stringUploadError) throws JUploadException { this.stringUploadError = stringUploadError; if (stringUploadError != null) { try { this.patternError = Pattern.compile(stringUploadError); } catch (PatternSyntaxException e) { throw new JUploadException("Invalid regex in parameter stringUploadError"); } } } /** * @param stringUploadSuccess * the stringUploadSuccess to set * @throws JUploadException */ protected void setStringUploadSuccess(String stringUploadSuccess) throws JUploadException { this.stringUploadSuccess = stringUploadSuccess; if (stringUploadSuccess != null) { try { this.patternSuccess = Pattern.compile(stringUploadSuccess); } catch (PatternSyntaxException e) { throw new JUploadException("Invalid regex in parameter stringUploadSuccess"); } } } /** * @param stringUploadWarning * the stringUploadWarning to set * @throws JUploadException */ protected void setStringUploadWarning(String stringUploadWarning) throws JUploadException { this.stringUploadWarning = stringUploadWarning; if (stringUploadWarning != null) { try { this.patternWarning = Pattern.compile(stringUploadWarning); } catch (PatternSyntaxException e) { throw new JUploadException("Invalid regex in parameter stringUploadWarning"); } } } /** @see wjhk.jupload2.policies.UploadPolicy#getUrlToSendErrorTo() */ public String getUrlToSendErrorTo() { return this.urlToSendErrorTo; } /** {@inheritDoc} */ public void setUrlToSendErrorTo(String urlToSendErrorTo) throws JUploadException { if (null == urlToSendErrorTo) return; String tmp = this.juploadContext.normalizeURL(urlToSendErrorTo); if (tmp.startsWith("ftp://")) { throw new JUploadException("urlToSendErrorTo: ftp scheme not supported."); } this.urlToSendErrorTo = tmp; } /** @see wjhk.jupload2.policies.UploadPolicy#getFormdata() */ public String getFormdata() { return this.formData; } /** @see wjhk.jupload2.policies.UploadPolicy#getAfterUploadTarget() */ public String getAfterUploadTarget() { return this.afterUploadTarget; } // ////////////////////////////////////////////////////////////////////////////////////////////// // /////////////////// Internal methods // ////////////////////////////////////////////////////////////////////////////////////////////// /** * Delete the current log. (called upon applet termination) */ public synchronized void deleteLog() { if (this.debugGenerateFile) { try { if (null != this.debugOut) { this.debugOut.close(); this.debugOut = null; } if (null != this.debugFile) { if (!this.debugFile.delete()) { displayWarn(this.debugFile.getName() + " was not correctly removed!"); } this.debugFile = null; } } catch (Exception e) { // nothing to do: we mask the exception. displayWarn(e.getClass().getName() + " occured in deleteLog(). Exception ignored."); } } } /** * This methods allows the applet to store all messages (debug, warning, * info, errors...) into a StringBuffer. If any problem occurs, the whole * output (displayed or not by the displayDebug, for instance) can be stored * in a file, or sent to the webmaster. This can help to identify and * correct problems that can occurs on the various computer configurations. * * @param msg */ protected synchronized void addMsgToDebugLog(String msg) { // If uploading lots of chunks, the buffer gets too large, resulting in // a OutOfMemoryError on the heap so we now use a temporary file for the // debug log. if (this.debugGenerateFile && this.debugOk) { try { if (null == this.debugOut) { this.juploadContext.registerUnload(this, "deleteLog"); this.debugFile = File.createTempFile("jupload_", "_log.txt"); this.debugOut = new PrintStream(new FileOutputStream(this.debugFile)); } boolean endsLF = msg.endsWith("\n"); msg = msg.replaceAll("\n", this.CRLF); if (endsLF) { this.debugOut.print(msg); } else { this.debugOut.println(msg); } } catch (IOException e) { this.debugOk = false; System.err.println( "IO error on debuglog " + this.debugFile.getPath() + "\nFallback to standard output."); System.out.println(msg); } } else { System.out.println(msg); } } /** * Displays a message. If the logWindow panel is set, the message is * displayed on it. If not, the System.out.println function is used. * * @param msg * The message to display. */ private void displayMsg(String tag, String msg) { String message; if (this.juploadContext.getLogWindow() == null) { message = tag + " - " + msg; System.out.println(message); } else { message = this.juploadContext.getLogWindow().displayMsg(tag, msg); } // Let's store all text in the debug logfile if (this.debugGenerateFile) { addMsgToDebugLog(message); } } /** * Default reaction after a successful drop operation: no action. * * @see UploadPolicy#afterFileDropped(DropTargetDropEvent) */ public void afterFileDropped(DropTargetDropEvent dropEvent) { // Default: no action. } /** * Default implementation for {@link UploadPolicy#createFileChooser()}: just * a creation of a {@link JUploadFileChooser}. * * @see UploadPolicy#createFileChooser() */ public JUploadFileChooser createFileChooser() { return new JUploadFileChooser(this); } /** * This method returns the response for the * {@link JUploadFileFilter#accept(File)} which just calls this method. This * method checks that the file extension corresponds to the * allowedFileExtensions applet parameter. * * @see UploadPolicy#fileFilterAccept(File) */ public boolean fileFilterAccept(File file) { if (file.isDirectory()) { return true; } else if (this.allowedFileExtensions == null || this.allowedFileExtensions.equals("")) { return true; } else { // Get the file extension String extension = DefaultFileData.getExtension(file).toLowerCase(); // allowedFileExtensions is : // - a list of file extensions, // - in lower case, // - separated by slash // - A slash has been added at the beginning in // setAllowedFileExtensions // - A slash has been added at the end in setAllowedFileExtensions // So, we just look for the /ext/ string in the stored // allowedFileExtensions. return (this.allowedFileExtensions.indexOf("/" + extension + "/")) >= 0; } } /** @see UploadPolicy#fileFilterGetDescription() */ public String fileFilterGetDescription() { if (this.allowedFileExtensions == null || this.allowedFileExtensions.equals("")) { return null; } else if (getFileFilterName() != null) { return getFileFilterName(); } else { return "JUpload file filter (" + this.allowedFileExtensions + ")"; } } /** * Returns null: the default icon is used. * * @see UploadPolicy#fileViewGetIcon(File) */ public Icon fileViewGetIcon(File file) { return null; } /** @see wjhk.jupload2.policies.UploadPolicy#getLastException() */ public JUploadException getLastException() { return this.lastException; } /** * Set the last exception. * * @param exception * The last exception that occurs into the applet. */ public void setLastException(JUploadException exception) { this.lastException = exception; // The log window may become visible. if (this.juploadContext.getUploadPanel() != null) { this.juploadContext.getUploadPanel().showOrHideLogWindow(); } } /** @see wjhk.jupload2.policies.UploadPolicy#getLastResponseBody() */ public String getLastResponseBody() { return this.lastResponseBody; } /** @see wjhk.jupload2.policies.UploadPolicy#getLastResponseMessage() */ public String getLastResponseMessage() { return (null != this.lastResponseMessage) ? this.lastResponseMessage : ""; } /** * @return The cursor that was active before setting the new one. Can be * used to restore its previous state. * @see UploadPolicy#setCursor(Cursor) */ public Cursor setCursor(Cursor cursor) { return this.juploadContext.setCursor(cursor); } /** * @return The cursor that was active before setting the new one. Can be * used to restore its previous state. * @see UploadPolicy#setWaitCursor() */ public Cursor setWaitCursor() { return this.juploadContext.setWaitCursor(); } @Override public void setCurrentDirectory(File currentDirectory) { this.currentDirectory = currentDirectory; } @Override public void setSelectedFiles(File[] selectedFiles) { this.selectedFiles = selectedFiles; } @Override public String getSelectedFilesInfoJSON() { JSONArray jsonArray = new JSONArray(); for (int i = 0; i < selectedFiles.length; i++) { JSONObject jsonObj = new JSONObject(); try { jsonObj.put("name", selectedFiles[i].getName()); jsonObj.put("size", selectedFiles[i].length()); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } jsonArray.put(jsonObj); } String sRet = jsonArray.toString(); return sRet; } }