![JAR search and dependency download from the Maven repository](/logo.png)
net.sf.yal10n.svn.SVNUtil Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of yal10n-maven-plugin Show documentation
Show all versions of yal10n-maven-plugin Show documentation
Yet Another L10N Maven Plugin
The newest version!
package net.sf.yal10n.svn;
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.security.MessageDigest;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import net.sf.yal10n.settings.ScmType;
import org.apache.commons.lang.StringUtils;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.scm.ChangeFile;
import org.apache.maven.scm.ChangeSet;
import org.apache.maven.scm.CommandParameters;
import org.apache.maven.scm.ScmException;
import org.apache.maven.scm.ScmFileSet;
import org.apache.maven.scm.ScmFileStatus;
import org.apache.maven.scm.ScmResult;
import org.apache.maven.scm.ScmRevision;
import org.apache.maven.scm.command.changelog.ChangeLogScmRequest;
import org.apache.maven.scm.command.changelog.ChangeLogScmResult;
import org.apache.maven.scm.command.checkout.CheckOutScmResult;
import org.apache.maven.scm.command.diff.DiffScmResult;
import org.apache.maven.scm.command.info.InfoItem;
import org.apache.maven.scm.command.info.InfoScmResult;
import org.apache.maven.scm.manager.BasicScmManager;
import org.apache.maven.scm.manager.ScmManager;
import org.apache.maven.scm.provider.ScmProvider;
import org.apache.maven.scm.provider.ScmProviderRepository;
import org.apache.maven.scm.provider.git.gitexe.GitExeScmProvider;
import org.apache.maven.scm.provider.svn.svnexe.SvnExeScmProvider;
import org.apache.maven.scm.repository.ScmRepository;
import org.codehaus.plexus.component.annotations.Component;
/**
* Simple SVN utility for checking out files from subversion.
*/
@Component( role = SVNUtil.class, hint = "SVNUtil" )
public class SVNUtil
{
private static final int BYTE_MASK = 0xff;
private ScmManager scmManager;
/**
* Instantiates a new SVN util.
*/
public SVNUtil()
{
scmManager = new BasicScmManager();
scmManager.setScmProvider( "svn", new SvnExeScmProvider() );
scmManager.setScmProvider( "git", new GitExeScmProvider() );
}
/**
* Determines the correct url. The url can start with a dot or two dots,
* which will be interpreted as a relative file url.
* @param svnUrl the url
* @return the SVN url
*/
private String getUrl( String svnUrl )
{
if ( svnUrl.startsWith( ".." ) || svnUrl.startsWith( "." ) )
{
String completePath = new File( ".", svnUrl ).getAbsolutePath();
return "file://" + completePath;
}
return svnUrl;
}
private String createScmSvnUrl( ScmType type, String svnUrl )
{
String result = getUrl( svnUrl );
if ( !result.startsWith( "scm:" ) )
{
switch ( type )
{
case SVN:
result = "scm:svn:" + result;
break;
case GIT:
result = "scm:git:" + result;
break;
default:
throw new RuntimeException( "Scm type " + type + " is not supported." );
}
}
return result;
}
private void checkResult( ScmResult result )
{
if ( !result.isSuccess() )
{
System.err.println( "Provider message:" );
System.err.println( result.getProviderMessage() == null ? "" : result.getProviderMessage() );
System.err.println( "Command output:" );
System.err.println( result.getCommandOutput() == null ? "" : result.getCommandOutput() );
throw new RuntimeException( "Command failed." + StringUtils.defaultString( result.getProviderMessage() ) );
}
}
/**
* Checkout from the given svn url to the destination directory.
*
* @param log the log
* @param type the scm type
* @param svnUrl the svn url
* @param destination the destination
* @return the current checked out version
*/
public String checkout( Log log, ScmType type, String svnUrl, String destination )
{
try
{
log.info( "Updating " + svnUrl );
String scmUrl = createScmSvnUrl( type, svnUrl );
log.debug( "Converted Url: " + scmUrl );
ScmProvider scm = scmManager.getProviderByUrl( scmUrl );
ScmRepository repository = scmManager.makeScmRepository( scmUrl );
ScmProviderRepository providerRepository = repository.getProviderRepository();
File dstPath = new File( destination );
if ( dstPath.exists() && !dstPath.isDirectory() )
{
throw new RuntimeException( "Path is not a directory: " + dstPath );
}
else if ( !dstPath.exists() && !dstPath.mkdirs() )
{
throw new RuntimeException( "Couldn't create directory " + dstPath );
}
CheckOutScmResult checkOutResult = scm.checkOut( repository, new ScmFileSet( dstPath ) );
checkResult( checkOutResult );
String revision = checkOutResult.getRevision();
if ( revision == null )
{
InfoScmResult info = scm.info( providerRepository, new ScmFileSet( dstPath ), null );
checkResult( info );
revision = info.getInfoItems().get( 0 ).getRevision();
}
log.info( "At revision " + revision );
return revision;
}
catch ( ScmException e )
{
throw new RuntimeException( e );
}
}
/**
* Gets the information about a file in a local working directory.
*
* @param log the log
* @param type the scm type
* @param svnUrl the checked out repository url
* @param baseDir the directory where the repository has been checked out
* @param relativeFilePath the file to check relative to baseDir
* @return the svn information like revision.
*/
public SVNInfo checkFile( Log log, ScmType type, String svnUrl, String baseDir, String relativeFilePath )
{
try
{
String scmUrl = createScmSvnUrl( type, svnUrl );
ScmProvider scm = scmManager.getProviderByUrl( scmUrl );
ScmRepository repository = scmManager.makeScmRepository( scmUrl );
ScmProviderRepository providerScmRepository = repository.getProviderRepository();
ScmFileSet fileSet = new ScmFileSet( new File( baseDir ), new File( relativeFilePath ) );
InfoScmResult info = scm.info( providerScmRepository, fileSet, (CommandParameters) null );
checkResult( info );
InfoItem item = info.getInfoItems().get( 0 );
return new SVNInfo( item.getLastChangedRevision(), item.getLastChangedDate() );
}
catch ( ScmException e )
{
throw new RuntimeException( e );
}
}
/**
* Determines whether a given file has been modified between two revisions.
*
* @param log the log
* @param type the scm type
* @param svnUrl the repository url
* @param checkoutDir the checkout directory
* @param relativeFilePath the file to check, relative to the checkout directory
* @param baseRevision the old revision (exclusive)
* @param newRevision the new revision (inclusive)
* @return the change type, e.g. ADD, MODIFICATION or NONE
*/
public SVNLogChange log( Log log, ScmType type, String svnUrl, String checkoutDir, String relativeFilePath,
String baseRevision, String newRevision )
{
try
{
String scmUrl = createScmSvnUrl( type, svnUrl );
ScmProvider scm = scmManager.getProviderByUrl( scmUrl );
ScmRepository repository = scmManager.makeScmRepository( scmUrl );
ChangeLogScmRequest scmRequest = new ChangeLogScmRequest( repository,
new ScmFileSet( new File( checkoutDir ), new File ( relativeFilePath ) ) );
scmRequest.setStartRevision( new ScmRevision( baseRevision ) );
scmRequest.setEndRevision( new ScmRevision( newRevision ) );
ChangeLogScmResult changeLog = scm.changeLog( scmRequest );
checkResult( changeLog );
Set changeTypes = new HashSet();
List changeSets = changeLog.getChangeLog().getChangeSets();
for ( ChangeSet cs : changeSets )
{
if ( cs.getRevision().equals( baseRevision ) )
{
continue;
}
for ( ChangeFile f : cs.getFiles() )
{
if ( f.getName().endsWith( relativeFilePath ) )
{
changeTypes.add( String.valueOf( f.getAction() ) );
}
}
}
SVNLogChange result;
if ( changeTypes.isEmpty() )
{
result = SVNLogChange.NONE;
}
else if ( changeTypes.contains( ScmFileStatus.ADDED.toString() ) )
{
result = SVNLogChange.ADD;
}
else
{
result = SVNLogChange.MODIFICATION;
}
return result;
}
catch ( ScmException e )
{
throw new RuntimeException( e );
}
}
/**
* Retrieves a unified diff for a given file and revision.
*
* @param log the log
* @param type the scm type
* @param svnUrl the repository url
* @param checkoutDir the checkout directory
* @param relativeFilePath the file to diff, relative to the checkout directory
* @param baseRevision the old revision
* @param newRevision the new revision
* @return the diff as a string
*/
public String diff( Log log, ScmType type, String svnUrl, String checkoutDir, String relativeFilePath,
String baseRevision, String newRevision )
{
try
{
String scmUrl = createScmSvnUrl( type, svnUrl );
ScmRepository repository = scmManager.makeScmRepository( scmUrl );
ScmFileSet scmFileSet = new ScmFileSet( new File( checkoutDir ), new File( relativeFilePath ) );
DiffScmResult diffResult = scmManager.diff( repository, scmFileSet,
new ScmRevision( baseRevision ), new ScmRevision( newRevision ) );
checkResult( diffResult );
return filterPatch( diffResult.getPatch(), relativeFilePath );
}
catch ( ScmException e )
{
throw new RuntimeException( e );
}
}
private static String filterPatch( String patch, String relativeFilePath )
{
BufferedReader r = new BufferedReader( new StringReader( patch ) );
String line;
StringBuilder newPatch = new StringBuilder();
boolean fileStarted = false;
try
{
while ( ( line = r.readLine() ) != null )
{
if ( !fileStarted && line.startsWith( "Index: " + relativeFilePath ) )
{
newPatch.append( line ).append( '\n' );
fileStarted = true;
}
else if ( fileStarted && line.startsWith( "Index: " ) )
{
fileStarted = false;
}
else if ( fileStarted )
{
newPatch.append( line ).append( '\n' );
}
}
}
catch ( IOException e )
{
throw new RuntimeException( e );
}
return newPatch.toString();
}
/**
* Utility method to combine a prefix and url to get the complete repository URL.
* Duplicated slashed will be removed.
* @param repoPrefix the prefix
* @param repoUrl the url
* @return the complete repo url
*/
public static String toCompleteUrl( String repoPrefix, String repoUrl )
{
String prefix = StringUtils.trimToEmpty( repoPrefix );
String suffix = StringUtils.trimToEmpty( repoUrl );
if ( !prefix.isEmpty() && !prefix.endsWith( "/" ) )
{
prefix = prefix + "/";
}
if ( suffix.startsWith( "/" ) )
{
suffix = suffix.substring( 1 );
}
if ( suffix.endsWith( "/" ) )
{
suffix = suffix.substring( 0, suffix.lastIndexOf( "/" ) );
}
return prefix + suffix;
}
/**
* Calculates a unique id for the given repo url.
* @param repoPrefix the prefix
* @param repoUrl the url
* @return the id
*/
public static String toRepoId( String repoPrefix, String repoUrl )
{
String completeUrl = toCompleteUrl( repoPrefix, repoUrl );
try
{
MessageDigest digest = MessageDigest.getInstance( "MD5" );
byte[] md5 = digest.digest( completeUrl.getBytes( "UTF-8" ) );
StringBuilder sb = new StringBuilder( 32 );
for ( int i = 0; i < md5.length; i++ )
{
int part = md5[i] & BYTE_MASK;
String h = Integer.toHexString( part );
if ( part < 0x10 )
{
sb.append( "0" );
}
sb.append( h );
}
return sb.toString();
}
catch ( Exception e )
{
throw new RuntimeException( e );
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy