       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 com.sun.javatest.JavaTestSecurityManager;
      30 import java.io.InputStream;
      31 import java.io.OutputStream;
      32 import java.io.IOException;
      33 import java.net.InetAddress;
      34 import java.net.Socket;
      35 import java.util.Hashtable;
      36
      37 import com.sun.javatest.util.Timer;
      38 import java.net.ServerSocket;
      39
      40 /**
      41  * A connection via a TCP/IP socket.
      42  */
      43 public class SocketConnection implements Connection {
      44
      45     /**
      46      * Create a connection via a TCP/IP socket.
      47      * @param socket The socket to use for the connection.
      48      * @throws IOException if an error occurs getting the streams for the connection.
      49      * @throws NullPointerException if socket is null
      50      */
      51     public SocketConnection(Socket socket) throws IOException {
      52         if (socket == null) {
      53             throw new NullPointerException();
      54         }
      55         this.socket = socket;
      56         socketInput = socket.getInputStream();
      57         socketOutput = socket.getOutputStream();
      58     }
      59
      60     /**
      61      * Create a connection via a TCP/IP socket.
      62      * @param host The host to which to try to connect to try and get a socket.
      63      * @param port The port on the host to which to connect to try and get a socket.
      64      * @throws IOException if an error occurs opening the socket.
      65      */
      66     public SocketConnection(final String host, final int port) throws IOException {
      67         if (host == null) {
      68             throw new NullPointerException();
      69         }
      70         /* experimental
      71         try {
      72             socket = (Socket) AccessController.doPrivileged(
      73                     new PrivilegedExceptionAction() {
      74
      75                         public Object run() throws IOException {
      76                             return new Socket(host, port);
      77                         }
      78                     });
      79         } catch (PrivilegedActionException e) {
      80             throw (IOException) e.getException();
      81         }*/
      82
      83         SecurityManager sm = System.getSecurityManager();
      84         JavaTestSecurityManager jtSm = null;
      85         boolean prev = false;
      86         if (sm != null && sm instanceof JavaTestSecurityManager) {
      87             jtSm = (JavaTestSecurityManager) sm;
      88             prev = jtSm.setAllowPropertiesAccess(true);
      89         }
      90         try {
      91             socket = new Socket(host, port);
      92         } finally {
      93             if (jtSm != null) {
      94                 jtSm.setAllowPropertiesAccess(prev);
      95             }
      96         }
      97
      98         socketInput = socket.getInputStream();
      99         socketOutput = socket.getOutputStream();
     100     }
     101
     102     public String getName() {
     103         if (name == null) {
     104             StringBuffer sb = new StringBuffer(32);
     105             sb.append(getHostName(socket.getInetAddress()));
     106             sb.append(",port=");
     107             sb.append(socket.getPort());
     108             sb.append(",localport=");
     109             sb.append(socket.getLocalPort());
     110             name = sb.toString();
     111         }
     112         return name;
     113     }
     114
     115     public InputStream getInputStream() {
     116         return socketInput;
     117     }
     118
     119     public OutputStream getOutputStream() {
     120         return socketOutput;
     121     }
     122
     123     public synchronized void close() throws IOException {
     124         socket.close();
     125         socketInput.close();
     126         socketOutput.close();
     127         closed = true;
     128
     129         if (waitThread != null) {
     130             waitThread.interrupt();
     131         }
     132     }
     133
     134     public synchronized boolean isClosed() {
     135         return closed;
     136     }
     137
     138     public void waitUntilClosed(int timeout) throws InterruptedException {
     139         synchronized (this) {
     140             waitThread = Thread.currentThread();
     141         }
     142
     143         Timer.Timeable cb = new Timer.Timeable() {
     144
     145             public void timeout() {
     146                 synchronized (SocketConnection.this) {
     147                     if (waitThread != null) {
     148                         waitThread.interrupt();
     149                     }
     150                     try {
     151                         socketInput.close();
     152                     } catch (IOException ignore) {
     153                     }
     154                     try {
     155                         socketOutput.close();
     156                     } catch (IOException ignore) {
     157                     }
     158                 }
     159             }
     160         };
     161
     162         Timer.Entry e = timer.requestDelayedCallback(cb, timeout);
     163         try {
     164             while (true) {
     165                 try {
     166                     int i = socketInput.read();
     167                     if (i == -1) {
     168                         break;
     169                     }
     170                 } catch (IOException ignore) {
     171                     break;
     172                 }
     173             }
     174         } finally {
     175             timer.cancel(e);
     176
     177             synchronized (this) {
     178                 waitThread = null;
     179             }
     180             if (Thread.interrupted()) {
     181                 throw new InterruptedException();
     182             }
     183         }
     184     }
     185
     186     private static String getHostName(InetAddress addr) {
     187         String s = addressCache.get(addr);
     188         if (s == null) {
     189             s = addr.getHostName();
     190             addressCache.put(addr, s);
     191         }
     192         return s;
     193     }
     194
     195     /**
     196      * Creates a ServerSocket instance in the environment where reading
     197      * of system properties is allowed.
     198      *
     199      * @param port - port to bind
     200      * @return new created ServerSocket
     201      * @throws java.io.IOException - if ServerSocket is not created
     202      */
     203     public static ServerSocket createServerSocket(int port) throws IOException {
     204         return createServerSocket(port, 50);
     205     }
     206
     207     /**
     208      * Creates a ServerSocket instance in the environment where reading
     209      * of system properties is allowed.
     210      *
     211      * @param port - port to bind
     212      * @param backlog - backlog
     213      * @return new created ServerSocket
     214      * @throws java.io.IOException - if ServerSocket is not created
     215      */
     216     public static synchronized ServerSocket createServerSocket(int port, int backlog)
     217             throws IOException {
     218         SecurityManager sm = System.getSecurityManager();
     219         JavaTestSecurityManager jtSm = null;
     220         boolean prev = false;
     221         if (sm != null && sm instanceof JavaTestSecurityManager) {
     222             jtSm = (JavaTestSecurityManager) sm;
     223             prev = jtSm.setAllowPropertiesAccess(true);
     224         }
     225         try {
     226             ServerSocket serverSocket = new ServerSocket(port, backlog);
     227             return serverSocket;
     228         } finally {
     229             if (jtSm != null) {
     230                 jtSm.setAllowPropertiesAccess(prev);
     231             }
     232         }
     233     }
     234     private final Socket socket;
     235     protected final InputStream socketInput;
     236     private final OutputStream socketOutput;
     237     private String name;
     238     private boolean closed;
     239     private Thread waitThread;
     240     private static Timer timer = new Timer();
     241     private static Hashtable<InetAddress, String> addressCache = new Hashtable<>();
     242 }
    --- EOF ---