File Source: LagDisplayPlugin.java
/*
P/P * Method: com.dmdirc.addons.lagdisplay.LagDisplayPlugin__static_init
*/
1 /*
2 * Copyright (c) 2006-2009 Chris Smith, Shane Mc Cormack, Gregory Holmes
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 * SOFTWARE.
21 */
22
23 package com.dmdirc.addons.lagdisplay;
24
25 import com.dmdirc.FrameContainer;
26 import com.dmdirc.Main;
27 import com.dmdirc.Server;
28 import com.dmdirc.ServerState;
29 import com.dmdirc.actions.ActionManager;
30 import com.dmdirc.actions.interfaces.ActionType;
31 import com.dmdirc.actions.CoreActionType;
32 import com.dmdirc.config.ConfigManager;
33 import com.dmdirc.config.IdentityManager;
34 import com.dmdirc.config.prefs.PreferencesCategory;
35 import com.dmdirc.config.prefs.PreferencesManager;
36 import com.dmdirc.config.prefs.PreferencesSetting;
37 import com.dmdirc.config.prefs.PreferencesType;
38 import com.dmdirc.interfaces.ActionListener;
39 import com.dmdirc.interfaces.ConfigChangeListener;
40 import com.dmdirc.plugins.Plugin;
41 import com.dmdirc.ui.interfaces.Window;
42 import com.dmdirc.util.RollingList;
43
44 import java.util.Date;
45 import java.util.HashMap;
46 import java.util.Map;
47 import java.util.WeakHashMap;
48
49 /**
50 * Displays the current server's lag in the status bar.
51 * @author chris
52 */
53 public final class LagDisplayPlugin extends Plugin implements ActionListener, ConfigChangeListener {
54
55 /** The panel we use in the status bar. */
56 private final LagDisplayPanel panel = new LagDisplayPanel(this);
57
58 /** A cache of ping times. */
59 private final Map<Server, String> pings = new WeakHashMap<Server, String>();
60
61 /** Ping history. */
62 private final Map<Server, RollingList<Long>> history
63 = new HashMap<Server, RollingList<Long>>();
64
65 /** Whether or not to show a graph in the info popup. */
66 private boolean showGraph = true;
67
68 /** Whether or not to show labels on that graph. */
69 private boolean showLabels = true;
70
71 /** The length of history to keep per-server. */
72 private int historySize = 100;
73
74 /** Creates a new instance of LagDisplayPlugin. */
75 public LagDisplayPlugin() {
/*
P/P * Method: void com.dmdirc.addons.lagdisplay.LagDisplayPlugin()
*
* Postconditions:
* this.history == &new HashMap(LagDisplayPlugin#3)
* this.historySize == 100
* this.panel == &new LagDisplayPanel(LagDisplayPlugin#1)
* this.pings == &new WeakHashMap(LagDisplayPlugin#2)
* this.showGraph == 1
* this.showLabels == 1
* new HashMap(LagDisplayPlugin#3) num objects == 1
* new LagDisplayPanel(LagDisplayPlugin#1) num objects == 1
* new WeakHashMap(LagDisplayPlugin#2) num objects == 1
* this.panel.plugin == this
* ...
*/
76 super();
77 }
78
79 /** {@inheritDoc} */
80 @Override
81 public void onLoad() {
/*
P/P * Method: void onLoad()
*
* Preconditions:
* com/dmdirc/Main.controller != null
*
* Presumptions:
* com.dmdirc.config.IdentityManager:getGlobalConfig(...)@83 != null
* com.dmdirc.ui.interfaces.UIController:getStatusBar(...)@82 != null
*
* Postconditions:
* init'ed(this.historySize)
* init'ed(this.showGraph)
* init'ed(this.showLabels)
*/
82 Main.getUI().getStatusBar().addComponent(panel);
83 IdentityManager.getGlobalConfig().addChangeListener(getDomain(), this);
84
85 readConfig();
86
87 ActionManager.addListener(this, CoreActionType.SERVER_GOTPING,
88 CoreActionType.SERVER_NOPING, CoreActionType.CLIENT_FRAME_CHANGED,
89 CoreActionType.SERVER_DISCONNECTED, CoreActionType.SERVER_PINGSENT,
90 CoreActionType.SERVER_NUMERIC);
91 }
92
93 /**
94 * Reads the plugin's global configuration settings.
95 */
96 protected void readConfig() {
/*
P/P * Method: void readConfig()
*
* Presumptions:
* com.dmdirc.config.IdentityManager:getGlobalConfig(...)@97 != null
*
* Postconditions:
* init'ed(this.historySize)
* init'ed(this.showGraph)
* init'ed(this.showLabels)
*/
97 final ConfigManager manager = IdentityManager.getGlobalConfig();
98 showGraph = manager.getOptionBool(getDomain(), "graph");
99 showLabels = manager.getOptionBool(getDomain(), "labels");
100 historySize = manager.getOptionInt(getDomain(), "history");
101 }
102
103 /**
104 * Retrieves the history of the specified server. If there is no history,
105 * a new list is added to the history map and returned.
106 *
107 * @param server The server whose history is being requested
108 * @return The history for the specified server
109 */
110 protected RollingList<Long> getHistory(final Server server) {
/*
P/P * Method: RollingList getHistory(Server)
*
* Preconditions:
* this.history != null
* (soft) init'ed(this.historySize)
*
* Postconditions:
* init'ed(return_value)
*
* Test Vectors:
* java.util.Map:containsKey(...)@111: {1}, {0}
*/
111 if (!history.containsKey(server)) {
112 history.put(server, new RollingList<Long>(historySize));
113 }
114
115 return history.get(server);
116 }
117
118 /**
119 * Determines if the {@link ServerInfoDialog} should show a graph of the
120 * ping time for the current server.
121 *
122 * @return True if a graph should be shown, false otherwise
123 */
124 public boolean shouldShowGraph() {
/*
P/P * Method: bool shouldShowGraph()
*
* Preconditions:
* init'ed(this.showGraph)
*
* Postconditions:
* return_value == this.showGraph
* init'ed(return_value)
*/
125 return showGraph;
126 }
127
128 /**
129 * Determines if the {@link PingHistoryPanel} should show labels on selected
130 * points.
131 *
132 * @return True if labels should be shown, false otherwise
133 */
134 public boolean shouldShowLabels() {
/*
P/P * Method: bool shouldShowLabels()
*
* Preconditions:
* init'ed(this.showLabels)
*
* Postconditions:
* return_value == this.showLabels
* init'ed(return_value)
*/
135 return showLabels;
136 }
137
138 /** {@inheritDoc} */
139 @Override
140 public void onUnload() {
/*
P/P * Method: void onUnload()
*
* Preconditions:
* com/dmdirc/Main.controller != null
*
* Presumptions:
* com.dmdirc.config.IdentityManager:getConfigIdentity(...)@142 != null
* com.dmdirc.ui.interfaces.UIController:getStatusBar(...)@141 != null
*/
141 Main.getUI().getStatusBar().removeComponent(panel);
142 IdentityManager.getConfigIdentity().removeListener(this);
143
144 ActionManager.removeListener(this);
145 }
146
147 /** {@inheritDoc} */
148 @Override
149 public void processEvent(final ActionType type, final StringBuffer format,
150 final Object... arguments) {
/*
P/P * Method: void processEvent(ActionType, StringBuffer, Object[])
*
* Preconditions:
* arguments != null
* type != null
* (soft) arguments.length in {3..232-1}
* (soft) arguments[0] != null
* (soft) arguments[0].channels != null
* (soft) arguments[0].parser != null
* (soft) arguments[0].queries != null
* (soft) init'ed(arguments[0].raw)
* (soft) init'ed(arguments[0].window)
* (soft) arguments[1] != null
* ...
*
* Presumptions:
* getServer(...).myState@198 != null
* getServer(...)@198 != null
* java.lang.Long:valueOf(...)@212 != null
* java.util.Date:getTime(...)@212 - java.lang.Long:parseLong(...)@211 in {-263..264-1}
* java.util.Map:get(...)@115 != null
*
* Test Vectors:
* arguments[...].config: Addr_Set{null}, Inverse{null}
* format: Addr_Set{null}, Inverse{null}
* getServer(...).myState.state@198: Addr_Set{&com.dmdirc.ServerState__static_init.new ServerState(ServerState__static_init#3)}, Inverse{&com.dmdirc.ServerState__static_init.new ServerState(ServerState__static_init#3)}
* getServer(...)@196: Inverse{null}, Addr_Set{null}
* java.lang.Integer:intValue(...)@207: {-231..420, 422..232-1}, {421}
* java.lang.Object:equals(...)@162: {0}, {1}
* java.lang.Object:equals(...)@174: {0}, {1}
* java.lang.Object:equals(...)@185: {0}, {1}
* java.lang.Object:equals(...)@194: {0}, {1}
* java.lang.Object:equals(...)@205: {0}, {1}
* ...
*/
151 boolean useAlternate = false;
152
153 for (Object obj : arguments) {
154 if (obj instanceof FrameContainer
155 && ((FrameContainer) obj).getConfigManager() != null) {
156 useAlternate = ((FrameContainer) obj).getConfigManager()
157 .getOptionBool(getDomain(), "usealternate");
158 break;
159 }
160 }
161
162 if (!useAlternate && type.equals(CoreActionType.SERVER_GOTPING)) {
163 final Window active = Main.getUI().getActiveWindow();
164 final String value = formatTime(arguments[1]);
165
166 getHistory(((Server) arguments[0])).add((Long) arguments[1]);
167 pings.put(((Server) arguments[0]), value);
168
169 if (((Server) arguments[0]).ownsFrame(active)) {
170 panel.setText(value);
171 }
172
173 panel.refreshDialog();
174 } else if (!useAlternate && type.equals(CoreActionType.SERVER_NOPING)) {
175 final Window active = Main.getUI().getActiveWindow();
176 final String value = formatTime(arguments[1]) + "+";
177
178 pings.put(((Server) arguments[0]), value);
179
180 if (((Server) arguments[0]).ownsFrame(active)) {
181 panel.setText(value);
182 }
183
184 panel.refreshDialog();
185 } else if (type.equals(CoreActionType.SERVER_DISCONNECTED)) {
186 final Window active = Main.getUI().getActiveWindow();
187
188 if (((Server) arguments[0]).ownsFrame(active)) {
189 panel.setText("Not connected");
190 pings.remove(arguments[0]);
191 }
192
193 panel.refreshDialog();
194 } else if (type.equals(CoreActionType.CLIENT_FRAME_CHANGED)) {
195 final FrameContainer source = (FrameContainer) arguments[0];
196 if (source.getServer() == null) {
197 panel.setText("Unknown");
198 } else if (source.getServer().getState() != ServerState.CONNECTED) {
199 panel.setText("Not connected");
200 } else {
201 panel.setText(getTime(source.getServer()));
202 }
203
204 panel.refreshDialog();
205 } else if (useAlternate && type.equals(CoreActionType.SERVER_PINGSENT)) {
206 ((Server) arguments[0]).getParser().sendLine("LAGCHECK_" + new Date().getTime());
207 } else if (useAlternate && type.equals(CoreActionType.SERVER_NUMERIC)
208 && ((Integer) arguments[1]).intValue() == 421
209 && ((String[]) arguments[2])[3].startsWith("LAGCHECK_")) {
210 try {
211 final long sent = Long.parseLong(((String[]) arguments[2])[3].substring(9));
212 final Long duration = Long.valueOf(new Date().getTime() - sent);
213 final String value = formatTime(duration);
214 final Window active = Main.getUI().getActiveWindow();
215
216 pings.put((Server) arguments[0], value);
217 getHistory(((Server) arguments[0])).add(duration);
218
219 if (((Server) arguments[0]).ownsFrame(active)) {
220 panel.setText(value);
221 }
222 } catch (NumberFormatException ex) {
223 pings.remove((Server) arguments[0]);
224 }
225
226 if (format != null) {
227 format.delete(0, format.length());
228 }
229
230 panel.refreshDialog();
231 }
232 }
233
234 /**
235 * Retrieves the ping time for the specified server.
236 *
237 * @param server The server whose ping time is being requested
238 * @return A String representation of the current lag, or "Unknown"
239 */
240 public String getTime(final Server server) {
/*
P/P * Method: String getTime(Server)
*
* Preconditions:
* this.pings != null
*
* Postconditions:
* init'ed(return_value)
*/
241 return pings.get(server) == null ? "Unknown" : pings.get(server);
242 }
243
244 /**
245 * Formats the specified time so it's a nice size to display in the label.
246 * @param object An uncast Long representing the time to be formatted
247 * @return Formatted time string
248 */
249 protected String formatTime(final Object object) {
/*
P/P * Method: String formatTime(Object)
*
* Preconditions:
* object != null
*
* Postconditions:
* java.lang.StringBuilder:toString(...)._tainted == 0
* init'ed(java.lang.StringBuilder:toString(...)._tainted)
* return_value in Addr_Set{&java.lang.StringBuilder:toString(...),&java.lang.StringBuilder:toString(...)}
*
* Test Vectors:
* java.lang.Long:longValue(...)@252: {-263..9_999}, {10_000..264-1}
*/
250 final Long time = (Long) object;
251
252 if (time >= 10000) {
253 return Math.round(time / 1000.0) + "s";
254 } else {
255 return time + "ms";
256 }
257 }
258
259 /** {@inheritDoc} */
260 @Override
261 public void showConfig(final PreferencesManager manager) {
/*
P/P * Method: void showConfig(PreferencesManager)
*
* Preconditions:
* manager != null
*
* Presumptions:
* com.dmdirc.config.prefs.PreferencesManager:getCategory(...)@277 != null
* init'ed(com.dmdirc.config.prefs.PreferencesType.BOOLEAN)
* init'ed(com.dmdirc.config.prefs.PreferencesType.INTEGER)
*/
262 final PreferencesCategory cat = new PreferencesCategory("Lag display plugin",
263 "");
264 cat.addSetting(new PreferencesSetting(PreferencesType.BOOLEAN,
265 getDomain(), "usealternate",
266 "Alternate method", "Use an alternate method of determining "
267 + "lag which bypasses bouncers or proxies that may reply?"));
268 cat.addSetting(new PreferencesSetting(PreferencesType.BOOLEAN,
269 getDomain(), "graph", "Show graph", "Show a graph of ping times " +
270 "for the current server in the information popup?"));
271 cat.addSetting(new PreferencesSetting(PreferencesType.BOOLEAN,
272 getDomain(), "labels", "Show labels", "Show labels on selected " +
273 "points on the ping graph?"));
274 cat.addSetting(new PreferencesSetting(PreferencesType.INTEGER,
275 getDomain(), "history", "Graph points", "Number of data points " +
276 "to plot on the graph, if enabled."));
277 manager.getCategory("Plugins").addSubCategory(cat);
278 }
279
280 /** {@inheritDoc} */
281 @Override
282 public void configChanged(final String domain, final String key) {
/*
P/P * Method: void configChanged(String, String)
*
* Postconditions:
* init'ed(this.historySize)
* init'ed(this.showGraph)
* init'ed(this.showLabels)
*/
283 readConfig();
284 }
285 }
SofCheck Inspector Build Version : 2.17854
| LagDisplayPlugin.java |
2009-Jun-25 01:54:24 |
| LagDisplayPlugin.class |
2009-Sep-02 17:04:15 |