package tutor; import java.net.*; import java.io.*; import java.util.*; import java.applet.*; /** * This class manages the process of downloading a set * of sound resources from the Internet. The class makes * the {@linkplain tutor.SoundDownload}s available to other classes incrementally * as they become available. This allows an application to * start using the sound files which are available without * waiting for the whole download process to complete. * * The code was based on a class called DownloadManager. * The code has been written to support old jvms (1.1) in order * to allow an applet to run on as many browsers as possible * * @see: RecordSet, SoundDownload, Record etc */ public class SoundLoadManager extends Object implements Runnable { //-------------------------------------------- /** A set of {@linkplain tutor.SoundDownload}s which need * to be downloaded or have been downloaded or have * failed to download */ private Vector tasks; //-------------------------------------------- /** represents those downloads which were successful */ private Vector goodDownloads; //-------------------------------------------- /** represents those downloads which were not successful */ private Vector badDownloads; //-------------------------------------------- /** This set contains those SoundDownloads which have been * downloaded since another class has called the * getFreshDownloads method */ private Vector freshDownloads; //-------------------------------------------- /** This flag gets set when a new language sound file is * successfully downloaded */ private boolean hasFreshDownloads; //-------------------------------------------- private Thread taskThread; //-------------------------------------------- /** a flag to allow the downloading thread to exit */ private boolean stopThread; //-------------------------------------------- /** an interval in milliseconds to pause between tasks */ private long taskPause; //-------------------------------------------- private Date startTime; //-------------------------------------------- private Date finishTime; //-------------------------------------------- private Applet appletReference; //-------------------------------------------- private static String NEWLINE = System.getProperty("line.separator"); //-------------------------------------------- /** a constructor which doesnt do much */ public SoundLoadManager() { this.hasFreshDownloads = false; this.tasks = new Vector(); this.goodDownloads = new Vector(); this.badDownloads = new Vector(); this.freshDownloads = new Vector(); this.stopThread = false; } //-- constr: () //-------------------------------------------- public SoundLoadManager(RecordSet rData) { this(); Vector dataSet = rData.getRecords(); String sBaseSoundUrl = rData.getBaseSoundUrl(); String sSoundFileFolder = rData.getSoundFileFolder(); StringBuffer sSoundUrl = new StringBuffer(""); StringBuffer sLocalFile = new StringBuffer(""); Record record; SoundDownload task; Enumeration ii = dataSet.elements(); while (ii.hasMoreElements()) { record = (Record)ii.nextElement(); sLocalFile.setLength(0); sLocalFile.append(sSoundFileFolder + "/" + record.getSoundUrl()); sSoundUrl.setLength(0); sSoundUrl.append(sBaseSoundUrl + record.getSoundUrl()); task = new SoundDownload(sSoundUrl.toString(), sLocalFile.toString()); this.tasks.addElement(task); } } //-- constr: (datafile) //-------------------------------------------- /** adds a task (a sound to download) to be managed */ public void addTask(SoundDownload ssSoundDownload) { this.tasks.addElement(ssSoundDownload); } //-------------------------------------------- /** clears the list of tasks */ public void clearTasks() { this.tasks.clear(); } //-------------------------------------------- public long getTaskPause() { return this.taskPause; } //-------------------------------------------- /** sets the pause between the execution of each task. * If the task involves downloading from a server, * for example, it may be courteous to pause between each * task */ public void setTaskPause(long lPause) { this.taskPause = lPause; } //-------------------------------------------- public void run() { this.download(); } //-------------------------------------------- /** starts the downloading task thread */ public void startDownloading() { this.stopThread = false; this.taskThread = new Thread(this); this.taskThread.start(); } //-------------------------------------------- /** stops the downloading process by setting a flag variable */ public void stopDownloading() { this.stopThread = true; } //-------------------------------------------- /** begin the process of downloading the sounds */ public void download() { this.startTime = new Date(); SoundDownload sdCurrent; Enumeration ii = this.tasks.elements(); while (ii.hasMoreElements() && !this.stopThread) { sdCurrent = (SoundDownload)ii.nextElement(); sdCurrent.download(); if (sdCurrent.wasSuccessful()) { this.goodDownloads.addElement(sdCurrent); this.freshDownloads.addElement(sdCurrent); this.hasFreshDownloads = true; } else { this.badDownloads.addElement(sdCurrent); } //-- if, else } //-- while this.finishTime = new Date(); } //-- method: startDownloading() //-------------------------------------------- /** informs how long the manager has been working, milliseconds */ public long getWorkTime() { if (this.startTime == null) { return 0; } if (this.finishTime == null) { Date dNow = new Date(); return dNow.getTime() - this.startTime.getTime(); } return this.finishTime.getTime() - this.startTime.getTime(); } //-- method getWorkTime //-------------------------------------------- /** informs how long the manager has been working in seconds */ public float getWorkTimeInSeconds() { if (this.startTime == null) { return 0; } return (float)this.getWorkTime()/1000; } //-------------------------------------------- public int completedDownloads() { int iCompletedDownloads = 0; Enumeration ii; SoundDownload dCurrentDownload; ii = this.tasks.elements(); while (ii.hasMoreElements()) { dCurrentDownload = (SoundDownload)ii.nextElement(); if (dCurrentDownload.hasFinished()) { iCompletedDownloads++; } } //-- while return iCompletedDownloads; } //-- m: completedDownloads //-------------------------------------------- /** tell the number of completed tasks, successful or failed */ public int countCompletedDownloads() { int iGoodDownloads = 0; Enumeration ii; SoundDownload dCurrentDownload; ii = this.tasks.elements(); while (ii.hasMoreElements()) { dCurrentDownload = (SoundDownload)ii.nextElement(); if (dCurrentDownload.hasFinished()) { iGoodDownloads++; } } //-- while return iGoodDownloads; } //-------------------------------------------- /** tell the number of successful tasks */ public int countGoodDownloads() { int iGoodDownloads = 0; Enumeration ii; SoundDownload dCurrentDownload; ii = this.tasks.elements(); while (ii.hasMoreElements()) { dCurrentDownload = (SoundDownload)ii.nextElement(); if (dCurrentDownload.hasFinished() && dCurrentDownload.wasSuccessful()) { iGoodDownloads++; } } //-- while return iGoodDownloads; } //-------------------------------------------- /** tell the number of unsuccessful tasks */ public int countBadDownloads() { int iBadDownloads = 0; Enumeration ii; SoundDownload dCurrentDownload; ii = this.tasks.elements(); while (ii.hasMoreElements()) { dCurrentDownload = (SoundDownload)ii.nextElement(); if (dCurrentDownload.hasFinished() && !dCurrentDownload.wasSuccessful()) { iBadDownloads++; } } //-- while return iBadDownloads; } //-------------------------------------------- /** allows another class to know if this class has * download new sound files and if it is worth * calling the getFreshDownloads method */ public boolean hasFreshDownloads() { return this.hasFreshDownloads; } //-------------------------------------------- /** retrieves the successful downloads */ public Vector getGoodDownloads() { return this.goodDownloads; } //-------------------------------------------- /** retrieves the unsuccessful downloads */ public Vector getBadDownloads() { return this.badDownloads; } //-------------------------------------------- /** * returns those downloads which have been retrieved since * the last call to this method. */ public Vector getFreshDownloads() { Vector aaReturn = new Vector(); Enumeration ii = this.freshDownloads.elements(); while (ii.hasMoreElements()) { aaReturn.addElement(ii.nextElement()); } this.freshDownloads.removeAllElements(); this.hasFreshDownloads = false; return aaReturn; } //-------------------------------------------- public String print() { StringBuffer sbReturn = new StringBuffer(); return this.toString(); } //-------------------------------------------- public String printFailedTasks() { StringBuffer sReturn = new StringBuffer(); Enumeration ii; SoundDownload dCurrentDownload; ii = this.tasks.elements(); while (ii.hasMoreElements()) { //sReturn.append("* "); dCurrentDownload = (SoundDownload)ii.nextElement(); if (dCurrentDownload.hasFinished() && !dCurrentDownload.wasSuccessful()) { sReturn.append(dCurrentDownload.toString()); sReturn.append(NEWLINE); } } //-- while return sReturn.toString(); } //-------------------------------------------- public String printSuccessfulTasks() { StringBuffer sReturn = new StringBuffer(); Enumeration ii; SoundDownload dCurrentDownload; ii = this.tasks.elements(); while (ii.hasMoreElements()) { //sReturn.append("* "); dCurrentDownload = (SoundDownload)ii.nextElement(); if (dCurrentDownload.hasFinished() && dCurrentDownload.wasSuccessful()) { sReturn.append(dCurrentDownload.toString()); sReturn.append(NEWLINE); } } //-- while return sReturn.toString(); } //-------------------------------------------- /** shows all tasks, or sound downloads which the manager * has carried out, or will carry out */ public String printAllTasks() { StringBuffer sReturn = new StringBuffer(); Enumeration ii; ii = this.tasks.elements(); while (ii.hasMoreElements()) { //sReturn.append("* "); //sdCurrentSoundDownload = (SoundDownload)ii.nextElement(); sReturn.append((SoundDownload)ii.nextElement()); sReturn.append(NEWLINE); } //-- while return sReturn.toString(); } //-------------------------------------------- /** shows those tasks (that is {@linkplain tutor.SoundDownload}s) * which the download manager has already completed, */ public String printCompletedTasks() { StringBuffer sReturn = new StringBuffer(); Enumeration ii; SoundDownload dCurrentDownload; ii = this.tasks.elements(); while (ii.hasMoreElements()) { dCurrentDownload = (SoundDownload)ii.nextElement(); if (dCurrentDownload.hasFinished()) { sReturn.append("* "); sReturn.append((SoundDownload)ii.nextElement()); sReturn.append(NEWLINE + NEWLINE); } } //-- while return sReturn.toString(); } //-------------------------------------------- /** displays a concise summary. */ public String toString() { StringBuffer sbReturn = new StringBuffer(); SoundDownload sdCurrentSoundDownload; sbReturn.append("Sound Download Manager: "); sbReturn.append("("); sbReturn.append(this.tasks.size()); sbReturn.append(" tasks, "); sbReturn.append("completed:" + this.countCompletedDownloads()); sbReturn.append(", successful:" + this.countGoodDownloads()); sbReturn.append(", failed:" + this.countBadDownloads()); sbReturn.append(", time taken:"); sbReturn.append(this.getWorkTimeInSeconds()); sbReturn.append(" secs"); sbReturn.append(")"); if (this.startTime != null) { sbReturn.append(" started at:"); sbReturn.append(this.startTime); } if (this.finishTime != null) { sbReturn.append(" -finished-"); } else { sbReturn.append(" -not started-"); } return sbReturn.toString(); } //-- method: toString //-------------------------------------------- /** * prints information about all the attempts to download resources. * * @see "the toString() and printFullReport() methods" * @return a string which is suitable for displaying somewhere */ public String printReport() { StringBuffer sbReturn = new StringBuffer(); SoundDownload sdCurrentSoundDownload; sbReturn.append("-Sound Download Manager-"); sbReturn.append(NEWLINE); sbReturn.append("number of tasks :"); sbReturn.append(this.tasks.size()); sbReturn.append(NEWLINE); sbReturn.append("completed tasks :"); sbReturn.append(this.countCompletedDownloads()); sbReturn.append(NEWLINE); sbReturn.append("successful loads :"); sbReturn.append(this.countGoodDownloads()); sbReturn.append(NEWLINE); sbReturn.append("failed loads :"); sbReturn.append(this.countBadDownloads()); sbReturn.append(NEWLINE); if (this.startTime == null) { sbReturn.append("start time :"); sbReturn.append(" -not started-"); } else { sbReturn.append("work time :"); sbReturn.append((float)this.getWorkTime()/1000); sbReturn.append(" secs"); sbReturn.append(NEWLINE); sbReturn.append("start time :"); sbReturn.append(this.startTime); } sbReturn.append(NEWLINE); if (this.finishTime == null) { sbReturn.append("finish time :"); sbReturn.append(" -not finished-"); } else { sbReturn.append("finish time :" + this.finishTime); } sbReturn.append(NEWLINE); sbReturn.append(NEWLINE); return sbReturn.toString(); } //-- method: printReport //-------------------------------------------- /** allows the display of information about all the attempts * to download resources from the internet. */ public String printLongReport() { StringBuffer sbReturn = new StringBuffer(); SoundDownload sdCurrentSoundDownload; sbReturn.append("**Sound Download Manager**"); sbReturn.append(NEWLINE); sbReturn.append("Total Successful Tasks :"); sbReturn.append(this.countGoodDownloads()); sbReturn.append(NEWLINE); sbReturn.append("Total Failed Tasks :"); sbReturn.append(this.countBadDownloads()); sbReturn.append(NEWLINE); sbReturn.append(NEWLINE); sbReturn.append("--successful loads--"); sbReturn.append(NEWLINE); Enumeration ii; ii = this.goodDownloads.elements(); while (ii.hasMoreElements()) { sbReturn.append(NEWLINE); sdCurrentSoundDownload = (SoundDownload)ii.nextElement(); sbReturn.append(sdCurrentSoundDownload.printStatistics()); } //-- while sbReturn.append("--failed loads--"); sbReturn.append(NEWLINE); ii = this.badDownloads.elements(); while (ii.hasMoreElements()) { sbReturn.append(NEWLINE); sdCurrentSoundDownload = (SoundDownload)ii.nextElement(); sbReturn.append(sdCurrentSoundDownload.printStatistics()); } //-- while return sbReturn.toString(); } //-- method: printFullReport //-------------------------------------------- /** provides a command loop to test the sound download manager */ public static void main(String[] args) throws Exception { StringBuffer sMessage = new StringBuffer(""); sMessage.append("usage: java SoundLoadManager [datafile] \n\n"); sMessage.append(" manages the downloading of sounds from \n"); sMessage.append(" the Internet. See http://bumble.sf.net/lengua/tutor \n"); if (args.length == 0) { System.out.println(sMessage); System.exit(-1); } StringBuffer sOutput = new StringBuffer(); RecordSet rData; rData = new RecordSet(args[0]); SoundLoadManager manager = new SoundLoadManager(rData); Vector soundDownloads = manager.getGoodDownloads(); //-- make a simple command loop //-- BufferedReader brUserInput = new BufferedReader( new InputStreamReader(System.in)); String sCommand = ""; sMessage.setLength(0); System.out.println("testing the download manager..."); System.out.println("commands:"); System.out.println(" h - show this help message"); System.out.println(" q - exit the program"); System.out.println(" r - show recordset data"); System.out.println(" d - start downloading "); System.out.println(" D - stop downloading "); System.out.println(" t - show all tasks "); System.out.println(" c - show completed tasks"); System.out.println(" s - show concise work summary"); System.out.println(" ss - show longer work summary"); System.out.println(" f - show downloads which failed"); System.out.println(" "); //---------------------------------- //-- the command loop //-- while (!sCommand.equals("q")) { //------------------------------------- //-- show all tasks if (sCommand.equals("r")) { System.out.println(rData.printReport()); } //------------------------------------- //-- show all tasks if (sCommand.equals("t")) { System.out.println(manager.printAllTasks()); } //------------------------------------- if (sCommand.equals("c")) { System.out.println(manager.printCompletedTasks()); } //------------------------------------- //-- start downloading if (sCommand.equals("d")) { System.out.println("starting to download..."); manager.startDownloading(); } //------------------------------------- //-- stop downloading if (sCommand.equals("D")) { System.out.println("stopping to download..."); manager.stopDownloading(); } //------------------------------------- //-- concise work summary if (sCommand.equals("s")) { System.out.println(manager.toString()); } //------------------------------------- //-- longer work summary if (sCommand.equals("ss")) { System.out.println(manager.printReport()); } //------------------------------------- //-- show failed downloads if (sCommand.equals("f")) { System.out.println(manager.printFailedTasks()); } //------------------------------------- //-- a help message if (sCommand.equals("h")) { System.out.println("testing the download manager..."); System.out.println("commands:"); System.out.println(" h - show this help message"); System.out.println(" q - exit the program"); System.out.println(" r - show recordset data"); System.out.println(" d - start the downloading "); System.out.println(" D - stop the downloading "); System.out.println(" t - show all tasks "); System.out.println(" c - show completed tasks"); System.out.println(" s - show concise work summary"); System.out.println(" ss - show longer work summary"); System.out.println(" f - show downloads which failed"); System.out.println(" "); } System.out.print(">"); sCommand = brUserInput.readLine(); } //-- while System.out.println("method: .printReport()"); System.out.println(manager.printReport()); System.out.println("method: .toString()"); System.out.println(manager.toString()); } //-- main() } //-- SoundLoadManager class