1 /* 2 * $Id$ 3 */ 4 5 /* 6 * Copyright (C) 2008 Ed Huott This program is free software; you can 7 * redistribute it and/or modify it under the terms of the GNU General Public 8 * License as published by the Free Software Foundation; either version 2 of the 9 * License, or (at your option) any later version. This program is distributed 10 * in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even 11 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 * See the GNU General Public License for more details. You should have received 13 * a copy of the GNU General Public License along with this program; if not, 14 * write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 15 * Boston, MA 02110-1301, USA. 16 */ 17 18 package wjhk.jupload2.context; 19 20 import wjhk.jupload2.gui.JUploadPanel; 21 import wjhk.jupload2.policies.UploadPolicy; 22 23 /** 24 * Separate thread spawned by the (signed) applet at initialization time so it 25 * will run in a context with the same privileges. Does nothing but wait to be 26 * notified of the presence of a command to be executed in the jsCommand String 27 * variable. 28 */ 29 public class JavascriptHandler extends Thread { 30 31 /** 32 * Command code, for upload. 33 */ 34 public final static String COMMAND_START_UPLOAD = "startUpload"; 35 36 /** 37 * One return code for doCommand: indicates that the thread is busy, and can 38 * execute this command. 39 */ 40 public final static String RETURN_BUSY = "busy"; 41 42 /** 43 * One return code for doCommand: indicates that the thread is busy, and can 44 * execute this command. 45 */ 46 public final static String RETURN_STARTED = "started"; 47 48 /** 49 * Reference to the current upload policy. 50 */ 51 private UploadPolicy uploadPolicy = null; 52 53 /** 54 * Reference to the main panel of the applet. 55 */ 56 private JUploadPanel jUploadPanel = null; 57 58 /** 59 * The current command, or null if the thread is not currently running 60 * command. 61 */ 62 private String jsCommand = null; 63 64 /** 65 * Constructor for JavascriptHandler 66 * 67 * @param uploadPolicy The current upload policy. Used for debug output. 68 * @param theJUploadPanel Whose methods will will be invoked in order to 69 * execute the received commands 70 */ 71 public JavascriptHandler(UploadPolicy uploadPolicy, 72 JUploadPanel theJUploadPanel) { 73 this.uploadPolicy = uploadPolicy; 74 this.jUploadPanel = theJUploadPanel; 75 76 setName(this.getClass().getName()); 77 78 // This thread will close as soon as the applet is closed: 79 setDaemon(true); 80 } 81 82 /** 83 * Method for passing a command (String) to be executed (asynchronously) by 84 * the run() method of this object's thread. Commands are accepted only if 85 * there is no previous command still executing. (Commands are not queued.) 86 * Return value indicates if command was successfully submitted. 87 * 88 * @param command 89 * @return the command string argument on success, empty string on failure. 90 */ 91 public synchronized String doCommand(String command) { 92 if (this.jsCommand != null) { 93 // The previous command not yet finished, we do nothing, and 94 // indicate it. 95 return RETURN_BUSY; 96 } 97 98 this.jsCommand = command; 99 this.uploadPolicy.displayDebug( 100 "JavascriptHandler - doCommand(): jsCommand is: [" 101 + this.jsCommand + "]", 30); 102 103 // send notify() to waiting thread so that command gets executed. 104 this.notify(); 105 106 // The job will go on. 107 return RETURN_STARTED; 108 } 109 110 /** 111 * Synchronized method allows for safely accessing jsCommand string. The 112 * command is cleared before returning. This avoid conflicts, and let any 113 * other thread to set the next command, while managing this one. 114 * 115 * @return Returns the current command. 116 */ 117 synchronized String getAndClearCommand() { 118 this.uploadPolicy.displayDebug("getCommand(): jsCommand is: [" 119 + this.jsCommand + "]", 30); 120 String curCommand = this.jsCommand; 121 clearCommand(); 122 return curCommand; 123 } 124 125 /** 126 * Synchronized method allows for safely clearing jsCommand string 127 */ 128 public synchronized void clearCommand() { 129 this.jsCommand = null; 130 this.uploadPolicy.displayDebug("clearCommand(): jsCommand is: [" 131 + this.jsCommand + "]", 30); 132 } 133 134 /** 135 * Synchronized method to enable call to wait() 136 * 137 * @throws InterruptedException 138 */ 139 public synchronized void doWait() throws InterruptedException { 140 wait(); 141 } 142 143 /** 144 * Method to run when thread is started. 145 */ 146 @Override 147 public void run() { 148 // Run in continuous loop waiting for commands to execute 149 while (true) { 150 try { 151 // simply wait to be notified that a command is ready to run 152 doWait(); 153 this.uploadPolicy.displayDebug("run(): Exited doWait()...", 50); 154 155 // handle new command 156 String curCommand = getAndClearCommand(); 157 if (curCommand != null) { 158 if (curCommand.equals(COMMAND_START_UPLOAD)) { 159 // start the upload 160 this.uploadPolicy.displayDebug( 161 "run(): Calling doStartUpload()", 50); 162 this.jUploadPanel.doStartUpload(); 163 } else { 164 this.uploadPolicy 165 .displayWarn("run(): unknown command in jsHandler (" 166 + curCommand + ")"); 167 } 168 } 169 } catch (Exception e) { 170 // We log everything that happens here. 171 this.uploadPolicy.displayWarn("Exception: [" + e.getMessage() 172 + "]"); 173 // But interruption is a valid exception: let's quit. 174 if (e instanceof InterruptedException) { 175 break; 176 } 177 } 178 } 179 } // run() 180 181 } // class JavascriptHandler