package ebuild.repo.svn; import org.tmatesoft.svn.core.SVNLock; import org.tmatesoft.svn.core.wc.ISVNStatusHandler; import org.tmatesoft.svn.core.wc.SVNRevision; import org.tmatesoft.svn.core.wc.SVNStatus; import org.tmatesoft.svn.core.wc.SVNStatusType; import ebuild.api.log.ILogger; import ebuild.util.StringUtil; public class SvnStatusChecker implements ISVNStatusHandler { final boolean remote; final ILogger logger; private boolean working = false; private long minRevision = -1; private long maxRevision = Long.MAX_VALUE; public SvnStatusChecker(boolean remote, ILogger logger){ this.remote = remote; this.logger = logger; } public boolean isWorking() { return working; } public long getMinRevision() { return minRevision; } public long getMaxRevision() { return maxRevision; } public void handleStatus( SVNStatus status ) { SVNStatusType contentsStatus = status.getContentsStatus( ); if ( contentsStatus == SVNStatusType.STATUS_IGNORED ) return; /* * Gets the status of file/directory/symbolic link text contents. * It is SVNStatusType who contains information on the state of an * item. */ char pathChangeType = contentsStatus.getCode(); boolean isAddedWithHistory = status.isCopied( ); if(contentsStatus!=SVNStatusType.STATUS_NORMAL){ working = true; } /* * If SVNStatusClient.doStatus(..) is invoked with remote = true the * following code finds out whether the current item has been changed * in the repository */ String remoteChangeType = " "; if ( status.getRemotePropertiesStatus( ) != SVNStatusType.STATUS_NONE || status.getRemoteContentsStatus( ) != SVNStatusType.STATUS_NONE ) { /* * the local item is out of date */ remoteChangeType = "*"; } /* * Now getting the status of properties of an item. SVNStatusType also * contains information on the properties state. */ SVNStatusType propertiesStatus = status.getPropertiesStatus( ); String propertiesChangeType = propertiesStatus.getCode()+""; /* * Whether the item was locked in the .svn working area (for example, * during a commit or maybe the previous operation was interrupted, in * this case the lock needs to be cleaned up). */ boolean isLocked = status.isLocked( ); /* * Whether the item is switched to a different URL (branch). */ boolean isSwitched = status.isSwitched( ); /* * If the item is a file it may be locked. */ SVNLock localLock = status.getLocalLock( ); /* * If doStatus() was run with remote = true and the item is a file, * checks whether a remote lock presents. */ SVNLock remoteLock = status.getRemoteLock( ); String lockLabel = " "; if ( localLock != null ) { /* * at first suppose the file is locKed */ lockLabel = "K"; if ( remoteLock != null ) { /* * if the lock-token of the local lock differs from the lock- * token of the remote lock - the lock was sTolen! */ if ( !remoteLock.getID( ).equals( localLock.getID( ) ) ) { lockLabel = "T"; } } else { if ( remote ) { /* * the local lock presents but there's no lock in the * repository - the lock was Broken. This is true only if * doStatus() was invoked with remote=true. */ lockLabel = "B"; } } } else if ( remoteLock != null ) { /* * the file is not locally locked but locked in the repository - * the lock token is in some Other working copy. */ lockLabel = "O"; } long baseRevision = getRevision(status.getRevision()); long committedRevision = getRevision(status.getCommittedRevision()); long remoteRevision = getRevision(status.getRemoteRevision()); minRevision = Math.max(committedRevision, minRevision); maxRevision = Math.min(remoteRevision-1, maxRevision); logger.log( pathChangeType + propertiesChangeType + ( isLocked ? "L" : " " ) + ( isAddedWithHistory ? "+" : " " ) + ( isSwitched ? "S" : " " ) + lockLabel + " " + pathChangeType + " " + remoteChangeType + " " + StringUtil.lpad(10, "b: "+baseRevision) + " " + StringUtil.lpad(10, "c: "+committedRevision) + " " + StringUtil.lpad(10, "r: "+remoteRevision) + " " + StringUtil.rpad(10, ( status.getAuthor( ) != null ? status.getAuthor( ) : "?" )) + " " + status.getFile( ).getPath( ) ); } private long getRevision(SVNRevision r){ if(r==null) return -1; return r.getNumber(); } }