SpeedDemon - has developed been developed in a highly modular fashion. By default, it supports HTTP 1.1 & 1.0. In fact, this support for HTTP is actually developed as a plugin to prove its modular & loosely coupled architecture. Support for a protocol is developed by implementing the 'IProtocolWrapper' interface in the 'sd.core.downloadmanager' package. The class which implements this interface along with any of it's supporting classes, should be packaged as a JAR file, and the Manifest's 'Main-Class' entry should point to this implementing class with the fully qualified package name (usual Manifest rules). This JAR must then be placed in the 'pw' (ProtocolWrapper) directory of the SpeedDemon main directory. If this package in turn depends upon other packages, then they should be placed in the 'ext' (External libraries) directory of the SpeedDemon directory.

A screenshot of the SpeedDemon project.
Working: I am going to explain the working by taking the HTTP support I have built. The 'CoreDownloadManager' is instantiated for every file that is being downloaded. This inturn has references to 'CoreDownloadWorkers' which interact with the 'IProtocolWrapper' implementation. For each URL entered in the 'Mirrors' screen, there is one 'CoreDownloadWorker'. The 'ProtocolWrapperFactory' dispenses out to the 'CoreDownloadWorker', new instances of 'IProtocolWrapper' implementations which have been registered by placing the JAR files in the 'pw' directory as explained earlier. The 'CoreDownloadManager' first collects information about the file it is about to download by invoking the 'getDownloadInfo()' method on each of the 'CoreDownloadWorkers'. The 'CoreDownloadWorker' actually invokes the 'IProtocolWrapper' 'getDownloadInfo()' in a separate thread. After which, the 'CoreDownloadWorker' expects the 'ProtocolWrapper' to fill in details such as - Content Length, Resume supported or not. For each such 'CoreDownloadWorkers', the 'CoreDownloadManager' goes through the results and retains only the URLs which support resuming, if there are any at all; or, retains all the URLs if none of them support resuming.
After this information has been collected, the user is prompted to specify the download directory and the file to save as. Also, the user can change the default 'CHUNK_SIZE' which would have been read from the 'SpeedDemon.properties' file in the main 'SpeedDemon' directory. Note that, this 'CHUNK_SIZE' cannot be lower than 1/7th of the size of the file being downloaded. This is just a precautionary measure to prevent spawning a large number of downloading-threads which can overload the system.
Now, the 'CoreDownloadManager' instantiates as many 'CoreDownloadWorkers' as there are URLs. Note that, if resuming is supported, then the number of 'CodeDownloadWorkers' will be ~= (File size/Chunk size). Suppose resuming is not supported, then there will be only one 'CoreDownloadWorker'. Each worker will have a Range start and a Range end, which specifies what range of bytes it has to download. This information will be passed to its corresponding 'IProtocolWrapper' implementation. Sequence diagrams: Part 1 and Part 2
When 'Stop' is clicked, the current state of the download is stored by serializing both the 'CoreDownloadManager' and its 'CoreDownloadWorkers' into 'DownloadInfo.ser' file. The 'IProtocolWrappers' will not be saved. They will be created afresh when the download is resumed. The downloading-threads keep saving their bytes they download into separate files in its specific directory. When all the downloading-threads complete, the separate files will be re-combined and saved into the directory that would have been specified by the user. The temporary directory where the downloading-threads store their bytes is specific to each file that the user downloads. The names of these directories are computed by hashing the URL that the user first specifies into an MD5 string.
Coming to the GUI, it has been designed very carefully so as not to slow-down or deadlock the 'AWT-EventHandler' thread. Also since there are multiple threads downloading the files, updating the UI quickly is of utmost importance. As said earlier, I have followed strictly the MVC, Observer, Factory, Singleton and the Visitor patterns. The UI updating is absolutely thread-safe. The 'DownloadPanelController' and the 'DownloadStatusPanelController' are very complex I must confess. It took me quite some time to design them. Simply put, they are like 2 state machines. I suggest you read the code to understand them better.
The 'MainFrame' is the main 'JFrame' class. It is a Singleton object, and therefore has a static method to access the single instance. The MainFrame's 'JDesktopPane', 'Command menu' and the 'JMenubar' have public access and so can be accessed/used by plugins.
To prevent multiple instances of SpeedDemon from being opened, SpeedDemon opens a 'ServerSocket' at the port number specified by the 'SERVER_PORT' field in the 'SpeedDemon.properties' file. Allowing multiple multiple instances might corrupt the 'URLs.ser' file which stores the serialized list of URLs that have been downloaded so far.
Nr. Classes Functions NCSS Package
1 1 10 82 http_protocolwrapper
2 2 7 86 sd
3 5 86 552 sd.core.downloadmanager
4 1 11 151 sd.gui
5 13 64 1502 sd.gui.downloadmanager
6 2 17 223 sd.util
--------- --------- ---------
24 195 2596 Total
Packages Classes Functions NCSS | per
---------------------------------------------------
6.00 24.00 195.00 2,596.00 | Project
4.00 32.50 432.67 | Package
8.13 108.17 | Class
13.31 | Function
Nr. NCSS Functions Classes Javadocs Class
1 9 0 0 1 sd.GlobalConstants
2 63 7 1 4 sd.SpeedDemon
3 217 35 0 11 sd.core.downloadmanager.CoreDownloadManager
4 210 35 2 6 sd.core.downloadmanager.CoreDownloadWorker
5 46 6 0 3 sd.core.downloadmanager.InputOutput
6 7 6 0 1 sd.core.downloadmanager.IProtocolWrapper
7 44 4 0 2 sd.core.downloadmanager.ProtocolWrapperFactory
8 139 11 7 4 sd.gui.MainFrame
9 12 3 0 3 sd.gui.downloadmanager.AddURLsPanel
10 12 3 0 3 sd.gui.downloadmanager.BlankPanel
11 109 7 3 3 sd.gui.downloadmanager.DownloadListPanel
12 91 6 0 6 sd.gui.downloadmanager.DownloadManager
13 11 0 0 1 sd.gui.downloadmanager.DownloadManagerGUIConstants
14 45 3 0 3 sd.gui.downloadmanager.DownloadPanel
15 482 13 4 7 sd.gui.downloadmanager.DownloadPanelController
16 53 3 2 3 sd.gui.downloadmanager.DownloadStatusPanel
17 314 8 4 5 sd.gui.downloadmanager.DownloadStatusPanelController
18 36 3 0 3 sd.gui.downloadmanager.DownloadStatusPanelListComponent
19 140 8 5 5 sd.gui.downloadmanager.FullDownloadDetailsPanel
20 101 6 0 1 sd.gui.downloadmanager.GridLayout2
21 2 1 0 1 sd.gui.downloadmanager.IHost
22 14 1 0 2 sd.util.FileRecombiner
23 201 16 5 0 sd.util.MD5
24 73 10 0 2 http_protocolwrapper.HTTP_ProtocolWrapper
Average Object NCSS: 101.29
Average Object Functions: 8.13
Average Object Inner Classes: 1.38
Average Object Javadoc Comments: 3.33
Program NCSS: 2,596.00