blob: 87a82a3a840c62e00cab95e28b5143f0b9ca1869 [file] [log] [blame]
package org.eclipse.team.internal.ccvs.core.client.listeners;
/*
* (c) Copyright IBM Corp. 2000, 2002.
* All Rights Reserved.
*/
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.team.ccvs.core.*;
import org.eclipse.team.ccvs.core.CVSTag;
import org.eclipse.team.ccvs.core.ICVSFolder;
import org.eclipse.team.internal.ccvs.core.resources.RemoteFile;
public class LogListener implements ICommandOutputListener {
private List entries;
private RemoteFile file;
// state
private final int BEGIN = 0, SYMBOLIC_NAMES = 1, REVISION = 2, COMMENT = 3, DONE = 4;
private List tagNames = new ArrayList(5);
private List tagRevisions = new ArrayList(5);
private int state = BEGIN; // current state
private String creationDate;
private String author;
private String revision; // revision number
private String fileState; //
private StringBuffer comment; // comment
public LogListener(RemoteFile file, List entries) {
this.file = file;
this.entries = entries;
}
public IStatus messageLine(String line, ICVSFolder commandRoot,
IProgressMonitor monitor) {
// Fields we will find in the log for a file
// keys = String (tag name), values = String (tag revision number) */
switch (state) {
case BEGIN:
if (line.startsWith("symbolic names:")) { //$NON-NLS-1$
state = SYMBOLIC_NAMES;
} else if (line.startsWith("revision ")) { //$NON-NLS-1$
revision = line.substring(9);
state = REVISION;
}
break;
case SYMBOLIC_NAMES:
if (line.startsWith("keyword substitution:")) { //$NON-NLS-1$
state = BEGIN;
} else {
int firstColon = line.indexOf(':');
String tagName = line.substring(1, firstColon);
String tagRevision = line.substring(firstColon + 2);
tagNames.add(tagName);
tagRevisions.add(tagRevision);
}
break;
case REVISION:
// date: 2000/06/19 04:56:21; author: somebody; state: Exp; lines: +114 -45
// get the creation date
int endOfDateIndex = line.indexOf(';', 6);
creationDate = line.substring(6, endOfDateIndex) + " GMT"; //$NON-NLS-1$
// get the author name
int endOfAuthorIndex = line.indexOf(';', endOfDateIndex + 1);
author = line.substring(endOfDateIndex + 11, endOfAuthorIndex);
// get the file state (because this revision might be "dead")
fileState = line.substring(endOfAuthorIndex + 10, line.indexOf(';', endOfAuthorIndex + 1));
comment = new StringBuffer();
state = COMMENT;
break;
case COMMENT:
// skip next line (info about branches) if it exists, if not then it is a comment line.
if (line.startsWith("branches:")) break; //$NON-NLS-1$
if (line.equals("=============================================================================") //$NON-NLS-1$
|| line.equals("----------------------------")) { //$NON-NLS-1$
state = DONE;
break;
}
if (comment.length() != 0) comment.append('\n');
comment.append(line);
break;
}
if (state == DONE) {
// we are only interested in tag names for this revision, remove all others.
List thisRevisionTags = new ArrayList(3);
for (int i = 0; i < tagNames.size(); i++) {
String tagName = (String) tagNames.get(i);
String tagRevision = (String) tagRevisions.get(i);
// If this is a branch tag then only include this tag with the revision
// that is the root of this branch (e.g. 1.1 is root of branch 1.1.2).
boolean isBranch = isBranchTag(tagRevision);
if (isBranch) {
int zeroIndex = tagRevision.lastIndexOf('0');
int lastDot = -1;
if (zeroIndex != -1)
lastDot = zeroIndex - 1;
else
lastDot = tagRevision.lastIndexOf('.');
tagRevision = tagRevision.substring(0, lastDot);
}
if (tagRevision.equals(revision)) {
int type = isBranch ? CVSTag.BRANCH : CVSTag.VERSION;
thisRevisionTags.add(new CVSTag(tagName, type));
}
}
LogEntry entry = new LogEntry(file, revision, author, creationDate,
comment.toString(), fileState, (CVSTag[]) thisRevisionTags.toArray(new CVSTag[0]));
entries.add(entry);
state = BEGIN;
// XXX should we reset the tagNames and tagRevisions stuff?
}
return OK;
}
public IStatus errorLine(String line, ICVSFolder commandRoot,
IProgressMonitor monitor) {
return OK;
}
/** branch tags have odd number of segments or have
* an even number with a zero as the second last segment
* e.g: 1.1.1, 1.26.0.2 are branch revision numbers */
protected boolean isBranchTag(String tagName) {
int numberOfSegments = 0;
boolean isBranch = false;
for (int i = 0; i < tagName.length(); i++) {
if (tagName.charAt(i) == '.')
numberOfSegments++;
}
isBranch = (numberOfSegments % 2) == 0;
if (!isBranch && tagName.lastIndexOf('0') != -1)
isBranch = true;
return isBranch;
}
}