001 /* 002 Copyright (C) 2003 Adam Olsen 003 004 This program is free software; you can redistribute it and/or modify 005 it under the terms of the GNU General Public License as published by 006 the Free Software Foundation; either version 1, or (at your option) 007 any later version. 008 009 This program is distributed in the hope that it will be useful, 010 but WITHOUT ANY WARRANTY; without even the implied warranty of 011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 012 GNU General Public License for more details. 013 014 You should have received a copy of the GNU General Public License 015 along with this program; if not, write to the Free Software 016 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 017 */ 018 019 package com.valhalla.pluginmanager; 020 021 import javax.swing.*; 022 import java.awt.*; 023 import java.awt.event.*; 024 import java.io.*; 025 import java.net.*; 026 import java.util.*; 027 import com.valhalla.gui.*; 028 029 /** 030 * Downloads plugins 031 * 032 * @author Adam Olsen 033 * @version 1.0 034 */ 035 public class PluginDownloaderThread implements Runnable 036 { 037 private ResourceBundle resources = 038 ResourceBundle.getBundle( "PluginManager", Locale.getDefault() ); 039 040 private PluginManager manager = null; 041 private ProgressDialog progress = null; 042 private ArrayList list = null; 043 private double size = 0; 044 private String mirror, script, installDir; 045 private boolean cancelled = false; 046 047 /** 048 * Sets up the thread 049 * @param manager the PluginManager that contains this thread 050 * @param list the list of plugins to download 051 * @param progress the dialog that tracks this threads progress 052 */ 053 public PluginDownloaderThread( PluginManager manager, ArrayList list ) 054 { 055 this.manager = manager; 056 this.list = list; 057 058 mirror = manager.getMirror(); 059 script = manager.getScript(); 060 installDir = manager.getInstallDir(); 061 062 size = calculateSize( list ); 063 064 this.progress = new ProgressDialog( resources.getString( "downloading" ), 0, (int)size + 1 ); 065 JButton button = this.progress.getButton(); 066 button.addActionListener( new ActionListener() 067 { 068 public void actionPerformed( ActionEvent e ) { progress.delete(); cancelled = true; } 069 } ); 070 } 071 072 /** 073 * Called by the enclosing Thread 074 */ 075 public void run() 076 { 077 if( size <= 0.0 ) 078 { 079 manager.throwError( "selectPlugins", true ); 080 progress.delete(); 081 082 return; 083 } 084 085 Socket socket = null; 086 PrintWriter out = null; 087 InputStream in = null; 088 BufferedReader bIn = null; 089 090 091 File cacheDir = new File( installDir, "downloadcache" ); 092 if( !cacheDir.isDirectory() && !cacheDir.mkdirs() ) 093 { 094 progress.delete(); 095 manager.throwError( "couldNotCreateCache", true ); 096 return; 097 } 098 099 try { 100 int totalRead = 0; 101 102 for( int i = 0; i < list.size(); i++ ) 103 { 104 if( cancelled ) return; 105 Properties props = (Properties)list.get( i ); 106 if( props.getProperty( "selected" ) != null ) 107 { 108 socket = new Socket( mirror, 80 ); 109 out = new PrintWriter( socket.getOutputStream(), true ); 110 in = socket.getInputStream(); 111 112 File outFile = new File( cacheDir, props.getProperty( "fileName" ) ); 113 int pluginSize = Integer.parseInt( props.getProperty( "size" ) ); 114 FileOutputStream fileOut = new FileOutputStream( outFile ); 115 116 out.println( "GET " + script + "?command=getPlugin&apiVersion=" + 117 PluginLoader.getAPIVersion() + "&plugin=" + props.getProperty( "fileName" ) + " HTTP/1.0" ); 118 out.println( "Host: " + mirror + "\n" ); 119 120 String checkString = null; 121 int checkCount = 0; 122 while( true ) 123 { 124 char c = (char)in.read(); 125 if( c == -1 ) break; 126 checkString += c; 127 if( checkString.length() >= 4 && 128 checkString.substring( checkString.length() - 4 ).equals( "\r\n\r\n" ) ) break; 129 } 130 131 int readSize = 0; 132 int totalSize = 0; 133 byte buf[] = new byte[1024]; 134 135 while( true ) 136 { 137 if( cancelled ) 138 { 139 in.close(); 140 fileOut.close(); 141 return; 142 } 143 144 readSize = in.read( buf, 0, 1024 ); 145 if( readSize == -1 ) break; 146 147 fileOut.write( buf, 0, readSize ); 148 totalRead += readSize; 149 totalSize += readSize; 150 151 final int tempSize = totalRead; 152 SwingUtilities.invokeLater( new Runnable() 153 { 154 public void run() 155 { 156 progress.setValue( tempSize ); 157 progress.repaint(); 158 } 159 } ); 160 } 161 162 fileOut.close(); 163 164 if( cancelled ) return; 165 166 if( totalSize != pluginSize ) 167 { 168 com.valhalla.Logger.debug( pluginSize + " " + totalSize ); 169 manager.throwError( "downloadError", true ); 170 progress.delete(); 171 return; 172 } 173 174 socket.close(); 175 } 176 } 177 178 } 179 catch( Exception e ) 180 { 181 manager.throwError( e.getMessage(), false ); 182 progress.delete(); 183 return; 184 } 185 186 if( cancelled ) return; 187 188 progress.delete(); 189 190 SwingUtilities.invokeLater( new Runnable() 191 { 192 public void run() 193 { 194 manager.doneDownloadingPlugins( list ); 195 } 196 } ); 197 } 198 199 /** 200 * Gets the size of the selected plugins in an array 201 * @param list the plugin list 202 * @return the size of the selected plugins 203 */ 204 public static double calculateSize( ArrayList list ) 205 { 206 double size = 0; 207 for( int i = 0; i < list.size(); i++ ) 208 { 209 Properties p = (Properties)list.get( i ); 210 if( p.getProperty( "selected" ) != null ) 211 { 212 try { 213 double s = Double.parseDouble( p.getProperty( "size" ) ); 214 size += s; 215 } 216 catch( Exception e ) { e.printStackTrace(); } 217 } 218 } 219 220 return size; 221 } 222 }