1 /*
   2  * $Id$
   3  *
   4  * Copyright (c) 1996, 2011, 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.Choice;
  30 import java.awt.GridBagConstraints;
  31 import java.awt.Label;
  32 import java.util.Enumeration;
  33 import java.util.Vector;
  34 import javax.comm.CommPortIdentifier;
  35 import javax.comm.NoSuchPortException;
  36 
  37 
  38 // The functionality of SerialPortModeOptions is split in two, to cope
  39 // with the possibility that the gnu.io extension might not be present.
  40 // SerialPortModeOptions is strictly GUI, and should always be usable.
  41 // Access to the serial ports is handled (internally) via a private interface,
  42 // Proxy, to a dynamically loaded implementation, ProxyImpl.
  43 
  44 class SerialPortModeOptions extends ModeOptions {
  45     SerialPortModeOptions() {
  46         super("serial port");
  47 
  48         try {
  49             Class<? extends Proxy> c = Class.forName(Proxy.class.getName() + "Impl").asSubclass(Proxy.class);
  50             proxy = c.getDeclaredConstructor().newInstance();
  51         }
  52         catch (Throwable ignore) {
  53             // leave proxy unset if we can't load the class, and cope with it later
  54         }
  55 
  56         GridBagConstraints c = new GridBagConstraints();
  57 
  58         Label portLabel = new Label("port:");
  59         c.weightx = 0;
  60         add(portLabel, c);
  61 
  62         portChoice = new Choice();
  63 
  64         if (proxy != null) {
  65             String[] portNames = proxy.getPortNames();
  66             for (int i = 0; i < portNames.length; i++)
  67                 portChoice.addItem(portNames[i]);
  68         }
  69 
  70         if (portChoice.getItemCount() == 0) {
  71             portChoice.addItem("no serial ports found or accessible");
  72             portChoice.setEnabled(false);
  73         }
  74 
  75         c.anchor = GridBagConstraints.WEST;
  76         c.weightx = 1.0;
  77         add(portChoice, c);
  78     }
  79 
  80     ConnectionFactory createConnectionFactory(int concurrency) throws BadValue {
  81         if (proxy == null)
  82             throw new BadValue("no serial ports found or accessible");
  83         else
  84             return proxy.createConnectionFactory(portChoice.getSelectedItem());
  85 
  86     }
  87 
  88     void setPort(String port) {
  89         portChoice.select(port);
  90     }
  91 
  92     private Choice portChoice;
  93     private Proxy proxy;
  94 }
  95 
  96 // A private interface for SerialPortModeOptions to access gnu.io
  97 // functionality, which may or may not be available.
  98 
  99 interface Proxy {
 100     String[] getPortNames();
 101     ConnectionFactory createConnectionFactory(String port) throws BadValue;
 102 }
 103 
 104 
 105 // A private implementation of the Proxy interface. Expect possible loading
 106 // errors when accessing this interface, if the gnu.io API is not available.
 107 // In the case of more lazy linkers, it is possible that the errors will not
 108 // arise until the methods are invoked; these errors are handled internally
 109 // and default answers or exceptions thrown.
 110 
 111 class ProxyImpl implements Proxy {
 112     public String[] getPortNames() {
 113         try {
 114             Vector<String> v = new Vector<>();
 115             for (Enumeration<?> e = CommPortIdentifier.getPortIdentifiers(); e.hasMoreElements(); ) {
 116                 CommPortIdentifier p = (CommPortIdentifier)(e.nextElement());
 117                 if (p.getPortType() == CommPortIdentifier.PORT_SERIAL)
 118                     v.addElement(p.getName());
 119             }
 120             String[] a = new String[v.size()];
 121             v.copyInto(a);
 122             return a;
 123         }
 124         catch (Throwable t) {
 125             return new String[] { };
 126         }
 127     }
 128 
 129 
 130     public ConnectionFactory createConnectionFactory(String port) throws BadValue {
 131         try {
 132             return new SerialPortConnectionFactory(port, Agent.productName, 10*1000);
 133         }
 134         catch (NoSuchPortException e) {
 135             throw new BadValue("invalid port: " + port);
 136         }
 137         catch (Throwable t) {
 138             throw new BadValue("problem accessing serial ports");
 139         }
 140     }
 141 }