buildframework/helium/sf/java/scm/src/com/nokia/maven/scm/provider/hg/command/log/HgChangeLogConsumer.java
/*
* Copyright (c) 2007-2008 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of the License "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:
*
*/
package com.nokia.maven.scm.provider.hg.command.log;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.maven.scm.ChangeFile;
import org.apache.maven.scm.ScmBranch;
import org.apache.maven.scm.ScmException;
import org.apache.maven.scm.ScmFileStatus;
import org.apache.maven.scm.ScmRevision;
import org.apache.maven.scm.ScmTag;
import org.apache.maven.scm.log.ScmLogger;
import org.apache.maven.scm.provider.hg.command.HgConsumer;
import com.nokia.maven.scm.provider.hg.VersionChangeSet;
/**
* Consumer of 'hg changelog' command output.
*/
public class HgChangeLogConsumer extends HgConsumer {
private static final String TIME_PATTERN = "EEE MMM dd HH:mm:ss yyyy Z";
private static final String REVNO_TAG = "changeset: ";
private static final String TAG_BRANCH = "branch: ";
private static final String TAG_TAG = "tag: ";
private static final String AUTHOR_TAG = "user: ";
private static final String TIME_STAMP_TOKEN = "date: ";
private static final String MESSAGE_TOKEN = "description:";
private static final String MERGED_TOKEN = "merged: ";
private static final String FILES_TOKEN = "files: ";
private String prevLine = "";
private String prevPrevLine = "";
private ArrayList<VersionChangeSet> logEntries = new ArrayList<VersionChangeSet>();
private VersionChangeSet currentChange;
private VersionChangeSet lastChange;
private boolean isMergeEntry;
private String currentRevision;
private String currentTag; // don't know what to do with this
private String currentBranch;
private String userDatePattern;
private boolean spoolingComments;
private List<String> currentComment;
public HgChangeLogConsumer(ScmLogger logger, String userDatePattern) {
super(logger);
this.userDatePattern = userDatePattern;
}
public List<VersionChangeSet> getModifications() {
return logEntries;
}
/** {@inheritDoc} */
public void consumeLine(String line) {
// override default behavior which tries to pick through things for
// some standard messages. that
// does not apply here
doConsume(null, line);
}
/** {@inheritDoc} */
public void doConsume(ScmFileStatus status, String line) {
String tmpLine = line;
// If current status == null then this is a new entry
// If the line == "" and previous line was "", then this is also a new
// entry
if ((line.equals("") && (prevLine.equals("") && prevPrevLine.equals("")))
|| currentComment == null) {
if (currentComment != null) {
StringBuffer comment = new StringBuffer();
int i = 0;
for (String eachComment : currentComment) {
comment.append(eachComment);
if (i + 1 < currentComment.size() - 1) {
comment.append('\n');
}
i += 1;
}
currentChange.setComment(comment.toString());
}
spoolingComments = false;
// If last entry was part a merged entry
if (isMergeEntry && lastChange != null) {
String comment = lastChange.getComment();
comment += "\n[MAVEN]: Merged from "
+ currentChange.getAuthor();
comment += "\n[MAVEN]: " + currentChange.getDateFormatted();
comment += "\n[MAVEN]: " + currentChange.getComment();
lastChange.setComment(comment);
}
// Init a new changeset
currentChange = new VersionChangeSet();
currentChange.setFiles(new ArrayList<ChangeFile>());
logEntries.add(currentChange);
// Reset member vars
currentComment = new ArrayList<String>();
currentRevision = "";
isMergeEntry = false;
}
if (spoolingComments) {
currentComment.add(line);
} else if (line.startsWith(MESSAGE_TOKEN)) {
spoolingComments = true;
} else if (line.startsWith(MERGED_TOKEN)) {
// This is part of lastChange and is not a separate log entry
isMergeEntry = true;
logEntries.remove(currentChange);
if (logEntries.size() > 0) {
lastChange = logEntries.get(logEntries
.size() - 1);
} else {
getLogger().warn("First entry was unexpectedly a merged entry");
lastChange = null;
}
} else if (line.startsWith(REVNO_TAG)) {
tmpLine = line.substring(REVNO_TAG.length()).trim();
currentRevision = tmpLine;
try {
currentChange.setScmVersion(new ScmRevision(tmpLine));
} catch (ScmException se) {
getLogger().warn(se.getMessage());
}
} else if (line.startsWith(TAG_TAG)) {
tmpLine = line.substring(TAG_TAG.length()).trim();
currentTag = tmpLine;
try {
currentChange.setScmVersion(new ScmTag(tmpLine));
} catch (ScmException se) {
getLogger().warn(se.getMessage());
}
} else if (line.startsWith(TAG_BRANCH)) {
tmpLine = line.substring(TAG_BRANCH.length()).trim();
currentBranch = tmpLine;
try {
currentChange.setScmVersion(new ScmBranch(tmpLine));
} catch (ScmException se) {
getLogger().warn(se.getMessage());
}
} else if (line.startsWith(AUTHOR_TAG)) {
tmpLine = line.substring(AUTHOR_TAG.length());
tmpLine = tmpLine.trim();
currentChange.setAuthor(tmpLine);
} else if (line.startsWith(TIME_STAMP_TOKEN)) {
tmpLine = line.substring(TIME_STAMP_TOKEN.length()).trim();
Date date = null;
try {
SimpleDateFormat format = new SimpleDateFormat(TIME_PATTERN);
date = format.parse(tmpLine);
currentChange.setDate(date);
} catch (ParseException e) {
getLogger().warn(
"Consumer Change Log Date Format not supported:"
+ e.getMessage());
}
} else if (line.startsWith(FILES_TOKEN)) {
tmpLine = line.substring(FILES_TOKEN.length()).trim();
String[] files = tmpLine.split(" ");
for (String eachFile : files) {
ChangeFile changeFile = new ChangeFile(eachFile, currentRevision);
currentChange.addFile(changeFile);
}
} else {
if (!line.equals("")) {
getLogger().warn("Could not figure out: " + line);
}
}
// record previous line
prevLine = line;
prevPrevLine = prevLine;
}
}