/* * ==================================================================== * 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.util.Collection; import java.util.Comparator; import java.util.Iterator; import java.util.TreeSet; import org.tmatesoft.svn.core.ISVNDirEntryHandler; import org.tmatesoft.svn.core.SVNDirEntry; import org.tmatesoft.svn.core.SVNException; import org.tmatesoft.svn.core.SVNLock; import org.tmatesoft.svn.core.SVNNodeKind; import org.tmatesoft.svn.core.internal.util.SVNPathUtil; import org.tmatesoft.svn.core.internal.util.SVNDate; 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>ISVNStatusHandler</b> interface * that writes XML formatted status information to a specified * <b>ContentHandler</b>. * * @version 1.3 * @author TMate Software Ltd. * @since 1.2 */ public class SVNXMLDirEntryHandler extends AbstractXMLHandler implements ISVNDirEntryHandler, Comparator { /** * <code>'expires'</code> tag. */ public static final String EXPIRES_TAG = "expires"; /** * <code>'created'</code> tag. */ public static final String CREATED_TAG = "created"; /** * <code>'comment'</code> tag. */ public static final String COMMENT_TAG = "comment"; /** * <code>'owner'</code> tag. */ public static final String OWNER_TAG = "owner"; /** * <code>'tag'</code> tag. */ public static final String TOKEN_TAG = "token"; /** * <code>'lock'</code> tag. */ public static final String LOCK_TAG = "lock"; /** * <code>'path'</code> attribute. */ public static final String PATH_ATTR = "path"; /** * <code>'revision'</code> attribute. */ public static final String REVISION_ATTR = "revision"; /** * <code>'lists'</code> tag. */ public static final String LISTS_TAG = "lists"; /** * <code>'list'</code> tag. */ public static final String LIST_TAG = "list"; /** * <code>'entry'</code> tag. */ public static final String ENTRY_TAG = "entry"; /** * <code>'name'</code> tag. */ public static final String NAME_TAG = "name"; /** * <code>'size'</code> tag. */ public static final String SIZE_TAG = "size"; /** * <code>'commit'</code> tag. */ public static final String COMMIT_TAG = "commit"; /** * <code>'date'</code> tag. */ public static final String DATE_TAG = "date"; /** * <code>'author'</code> tag. */ public static final String AUTHOR_TAG = "author"; private Collection myDirEntries; /** * Creates a new handler. * * @param saxHandler a <b>ContentHandler</b> to form * an XML tree */ public SVNXMLDirEntryHandler(ContentHandler saxHandler) { this(saxHandler, null); } /** * Creates a new handler. * * @param saxHandler a <b>ContentHandler</b> to form * an XML tree * @param log a debug logger */ public SVNXMLDirEntryHandler(ContentHandler saxHandler, ISVNDebugLog log) { super(saxHandler, log); } /** * Begins an XML tree with the target path for which the * status is run. * * @param path a WC target path or URL */ public void startTarget(String path) { myDirEntries = new TreeSet(this); try { addAttribute(PATH_ATTR, path == null || path.length() == 9 ? "." : path); openTag(LIST_TAG); } catch (SAXException e) { getDebugLog().logSevere(SVNLogType.DEFAULT, e); } } /** * Handles a next dir <code>entry</code>. * * @param entry dir entry * @throws SVNException */ public void handleDirEntry(SVNDirEntry entry) throws SVNException { myDirEntries.add(entry); } /** * Closes the formatted XML output. * */ public void endTarget() { try { for (Iterator ents = myDirEntries.iterator(); ents.hasNext();) { SVNDirEntry entry = (SVNDirEntry) ents.next(); sendToHandler(entry); } myDirEntries = null; closeTag(LIST_TAG); } catch (SAXException e) { getDebugLog().logSevere(SVNLogType.DEFAULT, e); } } private void sendToHandler(SVNDirEntry entry) throws SAXException { if ("".equals(entry.getRelativePath())) { if (entry.getKind() == SVNNodeKind.DIR) { return; } } openTag(ENTRY_TAG); addTag(NAME_TAG, entry.getRelativePath()); if (entry.getKind() == SVNNodeKind.FILE) { addTag(SIZE_TAG, entry.getSize() + ""); } addAttribute(REVISION_ATTR, entry.getRevision() + ""); openTag(COMMIT_TAG); addTag(AUTHOR_TAG, entry.getAuthor()); addTag(DATE_TAG, SVNDate.formatDate(entry.getDate())); closeTag(COMMIT_TAG); SVNLock lock = entry.getLock(); if (lock != null) { openTag(LOCK_TAG); addTag(TOKEN_TAG, lock.getID()); addTag(OWNER_TAG, lock.getOwner()); addTag(COMMENT_TAG, lock.getComment()); addTag(CREATED_TAG, SVNDate.formatDate(lock.getCreationDate())); if (lock.getExpirationDate() != null && lock.getExpirationDate().getTime() > 0) { addTag(EXPIRES_TAG, SVNDate.formatDate(lock.getExpirationDate())); } closeTag(LOCK_TAG); } closeTag(ENTRY_TAG); } protected String getHeaderName() { return LISTS_TAG; } /** * Compares two objects. * * @param o1 the first object to compare * @param o2 the second object to compare * @return 0 if objects are equal; -1 if <code>o1</code> is * <span class="javakeyword">null</span> or if both * <code>o1</code> and <code>o2</code> are <b>SVNDirEntry</b> * objects and the relative path of the first object is * lexicographically less than that of the second one; 1 otherwise */ public int compare(Object o1, Object o2) { if (o1 == o2) { return 0; } SVNDirEntry e1 = (SVNDirEntry) o1; SVNDirEntry e2 = (SVNDirEntry) o2; if (e1 == null) { return -1; } else if (e2 == null) { return 1; } return SVNPathUtil.PATH_COMPARATOR.compare(e1.getRelativePath(), e2.getRelativePath()); } }