710N/A/*
710N/A * CDDL HEADER START
710N/A *
710N/A * The contents of this file are subject to the terms of the
710N/A * Common Development and Distribution License (the "License").
710N/A * You may not use this file except in compliance with the License.
710N/A *
710N/A * See LICENSE.txt included in this distribution for the specific
710N/A * language governing permissions and limitations under the License.
710N/A *
710N/A * When distributing Covered Code, include this CDDL HEADER in each
710N/A * file and include the License file at LICENSE.txt.
710N/A * If applicable, add the following below this CDDL HEADER, with the
710N/A * fields enclosed by brackets "[]" replaced with your own identifying
710N/A * information: Portions Copyright [yyyy] [name of copyright owner]
710N/A *
710N/A * CDDL HEADER END
710N/A */
710N/A
710N/A/*
710N/A * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
710N/A * Use is subject to license terms.
710N/A */
710N/Apackage org.opensolaris.opengrok.history;
710N/A
710N/Aimport java.io.BufferedReader;
710N/Aimport java.io.ByteArrayInputStream;
710N/Aimport java.io.File;
710N/Aimport java.io.IOException;
710N/Aimport java.io.InputStream;
710N/Aimport java.io.InputStreamReader;
749N/Aimport java.text.DateFormat;
710N/Aimport java.text.ParseException;
710N/Aimport java.util.ArrayList;
710N/Aimport java.util.logging.Level;
1327N/Aimport java.util.logging.Logger;
1327N/A
710N/Aimport org.opensolaris.opengrok.util.Executor;
710N/A
710N/A/**
710N/A * Parse a stream of CVS log comments.
710N/A */
770N/Aclass CVSHistoryParser implements Executor.StreamHandler {
1327N/A private static final Logger logger = Logger.getLogger(CVSHistoryParser.class.getName());
710N/A private enum ParseState {
710N/A REVISION, METADATA, COMMENT
1190N/A }
710N/A
710N/A private History history;
754N/A private CVSRepository repository=new CVSRepository();
710N/A
710N/A /**
710N/A * Process the output from the log command and insert the HistoryEntries
710N/A * into the history field.
710N/A *
710N/A * @param input The output from the process
710N/A * @throws java.io.IOException If an error occurs while reading the stream
710N/A */
815N/A @Override
710N/A public void processStream(InputStream input) throws IOException {
749N/A DateFormat df = repository.getDateFormat();
710N/A ArrayList<HistoryEntry> entries = new ArrayList<HistoryEntry>();
710N/A
710N/A BufferedReader in = new BufferedReader(new InputStreamReader(input));
1190N/A
710N/A history = new History();
710N/A HistoryEntry entry = null;
710N/A ParseState state = ParseState.REVISION;
710N/A String s = in.readLine();
710N/A while (s != null) {
710N/A if (state == ParseState.REVISION && s.startsWith("revision")) {
710N/A if (entry != null) {
710N/A entries.add(entry);
710N/A }
710N/A entry = new HistoryEntry();
710N/A entry.setActive(true);
710N/A String commit = s.substring("revision".length()).trim();
710N/A entry.setRevision(commit);
710N/A state = ParseState.METADATA;
710N/A s = in.readLine();
710N/A }
710N/A if (state == ParseState.METADATA && s.startsWith("date:")) {
710N/A for (String pair : s.split(";")) {
710N/A String[] keyVal = pair.split(":", 2);
710N/A String key = keyVal[0].trim();
710N/A String val = keyVal[1].trim();
710N/A
710N/A if ("date".equals(key)) {
710N/A try {
751N/A val = val.replace('/', '-');
710N/A entry.setDate(df.parse(val));
710N/A } catch (ParseException pe) {
1327N/A logger.warning("Failed to parse date " + val
1327N/A + ": " + pe.getMessage());
1327N/A logger.log(Level.FINE, "processStream", pe);
710N/A }
710N/A } else if ("author".equals(key)) {
710N/A entry.setAuthor(val);
710N/A }
710N/A }
710N/A
710N/A state = ParseState.COMMENT;
710N/A s = in.readLine();
710N/A }
710N/A if (state == ParseState.COMMENT) {
710N/A if (s.startsWith("--------") || s.startsWith("========")) {
710N/A state = ParseState.REVISION;
710N/A } else {
710N/A if (entry != null) {
710N/A entry.appendMessage(s);
710N/A }
710N/A }
710N/A }
710N/A s = in.readLine();
710N/A }
710N/A
710N/A if (entry != null) {
710N/A entries.add(entry);
710N/A }
710N/A
710N/A history.setHistoryEntries(entries);
710N/A }
710N/A
710N/A /**
710N/A * Parse the history for the specified file.
710N/A *
710N/A * @param file the file to parse history for
710N/A * @param repos Pointer to the SubversionReporitory
710N/A * @return object representing the file's history
710N/A */
770N/A History parse(File file, Repository repos) throws HistoryException {
749N/A repository = (CVSRepository) repos;
1016N/A try {
1016N/A Executor executor = repository.getHistoryLogExecutor(file);
1016N/A int status = executor.exec(true, this);
710N/A
1016N/A if (status != 0) {
1327N/A throw new HistoryException("Failed to get history for '" +
1327N/A file.getAbsolutePath() + "' - Exit code " + status);
1016N/A }
1016N/A } catch (IOException e) {
1327N/A throw new HistoryException("Failed to get history for '" +
1327N/A file.getAbsolutePath() + "'", e);
710N/A }
710N/A
710N/A return history;
710N/A }
1190N/A
710N/A /**
710N/A * Parse the given string.
1190N/A *
710N/A * @param buffer The string to be parsed
710N/A * @return The parsed history
710N/A * @throws IOException if we fail to parse the buffer
710N/A */
770N/A History parse(String buffer) throws IOException {
710N/A processStream(new ByteArrayInputStream(buffer.getBytes("UTF-8")));
710N/A return history;
710N/A }
710N/A}