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.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 * BazaarAnnotationParser handles parsing the output of the {@code bzr blame} 38 * command into an annotation object. 39 */ 40 public class BazaarAnnotationParser implements Executor.StreamHandler { 41 42 private static final Logger LOGGER = LoggerFactory.getLogger(BazaarAnnotationParser.class); 43 44 /** 45 * Store annotation created by processStream. 46 */ 47 private final Annotation annotation; 48 49 /** 50 * Pattern used to extract author/revision. 51 */ 52 private static final Pattern BLAME_PATTERN 53 = Pattern.compile("^\\W*(\\S+)\\W+(\\S+).*$"); 54 55 /** 56 * @param fileName the name of the file being annotated 57 */ BazaarAnnotationParser(String fileName)58 public BazaarAnnotationParser(String fileName) { 59 annotation = new Annotation(fileName); 60 } 61 62 /** 63 * Returns the annotation that has been created. 64 * 65 * @return annotation an annotation object 66 */ getAnnotation()67 public Annotation getAnnotation() { 68 return annotation; 69 } 70 71 @Override processStream(InputStream input)72 public void processStream(InputStream input) throws IOException { 73 try (BufferedReader in = new BufferedReader(new InputStreamReader(input))) { 74 String line = ""; 75 int lineno = 0; 76 Matcher matcher = BLAME_PATTERN.matcher(line); 77 while ((line = in.readLine()) != null) { 78 ++lineno; 79 matcher.reset(line); 80 if (matcher.find()) { 81 String rev = matcher.group(1); 82 String author = matcher.group(2).trim(); 83 annotation.addLine(rev, author, true); 84 } else { 85 LOGGER.log(Level.SEVERE, 86 "Error: did not find annotation in line {0}: [{1}]", 87 new Object[]{String.valueOf(lineno), line}); 88 } 89 } 90 } 91 } 92 } 93