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 java.awt.event.ActionEvent;
022 import java.awt.event.ActionListener;
023 import java.io.BufferedReader;
024 import java.io.File;
025 import java.io.FileOutputStream;
026 import java.io.InputStream;
027 import java.io.PrintWriter;
028 import java.net.Socket;
029 import java.net.URL;
030 import java.net.ConnectException;
031 import java.util.ArrayList;
032 import java.util.Locale;
033 import java.util.Properties;
034 import java.util.ResourceBundle;
035
036 import javax.swing.*;
037
038 import com.valhalla.gui.ProgressDialog;
039
040 /**
041 * Downloads plugins
042 *
043 * @author Adam Olsen
044 * @version 1.0
045 */
046 public class PluginDownloaderThread implements Runnable {
047 private ResourceBundle resources = ResourceBundle.getBundle(
048 "PluginManager", Locale.getDefault());
049
050 private PluginManager manager = null;
051
052 private ProgressDialog progress = null;
053
054 private ArrayList list = null;
055
056 private double size = 0;
057
058 private String mirror, script, installDir;
059
060 private boolean cancelled = false;
061
062 /**
063 * Sets up the thread
064 *
065 * @param manager
066 * the PluginManager that contains this thread
067 * @param list
068 * the list of plugins to download
069 * @param progress
070 * the dialog that tracks this threads progress
071 */
072 public PluginDownloaderThread(PluginManager manager, ArrayList list) {
073 this.manager = manager;
074 this.list = list;
075
076 mirror = manager.getMirror();
077 script = manager.getScript();
078 installDir = manager.getInstallDir();
079
080 size = calculateSize(list);
081
082 this.progress = new ProgressDialog(manager, resources
083 .getString("downloading"), 0, (int) size + 1);
084 JButton button = this.progress.getButton();
085 button.addActionListener(new ActionListener() {
086 public void actionPerformed(ActionEvent e) {
087 progress.delete();
088 cancelled = true;
089 }
090 });
091 }
092
093 /**
094 * Called by the enclosing Thread
095 */
096 public void run() {
097 if (size <= 0.0) {
098 manager.throwError("selectPlugins", true);
099 progress.delete();
100
101 return;
102 }
103
104 InputStream in = null;
105 BufferedReader bIn = null;
106
107 File cacheDir = new File(installDir, "downloadcache");
108 if (!cacheDir.isDirectory() && !cacheDir.mkdirs()) {
109 progress.delete();
110 manager.throwError("couldNotCreateCache", true);
111 return;
112 }
113
114 try {
115 int totalRead = 0;
116
117 for (int i = 0; i < list.size(); i++) {
118 if (cancelled)
119 return;
120 Properties props = (Properties) list.get(i);
121 if (props.getProperty("selected") != null) {
122
123 URL url = new URL("http://" + mirror + script +
124 "?command=getPlugin&apiVersion=" + PluginLoader.getAPIVersion()
125 + "&plugin=" + props.getProperty("fileName"));
126 System.out.println("accessing URL:" + url);
127 in = url.openStream();
128
129 File outFile = new File(cacheDir, props
130 .getProperty("fileName"));
131 int pluginSize = Integer
132 .parseInt(props.getProperty("size"));
133 FileOutputStream fileOut = new FileOutputStream(outFile);
134
135 int readSize = 0;
136 int totalSize = 0;
137 byte buf[] = new byte[1024];
138
139 while (true) {
140 if (cancelled) {
141 in.close();
142 fileOut.close();
143 return;
144 }
145
146 readSize = in.read(buf, 0, 1024);
147 if (readSize == -1)
148 break;
149
150 fileOut.write(buf, 0, readSize);
151 totalRead += readSize;
152 totalSize += readSize;
153
154 final int tempSize = totalRead;
155 SwingUtilities.invokeLater(new Runnable() {
156 public void run() {
157 progress.setValue(tempSize);
158 progress.repaint();
159 }
160 });
161 }
162
163 fileOut.close();
164
165 if (cancelled)
166 return;
167
168 if (totalSize != pluginSize) {
169 com.valhalla.Logger.debug(pluginSize + " " + totalSize);
170 manager.throwError("downloadError", true);
171 progress.delete();
172 return;
173 }
174
175 in.close();
176 }
177 }
178
179 } catch (ConnectException e) {
180 JOptionPane.showMessageDialog(null,
181 resources.getString("couldNotConnectThroughProxy"),
182 resources.getString("connectionError"),
183 JOptionPane.ERROR_MESSAGE);
184 } catch (Exception e) {
185 manager.throwError(e.getMessage(), false);
186 progress.delete();
187 return;
188 }
189
190 if (cancelled)
191 return;
192
193 progress.delete();
194
195 SwingUtilities.invokeLater(new Runnable() {
196 public void run() {
197 manager.doneDownloadingPlugins(list);
198 }
199 });
200 }
201
202 /**
203 * Gets the size of the selected plugins in an array
204 *
205 * @param list
206 * the plugin list
207 * @return the size of the selected plugins
208 */
209 public static double calculateSize(ArrayList list) {
210 double size = 0;
211 for (int i = 0; i < list.size(); i++) {
212 Properties p = (Properties) list.get(i);
213 if (p.getProperty("selected") != null) {
214 try {
215 double s = Double.parseDouble(p.getProperty("size"));
216 size += s;
217 } catch (Exception e) {
218 e.printStackTrace();
219 }
220 }
221 }
222
223 return size;
224 }
225 }