/** * Copyright (C) 2008-2010, Squale Project - http://www.squale.org * * This file is part of Squale. * * Squale is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of the * License, or any later version. * * Squale is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Squale. If not, see <http://www.gnu.org/licenses/>. */ package org.squale.squalix.tools.scm.task; import java.io.File; import java.io.IOException; import java.util.Iterator; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.maven.scm.ScmException; import org.apache.maven.scm.ScmFile; import org.apache.maven.scm.ScmFileSet; import org.apache.maven.scm.command.checkout.CheckOutScmResult; import org.apache.maven.scm.manager.NoSuchScmProviderException; import org.apache.maven.scm.manager.ScmManager; import org.apache.maven.scm.repository.ScmRepository; import org.apache.maven.scm.repository.ScmRepositoryException; import org.codehaus.plexus.util.StringUtils; import org.squale.squalix.core.TaskException; import org.squale.squalix.util.file.FileUtility; /** * abstract class to connect to a repository (Cvs, Svn or local by example) */ public abstract class AbstractRepository { /** * Logger */ private static final Log LOGGER = LogFactory.getLog( AbstractRepository.class ); /** Scm Manager * */ private ScmManager scmManager; /** Temporary directory * */ private String scmTemporaryDirectory; /** location, directory to check out * */ private String location; /** login to access the repository */ private String login; /** Login's Password to access the repository */ private String password; /** check out success ? */ private boolean checkOut; /** * Accessor * * @return returns the scmManager property */ public ScmManager getScmManager() { return this.scmManager; } /** * Accessor * * @param pScmTemporaryDirectory temporary directory */ public void setScmTemporaryDirectory( String pScmTemporaryDirectory ) { this.scmTemporaryDirectory = pScmTemporaryDirectory; } /** * Accessor * * @return returns the local directory where check out are preformed */ public String getScmTemporaryDirectory() { return this.scmTemporaryDirectory; } /** * Accessor * * @param pScmManager type of Scm manager */ public void setScmManager( ScmManager pScmManager ) { this.scmManager = pScmManager; } /** * Accessor of the attribute checkOut * * @return check out success or not */ public boolean isCheckOut() { return checkOut; } /** * Accessor of the attribute checkOut * * @param pCheckOut check out success ? */ public void setCheckOut( boolean pCheckOut ) { this.checkOut = pCheckOut; } /** * Accessor * * @return location to check out (module or directory) */ public String getLocation() { return location; } /** * Accessor * * @param pLocation location to check out (module or directory) */ public void setLocation( String pLocation ) { this.location = pLocation; } /** * Accessor * * @return login to the repository */ public String getLogin() { return login; } /** * Accessor * * @param pLogin to the repository */ public void setLogin( String pLogin ) { this.login = pLogin; } /** * Accessor * * @return user profile's password to access the repository */ public String getPassword() { return password; } /** * Accessor * * @param pPassword user profile's password to access the repository */ public void setPassword( String pPassword ) { this.password = pPassword; } /** * Attempt to retrieve sources in a local directory * * @return repository local or remote repository * @throws ScmRepositoryException Scm exception * @throws NoSuchScmProviderException Scm exception */ public ScmRepository getScmRepository() throws ScmRepositoryException, NoSuchScmProviderException { ScmRepository repository = scmManager.makeScmRepository( this.location.trim() ); repository.getProviderRepository().setPersistCheckout( true ); if ( !StringUtils.isEmpty( this.login ) ) { repository.getProviderRepository().setUser( this.login ); if ( !StringUtils.isEmpty( this.password ) ) { repository.getProviderRepository().setPassword( this.password ); } else { repository.getProviderRepository().setPassword( "" ); } } return repository; } /** * Checks if the url to the repository is right * * @param pUrl url to check * @return list of errors */ public List validateRepository( String pUrl ) { return this.scmManager.validateScmRepository( pUrl ); } /** * Check out files in a local directory * * @param scmRepository repository sources are stored * @param workingDirectory local directory where sources are analyzed * @param defaultTemporaryDirectory default temporary directory where check out are performed * @throws ScmException Scm exception * @throws IOException Exception in files * @throws TaskException Exceptions occurs */ public void checkOut( File defaultTemporaryDirectory, ScmRepository scmRepository, File workingDirectory ) throws ScmException, IOException, TaskException { File temporaryDirectory = new File( this.getScmTemporaryDirectory() ); this.checkOut = true; // Temporary directory already exists !! if ( temporaryDirectory.exists() ) { this.checkOut = false; LOGGER.error( ScmMessages.getString( "exception.task.existing_directory", workingDirectory.getAbsolutePath() ) ); throw new TaskException(); } // Creation of the directory where sources are analyzed if ( !temporaryDirectory.mkdirs() ) { this.checkOut = false; LOGGER.error( ScmMessages.getString( "exception.task.creation_directory", workingDirectory.getAbsolutePath() ) ); throw new TaskException(); } // Check-out sources into the temporary directory CheckOutScmResult result = scmManager.checkOut( scmRepository, new ScmFileSet( temporaryDirectory ) ); // Copy local check out directory into local source code directory FileUtility.copyDirContentIntoDir( defaultTemporaryDirectory, workingDirectory ); // Deletion of the temporary directory FileUtility.deleteRecursively( defaultTemporaryDirectory ); // Display logs following to the scm connection in a remote repository if ( !result.isSuccess() && result.getProviderMessage() != null ) { this.checkOut = false; LOGGER.warn( ScmMessages.getString( "exception.task.provider", result.getProviderMessage() ) ); LOGGER.warn( ScmMessages.getString( "exception.task.provider", result.getCommandOutput() ) ); throw new TaskException(); } if ( LOGGER.isDebugEnabled() ) { List checkedOutFiles = result.getCheckedOutFiles(); if ( checkedOutFiles != null ) { // Display all objects in check-out for ( Iterator it = checkedOutFiles.iterator(); it.hasNext(); ) { ScmFile file = (ScmFile) it.next(); LOGGER.debug( ScmMessages.getString( "logs.task.checkout" ) + file.getPath() ); } } } } /** * Define a local temporary directory for the module. This method must be used for SCM like SVN, Git, Mercurial, ... * * @param pPath path to analyse * @param pTemporaryDirectory temporary directory when check out is performed * @return local temporary directory for the module */ protected String createModuleTempDirFromSlash( String pPath, String pTemporaryDirectory ) { StringBuffer moduleTempDirectory = new StringBuffer( pTemporaryDirectory ); int rank = pPath.lastIndexOf( "/" ); if ( rank > 0 && rank < pPath.length() ) { computeTempDirPath( moduleTempDirectory, pPath, rank ); } return moduleTempDirectory.toString(); } /** * Define a local temporary directory for the module. This method must be used for SCM like CVS, local, ... * * @param pPath path to analyse * @param pTemporaryDirectory temporary directory when check out is performed * @return local temporary directory for the module */ protected String createModuleTempDirFromPipeOrColon( String pPath, String pTemporaryDirectory ) { StringBuffer moduleTempDirectory = new StringBuffer( pTemporaryDirectory ); int rank = pPath.lastIndexOf( "|" ); if ( rank > 0 && rank < pPath.length() ) { // pipe is used on Windows when the URL has a colon computeTempDirPath( moduleTempDirectory, pPath, rank ); } else { // no pipe, then look for the colon rank = pPath.lastIndexOf( ":" ); if ( rank > 0 && rank < pPath.length() ) { // pipe is used on Windows when the URL has a colon computeTempDirPath( moduleTempDirectory, pPath, rank ); } } return moduleTempDirectory.toString(); } /** * Adds a last segment to the temp directory. This segment is the name of the module. * * @param moduleTempDirectory the base temp directory * @param pPath the SCM URL * @param rank the index of the last separator after which we can find the module name */ private void computeTempDirPath( StringBuffer moduleTempDirectory, String pPath, int rank ) { moduleTempDirectory.append( pPath.substring( rank + 1 ) + "/" ); } }