Author: koen.aers(a)jboss.com
Date: 2011-02-07 10:39:57 -0500 (Mon, 07 Feb 2011)
New Revision: 29050
Added:
trunk/forge/plugins/org.jboss.tools.seam.forge/src/org/jboss/tools/seam/forge/console/ConsoleInputStream.java
trunk/forge/plugins/org.jboss.tools.seam.forge/src/org/jboss/tools/seam/forge/console/ConsoleOutputStream.java
trunk/forge/plugins/org.jboss.tools.seam.forge/src/org/jboss/tools/seam/forge/console/ConsolePartition.java
trunk/forge/plugins/org.jboss.tools.seam.forge/src/org/jboss/tools/seam/forge/console/ConsolePartitioner.java
trunk/forge/plugins/org.jboss.tools.seam.forge/src/org/jboss/tools/seam/forge/temp/
Modified:
trunk/forge/plugins/org.jboss.tools.seam.forge/.classpath
trunk/forge/plugins/org.jboss.tools.seam.forge/META-INF/MANIFEST.MF
trunk/forge/plugins/org.jboss.tools.seam.forge/build.properties
trunk/forge/plugins/org.jboss.tools.seam.forge/src/org/jboss/tools/seam/forge/console/Console.java
trunk/forge/plugins/org.jboss.tools.seam.forge/src/org/jboss/tools/seam/forge/console/InputReadJob.java
trunk/forge/plugins/org.jboss.tools.seam.forge/src/org/jboss/tools/seam/forge/console/StreamListener.java
trunk/forge/plugins/org.jboss.tools.seam.forge/src/org/jboss/tools/seam/forge/view/ConsoleViewer.java
Log:
unbuffered input (to be continued)
Modified: trunk/forge/plugins/org.jboss.tools.seam.forge/.classpath
===================================================================
--- trunk/forge/plugins/org.jboss.tools.seam.forge/.classpath 2011-02-07 14:36:36 UTC (rev
29049)
+++ trunk/forge/plugins/org.jboss.tools.seam.forge/.classpath 2011-02-07 15:39:57 UTC (rev
29050)
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry exported="true" kind="lib"
path="lib/jline.jar"/>
<classpathentry kind="con"
path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
<classpathentry kind="con"
path="org.eclipse.pde.core.requiredPlugins"/>
- <classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="bin"/>
</classpath>
Modified: trunk/forge/plugins/org.jboss.tools.seam.forge/META-INF/MANIFEST.MF
===================================================================
--- trunk/forge/plugins/org.jboss.tools.seam.forge/META-INF/MANIFEST.MF 2011-02-07
14:36:36 UTC (rev 29049)
+++ trunk/forge/plugins/org.jboss.tools.seam.forge/META-INF/MANIFEST.MF 2011-02-07
15:39:57 UTC (rev 29050)
@@ -15,3 +15,5 @@
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Bundle-ActivationPolicy: lazy
Bundle-Activator: org.jboss.tools.seam.forge.Activator
+Bundle-ClassPath: .,
+ lib/jline.jar
Modified: trunk/forge/plugins/org.jboss.tools.seam.forge/build.properties
===================================================================
--- trunk/forge/plugins/org.jboss.tools.seam.forge/build.properties 2011-02-07 14:36:36
UTC (rev 29049)
+++ trunk/forge/plugins/org.jboss.tools.seam.forge/build.properties 2011-02-07 15:39:57
UTC (rev 29050)
@@ -1,7 +1,8 @@
-source.. = src/
output.. = bin/
bin.includes = META-INF/,\
plugin.xml,\
- bin/,\
lib/,\
- icons/
+ icons/,\
+ .,\
+ lib/jline.jar
+source.. = src/
Modified:
trunk/forge/plugins/org.jboss.tools.seam.forge/src/org/jboss/tools/seam/forge/console/Console.java
===================================================================
---
trunk/forge/plugins/org.jboss.tools.seam.forge/src/org/jboss/tools/seam/forge/console/Console.java 2011-02-07
14:36:36 UTC (rev 29049)
+++
trunk/forge/plugins/org.jboss.tools.seam.forge/src/org/jboss/tools/seam/forge/console/Console.java 2011-02-07
15:39:57 UTC (rev 29050)
@@ -15,67 +15,186 @@
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.Display;
-import org.eclipse.ui.console.IOConsole;
-import org.eclipse.ui.console.IOConsoleInputStream;
-import org.eclipse.ui.console.IOConsoleOutputStream;
+import org.eclipse.ui.WorkbenchEncoding;
+import org.eclipse.ui.console.IConsoleDocumentPartitioner;
+import org.eclipse.ui.console.IConsoleView;
+import org.eclipse.ui.console.TextConsole;
+import org.eclipse.ui.part.IPageBookViewPage;
-public class Console extends IOConsole implements IDebugEventSetListener {
-
+public class Console extends TextConsole implements IDebugEventSetListener {
+
private static final RGB INPUT_STREAM_RGB = new RGB(25, 225, 25);
private static final RGB ERROR_STREAM_RGB = new RGB(225, 25, 25);
private static final RGB OUTPUT_STREAM_RGB = new RGB(0, 0, 0);
private static final RGB CONSOLE_BACKGROUND_RGB = new RGB(255, 255, 255);
+ private ConsolePartitioner partitioner;
+ private ConsoleInputStream inputStream;
+ private List<Object> openStreams;
+ private String encoding = WorkbenchEncoding.getWorkbenchDefaultEncoding();
private IProcess process = null;
- private IOConsoleInputStream input;
- private boolean streamsClosed = false;
private List<StreamListener> streamListeners = new
ArrayList<StreamListener>();
+
public Console(IProcess process) {
- super("Forge Console", null, null, null, true);
+ super("Forge Console", null, null, true);
this.process = process;
- input = getInputStream();
- input.setColor(ColorManager.getInstance().getColor(INPUT_STREAM_RGB));
+ openStreams = new ArrayList<Object>();
+ inputStream = new ConsoleInputStream(this);
+ synchronized (openStreams) {
+ openStreams.add(inputStream);
+ }
+ partitioner = new ConsolePartitioner(inputStream, this);
+ partitioner.connect(getDocument());
+ inputStream.setColor(ColorManager.getInstance().getColor(INPUT_STREAM_RGB));
connect();
}
- public IOConsoleOutputStream getStream(String streamIdentifier) {
- for (StreamListener listener : streamListeners) {
- if (listener.getStreamId().equals(streamIdentifier)) {
- return listener.getStream();
- }
+ public void connect() {
+ IStreamsProxy streamsProxy = process.getStreamsProxy();
+ IStreamMonitor streamMonitor = streamsProxy.getErrorStreamMonitor();
+ if (streamMonitor != null) {
+ connect(streamMonitor, IDebugUIConstants.ID_STANDARD_ERROR_STREAM);
}
- return null;
+ streamMonitor = streamsProxy.getOutputStreamMonitor();
+ if (streamMonitor != null) {
+ connect(streamMonitor, IDebugUIConstants.ID_STANDARD_OUTPUT_STREAM);
+ }
+ InputReadJob inputReadJob = new InputReadJob(streamsProxy, inputStream);
+ inputReadJob.setSystem(true);
+ inputReadJob.schedule();
}
+
+ private void connect(IStreamMonitor streamMonitor, String streamIdentifier) {
+ ConsoleOutputStream stream = newOutputStream();
+ Color color = getColor(streamIdentifier);
+ stream.setColor(color);
+ synchronized (streamMonitor) {
+ StreamListener listener = new StreamListener(streamIdentifier, streamMonitor,
stream, getEncoding());
+ streamListeners.add(listener);
+ }
+ }
+ private Color getColor(String streamIdentifer) {
+ if (IDebugUIConstants.ID_STANDARD_OUTPUT_STREAM.equals(streamIdentifer)) {
+ return ColorManager.getInstance().getColor(OUTPUT_STREAM_RGB);
+ }
+ if (IDebugUIConstants.ID_STANDARD_ERROR_STREAM.equals(streamIdentifer)) {
+ return ColorManager.getInstance().getColor(ERROR_STREAM_RGB);
+ }
+ if (IDebugUIConstants.ID_STANDARD_INPUT_STREAM.equals(streamIdentifer)) {
+ return ColorManager.getInstance().getColor(INPUT_STREAM_RGB);
+ }
+ return null;
+ }
+
+ public IPageBookViewPage createPage(IConsoleView view) {
+ throw new UnsupportedOperationException();
+ }
+
+ public ConsoleOutputStream newOutputStream() {
+ ConsoleOutputStream outputStream = new ConsoleOutputStream(this);
+ outputStream.setEncoding(encoding);
+ synchronized(openStreams) {
+ openStreams.add(outputStream);
+ }
+ return outputStream;
+ }
+
+ public ConsoleInputStream getInputStream() {
+ return inputStream;
+ }
+
+ protected IConsoleDocumentPartitioner getPartitioner() {
+ return partitioner;
+ }
+
+ private void checkFinished() {
+ if (openStreams.isEmpty()) {
+ partitioner.streamsClosed();
+ }
+ }
+
+ void streamClosed(ConsoleOutputStream stream) {
+ synchronized (openStreams) {
+ openStreams.remove(stream);
+ checkFinished();
+ }
+ }
+
+ void streamClosed(ConsoleInputStream stream) {
+ synchronized (openStreams) {
+ openStreams.remove(stream);
+ checkFinished();
+ }
+ }
+
public void dispose() {
super.dispose();
+ partitioner.disconnect();
closeStreams();
disposeStreams();
DebugPlugin.getDefault().removeDebugEventListener(this);
}
- private synchronized void closeStreams() {
- if (streamsClosed) {
- return;
+ private synchronized void closeStreams() {
+ Object[] allStreams= openStreams.toArray();
+ for (int i = 0; i < allStreams.length; i++) {
+ Object stream = allStreams[i];
+ if (stream instanceof ConsoleInputStream) {
+ ConsoleInputStream is = (ConsoleInputStream) stream;
+ try {
+ is.close();
+ } catch (IOException e) {
+ }
+ } else if (stream instanceof ConsoleOutputStream) {
+ ConsoleOutputStream os = (ConsoleOutputStream) stream;
+ try {
+ os.close();
+ } catch (IOException e) {
+ }
+ }
}
- for (StreamListener listener : streamListeners) {
- listener.closeStream();
- }
- try {
- input.close();
- } catch (IOException e) {
- }
- streamsClosed = true;
- }
+// inputStream = null;
+ }
private synchronized void disposeStreams() {
for (StreamListener listener : streamListeners) {
listener.dispose();
}
- input = null;
+ inputStream = null;
}
+// private synchronized void closeStreams() {
+// if (streamsClosed) {
+// return;
+// }
+// for (StreamListener listener : streamListeners) {
+// listener.closeStream();
+// }
+// try {
+// input.close();
+// } catch (IOException e) {
+// }
+// streamsClosed = true;
+// }
+
+ public String getEncoding() {
+ return encoding;
+ }
+
+ public void handleDebugEvents(DebugEvent[] events) {
+ for (int i = 0; i < events.length; i++) {
+ DebugEvent event = events[i];
+ if (event.getSource().equals(process)) {
+ if (event.getKind() == DebugEvent.TERMINATE) {
+ closeStreams();
+ DebugPlugin.getDefault().removeDebugEventListener(this);
+ }
+ }
+ }
+ }
+
protected void init() {
super.init();
if (process.isTerminated()) {
@@ -91,54 +210,13 @@
});
}
- public void handleDebugEvents(DebugEvent[] events) {
- for (int i = 0; i < events.length; i++) {
- DebugEvent event = events[i];
- if (event.getSource().equals(process)) {
- if (event.getKind() == DebugEvent.TERMINATE) {
- closeStreams();
- DebugPlugin.getDefault().removeDebugEventListener(this);
- }
+ public ConsoleOutputStream getStream(String streamIdentifier) {
+ for (StreamListener listener : streamListeners) {
+ if (listener.getStreamId().equals(streamIdentifier)) {
+ return listener.getStream();
}
}
+ return null;
}
- public void connect() {
- IStreamsProxy streamsProxy = process.getStreamsProxy();
- IStreamMonitor streamMonitor = streamsProxy.getErrorStreamMonitor();
- if (streamMonitor != null) {
- connect(streamMonitor, IDebugUIConstants.ID_STANDARD_ERROR_STREAM);
- }
- streamMonitor = streamsProxy.getOutputStreamMonitor();
- if (streamMonitor != null) {
- connect(streamMonitor, IDebugUIConstants.ID_STANDARD_OUTPUT_STREAM);
- }
- InputReadJob inputReadJob = new InputReadJob(streamsProxy, input);
- inputReadJob.setSystem(true);
- inputReadJob.schedule();
- }
-
- private void connect(IStreamMonitor streamMonitor, String streamIdentifier) {
- IOConsoleOutputStream stream = newOutputStream();
- Color color = getColor(streamIdentifier);
- stream.setColor(color);
- synchronized (streamMonitor) {
- StreamListener listener = new StreamListener(streamIdentifier, streamMonitor,
stream, getEncoding());
- streamListeners.add(listener);
- }
- }
-
- public Color getColor(String streamIdentifer) {
- if (IDebugUIConstants.ID_STANDARD_OUTPUT_STREAM.equals(streamIdentifer)) {
- return ColorManager.getInstance().getColor(OUTPUT_STREAM_RGB);
- }
- if (IDebugUIConstants.ID_STANDARD_ERROR_STREAM.equals(streamIdentifer)) {
- return ColorManager.getInstance().getColor(ERROR_STREAM_RGB);
- }
- if (IDebugUIConstants.ID_STANDARD_INPUT_STREAM.equals(streamIdentifer)) {
- return ColorManager.getInstance().getColor(INPUT_STREAM_RGB);
- }
- return null;
- }
-
}
Added:
trunk/forge/plugins/org.jboss.tools.seam.forge/src/org/jboss/tools/seam/forge/console/ConsoleInputStream.java
===================================================================
---
trunk/forge/plugins/org.jboss.tools.seam.forge/src/org/jboss/tools/seam/forge/console/ConsoleInputStream.java
(rev 0)
+++
trunk/forge/plugins/org.jboss.tools.seam.forge/src/org/jboss/tools/seam/forge/console/ConsoleInputStream.java 2011-02-07
15:39:57 UTC (rev 29050)
@@ -0,0 +1,292 @@
+package org.jboss.tools.seam.forge.console;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.ui.console.IConsoleConstants;
+
+/**
+ * InputStream used to read input from an {@link Console}.
+ * This stream will buffer input that it receives until it has been read.
+ * An input stream is available from its {@link Console}.
+ * @since 3.1
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ * @noextend This class is not intended to be subclassed by clients.
+ *
+ */
+public class ConsoleInputStream extends InputStream implements KeyListener {
+ /**
+ * Buffer to hold data from console until it is read.
+ */
+ private byte[] input = new byte[100];
+
+ /**
+ * Location in the buffer that the next byte of data from the
+ * console should be stored.
+ */
+ private int inPointer = 0;
+
+ /**
+ * Location in the buffer that the next byte of data read from
+ * this stream should come from.
+ */
+ private int outPointer = 0;
+
+ /**
+ * The number of bytes of real data currently in the buffer.
+ */
+ private int size = 0;
+
+ /**
+ * Flag to indicate that EOF has been sent already.
+ */
+ private boolean eofSent = false;
+
+ /**
+ * Flag to indicate that the stream has been closed.
+ */
+ private boolean closed = false;
+
+ /**
+ * The console that this stream is connected to.
+ */
+ private Console console;
+
+ /**
+ * The color used to display input in the console.
+ */
+ private Color color;
+
+ /**
+ * The font style used to decorate input in the console.
+ */
+ private int fontStyle = SWT.NORMAL;
+
+
+ /**
+ * Constructs a new input stream on the given console.
+ *
+ * @param console I/O console
+ */
+ ConsoleInputStream(Console console) {
+ this.console = console;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see java.io.InputStream#read(byte[], int, int)
+ */
+ public synchronized int read(byte[] b, int off, int len) throws IOException {
+ waitForData();
+ if (available() == -1) {
+ return -1;
+ }
+
+ int toCopy = Math.min(len, size);
+ if(input.length-outPointer > toCopy) {
+ System.arraycopy(input, outPointer, b, off, toCopy);
+ outPointer += toCopy;
+ size -= toCopy;
+ } else {
+ int bytesToEnd = input.length-outPointer;
+ System.arraycopy(input, outPointer, b, off, bytesToEnd);
+ System.arraycopy(input, 0, b, off+bytesToEnd, toCopy-bytesToEnd);
+ outPointer = toCopy-bytesToEnd;
+ size -=toCopy;
+ }
+ return toCopy;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see java.io.InputStream#read(byte[])
+ */
+ public int read(byte[] b) throws IOException {
+ return read(b, 0, b.length);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see java.io.InputStream#read()
+ */
+ public synchronized int read() throws IOException {
+ waitForData();
+ if (available() == -1) {
+ return -1;
+ }
+
+ byte b = input[outPointer];
+ outPointer++;
+ if (outPointer == input.length) {
+ outPointer = 0;
+ }
+ size -= 1;
+ return b;
+ }
+
+ /**
+ * Blocks until data is available to be read.
+ * Ensure that the monitor for this object is obtained before
+ * calling this method.
+ */
+ private void waitForData() {
+ while (size == 0 && !closed) {
+ try {
+ wait();
+ } catch (InterruptedException e) {
+ System.out.println("interrupted!");
+ }
+ }
+ }
+
+ /**
+ * Appends text to this input stream's buffer.
+ *
+ * @param text the text to append to the buffer.
+ */
+ public synchronized void appendData(String text) {
+ String encoding = console.getEncoding();
+ byte[] newData;
+ if (encoding!=null)
+ try {
+ newData = text.getBytes(encoding);
+ } catch (UnsupportedEncodingException e) {
+ newData = text.getBytes();
+ }
+ else
+ newData = text.getBytes();
+
+ while(input.length-size < newData.length) {
+ growArray();
+ }
+
+ if (size == 0) { //inPointer == outPointer
+ System.arraycopy(newData, 0, input, 0, newData.length);
+ inPointer = newData.length;
+ size = newData.length;
+ outPointer = 0;
+ } else if (inPointer < outPointer || input.length - inPointer >
newData.length) {
+ System.arraycopy(newData, 0, input, inPointer, newData.length);
+ inPointer += newData.length;
+ size += newData.length;
+ } else {
+ System.arraycopy(newData, 0, input, inPointer, input.length-inPointer);
+ System.arraycopy(newData, input.length-inPointer, input, 0,
newData.length-(input.length-inPointer));
+ inPointer = newData.length-(input.length-inPointer);
+ size += newData.length;
+ }
+
+ if (inPointer == input.length) {
+ inPointer = 0;
+ }
+ notifyAll();
+ }
+
+ /**
+ * Enlarges the buffer.
+ */
+ private void growArray() {
+ byte[] newInput = new byte[input.length+1024];
+ if (outPointer < inPointer) {
+ System.arraycopy(input, outPointer, newInput, 0, size);
+ } else {
+ System.arraycopy(input, outPointer, newInput, 0, input.length-outPointer);
+ System.arraycopy(input, 0, newInput, input.length-outPointer, inPointer);
+ }
+ outPointer = 0;
+ inPointer = size;
+ input = newInput;
+ newInput = null;
+ }
+
+ /**
+ * Returns this stream's font style.
+ *
+ * @return the font style used to decorate input in the associated console
+ */
+ public int getFontStyle() {
+ return fontStyle;
+ }
+
+ /**
+ * Sets this stream's font style.
+ *
+ * @param newFontStyle the font style to be used to decorate input in the associated
console
+ */
+ public void setFontStyle(int newFontStyle) {
+ if (newFontStyle != fontStyle) {
+ int old = fontStyle;
+ fontStyle = newFontStyle;
+ console.firePropertyChange(this, IConsoleConstants.P_FONT_STYLE, new
Integer(old), new Integer(fontStyle));
+ }
+ }
+
+ /**
+ * Sets the color to used to decorate input in the associated console.
+ *
+ * @param newColor the color to used to decorate input in the associated console.
+ */
+ public void setColor(Color newColor) {
+ Color old = color;
+ if (old == null || !old.equals(newColor)) {
+ color = newColor;
+ console.firePropertyChange(this, IConsoleConstants.P_STREAM_COLOR, old,
newColor);
+ }
+ }
+
+ /**
+ * Returns the color used to decorate input in the associated console
+ *
+ * @return the color used to decorate input in the associated console
+ */
+ public Color getColor() {
+ return color;
+ }
+
+ /* (non-Javadoc)
+ * @see java.io.InputStream#available()
+ */
+ public int available() throws IOException {
+ if (closed && eofSent) {
+ throw new IOException("Input Stream Closed"); //$NON-NLS-1$
+ } else if (size == 0) {
+ if (!eofSent) {
+ eofSent = true;
+ return -1;
+ }
+ throw new IOException("Input Stream Closed"); //$NON-NLS-1$
+ }
+
+ return size;
+ }
+
+ /* (non-Javadoc)
+ * @see java.io.InputStream#close()
+ */
+ public synchronized void close() throws IOException {
+ if(closed) {
+ throw new IOException("Input Stream Closed"); //$NON-NLS-1$
+ }
+ closed = true;
+ notifyAll();
+ console.streamClosed(this);
+ }
+
+ @Override
+ public void keyPressed(KeyEvent e) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void keyReleased(KeyEvent e) {
+ String data = new StringBuffer().append(e.character).toString();
+ System.out.println("about to append data: " + data);
+ appendData(data);
+ }
+}
Property changes on:
trunk/forge/plugins/org.jboss.tools.seam.forge/src/org/jboss/tools/seam/forge/console/ConsoleInputStream.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added:
trunk/forge/plugins/org.jboss.tools.seam.forge/src/org/jboss/tools/seam/forge/console/ConsoleOutputStream.java
===================================================================
---
trunk/forge/plugins/org.jboss.tools.seam.forge/src/org/jboss/tools/seam/forge/console/ConsoleOutputStream.java
(rev 0)
+++
trunk/forge/plugins/org.jboss.tools.seam.forge/src/org/jboss/tools/seam/forge/console/ConsoleOutputStream.java 2011-02-07
15:39:57 UTC (rev 29050)
@@ -0,0 +1,260 @@
+package org.jboss.tools.seam.forge.console;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.ui.WorkbenchEncoding;
+import org.eclipse.ui.console.ConsolePlugin;
+import org.eclipse.ui.console.IConsoleConstants;
+
+/**
+ * OutputStream used to write to an IOConsole.
+ * <p>
+ * Clients are not intended to instantiate this class directly, instead
+ * use <code>IOConsole.newOutputStream()</code>.
+ * </p>
+ * <p>
+ * Clients should avoid writing large amounts of output to this stream in the UI
+ * thread. The console needs to process the output in the UI thread and if the client
+ * hogs the UI thread writing output to the console, the console will not be able
+ * to process the output.
+ * </p>
+ * @since 3.1
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class ConsoleOutputStream extends OutputStream {
+ /**
+ * Flag indicating whether this stream has been closed.
+ */
+ private boolean closed = false;
+
+ /**
+ * The console's document partitioner.
+ */
+ private ConsolePartitioner partitioner;
+
+ /**
+ * The console this stream is attached to.
+ */
+ private Console console;
+
+ /**
+ * Flag indicating that the console should be activated when data
+ * is written to this stream.
+ */
+ private boolean activateOnWrite = false;
+
+ /**
+ * The color used to decorate data written to this stream.
+ */
+ private Color color;
+
+ /**
+ * The font style used to decorate data written to this stream.
+ */
+ private int fontStyle;
+
+ private String fEncoding;
+ private String fDefaultEncoding = WorkbenchEncoding.getWorkbenchDefaultEncoding();
+
+ private boolean fNeedsEncoding = false;
+
+ private boolean prependCR;
+
+ /**
+ * Constructs a new output stream on the given console.
+ *
+ * @param console I/O console
+ */
+ ConsoleOutputStream(Console console) {
+ this.console = console;
+ this.partitioner = (ConsolePartitioner) console.getPartitioner();
+ }
+
+ /**
+ * Returns the font style used to decorate data written to this stream.
+ *
+ * @return the font style used to decorate data written to this stream
+ */
+ public int getFontStyle() {
+ return fontStyle;
+ }
+
+ /**
+ * Sets the font style to be used to decorate data written to this stream.
+ *
+ * @param newFontStyle the font style to be used to decorate data written to this
stream
+ */
+ public void setFontStyle(int newFontStyle) {
+ if (newFontStyle != fontStyle) {
+ int old = fontStyle;
+ fontStyle = newFontStyle;
+ console.firePropertyChange(this, IConsoleConstants.P_FONT_STYLE, new
Integer(old), new Integer(fontStyle));
+ }
+ }
+
+ /**
+ * Returns whether the console this stream is writing to will be activated when this
stream
+ * is written to.
+ *
+ * @return whether the console this stream is writing to will be activated when this
stream
+ * is written to.
+ */
+ public boolean isActivateOnWrite() {
+ return activateOnWrite;
+ }
+
+ /**
+ * Sets whether to activate the console this stream is writing to when this stream
+ * is written to.
+ *
+ * @param activateOnWrite whether the console this stream is writing to will be
activated when this stream
+ * is written to.
+ */
+ public void setActivateOnWrite(boolean activateOnWrite) {
+ this.activateOnWrite = activateOnWrite;
+ }
+
+ /**
+ * Sets the color of this stream. Use <code>null</code> to indicate
+ * the default color.
+ *
+ * @param newColor color of this stream, or <code>null</code>
+ */
+ public void setColor(Color newColor) {
+ Color old = color;
+ if (old == null || !old.equals(newColor)) {
+ color = newColor;
+ console.firePropertyChange(this, IConsoleConstants.P_STREAM_COLOR, old, newColor);
+ }
+ }
+
+ /**
+ * Returns the color of this stream, or <code>null</code>
+ * if default.
+ *
+ * @return the color of this stream, or <code>null</code>
+ */
+ public Color getColor() {
+ return color;
+ }
+
+ /**
+ * Returns true if the stream has been closed
+ * @return true is the stream has been closed, false otherwise.
+ */
+ public synchronized boolean isClosed() {
+ return closed;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see java.io.OutputStream#close()
+ */
+ public synchronized void close() throws IOException {
+ if(closed) {
+ throw new IOException("Output Stream is closed"); //$NON-NLS-1$
+ }
+ if (prependCR) { // force writing of last /r
+ prependCR = false;
+ notifyParitioner("\r"); //$NON-NLS-1$
+ }
+ console.streamClosed(this);
+ closed = true;
+ partitioner = null;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see java.io.OutputStream#flush()
+ */
+ public void flush() throws IOException {
+ if(closed) {
+ throw new IOException("Output Stream is closed"); //$NON-NLS-1$
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see java.io.OutputStream#write(byte[], int, int)
+ */
+ public void write(byte[] b, int off, int len) throws IOException {
+ if (fNeedsEncoding) {
+ encodedWrite(new String(b, off, len, fEncoding));
+ } else {
+ encodedWrite(new String(b, off, len));
+ }
+ }
+ /*
+ * (non-Javadoc)
+ * @see java.io.OutputStream#write(byte[])
+ */
+ public void write(byte[] b) throws IOException {
+ write(b, 0, b.length);
+ }
+ /*
+ * (non-Javadoc)
+ * @see java.io.OutputStream#write(int)
+ */
+ public void write(int b) throws IOException {
+ write(new byte[] {(byte)b}, 0, 1);
+ }
+
+ /**
+ * Writes a string to the attached console.
+ *
+ * @param str the string to write to the attached console.
+ * @throws IOException if the stream is closed.
+ */
+ public synchronized void write(String str) throws IOException {
+ if (fNeedsEncoding) {
+ byte[] defaultBytes = str.getBytes();
+ str = new String(defaultBytes, fEncoding);
+ }
+ encodedWrite(str);
+ }
+
+ private void encodedWrite(String encodedString) throws IOException {
+ if(closed) {
+ throw new IOException("Output Stream is closed"); //$NON-NLS-1$
+ }
+ if (prependCR){
+ encodedString="\r"+encodedString; //$NON-NLS-1$
+ prependCR=false;
+ }
+ if (encodedString.endsWith("\r")) { //$NON-NLS-1$
+ prependCR = true;
+ encodedString = new String(encodedString.substring(0,
encodedString.length()-1));
+ }
+ notifyParitioner(encodedString);
+ }
+
+ private void notifyParitioner(String encodedString) throws IOException {
+ try {
+ partitioner.streamAppended(this, encodedString);
+
+ if (activateOnWrite) {
+ console.activate();
+ } else {
+
ConsolePlugin.getDefault().getConsoleManager().warnOfContentChange(console);
+ }
+ } catch (IOException e) {
+ if (!closed) {
+ close();
+ }
+ throw e;
+ }
+ }
+
+ /**
+ * Sets the character encoding used to interpret characters written to this steam.
+ *
+ * @param encoding encoding identifier
+ */
+ public void setEncoding(String encoding) {
+ fEncoding = encoding;
+ fNeedsEncoding = (fEncoding!=null) &&
(!fEncoding.equals(fDefaultEncoding));
+ }
+}
Property changes on:
trunk/forge/plugins/org.jboss.tools.seam.forge/src/org/jboss/tools/seam/forge/console/ConsoleOutputStream.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added:
trunk/forge/plugins/org.jboss.tools.seam.forge/src/org/jboss/tools/seam/forge/console/ConsolePartition.java
===================================================================
---
trunk/forge/plugins/org.jboss.tools.seam.forge/src/org/jboss/tools/seam/forge/console/ConsolePartition.java
(rev 0)
+++
trunk/forge/plugins/org.jboss.tools.seam.forge/src/org/jboss/tools/seam/forge/console/ConsolePartition.java 2011-02-07
15:39:57 UTC (rev 29050)
@@ -0,0 +1,197 @@
+package org.jboss.tools.seam.forge.console;
+
+import org.eclipse.jface.text.ITypedRegion;
+import org.eclipse.swt.custom.StyleRange;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.ui.console.ConsolePlugin;
+
+/**
+ * A region in an IOConsole's document.
+ *
+ * @since 3.1
+ */
+public class ConsolePartition implements ITypedRegion {
+ public static final String OUTPUT_PARTITION_TYPE = ConsolePlugin.getUniqueIdentifier() +
".io_console_output_partition_type"; //$NON-NLS-1$
+ public static final String INPUT_PARTITION_TYPE = ConsolePlugin.getUniqueIdentifier() +
".io_console_input_partition_type"; //$NON-NLS-1$
+
+ /**
+ * The data contained by this partition.
+ */
+ private StringBuffer buffer;
+ private String type;
+ private int offset;
+ /**
+ * Output partitions are all read only.
+ * Input partitions are read only once they have been appended to the console's
input stream.
+ */
+ private boolean readOnly;
+
+ /**
+ * Only one of inputStream or outputStream will be null depending on the partitions
type.
+ */
+ private ConsoleOutputStream outputStream;
+ private ConsoleInputStream inputStream;
+ private int length;
+
+ /**
+ * Creates a new partition to contain output to console.
+ */
+ public ConsolePartition(ConsoleOutputStream outputStream, int length) {
+ this.outputStream = outputStream;
+ this.length = length;
+ this.type = OUTPUT_PARTITION_TYPE;
+ this.readOnly = true;
+ }
+
+ /**
+ * Creates a new partition to contain input from a console
+ */
+ public ConsolePartition(ConsoleInputStream inputStream, String text) {
+ this.inputStream = inputStream;
+ buffer = new StringBuffer(text);
+ length = text.length();
+ this.type = INPUT_PARTITION_TYPE;
+ this.readOnly = false;
+ }
+
+ /**
+ * Inserts a string into this partition.
+ * @param s The string to insert
+ * @param offset the offset in the partition
+ */
+ public void insert(String s, int insertOffset) {
+ buffer.insert(insertOffset, s);
+ length += s.length();
+ }
+
+ /**
+ * Deletes data from this partition.
+ * @param delOffset
+ * @param delLength
+ */
+ public void delete(int delOffset, int delLength) {
+ buffer.delete(delOffset, delOffset+delLength);
+ length -= delLength;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.text.ITypedRegion#getType()
+ */
+ public String getType() {
+ return type;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.text.IRegion#getLength()
+ */
+ public int getLength() {
+ return length;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.text.IRegion#getOffset()
+ */
+ public int getOffset() {
+ return offset;
+ }
+
+ /**
+ * Sets this partitions offset in the document.
+ *
+ * @param offset This partitions offset in the document.
+ */
+ public void setOffset(int offset) {
+ this.offset = offset;
+ }
+
+ /**
+ * Sets this partition's length.
+ *
+ * @param length
+ */
+ public void setLength(int length) {
+ this.length = length;
+ }
+
+ /**
+ * Returns the data contained in this partition.
+ * @return The data contained in this partition.
+ */
+ public String getString() {
+ return buffer.toString();
+ }
+
+ /**
+ * Returns a StyleRange object which may be used for setting the style
+ * of this partition in a viewer.
+ */
+ public StyleRange getStyleRange(int rangeOffset, int rangeLength) {
+ return new StyleRange(rangeOffset, rangeLength, getColor(), null,
getFontStyle());
+ }
+
+ /**
+ * Returns the font of the input stream if the type of the partition
+ * is <code>INPUT_PARTITION_TYPE</code>, otherwise it returns the output
+ * stream font
+ *
+ * @return the font of one of the backing streams
+ */
+ private int getFontStyle() {
+ if (type.equals(INPUT_PARTITION_TYPE)) {
+ return inputStream.getFontStyle();
+ }
+ return outputStream.getFontStyle();
+ }
+
+ /**
+ * Returns the colour of the input stream if the type of the partition
+ * is <code>INPUT_PARTITION_TYPE</code>, otherwise it returns the output
+ * stream colour
+ *
+ * @return the colour of one of the backing streams
+ */
+ public Color getColor() {
+ if (type.equals(INPUT_PARTITION_TYPE)) {
+ return inputStream.getColor();
+ }
+ return outputStream.getColor();
+ }
+
+ /**
+ * Returns if this partition is read-only.
+ *
+ * @see org.eclipse.ui.console.IConsoleDocumentPartitioner#isReadOnly(int)
+ * @return if this partition is read-only
+ */
+ public boolean isReadOnly() {
+ return readOnly;
+ }
+
+ /**
+ * Sets the read-only state of this partition to <code>true</code>.
+ *
+ * @see org.eclipse.ui.console.IConsoleDocumentPartitioner#isReadOnly(int)
+ */
+ public void setReadOnly() {
+ readOnly = true;
+ }
+
+ /**
+ * Clears the contents of the buffer
+ */
+ public void clearBuffer() {
+ buffer.setLength(0);
+ }
+
+ /**
+ * Returns the underlying output stream
+ *
+ * @return the underlying output stream
+ */
+ ConsoleOutputStream getStream() {
+ return outputStream;
+ }
+}
Property changes on:
trunk/forge/plugins/org.jboss.tools.seam.forge/src/org/jboss/tools/seam/forge/console/ConsolePartition.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added:
trunk/forge/plugins/org.jboss.tools.seam.forge/src/org/jboss/tools/seam/forge/console/ConsolePartitioner.java
===================================================================
---
trunk/forge/plugins/org.jboss.tools.seam.forge/src/org/jboss/tools/seam/forge/console/ConsolePartitioner.java
(rev 0)
+++
trunk/forge/plugins/org.jboss.tools.seam.forge/src/org/jboss/tools/seam/forge/console/ConsolePartitioner.java 2011-02-07
15:39:57 UTC (rev 29050)
@@ -0,0 +1,688 @@
+package org.jboss.tools.seam.forge.console;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.IJobManager;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentPartitionerExtension;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITypedRegion;
+import org.eclipse.jface.text.Region;
+import org.eclipse.swt.custom.StyleRange;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.console.ConsolePlugin;
+import org.eclipse.ui.console.IConsoleDocumentPartitioner;
+import org.eclipse.ui.progress.UIJob;
+import org.eclipse.ui.progress.WorkbenchJob;
+
+/**
+ * Partitions an IOConsole's document
+ * @since 3.1
+ *
+ */
+public class ConsolePartitioner implements IConsoleDocumentPartitioner,
IDocumentPartitionerExtension {
+ private PendingPartition consoleClosedPartition;
+ private IDocument document;
+ private ArrayList partitions;
+ /**
+ * Blocks of data that have not yet been appended to the document.
+ */
+ private ArrayList pendingPartitions;
+ /**
+ * A list of PendingPartitions to be appended by the updateJob
+ */
+ private ArrayList updatePartitions;
+ /**
+ * The last partition appended to the document
+ */
+ private ConsolePartition lastPartition;
+ /**
+ * Job that appends pending partitions to the document.
+ */
+ private QueueProcessingJob queueJob;
+ /**
+ * The input stream attached to this document.
+ */
+ private ConsoleInputStream inputStream;
+ /**
+ * Flag to indicate that the updateJob is updating the document.
+ */
+ private boolean updateInProgress;
+ /**
+ * A list of partitions containing input from the console, that have
+ * not been appended to the input stream yet.
+ */
+ private ArrayList inputPartitions;
+ /**
+ * offset used by updateJob
+ */
+ private int firstOffset;
+ /**
+ * An array of legal line delimiters
+ */
+ private String[] lld;
+ private int highWaterMark = -1;
+ private int lowWaterMark = -1;
+ private boolean connected = false;
+
+ private Console console;
+
+ private TrimJob trimJob = new TrimJob();
+ /**
+ * Lock for appending to and removing from the document - used
+ * to synchronize addition of new text/partitions in the update
+ * job and handling buffer overflow/clearing of the console.
+ */
+ private Object overflowLock = new Object();
+
+
+ private int fBuffer;
+
+ public ConsolePartitioner(ConsoleInputStream inputStream, Console console) {
+ this.inputStream = inputStream;
+ this.console = console;
+ trimJob.setRule(console.getSchedulingRule());
+ }
+
+ public IDocument getDocument() {
+ return document;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see
org.eclipse.jface.text.IDocumentPartitioner#connect(org.eclipse.jface.text.IDocument)
+ */
+ public void connect(IDocument doc) {
+ document = doc;
+ document.setDocumentPartitioner(this);
+ lld = document.getLegalLineDelimiters();
+ partitions = new ArrayList();
+ pendingPartitions = new ArrayList();
+ inputPartitions = new ArrayList();
+ queueJob = new QueueProcessingJob();
+ queueJob.setSystem(true);
+ queueJob.setPriority(Job.INTERACTIVE);
+ queueJob.setRule(console.getSchedulingRule());
+ connected = true;
+ }
+
+ public int getHighWaterMark() {
+ return highWaterMark;
+ }
+
+ public int getLowWaterMark() {
+ return lowWaterMark;
+ }
+
+ public void setWaterMarks(int low, int high) {
+ lowWaterMark = low;
+ highWaterMark = high;
+ ConsolePlugin.getStandardDisplay().asyncExec(new Runnable() {
+ public void run() {
+ checkBufferSize();
+ }
+ });
+ }
+
+ /**
+ * Notification from the console that all of its streams have been closed.
+ */
+ public void streamsClosed() {
+ consoleClosedPartition = new PendingPartition(null, null);
+ synchronized (pendingPartitions) {
+ pendingPartitions.add(consoleClosedPartition);
+ }
+ queueJob.schedule(); //ensure that all pending partitions are processed.
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.text.IDocumentPartitioner#disconnect()
+ */
+ public void disconnect() {
+ synchronized (overflowLock) {
+ document = null;
+ partitions.clear();
+ connected = false;
+ try {
+ inputStream.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see
org.eclipse.jface.text.IDocumentPartitioner#documentAboutToBeChanged(org.eclipse.jface.text.DocumentEvent)
+ */
+ public void documentAboutToBeChanged(DocumentEvent event) {
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see
org.eclipse.jface.text.IDocumentPartitioner#documentChanged(org.eclipse.jface.text.DocumentEvent)
+ */
+ public boolean documentChanged(DocumentEvent event) {
+ return documentChanged2(event) != null;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.text.IDocumentPartitioner#getLegalContentTypes()
+ */
+ public String[] getLegalContentTypes() {
+ return new String[] { ConsolePartition.OUTPUT_PARTITION_TYPE,
ConsolePartition.INPUT_PARTITION_TYPE };
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.text.IDocumentPartitioner#getContentType(int)
+ */
+ public String getContentType(int offset) {
+ return getPartition(offset).getType();
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.text.IDocumentPartitioner#computePartitioning(int, int)
+ */
+ public ITypedRegion[] computePartitioning(int offset, int length) {
+ int rangeEnd = offset + length;
+ int left= 0;
+ int right= partitions.size() - 1;
+ int mid= 0;
+ ConsolePartition position= null;
+
+ if (left == right) {
+ return new ConsolePartition[]{(ConsolePartition) partitions.get(0)};
+ }
+ while (left < right) {
+
+ mid= (left + right) / 2;
+
+ position= (ConsolePartition) partitions.get(mid);
+ if (rangeEnd < position.getOffset()) {
+ if (left == mid)
+ right= left;
+ else
+ right= mid -1;
+ } else if (offset > (position.getOffset() + position.getLength() - 1)) {
+ if (right == mid)
+ left= right;
+ else
+ left= mid +1;
+ } else {
+ left= right= mid;
+ }
+ }
+
+
+ List list = new ArrayList();
+ int index = left - 1;
+ if (index >= 0) {
+ position= (ConsolePartition) partitions.get(index);
+ while (index >= 0 && (position.getOffset() + position.getLength()) >
offset) {
+ index--;
+ if (index >= 0) {
+ position= (ConsolePartition) partitions.get(index);
+ }
+ }
+ }
+ index++;
+ position= (ConsolePartition) partitions.get(index);
+ while (index < partitions.size() && (position.getOffset() < rangeEnd)) {
+ list.add(position);
+ index++;
+ if (index < partitions.size()) {
+ position= (ConsolePartition) partitions.get(index);
+ }
+ }
+
+ return (ITypedRegion[]) list.toArray(new ConsolePartition[list.size()]);
+ }
+
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.text.IDocumentPartitioner#getPartition(int)
+ */
+ public ITypedRegion getPartition(int offset) {
+ for (int i = 0; i < partitions.size(); i++) {
+ ITypedRegion partition = (ITypedRegion) partitions.get(i);
+ int start = partition.getOffset();
+ int end = start + partition.getLength();
+ if (offset >= start && offset < end) {
+ return partition;
+ }
+ }
+
+ if (lastPartition == null) {
+ synchronized(partitions) {
+ lastPartition = new ConsolePartition(inputStream, ""); //$NON-NLS-1$
+ lastPartition.setOffset(offset);
+ partitions.add(lastPartition);
+ inputPartitions.add(lastPartition);
+ }
+ }
+ return lastPartition;
+ }
+
+ /**
+ * Enforces the buffer size.
+ * When the number of lines in the document exceeds the high water mark, the
+ * beginning of the document is trimmed until the number of lines equals the
+ * low water mark.
+ */
+ private void checkBufferSize() {
+ if (document != null && highWaterMark > 0) {
+ int length = document.getLength();
+ if (length > highWaterMark) {
+ if (trimJob.getState() == Job.NONE) { //if the job isn't already running
+ trimJob.setOffset(length - lowWaterMark);
+ trimJob.schedule();
+ }
+ }
+ }
+ }
+
+ /**
+ * Clears the console
+ */
+ public void clearBuffer() {
+ synchronized (overflowLock) {
+ trimJob.setOffset(-1);
+ trimJob.schedule();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
org.eclipse.jface.text.IDocumentPartitionerExtension#documentChanged2(org.eclipse.jface.text.DocumentEvent)
+ */
+ public IRegion documentChanged2(DocumentEvent event) {
+ if (document == null) {
+ return null; //another thread disconnected the partitioner
+ }
+ if (document.getLength() == 0) { //document cleared
+ if (lastPartition != null &&
lastPartition.getType().equals(ConsolePartition.INPUT_PARTITION_TYPE)) {
+ synchronized (partitions) {
+ partitions.remove(lastPartition);
+ inputPartitions.remove(lastPartition);
+ }
+ }
+ lastPartition = null;
+ return new Region(0, 0);
+ }
+
+
+ if (updateInProgress) {
+ synchronized(partitions) {
+ if (updatePartitions != null) {
+ for (Iterator i = updatePartitions.iterator(); i.hasNext(); ) {
+ PendingPartition pp = (PendingPartition) i.next();
+ if (pp == consoleClosedPartition) {
+ continue;
+ }
+
+ int ppLen = pp.text.length();
+ if (lastPartition != null && lastPartition.getStream() == pp.stream)
{
+ int len = lastPartition.getLength();
+ lastPartition.setLength(len + ppLen);
+ } else {
+ ConsolePartition partition = new ConsolePartition(pp.stream, ppLen);
+ partition.setOffset(firstOffset);
+ lastPartition = partition;
+ partitions.add(partition);
+ }
+ firstOffset += ppLen;
+ }
+ }
+ }
+ } else {// user input.
+ int amountDeleted = event.getLength() ;
+
+ if (amountDeleted > 0) {
+ int offset = event.fOffset;
+ ConsolePartition partition = (ConsolePartition) getPartition(offset);
+ if(partition == lastPartition) {
+ partition.delete(event.fOffset-partition.getOffset(), amountDeleted);
+ }
+ }
+
+ synchronized(partitions) {
+ if (lastPartition == null || lastPartition.isReadOnly()) {
+ lastPartition = new ConsolePartition(inputStream, event.fText);
+ lastPartition.setOffset(event.fOffset);
+ partitions.add(lastPartition);
+ inputPartitions.add(lastPartition);
+ } else {
+ lastPartition.insert(event.fText, (event.fOffset-lastPartition.getOffset()));
+ }
+
+ int lastLineDelimiter = -1;
+ String partitionText = lastPartition.getString();
+ lastLineDelimiter = partitionText.length();
+// for (int i = 0; i < lld.length; i++) {
+// String ld = lld[i];
+// int index = partitionText.lastIndexOf(ld);
+// if (index != -1) {
+// index += ld.length();
+// }
+// if (index > lastLineDelimiter) {
+// lastLineDelimiter = index;
+// }
+// }
+ if (lastLineDelimiter != -1) {
+ StringBuffer input = new StringBuffer();
+ Iterator it = inputPartitions.iterator();
+ while (it.hasNext()) {
+ ConsolePartition partition = (ConsolePartition) it.next();
+ if (partition.getOffset() + partition.getLength() <= event.fOffset +
lastLineDelimiter) {
+ if (partition == lastPartition) {
+ lastPartition = null;
+ }
+ input.append(partition.getString());
+ partition.clearBuffer();
+ partition.setReadOnly();
+ it.remove();
+ } else {
+ //create a new partition containing everything up to the line delimiter
+ //and append that to the string buffer.
+ String contentBefore = partitionText.substring(0, lastLineDelimiter);
+ ConsolePartition newPartition = new ConsolePartition(inputStream,
contentBefore);
+ newPartition.setOffset(partition.getOffset());
+ newPartition.setReadOnly();
+ newPartition.clearBuffer();
+ int index = partitions.indexOf(partition);
+ partitions.add(index, newPartition);
+ input.append(contentBefore);
+ //delete everything that has been appended to the buffer.
+ partition.delete(0, lastLineDelimiter);
+ partition.setOffset(lastLineDelimiter + partition.getOffset());
+ lastLineDelimiter = 0;
+ }
+ }
+ if (input.length() > 0) {
+ System.out.println("append text not!");
+ //inputStream.appendData(input.toString());
+ }
+
+ }
+ }
+ }
+
+ return new Region(event.fOffset, event.fText.length());
+ }
+
+ private void setUpdateInProgress(boolean b) {
+ updateInProgress = b;
+ }
+
+ /**
+ * A stream has been appended, add to pendingPartions list and schedule updateJob.
+ * updateJob is scheduled with a slight delay, this allows the console to run the job
+ * less frequently and update the document with a greater amount of data each time
+ * the job is run
+ * @param stream The stream that was written to.
+ * @param s The string that should be appended to the document.
+ */
+ public void streamAppended(ConsoleOutputStream stream, String s) throws IOException {
+ if (document == null) {
+ throw new IOException("Document is closed"); //$NON-NLS-1$
+ }
+ synchronized(pendingPartitions) {
+ PendingPartition last = (PendingPartition) (pendingPartitions.size() > 0 ?
pendingPartitions.get(pendingPartitions.size()-1) : null);
+ if (last != null && last.stream == stream) {
+ last.append(s);
+ } else {
+ pendingPartitions.add(new PendingPartition(stream, s));
+ if (fBuffer > 1000) {
+ queueJob.schedule();
+ } else {
+ queueJob.schedule(50);
+ }
+ }
+
+ if (fBuffer > 160000) {
+ if(Display.getCurrent() == null){
+ try {
+ pendingPartitions.wait();
+ } catch (InterruptedException e) {
+ }
+ } else {
+ /*
+ * if we are in UI thread we cannot lock it, so process
+ * queued output.
+ */
+ processQueue();
+ }
+ }
+ }
+ }
+
+ /**
+ * Holds data until updateJob can be run and the document can be updated.
+ */
+ private class PendingPartition {
+ StringBuffer text = new StringBuffer(8192);
+ ConsoleOutputStream stream;
+
+ PendingPartition(ConsoleOutputStream stream, String text) {
+ this.stream = stream;
+ if (text != null) {
+ append(text);
+ }
+ }
+
+ void append(String moreText) {
+ text.append(moreText);
+ fBuffer += moreText.length();
+ }
+ }
+
+ /**
+ * Updates the document. Will append everything that is available before
+ * finishing.
+ */
+ private class QueueProcessingJob extends UIJob {
+
+ QueueProcessingJob() {
+ super("IOConsole Updater"); //$NON-NLS-1$
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see
org.eclipse.core.internal.jobs.InternalJob#run(org.eclipse.core.runtime.IProgressMonitor)
+ */
+ public IStatus runInUIThread(IProgressMonitor monitor) {
+ processQueue();
+ return Status.OK_STATUS;
+ }
+
+ /*
+ * Job will process as much as it can each time it's run, but it gets
+ * scheduled everytime a PendingPartition is added to the list, meaning
+ * that this job could get scheduled unnecessarily in cases of heavy output.
+ * Note however, that schedule() will only reschedule a running/scheduled Job
+ * once even if it's called many times.
+ */
+ public boolean shouldRun() {
+ boolean shouldRun = connected && pendingPartitions != null &&
pendingPartitions.size() > 0;
+ return shouldRun;
+ }
+ }
+
+ void processQueue() {
+ synchronized (overflowLock) {
+ ArrayList pendingCopy = new ArrayList();
+ StringBuffer buffer = null;
+ boolean consoleClosed = false;
+ synchronized(pendingPartitions) {
+ pendingCopy.addAll(pendingPartitions);
+ pendingPartitions.clear();
+ fBuffer = 0;
+ pendingPartitions.notifyAll();
+ }
+ // determine buffer size
+ int size = 0;
+ for (Iterator i = pendingCopy.iterator(); i.hasNext(); ) {
+ PendingPartition pp = (PendingPartition) i.next();
+ if (pp != consoleClosedPartition) {
+ size+= pp.text.length();
+ }
+ }
+ buffer = new StringBuffer(size);
+ for (Iterator i = pendingCopy.iterator(); i.hasNext(); ) {
+ PendingPartition pp = (PendingPartition) i.next();
+ if (pp != consoleClosedPartition) {
+ buffer.append(pp.text);
+ } else {
+ consoleClosed = true;
+ }
+ }
+
+ if (connected) {
+ setUpdateInProgress(true);
+ updatePartitions = pendingCopy;
+ firstOffset = document.getLength();
+ try {
+ if (buffer != null) {
+ document.replace(firstOffset, 0, buffer.toString());
+ }
+ } catch (BadLocationException e) {
+ }
+ updatePartitions = null;
+ setUpdateInProgress(false);
+ }
+ if (consoleClosed) {
+ console.partitionerFinished();
+ }
+ checkBufferSize();
+ }
+
+ }
+
+ /**
+ * Job to trim the console document, runs in the UI thread.
+ */
+ private class TrimJob extends WorkbenchJob {
+
+ /**
+ * trims output up to the line containing the given offset,
+ * or all output if -1.
+ */
+ private int truncateOffset;
+
+ /**
+ * Creates a new job to trim the buffer.
+ */
+ TrimJob() {
+ super("Trim Job"); //$NON-NLS-1$
+ setSystem(true);
+ }
+
+ /**
+ * Sets the trim offset.
+ *
+ * @param offset trims output up to the line containing the given offset
+ */
+ public void setOffset(int offset) {
+ truncateOffset = offset;
+ }
+
+ /* (non-Javadoc)
+ * @see
org.eclipse.ui.progress.UIJob#runInUIThread(org.eclipse.core.runtime.IProgressMonitor)
+ */
+ public IStatus runInUIThread(IProgressMonitor monitor) {
+ IJobManager jobManager = Job.getJobManager();
+ try {
+ jobManager.join(console, monitor);
+ } catch (OperationCanceledException e1) {
+ return Status.CANCEL_STATUS;
+ } catch (InterruptedException e1) {
+ return Status.CANCEL_STATUS;
+ }
+ if (document == null) {
+ return Status.OK_STATUS;
+ }
+
+ int length = document.getLength();
+ if (truncateOffset < length) {
+ synchronized (overflowLock) {
+ try {
+ if (truncateOffset < 0) {
+ // clear
+ setUpdateInProgress(true);
+ document.set(""); //$NON-NLS-1$
+ setUpdateInProgress(false);
+ partitions.clear();
+ } else {
+ // overflow
+ int cutoffLine = document.getLineOfOffset(truncateOffset);
+ int cutOffset = document.getLineOffset(cutoffLine);
+
+
+ // set the new length of the first partition
+ ConsolePartition partition = (ConsolePartition) getPartition(cutOffset);
+ partition.setLength(partition.getOffset() + partition.getLength() -
cutOffset);
+
+ setUpdateInProgress(true);
+ document.replace(0, cutOffset, ""); //$NON-NLS-1$
+ setUpdateInProgress(false);
+
+ //remove partitions and reset Partition offsets
+ int index = partitions.indexOf(partition);
+ for (int i = 0; i < index; i++) {
+ partitions.remove(0);
+ }
+
+ int offset = 0;
+ for (Iterator i = partitions.iterator(); i.hasNext(); ) {
+ ConsolePartition p = (ConsolePartition) i.next();
+ p.setOffset(offset);
+ offset += p.getLength();
+ }
+ }
+ } catch (BadLocationException e) {
+ }
+ }
+ }
+ return Status.OK_STATUS;
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.console.IConsoleDocumentPartitioner#isReadOnly(int)
+ */
+ public boolean isReadOnly(int offset) {
+ return ((ConsolePartition)getPartition(offset)).isReadOnly();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.console.IConsoleDocumentPartitioner#computeStyleRange(int,
int)
+ */
+ public StyleRange[] getStyleRanges(int offset, int length) {
+ if (!connected) {
+ return new StyleRange[0];
+ }
+ ConsolePartition[] computedPartitions =
(ConsolePartition[])computePartitioning(offset, length);
+ StyleRange[] styles = new StyleRange[computedPartitions.length];
+ for (int i = 0; i < computedPartitions.length; i++) {
+ int rangeStart = Math.max(computedPartitions[i].getOffset(), offset);
+ int rangeLength = computedPartitions[i].getLength();
+ styles[i] = computedPartitions[i].getStyleRange(rangeStart, rangeLength);
+ }
+ return styles;
+ }
+}
Property changes on:
trunk/forge/plugins/org.jboss.tools.seam.forge/src/org/jboss/tools/seam/forge/console/ConsolePartitioner.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified:
trunk/forge/plugins/org.jboss.tools.seam.forge/src/org/jboss/tools/seam/forge/console/InputReadJob.java
===================================================================
---
trunk/forge/plugins/org.jboss.tools.seam.forge/src/org/jboss/tools/seam/forge/console/InputReadJob.java 2011-02-07
14:36:36 UTC (rev 29049)
+++
trunk/forge/plugins/org.jboss.tools.seam.forge/src/org/jboss/tools/seam/forge/console/InputReadJob.java 2011-02-07
15:39:57 UTC (rev 29050)
@@ -7,15 +7,14 @@
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.core.model.IStreamsProxy;
-import org.eclipse.ui.console.IOConsoleInputStream;
import org.jboss.tools.seam.forge.Activator;
class InputReadJob extends Job {
private IStreamsProxy streamsProxy;
- private IOConsoleInputStream input;
+ private ConsoleInputStream input;
- InputReadJob(IStreamsProxy streamsProxy, IOConsoleInputStream input) {
+ InputReadJob(IStreamsProxy streamsProxy, ConsoleInputStream input) {
super("Forge Console Input Job");
this.input = input;
this.streamsProxy = streamsProxy;
Modified:
trunk/forge/plugins/org.jboss.tools.seam.forge/src/org/jboss/tools/seam/forge/console/StreamListener.java
===================================================================
---
trunk/forge/plugins/org.jboss.tools.seam.forge/src/org/jboss/tools/seam/forge/console/StreamListener.java 2011-02-07
14:36:36 UTC (rev 29049)
+++
trunk/forge/plugins/org.jboss.tools.seam.forge/src/org/jboss/tools/seam/forge/console/StreamListener.java 2011-02-07
15:39:57 UTC (rev 29050)
@@ -5,19 +5,18 @@
import org.eclipse.debug.core.IStreamListener;
import org.eclipse.debug.core.model.IFlushableStreamMonitor;
import org.eclipse.debug.core.model.IStreamMonitor;
-import org.eclipse.ui.console.IOConsoleOutputStream;
import org.jboss.tools.seam.forge.Activator;
class StreamListener implements IStreamListener {
- private IOConsoleOutputStream stream;
+ private ConsoleOutputStream stream;
private IStreamMonitor streamMonitor;
private String streamId;
private boolean flushed = false;
private boolean listenerRemoved = false;
private String encoding;
- StreamListener(String streamIdentifier, IStreamMonitor monitor, IOConsoleOutputStream
stream, String encoding) {
+ StreamListener(String streamIdentifier, IStreamMonitor monitor, ConsoleOutputStream
stream, String encoding) {
this.streamId = streamIdentifier;
this.streamMonitor = monitor;
this.stream = stream;
@@ -30,7 +29,7 @@
return streamId;
}
- IOConsoleOutputStream getStream() {
+ ConsoleOutputStream getStream() {
return stream;
}
Modified:
trunk/forge/plugins/org.jboss.tools.seam.forge/src/org/jboss/tools/seam/forge/view/ConsoleViewer.java
===================================================================
---
trunk/forge/plugins/org.jboss.tools.seam.forge/src/org/jboss/tools/seam/forge/view/ConsoleViewer.java 2011-02-07
14:36:36 UTC (rev 29049)
+++
trunk/forge/plugins/org.jboss.tools.seam.forge/src/org/jboss/tools/seam/forge/view/ConsoleViewer.java 2011-02-07
15:39:57 UTC (rev 29050)
@@ -1,6 +1,5 @@
package org.jboss.tools.seam.forge.view;
-import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.DocumentEvent;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentListener;
@@ -8,18 +7,19 @@
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.console.ConsolePlugin;
-import org.eclipse.ui.console.IConsoleDocumentPartitioner;
-import org.eclipse.ui.console.TextConsole;
import org.eclipse.ui.console.TextConsoleViewer;
+import org.jboss.tools.seam.forge.console.Console;
public class ConsoleViewer extends TextConsoleViewer {
private boolean fAutoScroll = true;
+ private Console console = null;
private IDocumentListener fDocumentListener;
- public ConsoleViewer(Composite parent, TextConsole console) {
+ public ConsoleViewer(Composite parent, Console console) {
super(parent, console);
+ this.console = console;
}
public boolean isAutoScroll() {
@@ -31,40 +31,42 @@
}
protected void handleVerifyEvent(VerifyEvent e) {
- IDocument doc = getDocument();
- String[] legalLineDelimiters = doc.getLegalLineDelimiters();
- String eventString = e.text;
- try {
- IConsoleDocumentPartitioner partitioner = (IConsoleDocumentPartitioner)
doc.getDocumentPartitioner();
- if (!partitioner.isReadOnly(e.start)) {
- boolean isCarriageReturn = false;
- for (int i = 0; i < legalLineDelimiters.length; i++) {
- if (e.text.equals(legalLineDelimiters[i])) {
- isCarriageReturn = true;
- break;
- }
- }
-
- if (!isCarriageReturn) {
- super.handleVerifyEvent(e);
- return;
- }
- }
-
- int length = doc.getLength();
- if (e.start == length) {
- super.handleVerifyEvent(e);
- } else {
- try {
- doc.replace(length, 0, eventString);
- } catch (BadLocationException e1) {
- }
- e.doit = false;
- }
- } finally {
- StyledText text = (StyledText) e.widget;
- text.setCaretOffset(text.getCharCount());
- }
+ console.getInputStream().appendData(e.text);
+ e.doit = false;
+// IDocument doc = getDocument();
+// String[] legalLineDelimiters = doc.getLegalLineDelimiters();
+// String eventString = e.text;
+// try {
+// IConsoleDocumentPartitioner partitioner = (IConsoleDocumentPartitioner)
doc.getDocumentPartitioner();
+// if (!partitioner.isReadOnly(e.start)) {
+// boolean isCarriageReturn = false;
+// for (int i = 0; i < legalLineDelimiters.length; i++) {
+// if (e.text.equals(legalLineDelimiters[i])) {
+// isCarriageReturn = true;
+// break;
+// }
+// }
+//
+// if (!isCarriageReturn) {
+// super.handleVerifyEvent(e);
+// return;
+// }
+// }
+//
+// int length = doc.getLength();
+// if (e.start == length) {
+// super.handleVerifyEvent(e);
+// } else {
+// try {
+// doc.replace(length, 0, eventString);
+// } catch (BadLocationException e1) {
+// }
+// e.doit = false;
+// }
+// } finally {
+// StyledText text = (StyledText) e.widget;
+// text.setCaretOffset(text.getCharCount());
+// }
}
public void setReadOnly() {