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 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 m) {
 119         String l = (String) (m.get("listening"));
 120         try {
 121             String p = (String) (m.get("port"));
 122             if (p != null && p.length() != 0)
 123                 agentPoolSubpanel.setPort(Integer.parseInt(p));
 124 
 125             String t = (String) (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 e = activeAgentPool.elements(); e.hasMoreElements(); ) {
 196                 Connection conn = (Connection)(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 }