/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * See LICENSE.txt included in this distribution for the specific * language governing permissions and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at LICENSE.txt. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ package org.opensolaris.opengrok.history; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.logging.Level; import java.util.logging.Logger; import org.apache.commons.jrcs.diff.PatchFailedException; import org.apache.commons.jrcs.rcs.Archive; import org.apache.commons.jrcs.rcs.InvalidFileFormatException; import org.apache.commons.jrcs.rcs.Node; import org.apache.commons.jrcs.rcs.ParseException; import org.apache.commons.jrcs.rcs.Version; /** * Access to an RCS repository. */ public class RCSRepository extends Repository { private static final Logger logger = Logger.getLogger(RCSRepository.class.getName()); private static final long serialVersionUID = 1L; /** * Create a new instance of type {@code RCS}. */ public RCSRepository() { working = Boolean.TRUE; type = "RCS"; } /** * {@inheritDoc} */ @Override public boolean fileHasHistory(File file) { return getRCSFile(file) != null; } /** * {@inheritDoc} */ @Override public InputStream getHistoryGet(String parent, String basename, String rev) { try { File file = new File(parent, basename); File rcsFile = getRCSFile(file); return new RCSget(rcsFile.getPath(), rev); } catch (IOException ioe) { logger.warning("Failed to retrieve revision '" + rev + "' of '" + basename + "': " + ioe.getMessage()); logger.log(Level.FINE, "getHistoryGet", ioe); return null; } } /** * {@inheritDoc} */ @Override public boolean fileHasAnnotation(File file) { return fileHasHistory(file); } /** * {@inheritDoc} */ @Override protected Annotation annotate(File file, String revision) throws IOException { File rcsFile = getRCSFile(file); return rcsFile == null ? null : annotate(file, revision, rcsFile); } static Annotation annotate(File file, String revision, File rcsFile) throws IOException { try { Archive archive = new Archive(rcsFile.getPath()); // If revision is null, use current revision Version version = revision == null ? archive.getRevisionVersion() : archive.getRevisionVersion(revision); // Get the revision with annotation archive.getRevision(version, true); Annotation a = new Annotation(file.getName()); // A comment in Archive.getRevisionNodes() says that it is not // considered public API anymore, but it works. for (Node n : archive.getRevisionNodes()) { String rev = n.getVersion().toString(); String author = n.getAuthor(); a.addLine(rev, author); } return a; } catch (ParseException pe) { throw new IOException("Parse exception annotating RCS repository: " + pe.getMessage(), pe); } catch (InvalidFileFormatException iffe) { throw new IOException("File format exception annotating RCS repository: " + iffe.getMessage(), iffe); } catch (PatchFailedException pfe) { throw new IOException("Patch failed exception annotating RCS repository: " + pfe.getMessage(), pfe); } } @Override void update() throws IOException { throw new IOException("Not supported yet."); } /** * {@inheritDoc} */ @Override public boolean isRepositoryFor(File file) { File rcsDir = new File(file, "RCS"); return rcsDir.isDirectory(); } /** * Get a {@code File} object that points to the file that contains * RCS history for the specified file. * * @param file the file whose corresponding RCS file should be found * @return the file which contains the RCS history, or {@code null} if it * cannot be found */ @SuppressWarnings("static-method") protected File getRCSFile(File file) { File dir = new File(file.getParentFile(), "RCS"); String baseName = file.getName(); File rcsFile = new File(dir, baseName + ",v"); return rcsFile.exists() ? rcsFile : null; } /** * {@inheritDoc} */ @Override public boolean hasHistoryForDirectories() { return false; } /** * {@inheritDoc} */ @Override public History getHistory(File file) throws HistoryException { return new RCSHistoryParser().parse(file); } }