xref: /OpenGrok/opengrok-indexer/src/main/java/org/opengrok/indexer/util/HeadHandler.java (revision 5d9f3aa0ca3da3a714233f987fa732f62c0965f6)
1c4679defSVladimir Kotal /*
2c4679defSVladimir Kotal  * CDDL HEADER START
3c4679defSVladimir Kotal  *
4c4679defSVladimir Kotal  * The contents of this file are subject to the terms of the
5c4679defSVladimir Kotal  * Common Development and Distribution License (the "License").
6c4679defSVladimir Kotal  * You may not use this file except in compliance with the License.
7c4679defSVladimir Kotal  *
8c4679defSVladimir Kotal  * See LICENSE.txt included in this distribution for the specific
9c4679defSVladimir Kotal  * language governing permissions and limitations under the License.
10c4679defSVladimir Kotal  *
11c4679defSVladimir Kotal  * When distributing Covered Code, include this CDDL HEADER in each
12c4679defSVladimir Kotal  * file and include the License file at LICENSE.txt.
13c4679defSVladimir Kotal  * If applicable, add the following below this CDDL HEADER, with the
14c4679defSVladimir Kotal  * fields enclosed by brackets "[]" replaced with your own identifying
15c4679defSVladimir Kotal  * information: Portions Copyright [yyyy] [name of copyright owner]
16c4679defSVladimir Kotal  *
17c4679defSVladimir Kotal  * CDDL HEADER END
18c4679defSVladimir Kotal  */
19c4679defSVladimir Kotal 
20c4679defSVladimir Kotal /*
21*5d9f3aa0SAdam Hornáček  * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
22c4679defSVladimir Kotal  */
23c4679defSVladimir Kotal package org.opengrok.indexer.util;
24c4679defSVladimir Kotal 
25c4679defSVladimir Kotal import java.io.BufferedInputStream;
26c4679defSVladimir Kotal import java.io.BufferedReader;
27c4679defSVladimir Kotal import java.io.IOException;
28c4679defSVladimir Kotal import java.io.InputStream;
29c4679defSVladimir Kotal import java.io.InputStreamReader;
30c4679defSVladimir Kotal import java.nio.charset.Charset;
31c4679defSVladimir Kotal import java.nio.charset.StandardCharsets;
32c4679defSVladimir Kotal import java.util.ArrayList;
33c4679defSVladimir Kotal import java.util.List;
34c4679defSVladimir Kotal 
35c4679defSVladimir Kotal /**
36c4679defSVladimir Kotal  * The purpose of this class is to provide {@code StreamHandler} that limits the output
37c4679defSVladimir Kotal  * to specified number of lines. Compared to {@code SpoolHandler} it consumes
38c4679defSVladimir Kotal  * limited amount of heap.
39c4679defSVladimir Kotal  */
40c4679defSVladimir Kotal public class HeadHandler implements Executor.StreamHandler {
41c4679defSVladimir Kotal     private final int maxLines;
42c4679defSVladimir Kotal 
43c4679defSVladimir Kotal     private final List<String> lines = new ArrayList<>();
44c4679defSVladimir Kotal     private final Charset charset;
45c4679defSVladimir Kotal 
46c4679defSVladimir Kotal     private static final int bufferedReaderSize = 200;
47c4679defSVladimir Kotal 
48c4679defSVladimir Kotal     /**
49c4679defSVladimir Kotal      * Charset of the underlying reader is set to UTF-8.
50c4679defSVladimir Kotal      * @param maxLines maximum number of lines to store
51c4679defSVladimir Kotal      */
HeadHandler(int maxLines)52c4679defSVladimir Kotal     public HeadHandler(int maxLines) {
53c4679defSVladimir Kotal         this.maxLines = maxLines;
54c4679defSVladimir Kotal         this.charset = StandardCharsets.UTF_8;
55c4679defSVladimir Kotal     }
56c4679defSVladimir Kotal 
57c4679defSVladimir Kotal     /**
58c4679defSVladimir Kotal      * @param maxLines maximum number of lines to store
59c4679defSVladimir Kotal      * @param charset character set
60c4679defSVladimir Kotal      */
HeadHandler(int maxLines, Charset charset)61c4679defSVladimir Kotal     public HeadHandler(int maxLines, Charset charset) {
62c4679defSVladimir Kotal         this.maxLines = maxLines;
63c4679defSVladimir Kotal         this.charset = charset;
64c4679defSVladimir Kotal     }
65c4679defSVladimir Kotal 
66c4679defSVladimir Kotal     /**
67c4679defSVladimir Kotal      * @return number of lines read
68c4679defSVladimir Kotal      */
count()69c4679defSVladimir Kotal     public int count() {
70c4679defSVladimir Kotal         return lines.size();
71c4679defSVladimir Kotal     }
72c4679defSVladimir Kotal 
73c4679defSVladimir Kotal     /**
74c4679defSVladimir Kotal      * @param index index
75c4679defSVladimir Kotal      * @return line at given index. Will be non {@code null} for valid index.
76c4679defSVladimir Kotal      */
get(int index)77c4679defSVladimir Kotal     public String get(int index) {
78c4679defSVladimir Kotal         return lines.get(index);
79c4679defSVladimir Kotal     }
80c4679defSVladimir Kotal 
81c4679defSVladimir Kotal     // for testing
getBufferedReaderSize()82c4679defSVladimir Kotal     static int getBufferedReaderSize() {
83c4679defSVladimir Kotal         return bufferedReaderSize;
84c4679defSVladimir Kotal     }
85c4679defSVladimir Kotal 
86c4679defSVladimir Kotal     @Override
processStream(InputStream input)87c4679defSVladimir Kotal     public void processStream(InputStream input) throws IOException {
88c4679defSVladimir Kotal         try (BufferedInputStream bufStream = new BufferedInputStream(input);
89c4679defSVladimir Kotal         BufferedReader reader = new BufferedReader(new InputStreamReader(bufStream, this.charset),
90c4679defSVladimir Kotal                 bufferedReaderSize)) {
91c4679defSVladimir Kotal             int lineNum = 0;
92c4679defSVladimir Kotal             while (lineNum < maxLines) {
93c4679defSVladimir Kotal                 String line = reader.readLine();
94c4679defSVladimir Kotal                 if (line == null) { // EOF
95c4679defSVladimir Kotal                     return;
96c4679defSVladimir Kotal                 }
97c4679defSVladimir Kotal                 lines.add(line);
98c4679defSVladimir Kotal                 lineNum++;
99c4679defSVladimir Kotal             }
100c4679defSVladimir Kotal 
101c4679defSVladimir Kotal             // Read and forget the rest.
102c4679defSVladimir Kotal             byte[] buf = new byte[1024];
103c4679defSVladimir Kotal             while ((bufStream.read(buf)) != -1) {
104c4679defSVladimir Kotal                 ;
105c4679defSVladimir Kotal             }
106c4679defSVladimir Kotal         }
107c4679defSVladimir Kotal     }
108c4679defSVladimir Kotal }
109