xref: /OpenGrok/opengrok-indexer/src/main/java/org/opengrok/indexer/history/MercurialAnnotationParser.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) 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.File;
27 import java.io.IOException;
28 import java.io.InputStream;
29 import java.io.InputStreamReader;
30 import java.util.HashMap;
31 import java.util.logging.Level;
32 import java.util.logging.Logger;
33 import java.util.regex.Matcher;
34 import java.util.regex.Pattern;
35 import org.opengrok.indexer.logger.LoggerFactory;
36 import org.opengrok.indexer.util.Executor;
37 import org.opengrok.indexer.web.Util;
38 
39 /**
40  * handles parsing the output of the {@code hg annotate} command
41  * into an annotation object.
42  */
43 class MercurialAnnotationParser implements Executor.StreamHandler {
44     private static final Logger LOGGER = LoggerFactory.getLogger(MercurialAnnotationParser.class);
45 
46     private Annotation annotation = null;
47     HashMap<String, HistoryEntry> revs;
48     File file;
49 
50     /**
51      * Pattern used to extract author/revision from {@code hg annotate}.
52      */
53     private static final Pattern ANNOTATION_PATTERN
54             = Pattern.compile("^\\s*(\\d+):");
55 
MercurialAnnotationParser(File file, HashMap<String, HistoryEntry> revs)56     MercurialAnnotationParser(File file, HashMap<String, HistoryEntry> revs) {
57         this.file = file;
58         this.revs = revs;
59     }
60 
61     @Override
processStream(InputStream input)62     public void processStream(InputStream input) throws IOException {
63         annotation = new Annotation(file.getName());
64         String line;
65         int lineno = 0;
66         Matcher matcher = ANNOTATION_PATTERN.matcher("");
67 
68         try (BufferedReader in = new BufferedReader(new InputStreamReader(input))) {
69             while ((line = in.readLine()) != null) {
70                 ++lineno;
71                 matcher.reset(line);
72                 if (matcher.find()) {
73                     String rev = matcher.group(1);
74                     String author = "N/A";
75                     // Use the history index hash map to get the author.
76                     if (revs.get(rev) != null) {
77                         author = revs.get(rev).getAuthor();
78                     }
79                     annotation.addLine(rev, Util.getEmail(author.trim()), true);
80                 } else {
81                     LOGGER.log(Level.SEVERE,
82                             "Error: did not find annotation in line {0}: [{1}]",
83                             new Object[]{lineno, line});
84                 }
85             }
86         }
87     }
88 
getAnnotation()89     Annotation getAnnotation() {
90         return this.annotation;
91     }
92 }
93