xref: /OpenGrok/opengrok-indexer/src/main/java/org/opengrok/indexer/history/ClearCaseHistoryParser.java (revision 5d9f3aa0ca3da3a714233f987fa732f62c0965f6)
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