       1 /*
       2  * $Id$
       3  *
       4  * Copyright (c) 2001, 2013, 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 list;
     343         private DefaultListModel 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 = ((Entry)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 = (Entry)(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 = (Entry)(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 list;
     508         private DefaultListModel 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 }