update copyright
[fedora-idea.git] / plugins / xpath / xpath-lang / src / org / intellij / lang / xpath / xslt / run / ReadProcessThread.java
blobaf5b4412c8e9b15833458d228e5cbdd70daaaa6d
1 /*
2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package org.intellij.lang.xpath.xslt.run;
18 import com.intellij.util.Alarm;
20 import java.io.Reader;
21 import java.io.IOException;
23 /* Copied from com.intellij.execution.process.OSProcessHandler.ReadProcessThread */
24 @SuppressWarnings({"ALL"})
25 abstract class ReadProcessThread extends Thread {
26 private static final int NOTIFY_TEXT_DELAY = 300;
28 private final Reader myReader;
30 private final StringBuffer myBuffer = new StringBuffer();
31 private final Alarm myAlarm;
33 private boolean myIsClosed = false;
35 public ReadProcessThread(final Reader reader) {
36 //noinspection HardCodedStringLiteral
37 super("ReadProcessThread "+reader.getClass().getName());
38 setPriority(Thread.MAX_PRIORITY);
39 myReader = reader;
40 myAlarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD);
43 public void run() {
44 myAlarm.addRequest(new Runnable() {
45 public void run() {
46 if(!isClosed()) {
47 myAlarm.addRequest(this, NOTIFY_TEXT_DELAY);
48 checkTextAvailable();
51 }, NOTIFY_TEXT_DELAY);
53 try {
54 while (!isClosed()) {
55 final int c = readNextByte();
56 if (c == -1) {
57 break;
59 synchronized (myBuffer) {
60 myBuffer.append((char)c);
62 if (c == '\n') { // not by '\r' because of possible '\n'
63 checkTextAvailable();
67 catch (Exception e) {
68 e.printStackTrace();
71 close();
74 private int readNextByte() {
75 try {
76 return myReader.read();
78 catch (IOException e) {
79 return -1; // When process terminated Process.getInputStream()'s underlaying stream becomes closed on Linux.
83 private void checkTextAvailable() {
84 synchronized (myBuffer) {
85 if (myBuffer.length() == 0) return;
86 // warning! Since myBuffer is reused, do not use myBuffer.toString() to fetch the string
87 // because the created string will get StringBuffer's internal char array as a buffer which is possibly too large.
88 final String s = myBuffer.substring(0, myBuffer.length());
89 myBuffer.setLength(0);
90 textAvailable(s);
94 public void close() {
95 synchronized (this) {
96 if (isClosed()) {
97 return;
99 myIsClosed = true;
101 try {
102 if(Thread.currentThread() != this) {
103 join(0);
106 catch (InterruptedException e) {
108 // must close after the thread finished its execution, cause otherwise
109 // the thread will try to read from the closed (and nulled) stream
110 try {
111 myReader.close();
113 catch (IOException e1) {
114 // supressed
116 checkTextAvailable();
119 protected abstract void textAvailable(final String s);
121 private synchronized boolean isClosed() {
122 return myIsClosed;