1// BEGIN LICENSE BLOCK 2// Version: CMPL 1.1 3// 4// The contents of this file are subject to the Cisco-style Mozilla Public 5// License Version 1.1 (the "License"); you may not use this file except 6// in compliance with the License. You may obtain a copy of the License 7// at www.eclipse-clp.org/license. 8// 9// Software distributed under the License is distributed on an "AS IS" 10// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 11// the License for the specific language governing rights and limitations 12// under the License. 13// 14// The Original Code is The ECLiPSe Constraint Logic Programming System. 15// The Initial Developer of the Original Code is Cisco Systems, Inc. 16// Portions created by the Initial Developer are 17// Copyright (C) 2000 - 2006 Cisco Systems, Inc. All Rights Reserved. 18// 19// Contributor(s): Stefano Novello / Josh Singer, Parc Technologies 20// Joachim Schimpf / Andrew Cheadle, IC-Parc 21// 22// END LICENSE BLOCK 23 24//Title: Java/ECLiPSe interface 25//Version: $Id: AsyncEclipseQueue.java,v 1.1 2006/09/23 01:54:08 snovello Exp $ 26//Author: Stefano Novello / Josh Singer / J Schimpf / A Cheadle 27//Company: Parc Technologies / IC-Parc 28//Description: Asynchronous Queue for communication with ECLiPSe 29package com.parctechnologies.eclipse; 30import java.io.*; 31import java.util.*; 32import java.net.Socket; 33 34/** 35 * An asynchronous, bidirectional queue for communicating between ECLiPSe 36 * and Java. The following differences exist between a synchronous 37 * FromEclipseQueue/ToEclipseQueue and an asynchronous AsyncEclipseQueue: 38 * <ul> 39 * <li>an asynchronous queue can be read/written from the Java side even 40 * while the ECLiPSe side has control, e.g. during an RPC. This obviously 41 * has to happen from a different thread than the one that executes the RPC.</li> 42 * <li>I/O operations on asynchronous queues can block, they should therefore 43 * be done from a dedicated thread.</li> 44 * <li>the AsyncEclipseQueue class does not extend InputStream or OutputStream 45 * and can therefore not be used for I/O directly. Instead, a standard Java 46 * InputStream can be obtained from it via the getInputStream() method, and 47 * an OutputStream via the getOutputStream() method.</li> 48 * <li>on the ECLiPSe side, an event can (and should) be raised when data 49 * arrives from the Java side. If the ECLiPSe side has control at that time, 50 * it will handle the event. Otherwise, the event handling may be deferred 51 * until ECLiPSe has control back.</li> 52 * </ul> 53 * 54 * There is no public constructor; to access an <i>AsyncEclipseQueue</i>, 55 * use the <code>createAsyncEclipseQueue()</code> of an object implementing 56 * the {@link EclipseConnection} interface. But note that asynchronous 57 * queues are only implemented by the {@link RemoteEclipse} and {@link OutOfProcessEclipse} 58 * implementations, not the {@link EmbeddedEclipse} variant. 59 * 60 */ 61public class AsyncEclipseQueue { 62 /** 63 * This is the eclipse numeric id for the queue it is used to 64 * uniquely identify the stream 65 */ 66 private int id; 67 /** 68 * Name of the queue 69 */ 70 private String name; 71 72 /** 73 * The eclipse which this is a queue from 74 */ 75 private EclipseConnectionImpl eclipse; 76 77 /** 78 * Flag to indicate whether or not the queue has been closed. 79 */ 80 private boolean isClosed = false; 81 82 /** 83 * Flag indicating whether this is a system or user queue. The eclipse side of 84 * a System queue does not get closed when the EclipseConnectionImpl's 85 * closeAllQueues method is called. Examples of system queues are ec_rpc_in 86 * ec_rpc_out, and standard stream queues. 87 */ 88 private boolean systemQueue = false; 89 90 private InputStream cachedInputStream = null; 91 92 private OutputStream cachedOutputStream = null; 93 94 95 /** 96 * make new queue 97 */ 98 AsyncEclipseQueue(int id,String name, EclipseConnectionImpl eclipse) 99 { 100 this.eclipse = eclipse; 101 this.id = id; 102 this.name = name; 103 } 104 105 int getID() 106 { 107 return id; 108 } 109 110 /** 111 * Returns true if this queue is a system queue, such as ec_rpc_in. 112 */ 113 boolean isSystemQueue() 114 { 115 return(systemQueue); 116 } 117 118 /** 119 * sets flag indicating wether this is a system queue 120 */ 121 void setSystemQueue(boolean newValue) 122 { 123 systemQueue = newValue; 124 } 125 126 /** 127 * Closes the queue (both eclipse and Java sides) 128 */ 129 public void close() throws IOException 130 { 131 testClosed(); 132 close_cleanup(); 133 eclipse.closeAsyncEclipseStreamEclipseSide(id); 134 eclipse.closeAsyncEclipseStreamJavaSide(id); 135 } 136 137 // method to clean up locally 138 void close_cleanup() 139 { 140 isClosed = true; 141 } 142 143 /** 144 * Test whether the queue has been closed; if so, throw an IOException 145 * "Operation not possible: stream closed." 146 */ 147 private void testClosed() throws IOException 148 { 149 if(isClosed) 150 { 151 throw new IOException("Operation not possible: stream closed."); 152 } 153 } 154 155 /** 156 * Gets the InputStream associated with the (bidirectional) 157 * AsyncEclipseQueue. Throws an exception if the Queue is closed. 158 */ 159 public InputStream getInputStream() throws IOException 160 { 161 testClosed(); 162 return cachedInputStream != null ? cachedInputStream 163 : eclipse.getAsyncInputStream(id); 164 } 165 166 /** 167 * Gets the OutputStream associated with the (bidirectional) 168 * AsyncEclipseQueue. Throws an exception if the Queue is closed. 169 */ 170 public OutputStream getOutputStream() throws IOException 171 { 172 testClosed(); 173 return cachedOutputStream != null ? cachedOutputStream 174 : eclipse.getAsyncOutputStream(id); 175 } 176} 177