1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.xnap.plugin.freeway;
21
22 import java.awt.BorderLayout;
23 import java.awt.FlowLayout;
24 import java.awt.GridBagLayout;
25 import java.awt.event.ActionEvent;
26 import java.util.ArrayList;
27
28 import javax.swing.AbstractAction;
29 import javax.swing.Action;
30 import javax.swing.JLabel;
31 import javax.swing.JPanel;
32 import javax.swing.JScrollPane;
33 import javax.swing.JTable;
34 import javax.swing.SwingUtilities;
35 import javax.swing.border.EmptyBorder;
36
37 import org.gnu.freeway.DaemonSocket;
38 import org.gnu.freeway.protocol.afs.swing.SController;
39 import org.gnu.freeway.util.CSMessage;
40 import org.gnu.freeway.util.CSReturnValue;
41 import org.gnu.freeway.util.CSStatistics;
42 import org.gnu.freeway.util.CSStatisticsRequest;
43 import org.gnu.freeway.util.ConfigurationService;
44 import org.gnu.freeway.util.CronService;
45 import org.gnu.freeway.util.Statistic;
46 import org.xnap.XNap;
47 import org.xnap.gui.ActionProvider;
48 import org.xnap.gui.component.XNapButton;
49 import org.xnap.gui.table.AbstractColumnTableModel;
50 import org.xnap.gui.table.Column;
51 import org.xnap.gui.util.GUIHelper;
52 import org.xnap.gui.util.GridBagHelper;
53 import org.xnap.gui.util.IconHelper;
54 import org.xnap.util.Formatter;
55 import org.xnap.util.Preferences;
56
57 public class FreewayPanel extends JPanel implements ActionProvider {
58
59
60
61
62
63 private JLabel jlStatus;
64 private SController controller;
65 private FreewayStatsTableModel statsTableModel;
66
67
68
69 public FreewayPanel(SController controller)
70 {
71 this.controller = controller;
72
73 initialize();
74 }
75
76
77
78 public void initialize()
79 {
80 setBorder(new EmptyBorder(5, 5, 5, 5));
81 setLayout(new GridBagLayout());
82
83 JPanel jpStatus = new JPanel(new BorderLayout());
84 GridBagHelper.add(this, jpStatus);
85 jpStatus.setBorder(GUIHelper.createDefaultBorder(XNap.tr("Status")));
86
87 jlStatus = new JLabel(XNap.tr("Unknown"));
88 jpStatus.add(jlStatus, BorderLayout.CENTER);
89
90 JPanel statsPanel = new JPanel(new BorderLayout());
91 statsPanel.setBorder
92 (GUIHelper.createDefaultBorder(XNap.tr("Statistics")));
93 GridBagHelper.addPanel(this, statsPanel);
94
95 statsTableModel = new FreewayStatsTableModel();
96 JTable statsTable = statsTableModel.createTable(Preferences.getInstance(), "freewayStats");
97 statsPanel.add(new JScrollPane(statsTable), BorderLayout.CENTER);
98
99 GridBagHelper.addVerticalSpacer(this);
100
101 JPanel jpButtons = new JPanel(new FlowLayout(FlowLayout.LEFT));
102 GridBagHelper.add(this, jpButtons);
103 jpButtons.add(new XNapButton(new UpdateAction()));
104 }
105
106 public Action[] getActions()
107 {
108 return new Action[] { new UpdateAction() };
109 }
110
111 public void updateStatus()
112 {
113 jlStatus.setText(XNap.tr("Updating statistics") + "...");
114 statsTableModel.clear();
115
116 Thread t = new Thread(new StatsRunner(), "FreewayStatsRunner");
117 t.start();
118 }
119
120 /***
121 * @param text the status message
122 */
123 private void setStatusLater(final String text)
124 {
125 Runnable runner = new Runnable()
126 {
127 public void run()
128 {
129 jlStatus.setText(text);
130 }
131 };
132 SwingUtilities.invokeLater(runner);
133 }
134
135 private class UpdateAction extends AbstractAction
136 {
137 public UpdateAction()
138 {
139 putValue(Action.NAME, XNap.tr("Update"));
140 putValue(Action.SHORT_DESCRIPTION, XNap.tr("Updates the status."));
141 putValue(IconHelper.XNAP_ICON, "undo.png");
142 }
143
144 public void actionPerformed(ActionEvent event)
145 {
146 updateStatus();
147 }
148 }
149
150 public class FreewayStatsTableModel extends AbstractColumnTableModel
151 {
152
153
154
155 private ArrayList data = new ArrayList();
156
157
158
159 public FreewayStatsTableModel()
160 {
161 Column columns[] = new Column[] {
162 new Column("key", XNap.tr("Key"), String.class),
163 new Column("value", XNap.tr("Value"), String.class),
164 };
165 addColumns(columns);
166 }
167
168 /***
169 *
170 */
171 public void clear()
172 {
173 data.clear();
174 fireTableDataChanged();
175 }
176
177
178
179 public void add(final String key, final String value)
180 {
181 Runnable runner = new Runnable()
182 {
183 public void run()
184 {
185 data.add(new Item(key, value));
186 fireTableRowsInserted(data.size() - 1, data.size() - 1);
187 }
188 };
189 SwingUtilities.invokeLater(runner);
190 }
191
192 public int getRowCount()
193 {
194 return data.size();
195 }
196
197 public Object get(int i, int j)
198 {
199 Item item = (Item)data.get(i);
200
201 switch (j) {
202 case 0:
203 return item.key;
204 case 1:
205 return item.value;
206 default:
207 return null;
208 }
209 }
210
211
212
213 private class Item
214 {
215
216 String key;
217 String value;
218
219 public Item(String key, String value)
220 {
221 this.key = key;
222 this.value = value;
223 }
224
225 }
226
227 }
228
229
230 private class StatsRunner implements Runnable {
231
232 public void run()
233 {
234 DaemonSocket socket = DaemonSocket.create
235 ((ConfigurationService)controller.service(ConfigurationService.class),
236 controller.getPreferences());
237
238 if (socket == null) {
239 setStatusLater(XNap.tr("Could not establish connection to daemon."));
240 return;
241 }
242
243 socket.getDecoder().add(CSMessage.IS_STATISTICS,CSStatistics.class);
244 socket.getDecoder().add(CSMessage.IS_RETURN,CSReturnValue.class);
245
246 if (!socket.write(new CSStatisticsRequest())) {
247 setStatusLater("Error sending request for statistics to gnunetd.");
248 return;
249 }
250
251 int count = 0;
252 int totalCounters = 1;
253 while (count < totalCounters) {
254 CSStatistics msg = (CSStatistics)socket.read(CSStatistics.class);
255 if (msg == null) {
256 setStatusLater("Error receiving reply for statistics from gnunetd.");
257 return;
258 }
259
260 if (count == 0) {
261 long t = CronService.toSeconds(CronService.time()) - msg.getStartTime();
262 setStatusLater(XNap.tr("Daemon Uptime: {0}", Formatter.formatLength(t)));
263 totalCounters = msg.getTotalCounters();
264 }
265
266 if (msg.getTotalCounters() != totalCounters) {
267 setStatusLater("Corrupted data ?");
268 return;
269 }
270
271 Statistic[] stats = msg.getStatistics();
272 for (int i = 0; i < stats.length; i++) {
273 statsTableModel.add(stats[i].getName(), "" + stats[i].get());
274 }
275 count += stats.length;
276 }
277 socket.destroy();
278 }
279
280 }
281
282 }