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// 21// END LICENSE BLOCK 22 23//Title: Java/ECLiPSe interface 24//Version: $Id: ToEclipseQueue.java,v 1.1 2006/09/23 01:54:12 snovello Exp $ 25//Author: Stefano Novello / Josh Singer 26//Company: Parc Technologies 27//Description: Queue to send Java data to Eclipse 28package com.parctechnologies.eclipse; 29import java.util.*; 30import java.io.*; 31 32/** 33 * A queue for 34 * sending data from Java to ECLiPSe. This class performs no processing of the 35 * data and cannot for example, convert to EXDR format (see {@link EXDROutputStream} 36 * for a class which can do this). <p> 37 * 38 * In addition to the standard methods inherited from its superclass, this class 39 * also provides the ability to attach a {@link QueueListener} object to the 40 * ToEclipseQueue, as a handler for data requests from ECLiPSe. 41 * <p> 42 * There is no public constructor; to access an <i>ToEclipseQueue</i> use the 43 * <code>createToEclipseQueue()</code> of an object implementing the {@link 44 * EclipseConnection} interface or the <code>getEclipseStdin()</code> method of 45 * an object implementing the {@link EclipseEngine} interface. 46 * 47 */ 48public class ToEclipseQueue extends OutputStream { 49 50 /* Name of queue which is to be used by the user on the Java side. 51 The corresponding stream on the Eclipse 52 side may be referenced by the same string, but may also have other names. */ 53 private String name; 54 /* Stream number uniquely identifying the stream on the Eclipse side, and also 55 used by classes inside this package on the Java side */ 56 private int id; 57 /* The Eclipse which this queue is a queue to. Declared as an 58 EclipseConnectionImpl because this is the abstract class containing the methods 59 such as writeToStream which are called from this class */ 60 private EclipseConnectionImpl eclipse; 61 62 /** 63 * Listener for handling outgoing data, none by default 64 */ 65 private QueueListener listener = null; 66 67 /** 68 * Flag to indicate whether close() method has been called. 69 */ 70 private boolean isClosed = false; 71 72 /** 73 * Flag indicating whether this is a system or user queue. The eclipse side of 74 * a System queue does not get closed when the EclipseConnectionImpl's 75 * closeAllQueues method is called. Examples of system queues are ec_rpc_in 76 * ec_rpc_out, and standard stream queues. 77 */ 78 private boolean systemQueue = false; 79 80 81 /** 82 * construct a toEclipseQueue 83 */ 84 ToEclipseQueue(int id,String name, EclipseConnectionImpl eclipse) 85 { 86 this.eclipse = eclipse; 87 this.id = id; 88 this.name = name; 89 } 90 91 int getID() 92 { 93 return(id); 94 } 95 96 /** 97 * Returns true if this queue is a system queue, such as ec_rpc_in. 98 */ 99 boolean isSystemQueue() 100 { 101 return(systemQueue); 102 } 103 104 /** 105 * sets flag indicating wether this is a system queue 106 */ 107 void setSystemQueue(boolean newValue) 108 { 109 systemQueue = newValue; 110 } 111 112 113 // write a single byte: calls writeByteToStream in the 114 // EclipseConnectionImpl class. 115 116 public void write(int b) throws IOException 117 { 118 testClosed(); 119 eclipse.writeByteToStream(id, (byte) b); 120 } 121 122 // invokes a method in the underlying eclipse which writes to a stream 123 124 public void write(byte b[], int off, int len) throws IOException 125 { 126 testClosed(); 127 eclipse.writeToStream(id,b,off,len); 128 } 129 130 /** 131 * Attach a <i>QueueListener</i> to this <i>ToEclipseQueue</i> for handling 132 * requests for data. When ECLiPSe 133 * tries to read from an empty queue with a <i>QueueListener</i> 134 * attached, 135 * the <code>dataAvailable()</code> method of the 136 * <i>QueueListener</i> is invoked. 137 */ 138 public void setListener(QueueListener l) throws IOException 139 { 140 testClosed(); 141 listener = l; 142 } 143 144 /** 145 * Detach any <i>QueueListener</i> from this <i>ToEclipseQueue</i>. 146 */ 147 public void removeListener() throws IOException 148 { 149 testClosed(); 150 listener = null; 151 } 152 153 /** 154 * Called to notify that data has been requested, this forwards the request 155 * to any listeners. 156 */ 157 void notifyRequest() 158 { 159 // if there is a listener, invoke its dataRequest method 160 if(listener != null) 161 { 162 listener.dataRequest(this); 163 } 164 } 165 166 /** 167 * Calls the superclass' <code>flush</code> method 168 */ 169 public void flush() throws IOException 170 { 171 testClosed(); 172 // Get the underlying eclipse to flush the relevant stream 173 eclipse.flushStream(this.id); 174 175 // somehow here allow eclipse to handle events 176 } 177 178 /** 179 * Closes the queue (both eclipse and Java sides), removing any listener. 180 */ 181 public void close() throws IOException 182 { 183 testClosed(); 184 close_cleanup(); 185 eclipse.closeToEclipseStreamEclipseSide(id); 186 eclipse.closeToEclipseStreamJavaSide(id); 187 } 188 189 // method to clean up locally 190 void close_cleanup() 191 { 192 try 193 { 194 this.removeListener(); 195 } 196 catch(IOException ioe) 197 { 198 // only thrown if the queue has already been closed, which it hasn't 199 System.err.println("Error: removal of listener threw an IOException."); 200 System.err.flush(); 201 } 202 isClosed = true; 203 } 204 /** 205 * Test whether the queue has been closed; if so, throw an IOException 206 * "Operation not possible: stream closed." 207 */ 208 private void testClosed() throws IOException 209 { 210 if(isClosed) 211 { 212 throw new IOException("Operation not possible: stream closed."); 213 } 214 } 215 216} 217