Coverage Report - wjhk.jupload2.context.DefaultJUploadContext
 
Classes in this File Line Coverage Branch Coverage Complexity
DefaultJUploadContext
64 %
139/214
37 %
22/58
2,28
DefaultJUploadContext$1PropertySetter
69 %
9/13
50 %
3/6
2,28
DefaultJUploadContext$Callback
100 %
12/12
100 %
4/4
2,28
 
 1  
 // $Id: JUploadApplet.java 750 2009-05-06 14:36:50Z etienne_sf $
 2  
 //
 3  
 // jupload - A file upload applet.
 4  
 // Copyright 2007 The JUpload Team
 5  
 //
 6  
 // Created: ?
 7  
 // Creator: William JinHua Kwong
 8  
 // Last modified: $Date: 2009-05-06 16:36:50 +0200 (mer., 06 mai 2009) $
 9  
 //
 10  
 // This program is free software; you can redistribute it and/or modify it under
 11  
 // the terms of the GNU General Public License as published by the Free Software
 12  
 // Foundation; either version 2 of the License, or (at your option) any later
 13  
 // version. This program is distributed in the hope that it will be useful, but
 14  
 // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 15  
 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 16  
 // details. You should have received a copy of the GNU General Public License
 17  
 // along with this program; if not, write to the Free Software Foundation, Inc.,
 18  
 // 675 Mass Ave, Cambridge, MA 02139, USA.
 19  
 
 20  
 package wjhk.jupload2.context;
 21  
 
 22  
 import java.awt.Cursor;
 23  
 import java.awt.Frame;
 24  
 import java.io.InputStream;
 25  
 import java.lang.reflect.InvocationTargetException;
 26  
 import java.lang.reflect.Method;
 27  
 import java.text.MessageFormat;
 28  
 import java.util.ArrayList;
 29  
 import java.util.Date;
 30  
 import java.util.List;
 31  
 import java.util.Locale;
 32  
 import java.util.Properties;
 33  
 import java.util.Vector;
 34  
 
 35  
 import javax.swing.JApplet;
 36  
 import javax.swing.JOptionPane;
 37  
 import javax.swing.RootPaneContainer;
 38  
 import javax.swing.SwingUtilities;
 39  
 
 40  
 import wjhk.jupload2.exception.JUploadException;
 41  
 import wjhk.jupload2.gui.JUploadPanel;
 42  
 import wjhk.jupload2.gui.JUploadPanelImpl;
 43  
 import wjhk.jupload2.gui.JUploadTextArea;
 44  
 import wjhk.jupload2.gui.filepanel.FilePanel.FileListViewMode;
 45  
 import wjhk.jupload2.policies.UploadPolicy;
 46  
 import wjhk.jupload2.policies.UploadPolicyFactory;
 47  
 import wjhk.jupload2.upload.FileUploadManagerThread;
 48  
 
 49  
 /**
 50  
  * The Jupload Context. One such context is created at run time. It can be the Applet, or the 'main' class, depending on
 51  
  * the launch type. <BR>
 52  
  * It contains the call to the creation of the {@link wjhk.jupload2.gui.JUploadPanel}, which contains the real code, and
 53  
  * some technical stuff that depend on the technical context (mainly applet or stand alone application). <BR>
 54  
  * The functional control of JUpload is done by using {@link UploadPolicy}. This class should not be changed, in order
 55  
  * to remain compatible with next JUpload releases. <BR>
 56  
  * <BR>
 57  
  * <B>Technical note:</B> This class should be abstract. But it is used by the build.xml file, to load the version. So
 58  
  * all methods of the {@link JUploadContext} interface are implemented. Those who actually can't be coded here, just
 59  
  * generate a UnsupportedOperationException exception.
 60  
  * 
 61  
  * @author etienne_sf
 62  
  * @version $Revision: 750 $
 63  
  */
 64  33
 public class DefaultJUploadContext implements JUploadContext {
 65  
 
 66  
     /**
 67  
      * The final that contains the SVN properties. These properties are generated during compilation, by the build.xml
 68  
      * ant file.
 69  
      */
 70  
     private final static String SVN_PROPERTIES_FILENAME = "/conf/svn.properties";
 71  
 
 72  
     /**
 73  
      * Used as default value when calling getProperty, to identify missing properties, and have a correct behavior in
 74  
      * this case.
 75  
      */
 76  
     private final static String DEFAULT_PROP_UNKNOWN = "Unknown";
 77  
 
 78  
     /**
 79  
      * The properties, created at build time, by the build.xml ant file. Or a dummy property set, with 'unknown' values.
 80  
      */
 81  33
     Properties svnProperties = getSvnProperties();
 82  
 
 83  
     /**
 84  
      * The frame that contains the application. Mainly used to attached modal dialog.
 85  
      */
 86  33
     Frame frame = null;
 87  
 
 88  
     /**
 89  
      * variable to hold reference to JavascriptHandler object
 90  
      */
 91  33
     JavascriptHandler jsHandler = null;
 92  
 
 93  
     /**
 94  
      * the mime type list, coming from: http://www.mimetype.org/ Thanks to them!
 95  
      */
 96  33
     Properties mimeTypesProperties = null;
 97  
 
 98  
     /**
 99  
      * The current upload policy. This class is responsible for the call to the UploadPolicyFactory.
 100  
      */
 101  33
     UploadPolicy uploadPolicy = null;
 102  
 
 103  
     /**
 104  
      * The JUploadPanel, which actually contains all the applet components.
 105  
      */
 106  33
     JUploadPanel jUploadPanel = null;
 107  
 
 108  
     /**
 109  
      * The log messages should go there ...
 110  
      */
 111  33
     JUploadTextArea logWindow = null;
 112  
 
 113  
     /**
 114  
      * This class represent the Callback method. It is then possible to run the
 115  
      * {@link JUploadContext#registerUnload(Object, String)} method to register new callback methods. These callback
 116  
      * methods are executed when the applet or the application closes, by calling the {@link JUploadContext#runUnload()}
 117  
      * method.
 118  
      */
 119  
     static class Callback {
 120  
         private String method;
 121  
 
 122  
         private Object object;
 123  
 
 124  35
         Callback(Object object, String method) {
 125  35
             this.object = object;
 126  35
             this.method = method;
 127  35
         }
 128  
 
 129  
         void invoke() throws IllegalArgumentException, IllegalAccessException, InvocationTargetException,
 130  
                 SecurityException {
 131  2
             Object args[] = {};
 132  2
             Method methods[] = this.object.getClass().getMethods();
 133  102
             for (int i = 0; i < methods.length; i++) {
 134  100
                 if (methods[i].getName().equals(this.method)) {
 135  2
                     methods[i].invoke(this.object, args);
 136  
                 }
 137  
             }
 138  2
         }
 139  
 
 140  
         /**
 141  
          * @return the method
 142  
          */
 143  
         public String getMethod() {
 144  1
             return method;
 145  
         }
 146  
 
 147  
         /**
 148  
          * @return the object
 149  
          */
 150  
         public Object getObject() {
 151  2
             return object;
 152  
         }
 153  
 
 154  
     }
 155  
 
 156  
     /**
 157  
      * All registered callbacks.
 158  
      * 
 159  
      * @see Callback
 160  
      */
 161  33
     List<Callback> unloadCallbacks = new ArrayList<Callback>(20);
 162  
 
 163  
     /**
 164  
      * Reaction on the start of the applet: creation of each specific item of the GUI, and the upload policy. <BR>
 165  
      * This method needs that the initialization of the called is finished. For instance, {@link JUploadContextApplet}
 166  
      * needs to have set theApplet, to be able to properly execute some method calls that are in the init() method. So
 167  
      * we can not do this initialization in the constructor of DefaultJUploadContext.
 168  
      * 
 169  
      * @param frame The frame that contains the application. Mainly used to attached modal dialog.
 170  
      * @param rootPaneContainer The mother window (JApplet, JFrame...), which contains the rootPaneContainer. Used to
 171  
      *            set the {@link JUploadPanel} in it.
 172  
      */
 173  
     public void init(Frame frame, RootPaneContainer rootPaneContainer) {
 174  
         try {
 175  33
             this.frame = frame;
 176  
 
 177  
             // The standard thread name is: thread
 178  
             // applet-wjhk.jupload2.JUploadApplet.class
 179  
             // Too long ! :-)
 180  33
             Thread.currentThread().setName(rootPaneContainer.getClass().getName());
 181  
 
 182  
             // The logWindow must exist before the uploadPolicy creation. But it
 183  
             // needs the uploadPolicy, to know the logging parameters. We'll set
 184  
             // the uploadPolicy just after.
 185  33
             this.logWindow = new JUploadTextArea(20, 20, this.uploadPolicy);
 186  
 
 187  
             // Now we can create the upload policy: the logWindow exists.
 188  33
             this.uploadPolicy = UploadPolicyFactory.getUploadPolicy(this);
 189  33
             this.uploadPolicy.displayDebug("After UploadPolicyFactory.getUploadPolicy(this)", 80);
 190  
 
 191  
             // We set the uploadPolicy to the logWindow. The logThread starts,
 192  
             // and it register its unload method, to be called when the JUpload
 193  
             // finishes.
 194  33
             this.uploadPolicy.displayDebug("Before this.logWindow.setUploadPolicy(this.uploadPolicy)", 80);
 195  33
             this.logWindow.setUploadPolicy(this.uploadPolicy);
 196  
 
 197  
             // getMainPanel().setLayout(new BorderLayout());
 198  33
             this.uploadPolicy.displayDebug("Before new JUploadPanelImpl(this.logWindow,this.uploadPolicy)", 80);
 199  33
             this.jUploadPanel = new JUploadPanelImpl(this.logWindow, this.uploadPolicy);
 200  
 
 201  
             // getMainPanel().add(this.jUploadPanel, BorderLayout.CENTER);
 202  33
             this.uploadPolicy.displayDebug("Before rootPaneContainer.setContentPane(this.jUploadPanel);", 80);
 203  33
             rootPaneContainer.setContentPane(this.jUploadPanel.getJComponent());
 204  
 
 205  
             // We start the jsHandler thread, that allows javascript to send
 206  
             // upload command to the applet.
 207  33
             this.uploadPolicy.displayDebug("Before new JavascriptHandler(this.uploadPolicy, this.jUploadPanel)", 80);
 208  33
             this.jsHandler = new JavascriptHandler(this.uploadPolicy, this.jUploadPanel);
 209  33
             this.jsHandler.start();
 210  
             // Then we register the unload method, that'll be called like all
 211  
             // unload callbacks when the applet is stopped.
 212  33
             registerUnload(this, "unload");
 213  0
         } catch (final Exception e) {
 214  0
             System.out.println(e.getMessage());
 215  0
             e.printStackTrace();
 216  
             // TODO Translate this sentence
 217  0
             JOptionPane.showMessageDialog(null,
 218  0
                     "Error during applet initialization!\nHave a look in your Java console (" + e.getClass().getName()
 219  
                             + ")", "Error", JOptionPane.ERROR_MESSAGE);
 220  33
         }
 221  
 
 222  33
         this.uploadPolicy.displayDebug("Before new Properties();", 80);
 223  33
         this.mimeTypesProperties = new Properties();
 224  33
         final String mimetypePropertiesFilename = "/conf/mimetypes.properties";
 225  
         try {
 226  33
             InputStream isProperties = this.getClass().getResourceAsStream(mimetypePropertiesFilename);
 227  33
             this.mimeTypesProperties.load(isProperties);
 228  33
             isProperties.close();
 229  33
             this.uploadPolicy.displayDebug("Mime types list loaded Ok (" + mimetypePropertiesFilename + ")", 50);
 230  0
         } catch (Exception e) {
 231  0
             this.uploadPolicy.displayWarn("Unable to load the mime types list (" + mimetypePropertiesFilename + "): "
 232  0
                     + e.getClass().getName() + " (" + e.getMessage() + ")");
 233  33
         }
 234  
 
 235  33
         this.uploadPolicy.displayDebug("End of DefaultJUploadContext.init()", 80);
 236  33
     }
 237  
 
 238  
     /**
 239  
      * This method is called when the applet is unloaded (actually, when it is stopped). it is registered as a callback
 240  
      * in the {@link #init(Frame, RootPaneContainer)}, here above.
 241  
      */
 242  
     public void unload() {
 243  2
         if (this.jsHandler != null && this.jsHandler.isAlive()) {
 244  2
             this.jsHandler.interrupt();
 245  2
             this.jsHandler = null;
 246  
         }
 247  2
     }
 248  
 
 249  
     /** {@inheritDoc} */
 250  
     public String getDetailedVersionMessage() {
 251  0
         String version = getVersion();
 252  0
         String svnRevision = getSvnRevision();
 253  0
         boolean gotSvnRevision = !svnRevision.equals(DEFAULT_PROP_UNKNOWN);
 254  0
         int buildNumber = getBuildNumber();
 255  0
         boolean gotBuildNumber = buildNumber > 0;
 256  0
         String buildDate = getBuildDate();
 257  0
         boolean gotBuildDate = !buildDate.equals(DEFAULT_PROP_UNKNOWN);
 258  
 
 259  0
         StringBuffer sb = new StringBuffer();
 260  0
         sb.append(version);
 261  
 
 262  0
         if (gotSvnRevision || gotBuildNumber) {
 263  0
             sb.append(" [");
 264  0
             String space = "";
 265  0
             if (gotSvnRevision) {
 266  0
                 sb.append("SVN-Rev: ");
 267  0
                 sb.append(svnRevision);
 268  0
                 space = " ";
 269  
             }
 270  0
             if (gotBuildNumber) {
 271  0
                 sb.append(space);
 272  0
                 sb.append("build ");
 273  0
                 sb.append(buildNumber);
 274  
             }
 275  0
             sb.append("]");
 276  
         }
 277  
 
 278  0
         if (gotBuildDate) {
 279  0
             sb.append(" - ");
 280  0
             sb.append(buildDate);
 281  
         }
 282  0
         return sb.toString();
 283  
     }
 284  
 
 285  
     /** {@inheritDoc} */
 286  
     public String getVersion() {
 287  0
         return getProperty("jupload.version", DEFAULT_PROP_UNKNOWN);
 288  
     }
 289  
 
 290  
     /** {@inheritDoc} */
 291  
     public String getSvnRevision() {
 292  0
         String svnRevision = getProperty("jupload.svn.revision", DEFAULT_PROP_UNKNOWN);
 293  0
         if (svnRevision.startsWith("{") || svnRevision.startsWith("${")) {
 294  
             // This particular case should not happen with standard maven build.
 295  
             // But it occurs when launching after an eclipse automatic build.
 296  
             // Returning DEFAULT_PROP_UNKNOWN in this case, make the applet
 297  
             // behave like if it was built by maven.
 298  0
             return DEFAULT_PROP_UNKNOWN;
 299  
         } else {
 300  0
             return svnRevision;
 301  
         }
 302  
     }
 303  
 
 304  
     /** {@inheritDoc} */
 305  
     public String getLastModified() {
 306  1
         return getProperty("jupload.lastSrcDirModificationDate", DEFAULT_PROP_UNKNOWN);
 307  
     }
 308  
 
 309  
     /** {@inheritDoc} */
 310  
     public String getBuildDate() {
 311  1
         String timestamp = getProperty("jupload.buildTimestamp", DEFAULT_PROP_UNKNOWN);
 312  1
         if (timestamp.equals(DEFAULT_PROP_UNKNOWN)) {
 313  0
             return DEFAULT_PROP_UNKNOWN;
 314  
         } else {
 315  1
             Locale locale = Locale.getDefault();
 316  1
             if (this.uploadPolicy != null) {
 317  1
                 locale = this.uploadPolicy.getLocale();
 318  
             }
 319  1
             MessageFormat msgFormat = new MessageFormat("{0,date,medium}", locale);
 320  
             try {
 321  1
                 Object[] args = {
 322  1
                     new Date(Long.parseLong(timestamp))
 323  
                 };
 324  1
                 return msgFormat.format(args);
 325  0
             } catch (NumberFormatException e) {
 326  
                 // uploadPolicy is null at startup.
 327  
                 // TODO Better handling logging, here
 328  0
                 System.out.println("[WARN] The timestamp can not be read (" + timestamp + "). Will return '"
 329  
                         + DEFAULT_PROP_UNKNOWN + "'.");
 330  0
                 return DEFAULT_PROP_UNKNOWN;
 331  
             }
 332  
         }
 333  
     }
 334  
 
 335  
     /** {@inheritDoc} */
 336  
     public int getBuildNumber() {
 337  1
         String valuePropBuildNumber = getProperty("jupload.buildNumber", "-1");
 338  
         try {
 339  1
             return Integer.parseInt(valuePropBuildNumber);
 340  0
         } catch (java.lang.NumberFormatException e) {
 341  0
             System.out.println("[WARN] " + e.getClass().getName() + " when getting the buildNumber, while parsing '"
 342  
                     + valuePropBuildNumber + "'). Will return -1");
 343  0
             return -1;
 344  
         }
 345  
     }
 346  
 
 347  
     /**
 348  
      * Try to get a property from the loaded properties. If the property is not available, the default value is
 349  
      * returned.
 350  
      * 
 351  
      * @param propertyName
 352  
      * @param defaultValue
 353  
      * @return
 354  
      */
 355  
     private String getProperty(String propertyName, String defaultValue) {
 356  3
         String value = null;
 357  
         try {
 358  3
             value = this.svnProperties.getProperty(propertyName);
 359  0
         } catch (Exception e) {
 360  0
             System.out.println("[WARN] " + e.getClass().getName() + " when getting the " + propertyName + " property ("
 361  0
                     + e.getMessage() + "). Will return '" + value + "'");
 362  3
         }
 363  3
         return (value == null) ? defaultValue : value;
 364  
     }
 365  
 
 366  
     /** {@inheritDoc} */
 367  
     public JUploadTextArea getLogWindow() {
 368  1
         return this.logWindow;
 369  
     }
 370  
 
 371  
     /** {@inheritDoc} */
 372  
     public String getMimeType(String fileExtension) {
 373  4
         String mimeType = this.mimeTypesProperties.getProperty(fileExtension.toLowerCase());
 374  4
         return (mimeType == null) ? "application/octet-stream" : mimeType;
 375  
     }
 376  
 
 377  
     /** {@inheritDoc} */
 378  
     public JUploadPanel getUploadPanel() {
 379  2
         return this.jUploadPanel;
 380  
     }
 381  
 
 382  
     /**
 383  
      * Retrieves the current upload policy. The JUploadContext is responsible for storing the UploadPolicy associated
 384  
      * with the current instance.
 385  
      * 
 386  
      * @return the current upload policy of this instance.
 387  
      * @throws JUploadException
 388  
      */
 389  
     public UploadPolicy getUploadPolicy() throws JUploadException {
 390  27
         return this.uploadPolicy;
 391  
     }
 392  
 
 393  
     // ///////////////////////////////////////////////////////////////////////////////////////////////////////:
 394  
     // //////////////// FUNCTIONS INTENDED TO BE CALLED BY JAVASCRIPT FUNCTIONS
 395  
     // ////////////////////////////:
 396  
     // ///////////////////////////////////////////////////////////////////////////////////////////////////////:
 397  
 
 398  
     /**
 399  
      * This allow runtime modifications of properties, from javascript. Currently, this can only be used after full
 400  
      * initialization. This method only calls the UploadPolicy.setProperty method. <BR>
 401  
      * Ex: document.jupload.setProperty(prop, value);
 402  
      * 
 403  
      * @param prop The property name that must be set.
 404  
      * @param value The value of this property.
 405  
      */
 406  
     public void setProperty(String prop, String value) {
 407  
         // FIXME setProperty should use jsHandler
 408  
         class PropertySetter implements Runnable {
 409  
             String prop;
 410  
 
 411  
             String value;
 412  
 
 413  2
             PropertySetter(String prop, String value) {
 414  2
                 this.prop = prop;
 415  2
                 this.value = value;
 416  2
             }
 417  
 
 418  
             public void run() {
 419  
                 try {
 420  
                     // We'll wait up to 2s until the applet initialized (we need an upload policy).
 421  
                     // FIXME should be done in a separate thread (block the browser)
 422  2
                     for (int i = 0; i < 20 && uploadPolicy == null; i += 1) {
 423  0
                         this.wait(100);
 424  
                     }
 425  2
                     if (uploadPolicy == null) {
 426  0
                         System.out.println("uploadPolicy is null. Impossible to set " + prop + " to " + value);
 427  
                     } else {
 428  
                         // FIXME There should be a boolean: initialized, to indicate when property may be set.
 429  2
                         uploadPolicy.setProperty(prop, value);
 430  
                     }
 431  0
                 } catch (Exception e) {
 432  0
                     uploadPolicy.displayErr(e);
 433  2
                 }
 434  2
             }
 435  
         }
 436  
         try {
 437  2
             SwingUtilities.invokeLater(new PropertySetter(prop, value));
 438  0
         } catch (Exception e) {
 439  0
             if (this.uploadPolicy != null) {
 440  0
                 this.uploadPolicy.displayErr(e);
 441  
             } else {
 442  0
                 System.out.println(e.getClass().getName() + ": " + e.getMessage());
 443  
             }
 444  2
         }
 445  2
     }
 446  
 
 447  
     /** {@inheritDoc} */
 448  
     public String startUpload() {
 449  1
         return this.jsHandler.doCommand(JavascriptHandler.COMMAND_START_UPLOAD);
 450  
     }
 451  
 
 452  
     /**
 453  
      * Call to {@link UploadPolicy#displayErr(Exception)}
 454  
      * 
 455  
      * @param err The error text to be displayed.
 456  
      */
 457  
     public void displayErr(String err) {
 458  1
         this.uploadPolicy.displayErr(err);
 459  1
     }
 460  
 
 461  
     /**
 462  
      * Call to {@link UploadPolicy#displayInfo(String)}
 463  
      * 
 464  
      * @param info The info text to display
 465  
      */
 466  
     public void displayInfo(String info) {
 467  1
         this.uploadPolicy.displayInfo(info);
 468  1
     }
 469  
 
 470  
     /**
 471  
      * Call to {@link UploadPolicy#displayWarn(String)}
 472  
      * 
 473  
      * @param warn The error text to be displayed.
 474  
      */
 475  
     public void displayWarn(String warn) {
 476  1
         this.uploadPolicy.displayWarn(warn);
 477  1
     }
 478  
 
 479  
     /**
 480  
      * Call to {@link UploadPolicy#displayDebug(String, int)}
 481  
      * 
 482  
      * @param debug The debug message.
 483  
      * @param minDebugLevel The minimum level that debug level should have, to display this message. Values can go from
 484  
      *            0 to 100.
 485  
      */
 486  
     public void displayDebug(String debug, int minDebugLevel) {
 487  1
         this.uploadPolicy.displayDebug(debug, minDebugLevel);
 488  1
     }
 489  
 
 490  
     // /////////////////////////////////////////////////////////////////////////
 491  
     // ////////////////////// Helper functions
 492  
     // /////////////////////////////////////////////////////////////////////////
 493  
 
 494  
     /**
 495  
      * Helper function, to get the Revision number, if available. The applet must be built from the build.xml ant file.
 496  
      * 
 497  
      * @return The svn properties
 498  
      */
 499  
     public static Properties getSvnProperties() {
 500  34
         Properties properties = new Properties();
 501  34
         Boolean bPropertiesLoaded = false;
 502  
 
 503  
         // Let's try to load the properties file.
 504  
         // The upload policy is not created yet: we can not use its display
 505  
         // methods to trace what is happening here.
 506  
         try {
 507  34
             InputStream isProperties = Class.forName("wjhk.jupload2.JUploadApplet").getResourceAsStream(
 508  
                     SVN_PROPERTIES_FILENAME);
 509  34
             properties.load(isProperties);
 510  34
             isProperties.close();
 511  34
             bPropertiesLoaded = true;
 512  0
         } catch (Exception e) {
 513  
             // An error occurred when reading the file. The applet was
 514  
             // probably not built with the build.xml ant file.
 515  
             // We'll create a fake property list. See below.
 516  
 
 517  
             // We can not output to the uploadPolicy display method, as the
 518  
             // upload policy is not created yet. We output to the system output.
 519  
             // Consequence: if this doesn't work during build, you'll see an
 520  
             // error during the build: the generated file name will contain the
 521  
             // following error message.
 522  0
             System.out.println(e.getClass().getName() + " in DefaultJUploadContext.getSvnProperties() ("
 523  0
                     + e.getMessage() + ")");
 524  34
         }
 525  
 
 526  
         // If we could not read the property file. The applet was probably not
 527  
         // built with the build.xml ant file, we create a fake property list.
 528  34
         if (!bPropertiesLoaded) {
 529  0
             properties.setProperty("buildDate", "Unknown build date (please use the build.xml ant script)");
 530  0
             properties.setProperty("lastSrcDirModificationDate",
 531  
                     "Unknown last modification date (please use the build.xml ant script)");
 532  0
             properties.setProperty("revision", "Unknown revision (please use the build.xml ant script)");
 533  
         }
 534  34
         return properties;
 535  
     }
 536  
 
 537  
     /** {@inheritDoc} */
 538  
     public void registerUnload(Object object, String method) {
 539  
         // We insert each item at the beginning, so that the callbacks are
 540  
         // called in the reverse order of the order in which they were
 541  
         // registered.
 542  
         // For instance: the removal of the log file is the first one to be
 543  
         // registered ... and must be the last one to be executed.
 544  35
         this.unloadCallbacks.add(0, new Callback(object, method));
 545  35
     }
 546  
 
 547  
     /** {@inheritDoc} */
 548  
     public synchronized void runUnload() {
 549  
         // If an upload is runing on, we have to stop it.
 550  1
         FileUploadManagerThread fileUploadManagerThread = this.getUploadPanel().getFileUploadManagerThread();
 551  1
         if (fileUploadManagerThread != null) {
 552  0
             fileUploadManagerThread.stopUpload();
 553  
         }
 554  
 
 555  
         // Then we call all unload callback.
 556  1
         for (Callback callback : this.unloadCallbacks) {
 557  
             try {
 558  2
                 callback.invoke();
 559  0
             } catch (Exception e) {
 560  0
                 System.out.println(e.getClass().getName() + " while calling the callback: "
 561  0
                         + callback.getObject().getClass().getName() + "." + callback.getMethod());
 562  0
                 e.printStackTrace();
 563  2
             }
 564  2
         }
 565  1
         this.unloadCallbacks.clear();
 566  1
     }
 567  
 
 568  
     /**
 569  
      * Displays the debug information for the current parameter.
 570  
      */
 571  
     void displayDebugParameterValue(String key, String value) {
 572  13
         if (this.uploadPolicy != null && this.uploadPolicy.getDebugLevel() >= 80) {
 573  12
             this.uploadPolicy.displayDebug("Parameter '" + key + "' loaded. Value: " + value, 80);
 574  
         }
 575  13
     }
 576  
 
 577  
     /** {@inheritDoc} */
 578  
     public int parseInt(String value, int def) {
 579  4
         int ret = def;
 580  
         // Then, parse it as an integer.
 581  
         try {
 582  4
             ret = Integer.parseInt(value);
 583  1
         } catch (NumberFormatException e) {
 584  1
             ret = def;
 585  1
             if (this.uploadPolicy != null) {
 586  1
                 this.uploadPolicy.displayWarn("Invalid int value: " + value + ", using default value: " + def);
 587  
             }
 588  3
         }
 589  
 
 590  4
         return ret;
 591  
     }
 592  
 
 593  
     /** {@inheritDoc} */
 594  
     public float parseFloat(String value, float def) {
 595  4
         float ret = def;
 596  
         // Then, parse it as an integer.
 597  
         try {
 598  4
             ret = Float.parseFloat(value);
 599  1
         } catch (NumberFormatException e) {
 600  1
             ret = def;
 601  1
             if (this.uploadPolicy != null) {
 602  1
                 this.uploadPolicy.displayWarn("Invalid float value: " + value + ", using default value: " + def);
 603  
             }
 604  3
         }
 605  
 
 606  4
         return ret;
 607  
     }
 608  
 
 609  
     /** {@inheritDoc} */
 610  
     public long parseLong(String value, long def) {
 611  4
         long ret = def;
 612  
         // Then, parse it as an integer.
 613  
         try {
 614  4
             ret = Long.parseLong(value);
 615  1
         } catch (NumberFormatException e) {
 616  1
             ret = def;
 617  1
             if (this.uploadPolicy != null) {
 618  1
                 this.uploadPolicy.displayWarn("Invalid long value: " + value + ", using default value: " + def);
 619  
             }
 620  3
         }
 621  
 
 622  4
         return ret;
 623  
     }
 624  
 
 625  
     /** {@inheritDoc} */
 626  
     public boolean parseBoolean(String value, boolean def) {
 627  
         // Then, parse it as a boolean.
 628  8
         if (value.toUpperCase().equals("FALSE")) {
 629  3
             return false;
 630  5
         } else if (value.toUpperCase().equals("TRUE")) {
 631  3
             return true;
 632  
         } else {
 633  2
             if (this.uploadPolicy != null) {
 634  2
                 this.uploadPolicy.displayWarn("Invalid boolean value: " + value + ", using default value: " + def);
 635  
             }
 636  2
             return def;
 637  
         }
 638  
     }
 639  
 
 640  
     /** {@inheritDoc} */
 641  
     public FileListViewMode parseFileListViewMode(String value, FileListViewMode def) {
 642  0
         FileListViewMode ret = null;
 643  
         try {
 644  0
             ret = FileListViewMode.valueOf(value.toUpperCase());
 645  0
         } catch (IllegalArgumentException e) {
 646  0
             ret = def;
 647  0
             String msg = "Unknown FileListViewMode value '" + value + "'. Using default value: '" + def.toString()
 648  
                     + "'";
 649  0
             if (this.uploadPolicy != null) {
 650  0
                 this.uploadPolicy.displayWarn(msg);
 651  
             } else {
 652  0
                 System.out.println(msg);
 653  
             }
 654  0
         }
 655  0
         return ret;
 656  
     }
 657  
 
 658  
     /**
 659  
      * @return The cursor that was active before the call to this method
 660  
      * @see JUploadContext#setCursor(Cursor)
 661  
      */
 662  
     public Cursor setWaitCursor() {
 663  1
         return setCursor(new Cursor(Cursor.WAIT_CURSOR));
 664  
     }
 665  
 
 666  
     /**
 667  
      * Just throws a UnsupportedOperationException exception.
 668  
      * 
 669  
      * @param url
 670  
      * @param success
 671  
      */
 672  
     public void displayURL(String url, boolean success) {
 673  1
         throw new UnsupportedOperationException("DefaultJUploadContext.displayURL()");
 674  
     }
 675  
 
 676  
     /**
 677  
      * Just throws a UnsupportedOperationException exception.
 678  
      * 
 679  
      * @return Not used
 680  
      */
 681  
     public JApplet getApplet() {
 682  0
         throw new UnsupportedOperationException("DefaultJUploadContext.getApplet()");
 683  
     }
 684  
 
 685  
     /** @see JUploadContext#getFrame() */
 686  
     public Frame getFrame() {
 687  1
         return this.frame;
 688  
     }
 689  
 
 690  
     /**
 691  
      * Just throws a UnsupportedOperationException exception.
 692  
      * 
 693  
      * @return Not used.
 694  
      */
 695  
     public Cursor getCursor() {
 696  1
         throw new UnsupportedOperationException("DefaultJUploadContext.getCursor()");
 697  
     }
 698  
 
 699  
     /**
 700  
      * Just throws a UnsupportedOperationException exception.
 701  
      * 
 702  
      * @param key
 703  
      * @param def
 704  
      * @return Not used
 705  
      */
 706  
     public String getParameter(String key, String def) {
 707  1
         throw new UnsupportedOperationException("DefaultJUploadContext.getParameter(String, String)");
 708  
     }
 709  
 
 710  
     /**
 711  
      * Just throws a UnsupportedOperationException exception.
 712  
      * 
 713  
      * @param key
 714  
      * @param def
 715  
      * @return Not used
 716  
      */
 717  
     public int getParameter(String key, int def) {
 718  1
         throw new UnsupportedOperationException("DefaultJUploadContext.getParameter(String, int))");
 719  
     }
 720  
 
 721  
     /**
 722  
      * Just throws a UnsupportedOperationException exception.
 723  
      * 
 724  
      * @param key
 725  
      * @param def
 726  
      * @return Not used
 727  
      */
 728  
     public float getParameter(String key, float def) {
 729  1
         throw new UnsupportedOperationException("DefaultJUploadContext.getParameter(String, float)");
 730  
     }
 731  
 
 732  
     /**
 733  
      * Just throws a UnsupportedOperationException exception.
 734  
      * 
 735  
      * @param key
 736  
      * @param def
 737  
      * @return Not used
 738  
      */
 739  
     public long getParameter(String key, long def) {
 740  1
         throw new UnsupportedOperationException("DefaultJUploadContext.getParameter(String, long)");
 741  
     }
 742  
 
 743  
     /**
 744  
      * Just throws a UnsupportedOperationException exception.
 745  
      * 
 746  
      * @param key
 747  
      * @param def
 748  
      * @return Not used
 749  
      */
 750  
     public boolean getParameter(String key, boolean def) {
 751  1
         throw new UnsupportedOperationException("DefaultJUploadContext.getParameter(String, boolean)");
 752  
     }
 753  
 
 754  
     /**
 755  
      * Just throws a UnsupportedOperationException exception.
 756  
      * 
 757  
      * @param key
 758  
      * @param def
 759  
      * @return Not used
 760  
      */
 761  
     public FileListViewMode getParameter(String key, FileListViewMode def) {
 762  0
         throw new UnsupportedOperationException("DefaultJUploadContext.getParameter(String, FileListViewMode)");
 763  
     }
 764  
 
 765  
     /**
 766  
      * Just throws a UnsupportedOperationException exception.
 767  
      * 
 768  
      * @param url
 769  
      * @return Not used
 770  
      * @throws JUploadException
 771  
      */
 772  
     public String normalizeURL(String url) throws JUploadException {
 773  1
         throw new UnsupportedOperationException("DefaultJUploadContext.normalizeURL()");
 774  
     }
 775  
 
 776  
     /**
 777  
      * Just throws a UnsupportedOperationException exception.
 778  
      * 
 779  
      * @param headers
 780  
      */
 781  
     public void readCookieFromNavigator(Vector<String> headers) {
 782  1
         throw new UnsupportedOperationException("DefaultJUploadContext.readCookieFromNavigator()");
 783  
     }
 784  
 
 785  
     /**
 786  
      * Just throws a UnsupportedOperationException exception.
 787  
      * 
 788  
      * @param headers
 789  
      */
 790  
     public void readUserAgentFromNavigator(Vector<String> headers) {
 791  1
         throw new UnsupportedOperationException("DefaultJUploadContext.readUserAgentFromNavigator()");
 792  
     }
 793  
 
 794  
     /**
 795  
      * Just throws a UnsupportedOperationException exception.
 796  
      * 
 797  
      * @param cursor
 798  
      * @return Not used
 799  
      */
 800  
     public Cursor setCursor(Cursor cursor) {
 801  2
         throw new UnsupportedOperationException("DefaultJUploadContext.setCursor(Cursor)");
 802  
     }
 803  
 
 804  
     /**
 805  
      * Just throws a UnsupportedOperationException exception.
 806  
      * 
 807  
      * @param status
 808  
      */
 809  
     public void showStatus(String status) {
 810  1
         throw new UnsupportedOperationException("DefaultJUploadContext.showStatus()");
 811  
     }
 812  
 
 813  
 }