xref: /OpenGrok/opengrok-indexer/src/main/java/org/opengrok/indexer/history/CVSAnnotationParser.java (revision 0e4c55544f8ea0a68e8bae37b0e502097e008ec1)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * See LICENSE.txt included in this distribution for the specific
9  * language governing permissions and limitations under the License.
10  *
11  * When distributing Covered Code, include this CDDL HEADER in each
12  * file and include the License file at LICENSE.txt.
13  * If applicable, add the following below this CDDL HEADER, with the
14  * fields enclosed by brackets "[]" replaced with your own identifying
15  * information: Portions Copyright [yyyy] [name of copyright owner]
16  *
17  * CDDL HEADER END
18  */
19 
20 /*
21  * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
22  */
23 package org.opengrok.indexer.history;
24 
25 import java.io.BufferedReader;
26 import java.io.IOException;
27 import java.io.InputStream;
28 import java.io.InputStreamReader;
29 import java.util.logging.Level;
30 import java.util.logging.Logger;
31 import java.util.regex.Matcher;
32 import java.util.regex.Pattern;
33 import org.opengrok.indexer.logger.LoggerFactory;
34 import org.opengrok.indexer.util.Executor;
35 
36 /**
37  * handles parsing the output of the {@code cvs annotate} command
38  * into an annotation object.
39  */
40 public class CVSAnnotationParser implements Executor.StreamHandler {
41     private static final Logger LOGGER = LoggerFactory.getLogger(CVSAnnotationParser.class);
42 
43     /**
44      * Pattern used to extract author/revision from {@code cvs annotate}.
45      */
46     private static final Pattern ANNOTATE_PATTERN
47             = Pattern.compile("([\\.\\d]+)\\W+\\((\\w+)");
48 
49     /**
50      * Store annotation created by processStream.
51      */
52     private final Annotation annotation;
53 
54     /**
55      * @param fileName the name of the file being annotated
56      */
CVSAnnotationParser(String fileName)57     public CVSAnnotationParser(String fileName) {
58         annotation = new Annotation(fileName);
59     }
60 
61     /**
62      * Returns the annotation that has been created.
63      *
64      * @return annotation an annotation object
65      */
getAnnotation()66     public Annotation getAnnotation() {
67         return annotation;
68     }
69 
70     @Override
processStream(InputStream input)71     public void processStream(InputStream input) throws IOException {
72         BufferedReader in = new BufferedReader(new InputStreamReader(input));
73         String line = "";
74         int lineno = 0;
75         boolean hasStarted = false;
76         Matcher matcher = ANNOTATE_PATTERN.matcher(line);
77         while ((line = in.readLine()) != null) {
78             // Skip header
79             if (!hasStarted && (line.length() == 0
80                     || !Character.isDigit(line.charAt(0)))) {
81                 continue;
82             }
83             hasStarted = true;
84 
85             // Start parsing
86             ++lineno;
87             matcher.reset(line);
88             if (matcher.find()) {
89                 String rev = matcher.group(1);
90                 String author = matcher.group(2).trim();
91                 annotation.addLine(rev, author, true);
92             } else {
93                 LOGGER.log(Level.SEVERE,
94                         "Error: did not find annotation in line {0}: [{1}]",
95                         new Object[]{String.valueOf(lineno), line});
96             }
97         }
98     }
99 }
100