Home | History | Annotate | Download | only in share
      1 /*
      2  * Licensed to the Apache Software Foundation (ASF) under one or more
      3  * contributor license agreements.  See the NOTICE file distributed with
      4  * this work for additional information regarding copyright ownership.
      5  * The ASF licenses this file to You under the Apache License, Version 2.0
      6  * (the "License"); you may not use this file except in compliance with
      7  * the License.  You may obtain a copy of the License at
      8  *
      9  *     http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *
     15  *  See the License for the specific language governing permissions and
     16  *  limitations under the License.
     17  */
     18 
     19 /**
     20  * @author Vitaly A. Provodin
     21  */
     22 
     23 /**
     24  * Created on 29.01.2005
     25  */
     26 package org.apache.harmony.jpda.tests.share;
     27 
     28 import java.io.DataInputStream;
     29 import java.io.DataOutputStream;
     30 import java.io.EOFException;
     31 import java.io.IOException;
     32 import java.net.Socket;
     33 import java.net.ServerSocket;
     34 
     35 import org.apache.harmony.jpda.tests.framework.DebuggeeSynchronizer;
     36 import org.apache.harmony.jpda.tests.framework.LogWriter;
     37 import org.apache.harmony.jpda.tests.framework.TestErrorException;
     38 import org.apache.harmony.jpda.tests.framework.TestOptions;
     39 
     40 /**
     41  * This class implements <code>DebuggeeSynchronizer</code> interface using
     42  * TCP/IP sockets. All operations can be timed out according to default timeout.
     43  */
     44 public class JPDADebuggeeSynchronizer implements DebuggeeSynchronizer {
     45 
     46     public final static String SGNL_READY = "ready";
     47 
     48     public final static String SGNL_CONTINUE = "continue";
     49 
     50     protected Socket clientSocket = null;
     51 
     52     protected ServerSocket serverSocket = null;
     53 
     54     protected DataOutputStream out;
     55 
     56     protected DataInputStream in;
     57 
     58     protected TestOptions settings;
     59 
     60     protected LogWriter logWriter;
     61 
     62     /**
     63      * A constructor that initializes an instance of the class with specified
     64      * <code>LogWriter</code> and <code>TestOptions</code>.
     65      *
     66      * @param logWriter
     67      *            The instance of implementation of LogWriter.
     68      * @param settings
     69      *            Instance of test options.
     70      */
     71     public JPDADebuggeeSynchronizer(LogWriter logWriter, TestOptions settings) {
     72         super();
     73         this.logWriter = logWriter;
     74         this.settings = settings;
     75     }
     76 
     77     /**
     78      * Sends specified message to synchronization channel.
     79      *
     80      * @param message
     81      *            a message to be sent.
     82      */
     83     public synchronized void sendMessage(String message) {
     84         try {
     85             out.writeUTF(message);
     86             out.flush();
     87             logWriter.println("[SYNC] Message sent: " + message);
     88         } catch (IOException e) {
     89             throw new TestErrorException(e);
     90         }
     91     }
     92 
     93     /**
     94      * Receives message from synchronization channel and compares it with the
     95      * expected <code>message</code>.
     96      *
     97      * @param message
     98      *            expected message.
     99      * @return <code>true</code> if received string is equals to
    100      *         <code>message</code> otherwise - <code>false</code>.
    101      *
    102      */
    103     public synchronized boolean receiveMessage(String message) {
    104         String msg;
    105         try {
    106             logWriter.println("[SYNC] Waiting for message: " + message);
    107             msg = in.readUTF();
    108             logWriter.println("[SYNC] Received message: " + msg);
    109         } catch (EOFException e) {
    110             return false;
    111         } catch (IOException e) {
    112             logWriter.printError(e);
    113             return false;
    114         }
    115         return message.equalsIgnoreCase(msg);
    116     }
    117 
    118     /**
    119      * Receives message from synchronization channel.
    120      *
    121      * @return received string or null if connection was closed.
    122      */
    123     public synchronized String receiveMessage() {
    124         String msg;
    125         try {
    126             logWriter.println("[SYNC] Waiting for any messsage");
    127             msg = in.readUTF();
    128             logWriter.println("[SYNC] Received message: " + msg);
    129         } catch (EOFException e) {
    130             return null;
    131         } catch (IOException e) {
    132             throw new TestErrorException(e);
    133         }
    134         return msg;
    135     }
    136 
    137     /**
    138      * Receives message from synchronization channel without Exception.
    139      *
    140      * @return received string
    141      */
    142     public synchronized String receiveMessageWithoutException(String invoker) {
    143         String msg;
    144         try {
    145             logWriter.println("[SYNC] Waiting for any message");
    146             msg = in.readUTF();
    147             logWriter.println("[SYNC] Received message: " + msg);
    148         } catch (Throwable thrown) {
    149             if (invoker != null) {
    150                 logWriter.println("#### receiveMessageWithoutException: Exception occurred:");
    151                 logWriter.println("#### " + thrown);
    152                 logWriter.println("#### Invoker = " + invoker);
    153             }
    154             msg = "" + thrown;
    155         }
    156         return msg;
    157     }
    158 
    159     /**
    160      * Returns socket port to be used for connection.
    161      *
    162      * @return port number
    163      */
    164     public int getSyncPortNumber() {
    165         return settings.getSyncPortNumber();
    166     }
    167 
    168     /**
    169      * Binds server to listen socket port.
    170      *
    171      * @return port number
    172      */
    173     public synchronized int bindServer() {
    174         int port = getSyncPortNumber();
    175         try {
    176             logWriter.println("[SYNC] Binding socket on port: " + port);
    177             serverSocket = new ServerSocket(port);
    178             port = serverSocket.getLocalPort();
    179             logWriter.println("[SYNC] Bound socket on port: " + port);
    180             return port;
    181         } catch (IOException e) {
    182             throw new TestErrorException(
    183                     "[SYNC] Exception in binding for socket sync connection", e);
    184         }
    185     }
    186 
    187     /**
    188      * Accepts sync connection form server side.
    189      */
    190     public synchronized void startServer() {
    191         long timeout = settings.getTimeout();
    192         try {
    193             serverSocket.setSoTimeout((int) timeout);
    194             logWriter.println("[SYNC] Accepting socket connection");
    195             clientSocket = serverSocket.accept();
    196             logWriter.println("[SYNC] Accepted socket connection");
    197 
    198             clientSocket.setSoTimeout((int) timeout);
    199             out = new DataOutputStream(clientSocket.getOutputStream());
    200             in = new DataInputStream(clientSocket.getInputStream());
    201         } catch (IOException e) {
    202             throw new TestErrorException(
    203                     "[SYNC] Exception in accepting socket sync connection", e);
    204         }
    205     }
    206 
    207     /**
    208      * Attaches for sync connection from client side..
    209      */
    210     public synchronized void startClient() {
    211         long timeout = settings.getTimeout();
    212         String host = "localhost";
    213         int port = getSyncPortNumber();
    214         try {
    215             logWriter.println("[SYNC] Attaching socket to: " + host + ":" + port);
    216             clientSocket = new Socket(host, port);
    217             logWriter.println("[SYNC] Attached socket");
    218 
    219             clientSocket.setSoTimeout((int) timeout);
    220             out = new DataOutputStream(clientSocket.getOutputStream());
    221             in = new DataInputStream(clientSocket.getInputStream());
    222         } catch (IOException e) {
    223             throw new TestErrorException(
    224                     "[SYNC] Exception in attaching for socket sync connection", e);
    225         }
    226     }
    227 
    228     /**
    229      * Stops synchronization work. It ignores <code>IOException</code> but
    230      * prints a message.
    231      */
    232     public void stop() {
    233         try {
    234             if (out != null)
    235                 out.close();
    236             if (in != null)
    237                 in.close();
    238             if (clientSocket != null)
    239                 clientSocket.close();
    240             if (serverSocket != null)
    241                 serverSocket.close();
    242         } catch (IOException e) {
    243             logWriter.println
    244                     ("[SYNC] Ignoring exception in closing socket sync connection: " + e);
    245         }
    246         logWriter.println("[SYNC] Closed socket");
    247     }
    248 }
    249