View Javadoc

1   /*
2    *  XNap - A P2P framework and client.
3    *
4    *  See the file AUTHORS for copyright information.
5    *
6    *  This program is free software; you can redistribute it and/or modify
7    *  it under the terms of the GNU General Public License as published by
8    *  the Free Software Foundation.
9    *
10   *  This program is distributed in the hope that it will be useful,
11   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   *  GNU General Public License for more details.
14   *
15   *  You should have received a copy of the GNU General Public License
16   *  along with this program; if not, write to the Free Software
17   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18   */
19  
20  package org.xnap.plugin.gift;
21  
22  import java.io.File;
23  import java.io.IOException;
24  import java.util.List;
25  
26  import javax.swing.Icon;
27  import javax.swing.*;
28  
29  import org.apache.log4j.Logger;
30  import org.xnap.XNap;
31  import org.xnap.XNapFacade;
32  import org.xnap.gui.AbstractPreferencesDialog;
33  import org.xnap.gui.DefaultPrefsWizardDialog;
34  import org.xnap.gui.StatusBar;
35  import org.xnap.gui.XNapFrame;
36  import org.xnap.gui.component.XNapMenu;
37  import org.xnap.gui.component.XNapMenuItem;
38  import org.xnap.gui.event.AbstractPreferencesDialogListener;
39  import org.xnap.gui.util.IconHelper;
40  import org.xnap.plugin.AbstractPlugin;
41  import org.xnap.plugin.gift.action.ConnectToGiFTAction;
42  import org.xnap.plugin.gift.action.DisconnectFromGiFTAction;
43  import org.xnap.plugin.gift.action.ShowPreferencesAction;
44  import org.xnap.plugin.gift.action.ShutdownGiFTAction;
45  import org.xnap.plugin.gift.action.StartGiFTAction;
46  import org.xnap.plugin.gift.action.UpdateGiFTStatsAction;
47  import org.xnap.plugin.gift.gui.GiFTDaemonPanel;
48  import org.xnap.plugin.gift.gui.GiFTPreferencesPanel;
49  import org.xnap.plugin.gift.gui.GiFTStatusPanel;
50  import org.xnap.plugin.gift.net.GiFTDaemon;
51  import org.xnap.plugin.gift.net.GiFTDaemonListener;
52  import org.xnap.plugin.gift.net.GiFTSearch;
53  import org.xnap.plugin.gift.net.event.ErrorEvent;
54  import org.xnap.plugin.gift.net.event.OfflineEvent;
55  import org.xnap.plugin.gift.net.event.OnlineEvent;
56  import org.xnap.plugin.gift.net.event.StatsEvent;
57  import org.xnap.plugin.gift.util.GiFTPreferences;
58  import org.xnap.search.MediaType;
59  import org.xnap.search.Search;
60  import org.xnap.search.SearchFilter;
61  import org.xnap.search.SearchManager;
62  import org.xnap.search.SearchProvider;
63  import org.xnap.util.Preferences;
64  import org.xnap.util.Scheduler;
65  
66  
67  /***
68   * GiFTPlugin
69   *
70   * @author $author$
71   * @version $Revision: 1.3 $
72   */
73  public class GiFTPlugin extends AbstractPlugin 
74  	implements GiFTDaemonListener, SearchProvider {
75  
76  	private StartGiFTAction acStart;
77  
78  	private XNapMenu jmGift;
79  
80  	private Process giftProcess;
81  
82  	public static Icon ICON_16
83  	= IconHelper.getIcon("gift.png", 16, false);
84  
85      //~ Static fields/initializers ---------------------------------------------
86  
87  	private PreferencesDialogListener listener;
88  	private GiFTStatusPanel spGift;
89  	private ShutdownGiFTAction acShutdown;
90  	private DisconnectFromGiFTAction acDisconnect;
91  	private ConnectToGiFTAction acConnect;
92  	private ShowPreferencesAction acConfigure;
93  	private UpdateGiFTStatsAction acUpdate;
94  	private static GiFTPlugin singleton;
95  	private GiFTDaemon daemon;
96  	private boolean connected = false;
97  
98      //~ Instance fields --------------------------------------------------------
99  	private Logger logger = Logger.getLogger(GiFTPlugin.class);
100     private GiFTPreferences giftPrefs = GiFTPreferences.getInstance();
101   
102 	private JTabbedPane jtpGift;
103 	private GiFTDaemonPanel jpDaemon;
104 
105     //~ Constructors -----------------------------------------------------------
106 
107     /***
108      * Creates a new GiFTPlugin object.
109      */
110     public GiFTPlugin() {
111         singleton = this;
112 		acConnect = new ConnectToGiFTAction();
113 		acDisconnect = new DisconnectFromGiFTAction();
114 		acShutdown = new ShutdownGiFTAction();     
115 		acUpdate = new UpdateGiFTStatsAction();
116 		acConfigure = new ShowPreferencesAction();
117 		acStart = new StartGiFTAction();
118     }
119 
120     //~ Methods ----------------------------------------------------------------
121 
122     /***
123      * Singleton getInstance
124      *
125      * @return GiFTPlugin
126      */
127     public static GiFTPlugin getInstance() {
128         return singleton;
129     }
130 
131     
132     /***
133      * @see xnap.plugin.gift.net.event.listener.NetworkEventListener#attached(xnap.plugin.gift.net.event.OnlineEvent)
134      */
135     public void attached(OnlineEvent evt) {
136         SearchManager.getInstance().add(this);
137         acConnect.setEnabled(false);
138         acDisconnect.setEnabled(true);
139         
140         if (giftPrefs.getStartDaemon())  
141 			acShutdown.setEnabled(true);
142         else acShutdown.setEnabled(false); 
143         	
144         acUpdate.setEnabled(true);
145      }
146 
147     /***
148      * @see xnap.plugin.gift.net.event.listener.NetworkEventListener#detached(xnap.plugin.gift.net.event.OfflineEvent)
149      */
150     public void detached(OfflineEvent evt) {
151         SearchManager.getInstance().remove(this);
152         acConnect.setEnabled(true);
153         acDisconnect.setEnabled(false);
154         acShutdown.setEnabled(false);
155 		acUpdate.setEnabled(false);
156     }
157 
158     /***
159      * @see xnap.plugin.gift.net.event.listener.ErrorEventListener#onError(xnap.plugin.gift.net.event.ErrorEvent)
160      */
161     public void onError(ErrorEvent evt) {
162         logger.debug(evt.getErrorMessage(), evt.getException());
163     }
164 
165     /***
166      * @see xnap.plugin.INetworkPlugin#search(xnap.util.SearchFilter, int)
167      */
168     public Search search(SearchFilter filter) {
169         GiFTSearch search = new GiFTSearch(filter, daemon);
170         return search;
171     }
172 
173     /***
174      * @see xnap.plugin.IPlugin#start()
175      */
176     public void start() {
177 		singleton = this;
178 		startGiftConnection();
179     }
180 
181 	public void startGiftConnection() {
182 		acStart.setEnabled(false);
183 		acShutdown.setEnabled(false);
184 		acConnect.setEnabled(true);
185 
186 		String command = giftPrefs.getGiftDaemon();
187 		if (giftPrefs.getStartDaemon() && command.length() > 0) {
188 			String[] args = new String[] { command, "-d" };
189 			try {
190 				logger.debug("launching giFT daemon");
191 				giftProcess = Runtime.getRuntime().exec
192 					(args, null, (new File(command)).getParentFile());
193 
194 				acStart.setEnabled(false);
195 				acShutdown.setEnabled(true);
196 			}
197 			catch (IOException ie) {
198 				logger.debug("Could not launch giFT daemon", ie);
199 			}
200 		}
201 		
202 		daemon = new GiFTDaemon(giftPrefs.getGiftHost(),
203 								giftPrefs.getDaemonPort(),
204 								Preferences.getInstance().getUsername());
205 		daemon.addDaemonListener(this);
206 		
207 		// start core after 5 seconds delay
208 		if (giftPrefs.getAutoconnect()) {
209 			Scheduler.run(5 * 1000, new Runnable() {
210 					public void run()
211 					{
212 						daemon.start();
213 					}
214 				});
215 		}
216 	}
217 
218     public void stopGiftConnection() {
219     	if (giftProcess != null) {
220 			daemon.stop(true);
221 			Scheduler.run(5 * 1000, new Runnable() {
222 					public void run()
223 					{
224 						if (giftProcess != null) {
225 							giftProcess.destroy();							
226 						}
227 						giftProcess = null;
228 					}
229 				});
230     	} else {
231 			daemon.stop(false);
232     	}
233 
234 		
235 		acShutdown.setEnabled(false);
236 		acConnect.setEnabled(false);
237 		String command = giftPrefs.getGiftDaemon();
238 		if (giftPrefs.getStartDaemon() && command.length() > 0)
239 			acStart.setEnabled(true);
240     }
241     
242     /***
243      * @see xnap.plugin.gift.net.event.listener.NetworkEventListener#statsUpdate(xnap.plugin.gift.net.event.StatsEvent)
244      */
245     public void statsUpdate(StatsEvent evt) {
246     }
247 
248     /***
249      * @see xnap.plugin.IPlugin#stop()
250      */
251     public void stop() {
252         stopGiftConnection();
253 
254 	// we can not cleanly unload the plugin...
255         //singleton = null;
256     }
257 	/***
258 	 * @see xnap.search.SearchProvider#getName()
259 	 */
260 	public String getName() {
261 		return "giFT";
262 	}
263 
264 	/***
265 	 * @see xnap.search.SearchProvider#getSupportedMediaTypes()
266 	 */
267 	public MediaType[] getSupportedMediaTypes() {
268 		return new MediaType[] {SearchManager.MEDIA_ANYTHING};
269 	}
270 
271 	/***
272 	 * @see xnap.plugin.Plugin#startGUI()
273 	 */
274 	public void startGUI() {
275 		spGift = new GiFTStatusPanel(daemon);
276 		daemon.addDaemonListener(spGift);
277 		StatusBar.getInstance().addComponent(spGift);
278 		
279 		listener = new PreferencesDialogListener();
280 		XNapFacade.addPluginPreferencesDialogListener(listener);
281 		initializeMenu();
282 		XNapFrame.getInstance().getMainMenuBar().addPluginMenu(jmGift);
283 		
284 		jtpGift = new JTabbedPane();
285 		
286 		jpDaemon = new GiFTDaemonPanel(daemon);
287 		daemon.addDaemonListener(jpDaemon);
288 		jtpGift.addTab(XNap.tr("Daemon"), jpDaemon);
289 		
290 		XNapFrame.getInstance().insertTab("giFT", IconHelper.getListIcon("gift.png"), jtpGift);
291 
292 		/* show prefs panel in dialog when plugin is started for the first
293 		   time.  */
294 		if (!giftPrefs.getBoolean("seenStartupWizard")) {
295 			showPrefsDialog();
296 		}
297 
298 	}
299 
300 	/***
301 	 * @see xnap.plugin.Plugin#stopGUI()
302 	 */
303 	public void stopGUI() {
304 		XNapFrame.getInstance().getMainMenuBar().removePluginMenu(jmGift);
305 		jmGift = null;
306 
307 		daemon.removeDaemonListener(spGift);
308 		StatusBar.getInstance().removeComponent(spGift);
309 		spGift = null;
310 		
311 		daemon.removeDaemonListener(jpDaemon);
312 
313 		listener.dispose();
314 		XNapFacade.removePluginPreferencesDialogListener(listener);
315 		listener = null;
316 		
317 		XNapFrame.getInstance().removeTab(jtpGift);
318 		jtpGift = null;
319 	}
320 
321 	private void initializeMenu()
322 	{
323 		jmGift = new XNapMenu(getName());
324 		jmGift.setIcon(IconHelper.getMenuIcon("gift.png"));
325 		jmGift.add(new XNapMenuItem(acConnect));
326 		jmGift.add(new XNapMenuItem(acDisconnect));
327 		jmGift.add(new XNapMenuItem(acUpdate));
328 		jmGift.addSeparator();
329 		jmGift.add(new XNapMenuItem(acStart));
330 		jmGift.add(new XNapMenuItem(acShutdown));
331 		jmGift.addSeparator();
332 		jmGift.add(new XNapMenuItem(acConfigure));
333 	}
334 
335 	public void showPrefsDialog() 
336 	{
337 		DefaultPrefsWizardDialog dfd 
338 			= new DefaultPrefsWizardDialog(giftPrefs, "seenStartupWizard");
339 		dfd.addPanel(new GiFTPreferencesPanel());
340 		dfd.pack();
341 		dfd.show(XNapFrame.getInstance());
342 	}
343 	
344 	/***
345 	 * 
346 	 */
347 	public ConnectToGiFTAction getConnectAction() 
348 	{
349 		return acConnect;
350 	}
351 
352 	public GiFTDaemon getDaemon()
353 	{
354 		return daemon;
355 	}
356 
357 	/***
358 	 * 
359 	 */
360 	public DisconnectFromGiFTAction getDisconnectAction() 
361 	{
362 		return acDisconnect;
363 	}
364 
365 	/***
366 	 * 
367 	 */
368 	public ShutdownGiFTAction getShutdownAction() 
369 	{
370 		return acShutdown;
371 	}
372 
373 	/***
374 	 *
375 	 */
376 	public StartGiFTAction getStartAction() 
377 	{
378 		return acStart;
379 	}
380 
381 	/***
382 	 *
383 	 */
384 	public UpdateGiFTStatsAction getUpdateAction() 
385 	{
386 		return acUpdate;
387 	}
388 
389 	private class PreferencesDialogListener 
390 		extends AbstractPreferencesDialogListener
391 	{
392 		
393 		public void addPanels(AbstractPreferencesDialog dialog, List panels) 
394 		{
395 			GiFTPreferencesPanel jpp = new GiFTPreferencesPanel();
396 			panels.add(jpp);
397 			panels.add(dialog.addPanel(jpp, "gift.png"));
398 		}
399 
400 	}
401 
402 	/***
403 	 *  @see org.xnap.plugin.gift.net.GiFTDaemonListener#statusChanged(org.xnap.plugin.gift.net.GiFTDaemon, java.lang.String)
404 	 */
405 	public synchronized void statusChanged(final GiFTDaemon daemon) 
406 	{
407 		if (daemon.isConnected()) {
408 			if (!connected) {
409 				connected = true;
410 				SearchManager.getInstance().add(this);
411 			}
412 		}
413 		else {
414 			if (connected) {
415 				connected = false;
416 				SearchManager.getInstance().remove(this);
417 			}
418 		}
419 
420 		Runnable runner = new Runnable() 
421 			{
422 				public void run() 
423 				{
424 					acConnect.setEnabled(daemon.isDisconnected());
425 					acDisconnect.setEnabled(daemon.isConnected());
426 				}
427 			};
428 		SwingUtilities.invokeLater(runner);
429 	}
430 
431 }