/* * ==================================================================== * 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 org.tmatesoft.svn.core.SVNErrorCode; import org.tmatesoft.svn.core.SVNErrorMessage; import org.tmatesoft.svn.core.SVNException; import org.tmatesoft.svn.core.SVNLock; import org.tmatesoft.svn.core.SVNURL; import org.tmatesoft.svn.core.internal.util.SVNDate; import org.tmatesoft.svn.core.internal.wc.SVNErrorManager; import org.tmatesoft.svn.core.wc.ISVNInfoHandler; import org.tmatesoft.svn.core.wc.SVNInfo; import org.tmatesoft.svn.util.ISVNDebugLog; import org.tmatesoft.svn.util.SVNLogType; import org.xml.sax.ContentHandler; import org.xml.sax.SAXException; /** * @version 1.3 * @author TMate Software Ltd. * @since 1.2 */ public class SVNXMLInfoHandler extends AbstractXMLHandler implements ISVNInfoHandler { private static final String INFO_TAG = "info"; private static final String ENTRY_TAG = "entry"; private static final String REVISION_ATTR = "revision"; private static final String PATH_ATTR = "path"; private static final String KIND_ATTR = "kind"; private static final String URL_TAG = "url"; private static final String REPOSITORY_TAG = "repository"; private static final String UUID_TAG = "uuid"; private static final String ROOT_TAG = "root"; private static final String WC_INFO_TAG = "wc-info"; private static final String SCHEDULE_TAG = "schedule"; private static final String COPY_FROM_URL_TAG = "copy-from-url"; private static final String COPY_FROM_REVISION_TAG = "copy-from-rev"; private static final String CHECKSUM_TAG = "checksum"; private static final String TEXT_TIME_TAG = "text-update"; private static final String PROP_TIME_TAG = "prop-updated"; private static final String COMMIT_TAG = "commit"; private static final String AUTHOR_TAG = "author"; private static final String DATE_TAG = "date"; private static final String CONFLICT_TAG = "conflict"; private static final String OLD_CONFLICT_TAG = "prev-base-file"; private static final String WRK_CONFLICT_TAG = "prev-wc-file"; private static final String NEW_CONFLICT_TAG = "cur-base-file"; private static final String PROP_CONFLICT_TAG = "prop-file"; private static final String TOKEN_TAG = "token"; private static final String OWNER_TAG = "owner"; private static final String COMMENT_TAG = "comment"; private static final String CREATED_TAG = "created"; private static final String EXPIRES_TAG = "expires"; private static final String LOCK_TAG = "lock"; private static final String DEPTH_TAG = "depth"; private static final String CHANGELIST_TAG = "changelist"; private File myTargetPath; /** * Creates a new info handler. * * @param contentHandler a <b>ContentHandler</b> to form * an XML tree */ public SVNXMLInfoHandler(ContentHandler contentHandler) { this(contentHandler, null); } /** * Creates a new info handler. * * @param contentHandler a <b>ContentHandler</b> to form * an XML tree * @param log a debug logger */ public SVNXMLInfoHandler(ContentHandler contentHandler, ISVNDebugLog log) { super(contentHandler, log); } /** * Sets the target path what makes all paths be relative to this one. * * @param path target path */ public void setTargetPath(File path) { myTargetPath = path; } protected String getHeaderName() { return INFO_TAG; } /** * Handles info producing corresponding xml. * * @param info info * @throws SVNException */ public void handleInfo(SVNInfo info) throws SVNException { try { sendToHandler(info); } catch (SAXException e) { getDebugLog().logSevere(SVNLogType.DEFAULT, e); SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.XML_MALFORMED, e.getMessage()); SVNErrorManager.error(err, e, SVNLogType.DEFAULT); } } private void sendToHandler(SVNInfo info) throws SAXException { addAttribute(KIND_ATTR, info.getKind().toString()); if (info.getFile() != null) { addAttribute(PATH_ATTR, getRelativePath(info.getFile())); } else if (info.getPath() != null){ addAttribute(PATH_ATTR, info.getPath()); } addAttribute(REVISION_ATTR, info.getRevision().toString()); openTag(ENTRY_TAG); if (info.getURL() != null) { addTag(URL_TAG, info.getURL().toString()); } SVNURL rootURL = info.getRepositoryRootURL(); String uuid = info.getRepositoryUUID(); if (rootURL != null || uuid != null) { openTag(REPOSITORY_TAG); if (rootURL != null) { addTag(ROOT_TAG, rootURL.toString()); } if (uuid != null) { addTag(UUID_TAG, uuid); } closeTag(REPOSITORY_TAG); } if (info.getFile() != null) { openTag(WC_INFO_TAG); String schedule = info.getSchedule(); if (schedule == null || "".equals(schedule)) { schedule = "normal"; } addTag(SCHEDULE_TAG, schedule); if (info.getDepth() != null) { addTag(DEPTH_TAG, info.getDepth().getName()); } if (info.getCopyFromURL() != null) { addTag(COPY_FROM_URL_TAG, info.getCopyFromURL().toString()); } if (info.getCopyFromRevision() != null && info.getCopyFromRevision().isValid()) { addTag(COPY_FROM_REVISION_TAG, info.getCopyFromRevision().toString()); } if (info.getTextTime() != null) { addTag(TEXT_TIME_TAG, SVNDate.formatDate(info.getTextTime())); } if (info.getPropTime() != null) { addTag(PROP_TIME_TAG, SVNDate.formatDate(info.getPropTime())); } if (info.getChecksum() != null) { addTag(CHECKSUM_TAG, info.getChecksum()); } if (info.getChangelistName() != null) { addTag(CHANGELIST_TAG, info.getChangelistName()); } closeTag(WC_INFO_TAG); } if (info.getAuthor() != null || info.getCommittedRevision().isValid() || info.getCommittedDate() != null) { if (info.getCommittedRevision().isValid()) { addAttribute(REVISION_ATTR, info.getCommittedRevision().toString()); } openTag(COMMIT_TAG); addTag(AUTHOR_TAG, info.getAuthor()); if (info.getCommittedDate() != null) { addTag(DATE_TAG, SVNDate.formatDate(info.getCommittedDate())); } closeTag(COMMIT_TAG); } if (info.getConflictNewFile() != null || info.getConflictOldFile() != null || info.getConflictWrkFile() != null || info.getPropConflictFile() != null) { openTag(CONFLICT_TAG); if (info.getConflictOldFile() != null) { addTag(OLD_CONFLICT_TAG, info.getConflictOldFile().getName()); } if (info.getConflictWrkFile() != null) { addTag(WRK_CONFLICT_TAG, info.getConflictWrkFile().getName()); } if (info.getConflictNewFile() != null) { addTag(NEW_CONFLICT_TAG, info.getConflictNewFile().getName()); } if (info.getPropConflictFile() != null) { addTag(PROP_CONFLICT_TAG, info.getPropConflictFile().getName()); } closeTag(CONFLICT_TAG); } if (info.getLock() != null) { SVNLock lock = info.getLock(); openTag(LOCK_TAG); if (lock.getID() != null) { addTag(TOKEN_TAG, lock.getID()); } if (lock.getOwner() != null) { addTag(OWNER_TAG, lock.getOwner()); } if (lock.getComment() != null) { addTag(COMMENT_TAG, lock.getComment()); } if (lock.getCreationDate() != null) { addTag(CREATED_TAG, SVNDate.formatDate(lock.getCreationDate())); } if (lock.getExpirationDate() != null) { addTag(EXPIRES_TAG, SVNDate.formatDate(lock.getExpirationDate())); } closeTag(LOCK_TAG); } closeTag(ENTRY_TAG); } protected String getRelativePath(File path) { String fullPath = path.getAbsoluteFile().getAbsolutePath(); if (myTargetPath == null) { return fullPath; } StringBuffer relativePath = new StringBuffer(); // collect path till target is met, then prepend target. char pathSeparator = File.separatorChar; boolean targetMeet = false; if (!path.getAbsoluteFile().equals(myTargetPath.getAbsoluteFile())) { do { if (relativePath.length() > 0) { relativePath.insert(0, pathSeparator); } relativePath = relativePath.insert(0, path.getName()); path = path.getParentFile(); if (path != null) { targetMeet = path.getAbsoluteFile().equals(myTargetPath.getAbsoluteFile()); } } while(path !=null && !targetMeet); } else { return myTargetPath.getPath(); } if (path != null) { if (relativePath.length() > 0) { relativePath.insert(0, pathSeparator); } relativePath = relativePath.insert(0, myTargetPath.getPath()); } else { return fullPath; } return relativePath.toString(); } protected String getTargetPath() { return getRelativePath(myTargetPath); } }