/*
* ====================================================================
* Copyright (c) 2004-2012 TMate Software Ltd. All rights reserved.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://svnkit.com/license.html
* If newer versions of this license are posted there, you may use a
* newer version instead, at your option.
* ====================================================================
*/
package org.tmatesoft.svn.core.wc.xml;
import java.io.File;
import java.util.Date;
import org.tmatesoft.svn.core.SVNErrorCode;
import org.tmatesoft.svn.core.SVNErrorMessage;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.internal.util.SVNDate;
import org.tmatesoft.svn.core.internal.wc.SVNErrorManager;
import org.tmatesoft.svn.core.wc.ISVNAnnotateHandler;
import org.tmatesoft.svn.util.ISVNDebugLog;
import org.tmatesoft.svn.util.SVNLogType;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
/**
* This is an implementation of the <b>ISVNAnnotateHandler</b> interface
* that writes XML formatted annotation information to a specified
* <b>ContentHandler</b>.
*
* @version 1.3
* @author TMate Software Ltd.
* @since 1.2
*/
public class SVNXMLAnnotateHandler extends AbstractXMLHandler implements ISVNAnnotateHandler {
/**
* <code>'path'</code> attribute.
*/
public static final String PATH_ATTR = "path";
/**
* <code>'revision'</code> attribute.
*/
public static final String REVISION_ATTR = "revision";
/**
* <code>'date'</code> tag.
*/
public static final String DATE_TAG = "date";
/**
* <code>'author'</code> tag.
*/
public static final String AUTHOR_TAG = "author";
/**
* <code>'commit'</code> tag.
*/
public static final String COMMIT_TAG = "commit";
/**
* <code>'entry'</code> tag.
*/
public static final String ENTRY_TAG = "entry";
/**
* <code>'line-number'</code> tag.
*/
public static final String LINE_NUMBER_TAG = "line-number";
/**
* <code>'target'</code> tag.
*/
public static final String TARGET_TAG = "target";
/**
* <code>'blame'</code> tag.
*/
public static final String BLAME_TAG = "blame";
/**
* <code>'merged'</code> tag.
*/
public static final String MERGED_TAG = "merged";
private long myLineNumber;
private boolean myIsUseMergeHistory;
/**
* Creates a new annotation handler.
*
* @param contentHandler a <b>ContentHandler</b> to form
* an XML tree
*/
public SVNXMLAnnotateHandler(ContentHandler contentHandler) {
this(contentHandler, null);
}
/**
* Creates a new annotation handler.
*
* @param contentHandler a <b>ContentHandler</b> to form
* an XML tree
* @param log a debug logger
*/
public SVNXMLAnnotateHandler(ContentHandler contentHandler, ISVNDebugLog log) {
this(contentHandler, log, false);
}
/**
* Creates a new annotation handler.
*
* @param contentHandler a <b>ContentHandler</b> to form
* an XML tree
* @param log a debug logger
* @param isUseMergeHistory whether merge history should be taken into account or not
*/
public SVNXMLAnnotateHandler(ContentHandler contentHandler, ISVNDebugLog log, boolean isUseMergeHistory) {
super(contentHandler, log);
myIsUseMergeHistory = isUseMergeHistory;
}
protected String getHeaderName() {
return BLAME_TAG;
}
/**
* Begins an XML tree with the target path/URL for which
* annotating is run.
*
* @param pathOrURL a target file WC path or URL
*/
public void startTarget(String pathOrURL) {
myLineNumber = 1;
try {
addAttribute(PATH_ATTR, pathOrURL);
openTag(TARGET_TAG);
} catch (SAXException e) {
getDebugLog().logSevere(SVNLogType.DEFAULT, e);
}
}
/**
* Closes the formatted XML output.
*
*/
public void endTarget() {
myLineNumber = 1;
try {
closeTag(TARGET_TAG);
} catch (SAXException e) {
getDebugLog().logSevere(SVNLogType.DEFAULT, e);
}
}
/**
* Handles line annotation producing corresponding xml tags.
*
* @param date
* @param revision
* @param author
* @param line
* @throws SVNException
*/
public void handleLine(Date date, long revision, String author, String line) throws SVNException {
try {
addAttribute(LINE_NUMBER_TAG, myLineNumber + "");
openTag(ENTRY_TAG);
if (revision >= 0) {
addAttribute(REVISION_ATTR, revision + "");
openTag(COMMIT_TAG);
addTag(AUTHOR_TAG, author);
addTag(DATE_TAG, SVNDate.formatDate(date));
closeTag(COMMIT_TAG);
}
closeTag(ENTRY_TAG);
} catch (SAXException e) {
getDebugLog().logSevere(SVNLogType.DEFAULT, e);
SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.XML_MALFORMED, e.getLocalizedMessage());
SVNErrorManager.error(err, e, SVNLogType.DEFAULT);
} finally {
myLineNumber++;
}
}
/**
* Handles line annotation producing corresponding xml tags.
*
* @param date
* @param revision
* @param author
* @param line
* @param mergedDate
* @param mergedRevision
* @param mergedAuthor
* @param mergedPath
* @param lineNumber
* @throws SVNException
*/
public void handleLine(Date date, long revision, String author, String line,
Date mergedDate, long mergedRevision, String mergedAuthor,
String mergedPath, int lineNumber) throws SVNException {
try {
addAttribute(LINE_NUMBER_TAG, ++lineNumber + "");
openTag(ENTRY_TAG);
if (revision >= 0) {
addAttribute(REVISION_ATTR, revision + "");
openTag(COMMIT_TAG);
addTag(AUTHOR_TAG, author);
addTag(DATE_TAG, SVNDate.formatDate(date));
closeTag(COMMIT_TAG);
}
if (myIsUseMergeHistory && mergedRevision >= 0) {
addAttribute(PATH_ATTR, mergedPath);
openTag(MERGED_TAG);
addAttribute(REVISION_ATTR, mergedRevision + "");
openTag(COMMIT_TAG);
addTag(AUTHOR_TAG, mergedAuthor);
addTag(DATE_TAG, SVNDate.formatDate(mergedDate));
closeTag(COMMIT_TAG);
closeTag(MERGED_TAG);
}
closeTag(ENTRY_TAG);
} catch (SAXException e) {
getDebugLog().logSevere(SVNLogType.DEFAULT, e);
SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.XML_MALFORMED, e.getLocalizedMessage());
SVNErrorManager.error(err, e, SVNLogType.DEFAULT);
}
}
/**
* Just returns <span class="javakeyword">false</span>.
* @param date
* @param revision
* @param author
* @param contents
* @return <span class="javakeyword">false</span>
* @throws SVNException
*/
public boolean handleRevision(Date date, long revision, String author, File contents) throws SVNException {
return false;
}
/**
* Does nothing.
*/
public void handleEOF() {
}
}