Package hudson.scm

Source Code of hudson.scm.DirAwareSVNXMLLogHandler$MergeFrame

/*
* ====================================================================
* 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://lib.svnkit.com/license.html
* If newer versions of this license are posted there, you may use a
* newer version instead, at your option.
* ====================================================================
*/
package hudson.scm;

import java.io.File;
import java.util.Iterator;
import java.util.LinkedList;

import org.tmatesoft.svn.core.ISVNLogEntryHandler;
import org.tmatesoft.svn.core.SVNErrorCode;
import org.tmatesoft.svn.core.SVNErrorMessage;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNLogEntry;
import org.tmatesoft.svn.core.SVNLogEntryPath;
import org.tmatesoft.svn.core.internal.util.SVNDate;
import org.tmatesoft.svn.core.internal.wc.SVNErrorManager;
import org.tmatesoft.svn.core.wc.xml.SVNXMLLogHandler;
import org.tmatesoft.svn.util.ISVNDebugLog;
import org.tmatesoft.svn.util.SVNLogType;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;

/**
* Special XML Log Handler that includes the "kind" attribute for path nodes which are ommited by the original.
*
*  This is a lot of copy paste code
* @author qxa4177
*/
public class DirAwareSVNXMLLogHandler extends SVNXMLLogHandler implements ISVNLogEntryHandler {
 
  public static final String KIND_ATTR = "kind";
  public static final String REL_PATH_ATTR = "localPath";
 
  private boolean myIsOmitLogMessage;

  private LinkedList<MergeFrame> myMergeStack;

  private SVNLogFilter filter = new NullSVNLogFilter();

  private SubversionChangeLogBuilder.PathContext context;

  public DirAwareSVNXMLLogHandler(ContentHandler contentHandler, SVNLogFilter filter) {
    super(contentHandler);
    this.filter = filter;
  }

  public DirAwareSVNXMLLogHandler(ContentHandler contentHandler, ISVNDebugLog log) {
    super(contentHandler, log);
  }

  public DirAwareSVNXMLLogHandler(ContentHandler contentHandler) {
    super(contentHandler);
  }

  /**
   * Sets whether log messages must be omitted or not.
   *
   * @param omitLogMessage  <span class="javakeyword">true</span> to omit;
   *                        otherwise <span class="javakeyword">false</span>
   */
  public void setOmitLogMessage(boolean omitLogMessage) {
      myIsOmitLogMessage = omitLogMessage;
  }

  /**
   * Handles a next log entry producing corresponding xml.
   *
   * @param  logEntry       log entry
   * @throws SVNException
   */
  public void handleLogEntry(SVNLogEntry logEntry) throws SVNException {
      try {
          if (filter == null || !filter.hasExclusionRule() || filter.isIncluded(logEntry)) {
              sendToHandler(logEntry);
          }
      } catch (SAXException e) {
          SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.XML_MALFORMED, e.getLocalizedMessage());
          SVNErrorManager.error(err, e, SVNLogType.DEFAULT);
      }
  }

  // unfortunately, the original method is private, so we need to copy / paste it
  // copied from SVNXMLLogHandler
  //
  protected void sendToHandler(SVNLogEntry logEntry) throws SAXException {
    if (logEntry.getRevision() == 0 && logEntry.getMessage() == null) {
        return;
    }
    addAttribute(REVISION_ATTR, logEntry.getRevision() + "");
    openTag(LOGENTRY_TAG);
    if (logEntry.getAuthor() != null) {
        addTag(AUTHOR_TAG, logEntry.getAuthor());
    }
    if (logEntry.getDate() != null && logEntry.getDate().getTime() != 0) {
        addTag(DATE_TAG, SVNDate.formatDate(logEntry.getDate()));
    }
    if (logEntry.getChangedPaths() != null && !logEntry.getChangedPaths().isEmpty()) {
        openTag(PATHS_TAG);
        for (Iterator<String> paths = logEntry.getChangedPaths().keySet().iterator(); paths.hasNext();) {
            String key = paths.next();
            SVNLogEntryPath path = (SVNLogEntryPath) logEntry.getChangedPaths().get(key);
            addAttribute(ACTION_ATTR, path.getType() + "");

            // the path within the repo to the location checked out
            String modulePath = context.url.substring(context.repoUrl.length());

            if (path.getPath().startsWith(modulePath)) {
                // this path is inside the locally checked out module location, so set relativePath attribute
                String relativeWorkspacePath = context.moduleWorkspacePath + path.getPath().substring(context.url.length() - context.repoUrl.length());
                if (".".equals(context.moduleWorkspacePath) && relativeWorkspacePath.length() >= 2) {
                    // use 'foo', not './foo'
                    relativeWorkspacePath = relativeWorkspacePath.substring(2); // "./".length()
                }
                // use File/toString to get rid of duplicate separators
                addAttribute(REL_PATH_ATTR, new File(relativeWorkspacePath).toString());
            }

            if (path.getCopyPath() != null) {
                addAttribute(COPYFROM_PATH_ATTR, path.getCopyPath());
                addAttribute(COPYFROM_REV_ATTR, path.getCopyRevision() + "");
            }
            if (path.getKind() != null) {
                addAttribute(KIND_ATTR, path.getKind().toString());
            }
            addTag(PATH_TAG, path.getPath());
        }
        closeTag(PATHS_TAG);
    }
   
    if (!myIsOmitLogMessage) {
        String message = logEntry.getMessage();
        message = message == null ? "" : message;
        addTag(MSG_TAG, message);
    }
   
    if (myMergeStack != null && !myMergeStack.isEmpty()) {
        MergeFrame frame = (MergeFrame) myMergeStack.getLast();
        frame.myNumberOfChildrenRemaining--;
    }
   
    if (logEntry.hasChildren()) {
        MergeFrame frame = new MergeFrame();
        if (myMergeStack == null) {
            myMergeStack = new LinkedList<MergeFrame>();
        }
        myMergeStack.addLast(frame);
    } else {
        while(myMergeStack != null && !myMergeStack.isEmpty()) {
            MergeFrame frame = (MergeFrame) myMergeStack.getLast();
            if (frame.myNumberOfChildrenRemaining == 0) {
                closeTag(LOGENTRY_TAG);
                myMergeStack.removeLast();
            } else {
                break;
            }
        }
        closeTag(LOGENTRY_TAG);
    }
  }

  void setContext(SubversionChangeLogBuilder.PathContext context) {
    this.context = context;
  }

  private class MergeFrame {
    private long myNumberOfChildrenRemaining;
  }

}
TOP

Related Classes of hudson.scm.DirAwareSVNXMLLogHandler$MergeFrame

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.