001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: *
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: */
018:
019: /**
020: * @author Vitaly A. Provodin
021: * @version $Revision: 1.5 $
022: */
023:
024: /**
025: * Created on 29.01.2005
026: */package org.apache.harmony.jpda.tests.share;
027:
028: import java.io.DataInputStream;
029: import java.io.DataOutputStream;
030: import java.io.EOFException;
031: import java.io.IOException;
032: import java.net.Socket;
033: import java.net.ServerSocket;
034:
035: import org.apache.harmony.jpda.tests.framework.DebuggeeSynchronizer;
036: import org.apache.harmony.jpda.tests.framework.LogWriter;
037: import org.apache.harmony.jpda.tests.framework.TestErrorException;
038: import org.apache.harmony.jpda.tests.framework.TestOptions;
039:
040: /**
041: * This class implements <code>DebuggeeSynchronizer</code> interface using
042: * TCP/IP sockets. All operations can be timed out according to default timeout.
043: */
044: public class JPDADebuggeeSynchronizer implements DebuggeeSynchronizer {
045:
046: public final static String SGNL_READY = "ready";
047:
048: public final static String SGNL_CONTINUE = "continue";
049:
050: protected Socket clientSocket = null;
051:
052: protected ServerSocket serverSocket = null;
053:
054: protected DataOutputStream out;
055:
056: protected DataInputStream in;
057:
058: protected TestOptions settings;
059:
060: protected LogWriter logWriter;
061:
062: /**
063: * A constructor that initializes an instance of the class with specified
064: * <code>LogWriter</code> and <code>TestOptions</code>.
065: *
066: * @param logWriter
067: * The instance of implementation of LogWriter.
068: * @param settings
069: * Instance of test options.
070: */
071: public JPDADebuggeeSynchronizer(LogWriter logWriter,
072: TestOptions settings) {
073: super ();
074: this .logWriter = logWriter;
075: this .settings = settings;
076: }
077:
078: /**
079: * Sends specified message to synchronization channel.
080: *
081: * @param message
082: * a message to be sent.
083: */
084: public synchronized void sendMessage(String message) {
085: try {
086: out.writeUTF(message);
087: out.flush();
088: logWriter.println("[SYNC] Message sent: " + message);
089: } catch (IOException e) {
090: throw new TestErrorException(e);
091: }
092: }
093:
094: /**
095: * Receives message from synchronization channel and compares it with the
096: * expected <code>message</code>.
097: *
098: * @param message
099: * expected message.
100: * @return <code>true</code> if received string is equals to
101: * <code>message</code> otherwise - <code>false</code>.
102: *
103: */
104: public synchronized boolean receiveMessage(String message) {
105: String msg;
106: try {
107: logWriter.println("[SYNC] Waiting for message: " + message);
108: msg = in.readUTF();
109: logWriter.println("[SYNC] Received message: " + msg);
110: } catch (EOFException e) {
111: return false;
112: } catch (IOException e) {
113: logWriter.printError(e);
114: return false;
115: }
116: return message.equalsIgnoreCase(msg);
117: }
118:
119: /**
120: * Receives message from synchronization channel.
121: *
122: * @return received string or null if connection was closed.
123: */
124: public synchronized String receiveMessage() {
125: String msg;
126: try {
127: logWriter.println("[SYNC] Waiting for any messsage");
128: msg = in.readUTF();
129: logWriter.println("[SYNC] Received message: " + msg);
130: } catch (EOFException e) {
131: return null;
132: } catch (IOException e) {
133: throw new TestErrorException(e);
134: }
135: return msg;
136: }
137:
138: /**
139: * Receives message from synchronization channel without Exception.
140: *
141: * @return received string
142: */
143: public synchronized String receiveMessageWithoutException(
144: String invoker) {
145: String msg;
146: try {
147: logWriter.println("[SYNC] Waiting for any message");
148: msg = in.readUTF();
149: logWriter.println("[SYNC] Received message: " + msg);
150: } catch (Throwable thrown) {
151: if (invoker != null) {
152: logWriter
153: .println("#### receiveMessageWithoutException: Exception occurred:");
154: logWriter.println("#### " + thrown);
155: logWriter.println("#### Invoker = " + invoker);
156: }
157: msg = "" + thrown;
158: }
159: return msg;
160: }
161:
162: /**
163: * Returns socket port to be used for connection.
164: *
165: * @return port number
166: */
167: public int getSyncPortNumber() {
168: return settings.getSyncPortNumber();
169: }
170:
171: /**
172: * Binds server to listen socket port.
173: *
174: * @return port number
175: */
176: public synchronized int bindServer() {
177: int port = getSyncPortNumber();
178: try {
179: logWriter.println("[SYNC] Binding socket on port: " + port);
180: serverSocket = new ServerSocket(port);
181: port = serverSocket.getLocalPort();
182: logWriter.println("[SYNC] Bound socket on port: " + port);
183: return port;
184: } catch (IOException e) {
185: throw new TestErrorException(
186: "[SYNC] Exception in binding for socket sync connection",
187: e);
188: }
189: }
190:
191: /**
192: * Accepts sync connection form server side.
193: */
194: public synchronized void startServer() {
195: long timeout = settings.getTimeout();
196: try {
197: serverSocket.setSoTimeout((int) timeout);
198: logWriter.println("[SYNC] Accepting socket connection");
199: clientSocket = serverSocket.accept();
200: logWriter.println("[SYNC] Accepted socket connection");
201:
202: clientSocket.setSoTimeout((int) timeout);
203: out = new DataOutputStream(clientSocket.getOutputStream());
204: in = new DataInputStream(clientSocket.getInputStream());
205: } catch (IOException e) {
206: throw new TestErrorException(
207: "[SYNC] Exception in accepting socket sync connection",
208: e);
209: }
210: }
211:
212: /**
213: * Attaches for sync connection from client side..
214: */
215: public synchronized void startClient() {
216: long timeout = settings.getTimeout();
217: String host = "localhost";
218: int port = getSyncPortNumber();
219: try {
220: logWriter.println("[SYNC] Attaching socket to: " + host
221: + ":" + port);
222: clientSocket = new Socket(host, port);
223: logWriter.println("[SYNC] Attached socket");
224:
225: clientSocket.setSoTimeout((int) timeout);
226: out = new DataOutputStream(clientSocket.getOutputStream());
227: in = new DataInputStream(clientSocket.getInputStream());
228: } catch (IOException e) {
229: throw new TestErrorException(
230: "[SYNC] Exception in attaching for socket sync connection",
231: e);
232: }
233: }
234:
235: /**
236: * Stops synchronization work. It ignores <code>IOException</code> but
237: * prints a message.
238: */
239: public void stop() {
240: try {
241: if (out != null)
242: out.close();
243: if (in != null)
244: in.close();
245: if (clientSocket != null)
246: clientSocket.close();
247: if (serverSocket != null)
248: serverSocket.close();
249: } catch (IOException e) {
250: logWriter
251: .println("[SYNC] Ignoring exception in closing socket sync connection: "
252: + e);
253: }
254: logWriter.println("[SYNC] Closed socket");
255: }
256: }
|