1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.xnap.plugin.overnet.net;
21
22 import java.awt.event.ActionEvent;
23 import java.util.*;
24
25 import javax.swing.Action;
26 import javax.swing.JOptionPane;
27 import javax.swing.AbstractAction;
28 import javax.swing.Icon;
29
30 import org.apache.log4j.Logger;
31 import org.xnap.XNap;
32 import org.xnap.gui.*;
33 import org.xnap.gui.action.AbstractDownloadAction;
34 import org.xnap.peer.Peer;
35 import org.xnap.plugin.Plugin;
36 import org.xnap.plugin.overnet.OvernetPlugin;
37 import org.xnap.plugin.overnet.net.msg.client.DownloadLinkMessage;
38 import org.xnap.plugin.overnet.net.msg.core.SearchResultMessage;
39 import org.xnap.search.AbstractSearchResult;
40 import org.xnap.search.AbstractSearchResultContainer;
41 import org.xnap.search.SearchResult;
42 import org.xnap.search.SearchResultContainer;
43 import org.xnap.util.Formatter;
44 import org.xnap.gui.util.*;
45
46 public class OvernetSearchResult extends AbstractSearchResult
47 {
48
49
50
51
52 private String filename;
53 private int filesize;
54 private byte[] hash;
55 private int availability;
56
57 private static Logger logger = Logger.getLogger(OvernetSearchResult.class);
58
59
60
61 public OvernetSearchResult(SearchResultMessage sm)
62 {
63 filename = sm.filename;
64 filesize = sm.filesize;
65 hash = sm.hash;
66 availability = sm.availability;
67
68 put(XNap.tr("Filesize"), Formatter.formatSize(sm.filesize));
69 put(XNap.tr("Hash"), hashToString(sm.hash));
70 put(XNap.tr("Availability"), new Integer(sm.availability));
71 put(XNap.tr("Bitrate"), new Integer(sm.bitrate));
72 put(XNap.tr("Artist"), sm.artist);
73 put(XNap.tr("Title"), sm.title);
74 put(XNap.tr("Album"), sm.album);
75 put(XNap.tr("Length"), sm.length);
76 put(XNap.tr("Codec"), sm.codec);
77 put(XNap.tr("File Format"), sm.format);
78 }
79
80
81
82 public boolean canGroup(SearchResult result)
83 {
84 if (result instanceof OvernetSearchResult) {
85 OvernetSearchResult os = (OvernetSearchResult)result;
86 return Arrays.equals(hash, os.hash);
87 }
88 return false;
89 }
90
91 public SearchResultContainer createContainer()
92 {
93 return new OvernetSearchResultContainer(this);
94 }
95
96 public Action[] getActions()
97 {
98 return new Action[] { new OvernetDownloadAction(),
99 new OvernetDownloadAsAction()
100 };
101 }
102
103 public int getAvailability()
104 {
105 return availability;
106 }
107
108 public int getSourcesCount()
109 {
110 return availability;
111 }
112
113 public String getFilename()
114 {
115 return filename;
116 }
117
118 public long getFilesize()
119 {
120 return filesize;
121 }
122
123 public Object getHash()
124 {
125 return hashToString(hash);
126 }
127
128 public Icon getIcon()
129 {
130 return OvernetPlugin.ICON_16;
131 }
132
133 public Plugin getPlugin()
134 {
135 return OvernetPlugin.getInstance();
136 }
137
138 public Peer getPeer()
139 {
140 return null;
141 }
142
143 /***
144 * Converts a byte array to a string representation using base 16 and
145 * capital letters.
146 *
147 * @param hash the array to convert
148 * @return a string of length <code>2 * hash.length</code>
149 */
150 private String hashToString(byte[] hash)
151 {
152 char[] digits = new char[] { '0', '1', '2', '3', '4', '5', '6', '7',
153 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
154 StringBuffer sb = new StringBuffer(2 * hash.length);
155 for (int i = 0; i < hash.length; i++) {
156 sb.append(digits[(hash[i] & 0xF0) >> 4]);;
157 sb.append(digits[(hash[i] & 0x0F)]);
158 }
159 return sb.toString();
160 }
161
162 private class OvernetSearchResultContainer
163 extends AbstractSearchResultContainer
164 {
165 private OvernetSearchResult os;
166
167 public OvernetSearchResultContainer(OvernetSearchResult os)
168 {
169 this.os = os;
170 }
171
172 /***
173 * Discards search results having the same file name, they don't
174 * provide any new information to the user.
175 */
176 public boolean add(SearchResult result)
177 {
178 for (Iterator i = iterator(); i.hasNext();) {
179 SearchResult sr = (SearchResult)i.next();
180 if (sr.getFilename().equals(result.getFilename())) {
181 return false;
182 }
183 }
184 return super.add(result);
185 }
186
187 public Action[] getActions()
188 {
189 return new Action[] { new OvernetDownloadAction(),
190 new OvernetDownloadAsAction()
191 };
192 }
193 }
194
195 private class OvernetDownloadAction extends AbstractDownloadAction
196 {
197 public void actionPerformed(ActionEvent e)
198 {
199 DownloadLinkMessage dm =
200 new DownloadLinkMessage(hash, filesize, filename);
201 OvernetCore.send(dm);
202 FocusManager.setFocusTo("transfer", e);
203 }
204 }
205
206 private class OvernetDownloadAsAction extends AbstractAction
207 {
208 public OvernetDownloadAsAction()
209 {
210 putValue(Action.NAME, XNap.tr("Download as") + "...");
211 putValue(IconHelper.XNAP_ICON, "down.png");
212 }
213
214 public void actionPerformed(ActionEvent e)
215 {
216 String name = JOptionPane.showInputDialog
217 (XNapFrame.getInstance(),
218 XNap.tr("Save Download As:"),
219 filename);
220
221 if (name != null) {
222 DownloadLinkMessage dm =
223 new DownloadLinkMessage(hash, filesize, name);
224 OvernetCore.send(dm);
225 FocusManager.setFocusTo("transfer", e);
226 }
227 }
228 }
229
230 }