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) 2017, 2020, 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.ByteArrayInputStream; 27 import java.io.File; 28 import java.io.IOException; 29 import java.io.InputStream; 30 import java.io.InputStreamReader; 31 import java.nio.charset.StandardCharsets; 32 import java.text.ParseException; 33 import java.util.ArrayList; 34 import java.util.List; 35 import org.opengrok.indexer.util.Executor; 36 37 /** 38 * Parse a stream of ClearCase log comments. 39 */ 40 class ClearCaseHistoryParser implements Executor.StreamHandler { 41 42 private History history; 43 private ClearCaseRepository repository = new ClearCaseRepository(); 44 parse(File file, Repository repos)45 History parse(File file, Repository repos) throws HistoryException { 46 repository = (ClearCaseRepository) repos; 47 try { 48 Executor executor = repository.getHistoryLogExecutor(file); 49 int status = executor.exec(true, this); 50 51 if (status != 0) { 52 throw new HistoryException("Failed to get history for: \"" + 53 file.getAbsolutePath() + "\" Exit code: " + status); 54 } 55 56 return history; 57 } catch (IOException e) { 58 throw new HistoryException("Failed to get history for: \"" + 59 file.getAbsolutePath() + "\"", e); 60 } 61 } 62 63 /** 64 * Process the output from the log command and insert the HistoryEntries 65 * into the history field. 66 * 67 * @param input The output from the process 68 * @throws java.io.IOException If an error occurs while reading the stream 69 */ 70 @Override processStream(InputStream input)71 public void processStream(InputStream input) throws IOException { 72 BufferedReader in = new BufferedReader(new InputStreamReader(input)); 73 List<HistoryEntry> entries = new ArrayList<>(); 74 String s; 75 HistoryEntry entry = null; 76 while ((s = in.readLine()) != null) { 77 if (!"create version".equals(s) && !"create directory version".equals(s)) { 78 // skip this history entry 79 while ((s = in.readLine()) != null) { 80 if (".".equals(s)) { 81 break; 82 } 83 } 84 continue; 85 } 86 87 entry = new HistoryEntry(); 88 if ((s = in.readLine()) != null) { 89 try { 90 entry.setDate(repository.parse(s)); 91 } catch (ParseException pe) { 92 // 93 // Overriding processStream() thus need to comply with the 94 // set of exceptions it can throw. 95 // 96 throw new IOException("Could not parse date: " + s, pe); 97 } 98 } 99 if ((s = in.readLine()) != null) { 100 entry.setAuthor(s); 101 } 102 if ((s = in.readLine()) != null) { 103 s = s.replace('\\', '/'); 104 entry.setRevision(s); 105 } 106 107 StringBuilder message = new StringBuilder(); 108 String glue = ""; 109 while ((s = in.readLine()) != null && !".".equals(s)) { 110 if (s.isEmpty()) { 111 // avoid empty lines in comments 112 continue; 113 } 114 message.append(glue); 115 message.append(s.trim()); 116 glue = "\n"; 117 } 118 entry.setMessage(message.toString()); 119 entry.setActive(true); 120 entries.add(entry); 121 } 122 history = new History(); 123 history.setHistoryEntries(entries); 124 } 125 126 /** 127 * Parse the given string. 128 * 129 * @param buffer The string to be parsed 130 * @return The parsed history 131 * @throws IOException if we fail to parse the buffer 132 */ parse(String buffer)133 History parse(String buffer) throws IOException { 134 processStream(new ByteArrayInputStream(buffer.getBytes(StandardCharsets.UTF_8))); 135 return history; 136 } 137 } 138