View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *  http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.any23.cli;
19  
20  import java.io.IOException;
21  import java.io.OutputStream;
22  import java.io.PrintStream;
23  
24  /**
25   * This class reduces the verbosity of testing command-line
26   * console output by intercepting the underlying {@link PrintStream}
27   * when applicable and replacing it with a more concise version.
28   *
29   * @author Hans Brende (hansbrende@apache.org)
30   */
31  abstract class BaseTool implements Tool {
32  
33      abstract PrintStream getOut();
34      abstract void setOut(PrintStream out);
35  
36      void run(boolean concise) throws Exception {
37          PrintStream out = concise(getOut(), concise);
38          setOut(out);
39          try {
40              run();
41          } finally {
42              close(out);
43          }
44      }
45  
46      private static void close(PrintStream stream) {
47          if (stream != null && stream != System.out && stream != System.err) {
48              try {
49                  stream.close();
50              } catch (Throwable th) {
51                  //ignore
52              }
53          }
54      }
55  
56      private static PrintStream concise(PrintStream out, boolean concise) {
57          return (concise && (out == System.out || out == System.err)) ? new ConcisePrintStream(out)
58                  : (out instanceof ConcisePrintStream ? ((ConcisePrintStream) out).out : out);
59      }
60  
61      private static final class ConcisePrintStream extends PrintStream {
62  
63          private PrintStream out;
64  
65          private ConcisePrintStream(PrintStream out) {
66              super(new OutputStream() {
67                  StringBuilder sb = new StringBuilder();
68                  int lineCount;
69                  boolean truncated = false;
70                  @Override
71                  public void write(int b) throws IOException {
72                      if (sb == null) {
73                          throw new IOException("stream closed");
74                      }
75                      if (b == '\n') {
76                          lineCount++;
77                      }
78                      if (lineCount == 0 && sb.length() < 200) {
79                          sb.append((char)b);
80                      } else if (!Character.isWhitespace(b)) {
81                          truncated = true;
82                      }
83                  }
84  
85                  @Override
86                  public void close() {
87                      if (sb == null) {
88                          return;
89                      }
90                      if (truncated) {
91                          sb.append("...");
92                      }
93                      if (lineCount > 1) {
94                          sb.append("\n...\n[Suppressed ").append(lineCount).append(" lines of output.]");
95                      }
96  
97                      out.println(sb);
98                      sb = null;
99                      BaseTool.close(out);
100                 }
101             }, true);
102             this.out = out;
103         }
104 
105     }
106 
107 }