87N/A/*
87N/A * CDDL HEADER START
87N/A *
87N/A * The contents of this file are subject to the terms of the
87N/A * Common Development and Distribution License (the "License").
87N/A * You may not use this file except in compliance with the License.
87N/A *
87N/A * See LICENSE.txt included in this distribution for the specific
87N/A * language governing permissions and limitations under the License.
87N/A *
87N/A * When distributing Covered Code, include this CDDL HEADER in each
87N/A * file and include the License file at LICENSE.txt.
87N/A * If applicable, add the following below this CDDL HEADER, with the
87N/A * fields enclosed by brackets "[]" replaced with your own identifying
87N/A * information: Portions Copyright [yyyy] [name of copyright owner]
87N/A *
87N/A * CDDL HEADER END
87N/A */
87N/A
87N/A/*
87N/A * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
87N/A * Use is subject to license terms.
87N/A */
87N/A
87N/Apackage org.opensolaris.opengrok.history;
87N/A
878N/Aimport java.io.IOException;
878N/Aimport java.io.StringWriter;
878N/Aimport java.io.Writer;
87N/Aimport java.util.ArrayList;
878N/Aimport java.util.HashMap;
879N/Aimport java.util.HashSet;
878N/Aimport java.util.Iterator;
457N/Aimport java.util.List;
879N/Aimport java.util.Map;
878N/Aimport java.util.Map.Entry;
879N/Aimport java.util.Set;
879N/A
879N/Aimport java.util.logging.Logger;
878N/Aimport org.opensolaris.opengrok.web.Util;
878N/A
87N/A/**
87N/A * Class representing file annotation, i.e., revision and author for the last
87N/A * modification of each line in the file.
87N/A */
87N/Apublic class Annotation {
87N/A
457N/A private final List<Line> lines = new ArrayList<Line>();
879N/A private final Map<String, String> desc = new HashMap<String, String>();
87N/A private int widestRevision;
87N/A private int widestAuthor;
456N/A private final String filename;
879N/A static final Logger log = Logger.getLogger(Annotation.class.getName());
1190N/A
140N/A public Annotation(String filename) {
140N/A this.filename = filename;
140N/A }
1190N/A
87N/A /**
87N/A * Gets the revision for the last change to the specified line.
87N/A *
87N/A * @param line line number (counting from 1)
91N/A * @return revision string, or an empty string if there is no information
91N/A * about the specified line
87N/A */
87N/A public String getRevision(int line) {
91N/A try {
91N/A return lines.get(line-1).revision;
91N/A } catch (IndexOutOfBoundsException e) {
91N/A return "";
91N/A }
87N/A }
87N/A
87N/A /**
878N/A * Gets all revisions that are in use, first is the lowest one (sorted using natural order)
1190N/A *
878N/A * @return list of all revisions the file has
878N/A */
879N/A public Set<String> getRevisions() {
879N/A Set<String> ret=new HashSet<String>();
878N/A for (Iterator<Line> it = this.lines.iterator(); it.hasNext();) {
878N/A Line ln = it.next();
1190N/A ret.add(ln.revision);
1190N/A }
878N/A return ret;
878N/A }
878N/A
878N/A /**
87N/A * Gets the author who last modified the specified line.
87N/A *
87N/A * @param line line number (counting from 1)
91N/A * @return author, or an empty string if there is no information about the
91N/A * specified line
87N/A */
87N/A public String getAuthor(int line) {
91N/A try {
91N/A return lines.get(line-1).author;
91N/A } catch (IndexOutOfBoundsException e) {
91N/A return "";
91N/A }
87N/A }
87N/A
87N/A /**
168N/A * Gets the enabled state for the last change to the specified line.
168N/A *
168N/A * @param line line number (counting from 1)
168N/A * @return true if the xref for this revision is enabled, false otherwise
168N/A */
168N/A public boolean isEnabled(int line) {
168N/A try {
168N/A return lines.get(line-1).enabled;
168N/A } catch (IndexOutOfBoundsException e) {
168N/A return false;
168N/A }
168N/A }
168N/A
168N/A /**
87N/A * Returns the size of the file (number of lines).
87N/A *
87N/A * @return number of lines
87N/A */
87N/A public int size() {
87N/A return lines.size();
87N/A }
87N/A
87N/A /**
87N/A * Returns the widest revision string in the file (used for pretty
87N/A * printing).
87N/A *
87N/A * @return number of characters in the widest revision string
87N/A */
87N/A public int getWidestRevision() {
87N/A return widestRevision;
87N/A }
87N/A
87N/A /**
87N/A * Returns the widest author name in the file (used for pretty printing).
87N/A *
87N/A * @return number of characters in the widest author string
87N/A */
87N/A public int getWidestAuthor() {
87N/A return widestAuthor;
87N/A }
87N/A
87N/A /**
87N/A * Adds a line to the file.
87N/A *
87N/A * @param revision revision number
87N/A * @param author author name
87N/A */
168N/A void addLine(String revision, String author, boolean enabled) {
168N/A final Line line = new Line(revision, author, enabled);
117N/A lines.add(line);
117N/A widestRevision = Math.max(widestRevision, line.revision.length());
117N/A widestAuthor = Math.max(widestAuthor, line.author.length());
87N/A }
87N/A
1190N/A void addDesc(String revision, String description) {
878N/A desc.put(revision, Util.encode(description));
878N/A }
878N/A
1190N/A public String getDesc(String revision) {
878N/A return desc.get(revision);
878N/A }
878N/A
87N/A /** Class representing one line in the file. */
87N/A private static class Line {
87N/A final String revision;
87N/A final String author;
168N/A final boolean enabled;
168N/A Line(String rev, String aut, boolean ena) {
117N/A revision = (rev == null) ? "" : rev;
117N/A author = (aut == null) ? "" : aut;
168N/A enabled = ena;
87N/A }
87N/A }
140N/A
140N/A public String getFilename() {
140N/A return filename;
140N/A }
878N/A
878N/A //TODO below might be useless, need to test with more SCMs and different commit messages
878N/A // to see if it will not be usefull, if title attribute of <a> loses it's breath
878N/A public void writeTooltipMap(Writer out) throws IOException {
1227N/A out.append("<script type=\"text/javascript\">\nvar desc = new Object();\n");
878N/A for (Entry<String, String> entry : desc.entrySet()) {
1227N/A out.append("desc['");
1227N/A out.append(entry.getKey());
1227N/A out.append("'] = \"");
1227N/A out.append(entry.getValue());
1227N/A out.append("\";\n");
878N/A }
1227N/A out.append("</script>\n");
878N/A }
878N/A
878N/A @Override
878N/A public String toString() {
1227N/A StringWriter sw = new StringWriter();
972N/A for (Line line : lines) {
1227N/A sw.append(line.revision);
1227N/A sw.append("|");
1227N/A sw.append(line.author);
1227N/A sw.append(": \n");
972N/A }
1227N/A
972N/A try {
972N/A writeTooltipMap(sw);
972N/A } catch (IOException e) {
972N/A log.finest(e.getMessage());
972N/A }
878N/A
1227N/A return sw.toString();
972N/A }
87N/A}