1 /* 2 * $Id$ 3 * 4 * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. 5 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 6 * 7 * This code is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License version 2 only, as 9 * published by the Free Software Foundation. Oracle designates this 10 * particular file as subject to the "Classpath" exception as provided 11 * by Oracle in the LICENSE file that accompanied this code. 12 * 13 * This code is distributed in the hope that it will be useful, but WITHOUT 14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 16 * version 2 for more details (a copy is included in the LICENSE file that 17 * accompanied this code). 18 * 19 * You should have received a copy of the GNU General Public License version 20 * 2 along with this work; if not, write to the Free Software Foundation, 21 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 22 * 23 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 24 * or visit www.oracle.com if you need additional information or have any 25 * questions. 26 */ 27 package com.sun.javatest.agent; 28 29 import java.awt.Component; 30 import java.awt.EventQueue; 31 import java.awt.GridBagConstraints; 32 import java.awt.GridBagLayout; 33 import java.awt.event.ItemEvent; 34 import java.awt.event.ItemListener; 35 import java.io.IOException; 36 import java.util.Enumeration; 37 import java.util.Map; 38 import javax.swing.DefaultListCellRenderer; 39 import javax.swing.DefaultListModel; 40 import javax.swing.JCheckBox; 41 import javax.swing.JLabel; 42 import javax.swing.JList; 43 import javax.swing.JMenu; 44 import javax.swing.JMenuBar; 45 import javax.swing.JPanel; 46 import javax.swing.JTextField; 47 import javax.swing.event.ListSelectionEvent; 48 import javax.swing.event.ListSelectionListener; 49 50 import com.sun.javatest.Status; 51 import com.sun.javatest.tool.Tool; 52 import com.sun.javatest.util.StringArray; 53 54 /** 55 * The "Agent Monitor" tool, which allows a user to monitor and control 56 * the agents used to help run tests. 57 */ 58 public class AgentMonitorTool extends Tool 59 { 60 /*OLD 61 static AgentMonitorTool access() { 62 if (theOne == null) 63 theOne = new AgentMonitorTool(); 64 return theOne; 65 } 66 */ 67 68 /*OLD 69 private static AgentMonitorTool theOne; 70 */ 71 72 AgentMonitorTool(AgentMonitorToolManager m) { 73 super(m, "agentMonitor", "agent.window.csh"); 74 setI18NTitle("tool.title"); 75 setShortTitle(uif.getI18NString("tool.shortTitle")); 76 setLayout(new GridBagLayout()); 77 78 menuBar = new JMenuBar(); 79 menuBar.add(uif.createHorizontalGlue("tool.glue")); 80 81 JMenu helpMenu = uif.createMenu("tool.help"); 82 helpMenu.add(uif.createHelpMenuItem("tool.help.window", "agent.window.csh")); 83 menuBar.add(helpMenu); 84 85 GridBagConstraints c = new GridBagConstraints(); 86 c.fill = GridBagConstraints.BOTH; 87 c.gridwidth = GridBagConstraints.REMAINDER; 88 c.weightx = 1; 89 c.weighty = 1; 90 91 agentPoolSubpanel = new AgentPoolSubpanel(); 92 add(agentPoolSubpanel, c); 93 94 currAgentsSubpanel = new CurrentAgentsSubpanel(); 95 add(currAgentsSubpanel, c); 96 } 97 98 public JMenuBar getMenuBar() { 99 return menuBar; 100 } 101 102 public void save(Map<String, String> m) { 103 int port = agentPoolSubpanel.getPort(); 104 if (port != Integer.MIN_VALUE) 105 m.put("port", String.valueOf(port)); 106 int timeout = agentPoolSubpanel.getTimeout(); 107 if (timeout != Integer.MIN_VALUE) 108 m.put("timeout", String.valueOf(timeout)); 109 m.put("listening", String.valueOf(agentPoolSubpanel.isListening())); 110 } 111 112 /** 113 * Restore an AgentMonitorTool from its saved state. 114 * @param m The map containing the saved data 115 * @return An AgentMonitorTool restored from the data in the map. 116 */ 117 @Override 118 protected void restore(Map<String, String> m) { 119 String l = m.get("listening"); 120 try { 121 String p = m.get("port"); 122 if (p != null && p.length() != 0) 123 agentPoolSubpanel.setPort(Integer.parseInt(p)); 124 125 String t = m.get("timeout"); 126 if (t != null && t.length() != 0) 127 agentPoolSubpanel.setTimeout(Integer.parseInt(t)); 128 129 if (l != null && l.length() != 0) 130 agentPoolSubpanel.setListening(l.equals("true")); 131 } 132 catch (NumberFormatException ignore) { 133 } 134 } 135 136 private AgentManager agentManager = AgentManager.access(); 137 private ActiveAgentPool activeAgentPool = agentManager.getActiveAgentPool(); 138 private JMenuBar menuBar; 139 private AgentPoolSubpanel agentPoolSubpanel; 140 private CurrentAgentsSubpanel currAgentsSubpanel; 141 142 //----------nested classes------------------------------------------------------- 143 144 private class AgentPoolSubpanel extends JPanel 145 implements ItemListener, ActiveAgentPool.Observer 146 { 147 AgentPoolSubpanel() { 148 setName("tool.pool"); 149 setBorder(uif.createTitledBorder("tool.pool")); 150 setLayout(new GridBagLayout()); 151 uif.setAccessibleDescription(this, "tool.pool"); 152 153 GridBagConstraints lc = new GridBagConstraints(); 154 GridBagConstraints fc = new GridBagConstraints(); 155 fc.insets.right = 10; 156 157 listeningCheck = uif.createCheckBox("tool.pool.listen", false); 158 listeningCheck.setSelected(activeAgentPool.isListening()); 159 listeningCheck.addItemListener(this); 160 add(listeningCheck, fc); 161 162 portLabel = uif.createLabel("tool.pool.port", true); 163 add(portLabel, lc); 164 portField = uif.createInputField("tool.pool.port", 6); 165 portField.setText(String.valueOf(activeAgentPool.getPort())); 166 add(portField, fc); 167 portLabel.setLabelFor(portField); 168 169 timeoutLabel = uif.createLabel("tool.pool.timeout", true); 170 add(timeoutLabel, lc); 171 timeoutField = uif.createInputField("tool.pool.timeout", 6); 172 // agentMgr API is in msec; field is in seconds 173 int t = activeAgentPool.getTimeout(); // round to nearest second 174 timeoutField.setText(String.valueOf((t + 500)/1000)); 175 fc.anchor = GridBagConstraints.WEST; 176 fc.gridwidth = GridBagConstraints.REMAINDER; 177 fc.weightx = 1; 178 add(timeoutField, fc); 179 timeoutLabel.setLabelFor(timeoutField); 180 181 listData = new DefaultListModel<>(); 182 list = uif.createList("tool.pool", listData); 183 list.setPrototypeCellValue("abcdefghiklmnopqrstuvwxyz"); 184 list.setVisibleRowCount(3); 185 GridBagConstraints c = new GridBagConstraints(); 186 c.fill = GridBagConstraints.BOTH; 187 c.gridwidth = GridBagConstraints.REMAINDER; 188 c.weightx = 1; 189 c.weighty = 1; 190 add(uif.createScrollPane(list), c); 191 192 // Ensure any existing entries in the pool are displayed 193 // Note there is a slight synchronization window between the call of 194 // elements and that of addObserver. 195 for (Enumeration<Connection> e = activeAgentPool.elements(); e.hasMoreElements(); ) { 196 Connection conn = e.nextElement(); 197 listData.addElement(conn.getName()); 198 } 199 200 activeAgentPool.addObserver(this); 201 enableFields(); 202 } 203 204 public void itemStateChanged(ItemEvent e) { 205 if (e.getItemSelectable() == listeningCheck) { 206 try { 207 if (e.getStateChange() == ItemEvent.SELECTED) { 208 try { 209 int timeout = Integer.parseInt(timeoutField.getText()); 210 211 if (timeout <= 0) { 212 throw new NumberFormatException(); 213 } 214 215 // field is in seconds; agentMgr API is in msec 216 activeAgentPool.setTimeout(timeout*1000); 217 } catch (NumberFormatException ex) { 218 uif.showError("tool.badTimeout"); 219 return; 220 } 221 222 try { 223 int port = Integer.parseInt(portField.getText()); 224 activeAgentPool.setPort(port); 225 226 if (port < 0) { 227 throw new NumberFormatException(); 228 } 229 } 230 catch (NumberFormatException ex) { 231 uif.showError("tool.badPort"); 232 return; 233 } 234 235 try { 236 activeAgentPool.setListening(true); 237 } 238 catch (IOException ex) { 239 uif.showError("tool.listenOn", ex); 240 return; 241 } 242 } 243 else { 244 try { 245 activeAgentPool.setListening(false); 246 } 247 catch (IOException ex) { 248 uif.showError("tool.listenOff", ex); 249 return; 250 } 251 } 252 } 253 finally { 254 boolean b = activeAgentPool.isListening(); 255 if (b != listeningCheck.isSelected()) 256 listeningCheck.setSelected(b); 257 258 enableFields(); 259 } 260 } 261 } 262 263 public void addedToPool(final Connection c) { 264 // item must match that used in removedFromAgentPool 265 if (!EventQueue.isDispatchThread()) { 266 Runnable cmd = new Runnable() { 267 public void run() { 268 AgentMonitorTool.AgentPoolSubpanel.this.addedToPool(c); 269 } // run() 270 }; // end anon. class 271 272 EventQueue.invokeLater(cmd); 273 } 274 else { 275 listData.addElement(c.getName()); 276 } 277 } 278 279 public void removedFromPool(final Connection c) { 280 // item must match that used in addedToAgentPool 281 if (!EventQueue.isDispatchThread()) { 282 Runnable cmd = new Runnable() { 283 public void run() { 284 AgentMonitorTool.AgentPoolSubpanel.this.removedFromPool(c); 285 } // run() 286 }; // end anon. class 287 288 EventQueue.invokeLater(cmd); 289 } 290 else { 291 listData.removeElement(c.getName()); 292 } 293 } 294 295 boolean isListening() { 296 return listeningCheck.isSelected(); 297 } 298 299 void setListening(boolean b) { 300 listeningCheck.setSelected(b); 301 } 302 303 int getPort() { 304 try { 305 return Integer.parseInt(portField.getText()); 306 } 307 catch (NumberFormatException ex) { 308 return Integer.MIN_VALUE; 309 } 310 } 311 312 void setPort(int port) { 313 portField.setText(String.valueOf(port)); 314 } 315 316 int getTimeout() { 317 try { 318 return Integer.parseInt(timeoutField.getText()); 319 } 320 catch (NumberFormatException ex) { 321 return Integer.MIN_VALUE; 322 } 323 } 324 325 void setTimeout(int timeout) { 326 timeoutField.setText(String.valueOf(timeout)); 327 } 328 329 private void enableFields() { 330 boolean enable = !listeningCheck.isSelected(); 331 portLabel.setEnabled(enable); 332 portField.setEnabled(enable); 333 timeoutLabel.setEnabled(enable); 334 timeoutField.setEnabled(enable); 335 } 336 337 private JCheckBox listeningCheck; 338 private JLabel portLabel; 339 private JTextField portField; 340 private JLabel timeoutLabel; 341 private JTextField timeoutField; 342 private JList<String> list; 343 private DefaultListModel<String> listData; 344 } 345 346 private class CurrentAgentsSubpanel extends JPanel 347 implements ListSelectionListener, AgentManager.Observer 348 { 349 CurrentAgentsSubpanel() { 350 setName("tool.curr"); 351 setBorder(uif.createTitledBorder("tool.curr")); 352 setLayout(new GridBagLayout()); 353 uif.setToolTip(this, "tool.curr"); 354 355 listData = new DefaultListModel<>(); 356 list = uif.createList("tool.list.curr", listData); 357 list.setVisibleRowCount(5); 358 359 list.setCellRenderer(new DefaultListCellRenderer() { 360 public Component getListCellRendererComponent(JList<?> list, Object o, int index, boolean isSelected, boolean cellHasFocus) { 361 String name = o.toString(); 362 return super.getListCellRendererComponent(list, name, index, isSelected, cellHasFocus); 363 } 364 }); 365 366 list.addListSelectionListener(this); 367 368 GridBagConstraints c = new GridBagConstraints(); 369 c.fill = GridBagConstraints.BOTH; 370 c.gridwidth = GridBagConstraints.REMAINDER; 371 c.insets.bottom = 5; 372 c.weightx = 1; 373 c.weighty = 1; 374 add(uif.createScrollPane(list), c); 375 376 GridBagConstraints lc = new GridBagConstraints(); 377 lc.gridwidth = 1; 378 lc.weightx = 0; 379 lc.anchor = GridBagConstraints.EAST; 380 lc.insets.right = 5; 381 382 GridBagConstraints fc = new GridBagConstraints(); 383 fc.gridwidth = GridBagConstraints.REMAINDER; 384 fc.weightx = 1; 385 fc.anchor = GridBagConstraints.WEST; 386 fc.fill = GridBagConstraints.HORIZONTAL; 387 388 addressLabel = uif.createLabel("tool.curr.address", true); 389 add(addressLabel, lc); 390 addressField = uif.createOutputField("tool.curr.address", addressLabel); 391 add(addressField, fc); 392 393 tagLabel = uif.createLabel("tool.curr.tag", true); 394 add(tagLabel, lc); 395 tagField = uif.createOutputField("tool.curr.tag", tagLabel); 396 add(tagField, fc); 397 398 requestLabel = uif.createLabel("tool.curr.request", true); 399 add(requestLabel, lc); 400 requestField = uif.createOutputField("tool.curr.request", requestLabel); 401 add(requestField, fc); 402 403 execLabel = uif.createLabel("tool.curr.execute", true); 404 add(execLabel, lc); 405 execField = uif.createOutputField("tool.curr.execute", execLabel); 406 add(execField, fc); 407 408 argsLabel = uif.createLabel("tool.curr.args", true); 409 add(argsLabel, lc); 410 argsField = uif.createOutputField("tool.curr.args", argsLabel); 411 add(argsField, fc); 412 413 add(uif.createGlue("tool.curr.pad"), lc); 414 fc.fill = GridBagConstraints.VERTICAL; 415 fc.weightx = 0; 416 fc.anchor = GridBagConstraints.WEST; 417 localizeArgsCheck = uif.createCheckBox("tool.mapArgs", false); 418 add(localizeArgsCheck, fc); 419 420 agentManager.addObserver(this); 421 } 422 423 public synchronized void valueChanged(ListSelectionEvent ev) { 424 Entry e = list.getSelectedValue(); 425 if (e == null) { 426 addressField.setText(""); 427 tagField.setText(""); 428 requestField.setText(""); 429 execField.setText(""); 430 argsField.setText(""); 431 localizeArgsCheck.setSelected(false); 432 selectedEntry = null; 433 } 434 else { 435 addressField.setText(e.connection.getName()); 436 tagField.setText(e.tag); 437 requestField.setText(e.request); 438 execField.setText(e.executable); 439 argsField.setText(StringArray.join(e.args)); 440 localizeArgsCheck.setSelected(e.localizeArgs); 441 selectedEntry = e; 442 } 443 } 444 445 public synchronized void started(final Connection c, 446 final String tag, final String request, final String executable, 447 final String[] args, final boolean localizeArgs) { 448 if (!EventQueue.isDispatchThread()) { 449 Runnable cmd = new Runnable() { 450 public void run() { 451 AgentMonitorTool.CurrentAgentsSubpanel.this.started(c, tag, request, executable, args, localizeArgs); 452 } // run() 453 }; // end anon. class 454 455 EventQueue.invokeLater(cmd); 456 } 457 else 458 listData.addElement(new Entry(c, tag, request, executable, args, localizeArgs)); 459 } 460 461 public synchronized void finished(final Connection c, final Status status) { 462 if (!EventQueue.isDispatchThread()) { 463 Runnable cmd = new Runnable() { 464 public void run() { 465 AgentMonitorTool.CurrentAgentsSubpanel.this.finished(c, status); 466 } // run() 467 }; // end anon. class 468 469 EventQueue.invokeLater(cmd); 470 } 471 else { 472 for (int i = 0; i < listData.size(); i++) { 473 Entry e = listData.elementAt(i); 474 if (e.connection == c) { 475 listData.removeElement(e); 476 break; 477 } 478 } // for 479 } // else 480 } 481 482 private class Entry { 483 Entry(Connection connection, 484 String tag, String request, String executable, String[] args, 485 boolean localizeArgs) { 486 this.connection = connection; 487 this.tag = tag; 488 this.request = request; 489 this.executable = executable; 490 this.args = args; 491 this.localizeArgs = localizeArgs; 492 } 493 494 public String toString() { 495 return uif.getI18NString("tool.entry", 496 new Object[] {connection.getName(), tag}); 497 } 498 499 Connection connection; 500 String tag; 501 String request; 502 String executable; 503 String[] args; 504 boolean localizeArgs; 505 } 506 507 private JList<Entry> list; 508 private DefaultListModel<Entry> listData; 509 private Entry selectedEntry; 510 private JLabel addressLabel; 511 private JTextField addressField; 512 private JLabel tagLabel; 513 private JTextField tagField; 514 private JLabel requestLabel; 515 private JTextField requestField; 516 private JLabel execLabel; 517 private JTextField execField; 518 private JLabel argsLabel; 519 private JTextField argsField; 520 private JCheckBox localizeArgsCheck; 521 } 522 }