Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Copyright 2000-2011 JetBrains s.r.o.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   * http://www.apache.org/licenses/LICENSE-2.0
   *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 package com.intellij.execution.testframework.sm.runner;
 
 import  com.intellij.execution.process.ProcessOutputTypes;
 import  com.intellij.openapi.util.Key;
 import  gnu.trove.THashMap;
 import  org.jetbrains.annotations.NotNull;
 
 import java.util.List;
 import java.util.Map;
 
 
 public abstract class OutputLineSplitter {
   private static final String TEAMCITY_SERVICE_MESSAGE_PREFIX = "##teamcity[";
 
   private final boolean myStdinSupportEnabled;
 
   private final Map<Key, StringBuildermyBuffers = new THashMap<Key, StringBuilder>();
   private final List<OutputChunkmyStdOutChunks = new ArrayList<OutputChunk>();
 
   public OutputLineSplitter(boolean stdinEnabled) {
     .put(ProcessOutputTypes.SYSTEM, new StringBuilder());
     .put(ProcessOutputTypes.STDERR, new StringBuilder());
 
      = stdinEnabled;
   }
 
   public void process(final String textfinal Key outputType) {
     int from = 0;
     int to = 0;
     for (; to < text.length(); to++) {
       if (text.charAt(to) == '\n') {
         processLine(text.substring(fromto + 1), outputType);
         from = to + 1;
       }
     }
     if (from < text.length()) {
       processLine(text.substring(from), outputType);
     }
   }
 
   private void processLine(String text, Key outputType) {
     if (!.keySet().contains(outputType)) {
       processStdOutConsistently(textoutputType);
     }
     else {
       StringBuilder buffer = .get(outputType);
       if (!text.endsWith("\n")) {
         buffer.append(text);
         return;
       }
       if (buffer.length() > 0) {
         buffer.append(text);
         text = buffer.toString();
         buffer.setLength(0);
       }
 
       onLineAvailable(textoutputTypefalse);
     }
   }
 
   private void processStdOutConsistently(final String textfinal Key outputType) {
     final int textLength = text.length();
     if (textLength == 0) {
       return;
     }
 
     synchronized () {
       .add(new OutputChunk(outputTypetext));
     }
 
     final char lastChar = text.charAt(textLength - 1);
     if (lastChar == '\n' || lastChar == '\r') {
       // buffer contains consistent string
       flushStdOutBuffer();
     }
     else {
       // test framework may show some promt and ask user for smth. Question may not
       // finish with \n or \r thus buffer wont be flushed and user will have to input smth
       // before question. And question will became visible with next portion of text.
       // Such behaviour is confusing. So
       // 1. Let's assume that sevice messages starts with \n if console is editable
       // 2. Then we can suggest that each service message will start from new line and buffer should
       //    be flushed before every service message. Thus if chunks list is empty and output doesn't end
      //    with \n or \r but starts with ##teamcity then it is a service message and should be buffered otherwise
      //    we can safely flush buffer.
      // TODO if editable:
        flushStdOutBuffer();
      }
    }
  }
  private void flushStdOutBuffer() {
    // if osColoredProcessHandler was attached it can split string with several colors
    // in several  parts. Thus '\n' symbol may be send as one part with some color
    // such situation should differ from single '\n' from process that is used by TC reporters
    // to separate TC commands from other stuff + optimize flushing
    // TODO: probably in IDEA mode such runners shouldn't add explicit \n because we can
    // successfully process broken messages across several flushes
    // size of parts may tell us either \n was single in original flushed data or it was
    // separated by process handler
    List<OutputChunkchunks = new ArrayList<OutputChunk>();
    OutputChunk lastChunk = null;
    synchronized () {
      for (OutputChunk chunk : ) {
        if (lastChunk != null && chunk.getKey() == lastChunk.getKey()) {
          lastChunk.append(chunk.getText());
        }
        else {
          lastChunk = chunk;
          chunks.add(chunk);
        }
      }
      .clear();
    }
    final boolean isTCLikeFakeOutput = chunks.size() == 1;
    for (OutputChunk chunk : chunks) {
      onLineAvailable(chunk.getText(), chunk.getKey(), isTCLikeFakeOutput);
    }
  }
  public void flush() {
    for (Map.Entry<Key, StringBuildereach : .entrySet()) {
      StringBuilder buffer = each.getValue();
      if (buffer.length() > 0) {
        onLineAvailable(buffer.toString(), each.getKey(), false);
        buffer.setLength(0);
      }
    }
  }
  protected boolean isMostLikelyServiceMessagePart(@NotNull final String text) {
  }
  protected abstract void onLineAvailable(@NotNull String text, @NotNull Key outputTypeboolean tcLikeFakeOutput);
  private static class OutputChunk {
    private final Key myKey;
    private String myText;
    private OutputChunk(Key keyString text) {
       = key;
       = text;
    }
    public Key getKey() {
      return ;
    }
    public String getText() {
      return ;
    }
    public void append(String text) {
       += text;
    }
  }
New to GrepCode? Check out our FAQ X