1 /*
   2  * $Id$
   3  *
   4  * Copyright (c) 1996, 2014, 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.applet.Applet;
  30 import java.applet.AppletContext;
  31 import java.awt.Component;
  32 import java.awt.Container;
  33 import java.awt.Frame;
  34 import java.awt.GridBagConstraints;
  35 import java.awt.GridBagLayout;
  36 import java.awt.GridLayout;
  37 import java.awt.Label;
  38 import java.awt.Panel;
  39 import java.io.IOException;
  40 import java.lang.reflect.InvocationTargetException;
  41 import java.lang.reflect.Method;
  42 import java.net.URL;
  43 
  44 import com.sun.javatest.Status;
  45 import com.sun.javatest.util.MainAppletContext;
  46 import com.sun.javatest.util.MainFrame;
  47 
  48 /**
  49  * An applet that displays and controls a Agent.
  50  *
  51  * @see Agent
  52  * @see AgentMain
  53  * @see AgentFrame
  54  *
  55  **/
  56 public class AgentApplet extends Applet implements Agent.Observer
  57 {
  58 
  59     /**
  60      * Initialize the applet, based on the applet parameters.
  61      *
  62      * The following applet parameters are recognized
  63      * <table>
  64      * <tr><td>mode        <em>mode</em>        <td> set mode to be "active" or "passive"
  65      * <tr><td>activeHost  <em>hostname</em>    <td> set the host for active connections
  66      * <tr><td>activePort  <em>port</em>        <td> set the port for active connections
  67      * <tr><td>passivePort <em>port</em>        <td> set the port for passive connections
  68      * <tr><td>map         <em>url</em>         <td> map file for translating arguments of incoming requests; the url is relative to the applet's document base
  69      * <tr><td>concurrency <em>number</em>      <td> set the maximum number of simultaneous connections
  70      * <tr><td>history     <em>number</em>      <td> set the size of the execution history
  71      * <tr><td>trace       <em>boolean</em>     <td> trace the execution of the agent
  72      * <tr><td>observer    <em>classname</em>   <td> add an observer to the agent that is used
  73      * </table>
  74      */
  75     public void init() {
  76 
  77         String mode = getParameter("mode", "active");
  78         URL docBase = getDocumentBase(); // may be null if run standalone, sigh
  79         String defaultActiveHost = (docBase == null ? "localhost" : docBase.getHost());
  80         String activeHost = getParameter("activeHost", defaultActiveHost);
  81         int activePort = getIntParameter("activePort", Agent.defaultActivePort);
  82         int passivePort = getIntParameter("passivePort", Agent.defaultPassivePort);
  83         String serialPort = getParameter("serialPort");
  84         int concurrency = getIntParameter("concurrency", 1);
  85         int history = getIntParameter("history", -1);
  86         int delay = getIntParameter("retryDelay", -1);
  87         String mapFile = getParameter("map");
  88         String usac = getParameter("useSharedAppletContext");
  89         shareAppletContext = (usac != null && usac.equals("true"));
  90         String usf = getParameter("useSharedFrame");
  91         boolean shareFrame = (usf == null || usf.equals("true"));
  92         final boolean tracing = "true".equals(getParameter("trace"));
  93         boolean autostart = "true".equals(getParameter("start"));
  94         String observerClassName = getParameter("observer");
  95         String appletName;
  96 
  97         if (shareAppletContext) {
  98             appletName = getParameter("appletName");
  99             // do checks for use with MainAppletContext
 100             if (appletName == null) {
 101                 // the following normally executes on the test platform, so is not i18n
 102                 String line1 = "Error: Applet parameter \"appletName\" must be defined";
 103                 String line2 = "and match the applet's \"name\" attribute.";
 104                 showStatus("Error starting Applet: Applet parameter \"appletName\" must be defined.");
 105                 Panel p = new Panel(new GridLayout(0,1));
 106                 Label label1 = new Label(line1);
 107                 Label label2 = new Label(line2);
 108                 p.add(label1);
 109                 p.add(label2);
 110                 add(p);
 111                 return;
 112             }
 113         }
 114         else
 115             appletName = null;
 116 
 117         setLayout(new GridBagLayout());
 118 
 119         GridBagConstraints c = new GridBagConstraints();
 120 
 121         ActiveModeOptions amo = new ActiveModeOptions();
 122         if (activeHost != null)
 123             amo.setHost(activeHost);
 124         amo.setPort(activePort);
 125 
 126         PassiveModeOptions pmo = new PassiveModeOptions();
 127         pmo.setPort(passivePort);
 128 
 129         ModeOptions smo = null;
 130         try {
 131             Class<? extends ModeOptions> serial =
 132                     Class.forName("com.sun.javatest.agent.SerialPortModeOptions").asSubclass(ModeOptions.class);
 133             smo = serial.getDeclaredConstructor().newInstance();
 134         } catch (Exception e) {
 135             System.err.println("There is no support for serial port");
 136         }
 137         if (serialPort != null){
 138             try {
 139                 Method setPortMethod = smo.getClass().getMethod("setPort", String.class);
 140                 setPortMethod.invoke(smo, serialPort);
 141             }
 142             catch (SecurityException | NoSuchMethodException |
 143                     IllegalArgumentException| InvocationTargetException |
 144                     IllegalAccessException e) {
 145                 System.err.println("Could not set serial port:");
 146                 e.printStackTrace();
 147             }
 148         }
 149 
 150         ModeOptions[] modeOptions = new ModeOptions[] {amo, pmo, smo};
 151 
 152         AgentPanel.MapReader mapReader = new AgentPanel.MapReader() {
 153             public Map read(String name) throws IOException {
 154                 if (name == null || name.length() == 0)
 155                     return null;
 156                 else {
 157                     Map m = Map.readURL(new URL(getDocumentBase(), name));
 158                     m.setTracing(tracing, System.out);
 159                     return m;
 160                 }
 161             }
 162         };
 163         AgentPanel ap = new AgentPanel(modeOptions, mapReader);
 164 
 165         if (observerClassName != null) {
 166             try {
 167                 Class<? extends Agent.Observer> observerClass =
 168                         Class.forName(observerClassName).asSubclass(Agent.Observer.class);
 169                 Agent.Observer observer = observerClass.getDeclaredConstructor().newInstance();
 170                 ap.addObserver(observer);
 171             }
 172             catch (ClassCastException e) {
 173                 showStatus("observer is not of type " +
 174                         Agent.Observer.class.getName() + ": " + observerClassName);
 175             }
 176             catch (ClassNotFoundException e) {
 177                 showStatus("cannot find observer class: " + observerClassName);
 178             }
 179             catch (IllegalAccessException e) {
 180                 showStatus("problem instantiating observer: " + e);
 181             }
 182             catch (InstantiationException e) {
 183                 showStatus("problem instantiating observer: " + e);
 184             }
 185             catch (NoSuchMethodException e) {
 186                 showStatus("cannot find no-arg constructor. " + e);
 187             }
 188             catch (InvocationTargetException e) {
 189                 showStatus("exception thrown by no-arg constructor. " + e);
 190             }
 191         }
 192 
 193         ap.setMode(mode);
 194         ap.setConcurrency(concurrency);
 195         ap.setTracing(tracing, System.out);
 196 
 197         if (mapFile != null)
 198             ap.setMapFile(mapFile);
 199 
 200         if (history != -1)
 201             ap.setHistoryLimit(history);
 202 
 203         if (delay != -1)
 204             ap.setRetryDelay(delay);
 205 
 206         c.weightx = 1;
 207         c.weighty = 1;
 208         c.fill = GridBagConstraints.BOTH;
 209         add(ap, c);
 210 
 211         if (shareFrame) {
 212             try {
 213                 Container x = this;
 214                 while (x != null && !(x instanceof Frame))
 215                     x = x.getParent();
 216                 if (x != null)
 217                     MainFrame.setFrame((Frame)x);
 218             }
 219             catch (SecurityException e) {
 220                 System.err.println("Security Exception occurred while attempting to access shared frame; " + e);
 221             }
 222         }
 223 
 224         if (shareAppletContext) {
 225             AppletContext context = getAppletContext();
 226             MainAppletContext.setAppletContext(context);
 227             MainAppletContext.putApplet(appletName, this);
 228             MainAppletContext.setAgentApplet(this);
 229         }
 230 
 231         if (autostart)
 232             ap.start();
 233     }
 234 
 235     public void start() {
 236         if (shareAppletContext)
 237             MainAppletContext.setStarted(true);
 238         super.start();
 239     }
 240 
 241     public void destroy() {
 242         Component c = getComponent(0);
 243         if (c instanceof AgentPanel) {
 244             AgentPanel ap = (AgentPanel) c;
 245             ap.stop();
 246         }
 247     }
 248 
 249     /**
 250      * Returns a string containing information about
 251      * the author, version and copyright of the applet.
 252      */
 253     public String getAppletInfo() {
 254         return (Agent.productName + " " +
 255                 Agent.productVersion + " " +
 256                 Agent.productCopyright);
 257     }
 258 
 259     /**
 260      * Returns an array of strings describing the
 261      * parameters that are understood by this
 262      * applet.
 263      */
 264     public String[][] getParameterInfo() {
 265         String[][] pinfo = {
 266             {"mode",       "\"active\" or \"passive\"",
 267                                         "the mode for the agent"},
 268             {"activeHost",  "hostname", "the host for active connections"},
 269             {"activePort",  "port",     "the port for active connections"},
 270             {"passivePort", "port",     "the port for passive connections"},
 271             {"map",         "url",      "map file for translating arguments of incoming requests"},
 272             {"concurrency", "number",   "the maximum number of simultaneous connections"},
 273             {"history",     "int",      "the size of the execution history"},
 274             {"trace",       "boolean",  "trace the execution of the agent"}
 275         };
 276         return pinfo;
 277     }
 278 
 279     private int getIntParameter(String name, int dflt) {
 280         try {
 281             String s = getParameter(name);
 282             if (s != null)
 283                 return Integer.parseInt(s);
 284         }
 285         catch (NumberFormatException e) {
 286             // ignore
 287         }
 288         return dflt;
 289     }
 290 
 291     private String getParameter(String name, String dflt) {
 292         String s = getParameter(name);
 293         return (s == null ? dflt : s);
 294     }
 295 
 296     public void started(Agent sl) {
 297         showStatus("agent started");
 298     }
 299 
 300     public void errorOpeningConnection(Agent sl, Exception e) {
 301         showStatus("error opening connection: " + e.getMessage());
 302     }
 303 
 304     public void finished(Agent sl) {
 305         showStatus("agent stopped");
 306     }
 307 
 308     public synchronized void openedConnection(Agent sl, Connection c) {
 309         showStatus("OPENED SOCKET");
 310     }
 311 
 312     public synchronized void execTest(Agent sl, Connection c, String tag, String className, String[] args) {
 313         showStatus("EXEC");
 314     }
 315 
 316     public synchronized void execCommand(Agent sl, Connection c, String tag, String className, String[] args) {
 317         showStatus("EXEC");
 318     }
 319 
 320     public synchronized void execMain(Agent sl, Connection c, String tag, String className, String[] args) {
 321         showStatus("EXEC");
 322     }
 323 
 324     public synchronized void result(Agent sl, Connection c, Status r) {
 325         showStatus("RESULT");
 326     }
 327 
 328     public synchronized void exception(Agent sl, Connection c, Throwable t) {
 329         showStatus("EXCEPTION (NYI)");
 330     }
 331 
 332     public synchronized void completed(Agent sl, Connection c) {
 333         showStatus("COMPLETED (NYI)");
 334     }
 335 
 336     private boolean shareAppletContext;
 337 
 338 }