001: /*******************************************************************************
002: * Copyright (c) 2000, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.ui.console;
011:
012: import java.io.IOException;
013: import java.util.ArrayList;
014: import java.util.List;
015:
016: import org.eclipse.jface.resource.ImageDescriptor;
017: import org.eclipse.ui.WorkbenchEncoding;
018: import org.eclipse.ui.internal.console.IOConsolePage;
019: import org.eclipse.ui.internal.console.IOConsolePartitioner;
020: import org.eclipse.ui.part.IPageBookViewPage;
021:
022: /**
023: * A console that displays text from I/O streams. An I/O console can have multiple
024: * output streams connected to it and provides one input stream connected to the
025: * keyboard.
026: * <p>
027: * Clients may instantiate and subclass this class.
028: * </p>
029: * @since 3.1
030: */
031: public class IOConsole extends TextConsole {
032: /**
033: * The document partitioner
034: */
035: private IOConsolePartitioner partitioner;
036:
037: /**
038: * The stream from which user input may be read
039: */
040: private IOConsoleInputStream inputStream;
041:
042: /**
043: * A collection of open streams connected to this console.
044: */
045: private List openStreams;
046:
047: /**
048: * The encoding used to for displaying console output.
049: */
050: private String fEncoding = WorkbenchEncoding
051: .getWorkbenchDefaultEncoding();
052:
053: /**
054: * Constructs a console with the given name, type, image, and lifecycle, with the
055: * workbench's default encoding.
056: *
057: * @param name name to display for this console
058: * @param consoleType console type identifier or <code>null</code>
059: * @param imageDescriptor image to display for this console or <code>null</code>
060: * @param autoLifecycle whether lifecycle methods should be called automatically
061: * when this console is added/removed from the console manager
062: */
063: public IOConsole(String name, String consoleType,
064: ImageDescriptor imageDescriptor, boolean autoLifecycle) {
065: this (name, consoleType, imageDescriptor, null, autoLifecycle);
066: }
067:
068: /**
069: * Constructs a console with the given name, type, image, encoding and lifecycle.
070: *
071: * @param name name to display for this console
072: * @param consoleType console type identifier or <code>null</code>
073: * @param imageDescriptor image to display for this console or <code>null</code>
074: * @param autoLifecycle whether lifecycle methods should be called automatically
075: * when this console is added/removed from the console manager
076: */
077: public IOConsole(String name, String consoleType,
078: ImageDescriptor imageDescriptor, String encoding,
079: boolean autoLifecycle) {
080: super (name, consoleType, imageDescriptor, autoLifecycle);
081: if (encoding != null) {
082: fEncoding = encoding;
083: }
084: openStreams = new ArrayList();
085: inputStream = new IOConsoleInputStream(this );
086: synchronized (openStreams) {
087: openStreams.add(inputStream);
088: }
089:
090: partitioner = new IOConsolePartitioner(inputStream, this );
091: partitioner.connect(getDocument());
092: }
093:
094: /**
095: * Constructs a console with the given name, type, and image with the workbench's
096: * default encoding. Lifecycle methods will be called when this console is
097: * added/removed from the console manager.
098: *
099: * @param name name to display for this console
100: * @param consoleType console type identifier or <code>null</code>
101: * @param imageDescriptor image to display for this console or <code>null</code>
102: */
103: public IOConsole(String name, String consoleType,
104: ImageDescriptor imageDescriptor) {
105: this (name, consoleType, imageDescriptor, true);
106: }
107:
108: /**
109: * Constructs a console with the given name and image. Lifecycle methods
110: * will be called when this console is added/removed from the console manager.
111: * This console will have an unspecified (<code>null</code>) type.
112: *
113: * @param name name to display for this console
114: * @param imageDescriptor image to display for this console or <code>null</code>
115: */
116: public IOConsole(String name, ImageDescriptor imageDescriptor) {
117: this (name, null, imageDescriptor);
118: }
119:
120: /* (non-Javadoc)
121: * @see org.eclipse.ui.console.IConsole#createPage(org.eclipse.ui.console.IConsoleView)
122: */
123: public IPageBookViewPage createPage(IConsoleView view) {
124: return new IOConsolePage(this , view);
125: }
126:
127: /**
128: * Creates and returns a new output stream which may be used to write to this console.
129: * A console may be connected to more than one output stream at once. Clients are
130: * responsible for closing any output streams created on this console.
131: * <p>
132: * Clients should avoid writing large amounts of output to this stream in the UI
133: * thread. The console needs to process the output in the UI thread and if the client
134: * hogs the UI thread writing output to the console, the console will not be able
135: * to process the output.
136: * </p>
137: * @return a new output stream connected to this console
138: */
139: public IOConsoleOutputStream newOutputStream() {
140: IOConsoleOutputStream outputStream = new IOConsoleOutputStream(
141: this );
142: outputStream.setEncoding(fEncoding);
143: synchronized (openStreams) {
144: openStreams.add(outputStream);
145: }
146: return outputStream;
147: }
148:
149: /**
150: * Returns the input stream connected to the keyboard.
151: *
152: * @return the input stream connected to the keyboard.
153: */
154: public IOConsoleInputStream getInputStream() {
155: return inputStream;
156: }
157:
158: /**
159: * Returns this console's document partitioner.
160: *
161: * @return this console's document partitioner
162: */
163: protected IConsoleDocumentPartitioner getPartitioner() {
164: return partitioner;
165: }
166:
167: /**
168: * Returns the maximum number of characters that the console will display at
169: * once. This is analogous to the size of the text buffer this console
170: * maintains.
171: *
172: * @return the maximum number of characters that the console will display
173: */
174: public int getHighWaterMark() {
175: return partitioner.getHighWaterMark();
176: }
177:
178: /**
179: * Returns the number of characters that will remain in this console
180: * when its high water mark is exceeded.
181: *
182: * @return the number of characters that will remain in this console
183: * when its high water mark is exceeded
184: */
185: public int getLowWaterMark() {
186: return partitioner.getLowWaterMark();
187: }
188:
189: /**
190: * Sets the text buffer size for this console. The high water mark indicates
191: * the maximum number of characters stored in the buffer. The low water mark
192: * indicates the number of characters remaining in the buffer when the high
193: * water mark is exceeded.
194: *
195: * @param low the number of characters remaining in the buffer when the high
196: * water mark is exceeded (if -1 the console does not limit output)
197: * @param high the maximum number of characters this console will cache in
198: * its text buffer (if -1 the console does not limit output)
199: * @exception IllegalArgumentException if low >= high & low != -1
200: */
201: public void setWaterMarks(int low, int high) {
202: if (low >= 0) {
203: if (low >= high) {
204: throw new IllegalArgumentException(
205: "High water mark must be greater than low water mark"); //$NON-NLS-1$
206: }
207: }
208: partitioner.setWaterMarks(low, high);
209: }
210:
211: /**
212: * Check if all streams connected to this console are closed. If so,
213: * notify the partitioner that this console is finished.
214: */
215: private void checkFinished() {
216: if (openStreams.isEmpty()) {
217: partitioner.streamsClosed();
218: }
219: }
220:
221: /**
222: * Notification that an output stream connected to this console has been closed.
223: *
224: * @param stream stream that closed
225: */
226: void streamClosed(IOConsoleOutputStream stream) {
227: synchronized (openStreams) {
228: openStreams.remove(stream);
229: checkFinished();
230: }
231: }
232:
233: /**
234: * Notification that the input stream connected to this console has been closed.
235: *
236: * @param stream stream that closed
237: */
238: void streamClosed(IOConsoleInputStream stream) {
239: synchronized (openStreams) {
240: openStreams.remove(stream);
241: checkFinished();
242: }
243: }
244:
245: /* (non-Javadoc)
246: * @see org.eclipse.ui.console.TextConsole#clearConsole()
247: */
248: public void clearConsole() {
249: if (partitioner != null) {
250: partitioner.clearBuffer();
251: }
252: }
253:
254: /**
255: * Disposes this console.
256: */
257: protected void dispose() {
258: super .dispose();
259: partitioner.disconnect();
260: //make a copy of the open streams and close them all
261: //a copy is needed as close the streams results in a callback that
262: //removes the streams from the openStreams collection (bug 152794)
263: Object[] allStreams = openStreams.toArray();
264: for (int i = 0; i < allStreams.length; i++) {
265: Object stream = allStreams[i];
266: if (stream instanceof IOConsoleInputStream) {
267: IOConsoleInputStream is = (IOConsoleInputStream) stream;
268: try {
269: is.close();
270: } catch (IOException e) {
271: }
272: } else if (stream instanceof IOConsoleOutputStream) {
273: IOConsoleOutputStream os = (IOConsoleOutputStream) stream;
274: try {
275: os.close();
276: } catch (IOException e) {
277: }
278: }
279: }
280: inputStream = null;
281: }
282:
283: /**
284: * Returns the encoding for this console, or <code>null</code> to indicate
285: * default encoding.
286: *
287: * @return the encoding set for this console, or <code>null</code> to indicate
288: * default encoding
289: * @since 3.3
290: */
291: public String getEncoding() {
292: return fEncoding;
293: }
294: }
|