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.jtella;
21  
22  import java.io.IOException;
23  import java.util.List;
24  import java.util.StringTokenizer;
25  
26  import org.apache.log4j.Logger;
27  import org.xnap.XNapFacade;
28  import org.xnap.gui.AbstractPreferencesDialog;
29  import org.xnap.gui.XNapFrame;
30  import org.xnap.gui.event.AbstractPreferencesDialogListener;
31  import org.xnap.gui.util.IconHelper;
32  import org.xnap.plugin.AbstractPlugin;
33  import org.xnap.search.MediaType;
34  import org.xnap.search.Search;
35  import org.xnap.search.SearchFilter;
36  import org.xnap.search.SearchManager;
37  import org.xnap.search.SearchProvider;
38  import org.xnap.util.PortRange;
39  
40  import com.kenmccrary.jtella.ConnectionData;
41  import com.kenmccrary.jtella.GNUTellaConnection;
42  
43  /***
44   * Provides a gnutella network plugin based on the jtella library.
45   */
46  public class JTellaPlugin extends AbstractPlugin implements SearchProvider
47  {
48  
49      //--- Constant(s) ---
50      
51      //--- Data Field(s) ---
52  
53      private static Logger logger = Logger.getLogger(JTellaPlugin.class);
54      private static JTellaPlugin singleton;
55  
56      private JTellaPreferences jtellaPrefs;
57      private GNUTellaConnection connection;
58      private JTellaPanel jpJTella;
59      private PreferencesDialogListener pdl;
60  
61      private boolean started = false;
62  
63      //--- Constructor(s) ---
64  
65      public JTellaPlugin()
66      {
67      }
68  
69      //--- Method(s) ---
70  
71      public static JTellaPlugin getInstance()
72      {
73  		return singleton;
74      }
75  
76  	public static JTellaPreferences getPreferences()
77  	{
78  		return singleton.jtellaPrefs;
79  	}
80      
81      /***
82       * Returns the network connection.
83       */
84      public GNUTellaConnection getConnection()
85      {
86  		return connection;
87      }
88  
89      /***
90       * Returns the name of the plugin.
91  	 *
92  	 * @see SearchProvider#getName()
93       */
94      public String getName()
95      {
96  		return getInfo().getName();
97      }
98  
99      /***
100      * Returns all supported search media types.
101      */
102     public MediaType[] getSupportedMediaTypes()
103     {
104 		return new MediaType[] { SearchManager.MEDIA_ANYTHING };
105     }
106 
107     /***
108      * Creates and returns a {@link JTellaSearch} object.
109      */
110     public Search search(SearchFilter filter)
111     {
112 		return new JTellaSearch(filter);
113     }
114 
115     /***
116      * Starts the plugin.
117      */
118     public void start() 
119     {
120 		singleton = this;
121 
122 		jtellaPrefs = new JTellaPreferences();
123 
124 		//System.setProperty("JTella.Debug", "true");
125 		createConnection();
126 
127 		// auto start
128 		if (getPreferences().getAutoConnect()) {
129 			startConnection();
130 		}
131     }
132 
133     /***
134      * Starts the GUI of the plugin.
135      */
136     public void startGUI()
137     {
138 		jpJTella = new JTellaPanel();
139 		XNapFrame.getInstance().insertTab
140 			(getName(), IconHelper.getListIcon("socket.png"), jpJTella);
141 		
142 		pdl = new PreferencesDialogListener();
143 		XNapFacade.addPluginPreferencesDialogListener(pdl);
144     }
145 
146     /***
147      * Stops the plugin. Disposes all singletons.
148      */
149     public void stop()
150     {
151 		stopConnection(false);
152 		SearchManager.getInstance().remove(JTellaPlugin.getInstance());
153 
154 		connection = null;
155 
156 		jtellaPrefs = null;
157 
158 		singleton = null;
159     }
160 
161     /***
162      * Stops the GUI of the plugin.
163      */
164     public void stopGUI()
165     {
166 		pdl.dispose();
167 		XNapFacade.removePluginPreferencesDialogListener(pdl);
168 		pdl = null;
169 
170 		// stop update timer
171 		jpJTella.setConnected(false);
172 
173 		XNapFrame.getInstance().removeTab(jpJTella);
174 		jpJTella = null;
175     }
176 
177     /***
178      * Creates a new connection.
179      */
180     public void createConnection()
181     {
182 		ConnectionData data = new ConnectionData();
183 		PortRange range
184 			= new PortRange(JTellaPlugin.getPreferences().getLocalPortRange());
185 		data.setIncomingPort(range.getRandom(6348));
186 		data.setVendorCode
187 			("XNap " + JTellaPlugin.getInstance().getInfo().getVersion());
188 
189 		try {
190 			connection = new GNUTellaConnection(data);
191 		}
192 		catch (IOException e) {
193 		}
194     }
195 
196     public boolean isStarted()
197     {
198 		return started;
199     }
200 
201     /***
202      * Starts the network connection.
203      */
204     public void startConnection()
205     {
206 		connection.start();
207 
208 		// add host caches
209 		String[] hostCaches = JTellaPlugin.getPreferences().getHostCaches();
210 		for (int i = 0; i < hostCaches.length; i++) {
211 			StringTokenizer t = new StringTokenizer(hostCaches[i], ":");
212 			try {
213 				String host = t.nextToken();
214 				int port = Integer.parseInt(t.nextToken());
215 				connection.addHostCacheServant(host, port);
216 			}
217 			catch (Exception e) {
218 				logger.debug("could not add host cache", e);
219 			}
220 		}
221 
222 		started = true;
223 		SearchManager.getInstance().add(this);
224 
225 		if (jpJTella != null) {
226 			jpJTella.setConnected(true);
227 		}
228     }
229 
230     /***
231      * Stops the connection.
232      *
233      * @param createNew if true, a new connection will be created
234      * @see #createConnection()
235      */
236     private void stopConnection(boolean createNew)
237     {
238 		connection.stop();
239 		SearchManager.getInstance().remove(this);
240 		started = false;
241 
242 		if (createNew) {
243 			createConnection();
244 		}
245 
246 		if (jpJTella != null) {
247 			jpJTella.setConnected(false);
248 		}
249     }
250 
251     /***
252      * Stops the connection and creates a new one.
253      *
254      * @see #createConnection(boolean)
255      */
256     public void stopConnection()
257     {
258 		stopConnection(true);
259     }
260 
261     // --- Inner Class(es) ---
262 
263     private class PreferencesDialogListener 
264 		extends AbstractPreferencesDialogListener
265     {
266 
267 		public void addPanels(AbstractPreferencesDialog dialog, List panels) 
268 		{
269 			JTellaPreferencesPanel jpp = new JTellaPreferencesPanel();
270 			panels.add(jpp);
271 			panels.add(dialog.addPanel(jpp, "socket.png"));
272 		}
273 
274     }
275 
276 }