| package org.apache.maven.scm.provider.accurev; |
| |
| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you 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.File; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.Date; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import org.apache.maven.scm.ChangeFile; |
| import org.apache.maven.scm.ChangeSet; |
| import org.apache.maven.scm.CommandParameter; |
| import org.apache.maven.scm.CommandParameters; |
| import org.apache.maven.scm.ScmException; |
| import org.apache.maven.scm.ScmFile; |
| import org.apache.maven.scm.ScmFileSet; |
| import org.apache.maven.scm.ScmRevision; |
| import org.apache.maven.scm.command.add.AddScmResult; |
| import org.apache.maven.scm.command.blame.BlameScmResult; |
| import org.apache.maven.scm.command.changelog.ChangeLogScmResult; |
| import org.apache.maven.scm.command.checkin.CheckInScmResult; |
| import org.apache.maven.scm.command.checkout.CheckOutScmResult; |
| import org.apache.maven.scm.command.export.ExportScmResult; |
| import org.apache.maven.scm.command.login.LoginScmResult; |
| import org.apache.maven.scm.command.remove.RemoveScmResult; |
| import org.apache.maven.scm.command.status.StatusScmResult; |
| import org.apache.maven.scm.command.tag.TagScmResult; |
| import org.apache.maven.scm.command.update.UpdateScmResult; |
| import org.apache.maven.scm.provider.AbstractScmProvider; |
| import org.apache.maven.scm.provider.ScmProviderRepository; |
| import org.apache.maven.scm.provider.accurev.cli.AccuRevCommandLine; |
| import org.apache.maven.scm.provider.accurev.command.add.AccuRevAddCommand; |
| import org.apache.maven.scm.provider.accurev.command.blame.AccuRevBlameCommand; |
| import org.apache.maven.scm.provider.accurev.command.changelog.AccuRevChangeLogCommand; |
| import org.apache.maven.scm.provider.accurev.command.checkin.AccuRevCheckInCommand; |
| import org.apache.maven.scm.provider.accurev.command.checkout.AccuRevCheckOutCommand; |
| import org.apache.maven.scm.provider.accurev.command.export.AccuRevExportCommand; |
| import org.apache.maven.scm.provider.accurev.command.login.AccuRevLoginCommand; |
| import org.apache.maven.scm.provider.accurev.command.remove.AccuRevRemoveCommand; |
| import org.apache.maven.scm.provider.accurev.command.status.AccuRevStatusCommand; |
| import org.apache.maven.scm.provider.accurev.command.tag.AccuRevTagCommand; |
| import org.apache.maven.scm.provider.accurev.command.update.AccuRevUpdateCommand; |
| import org.apache.maven.scm.provider.accurev.command.update.AccuRevUpdateScmResult; |
| import org.apache.maven.scm.provider.accurev.util.QuotedPropertyParser; |
| import org.apache.maven.scm.repository.ScmRepositoryException; |
| import org.apache.maven.scm.repository.UnknownRepositoryStructure; |
| import org.codehaus.plexus.util.StringUtils; |
| |
| /** |
| * AccuRev integration with Maven SCM |
| * |
| * @plexus.component role="org.apache.maven.scm.provider.ScmProvider" role-hint="accurev" |
| */ |
| public class AccuRevScmProvider |
| extends AbstractScmProvider |
| { |
| |
| public static final String ACCUREV_EXECUTABLE_PROPERTY = "accurevExe"; |
| |
| public static final String TAG_FORMAT_PROPERTY = "tagFormat"; |
| |
| public static final String SYSTEM_PROPERTY_PREFIX = "maven.scm.accurev."; |
| |
| public String getScmType() |
| { |
| |
| return "accurev"; |
| } |
| |
| /** |
| * The basic url parsing approach is to be as loose as possible. If you specify as per the docs you'll get what you |
| * expect. If you do something else the result is undefined. Don't use "/" "\" or "@" as the delimiter, |
| */ |
| public ScmProviderRepository makeProviderScmRepository( String scmSpecificUrl, char delimiter ) |
| throws ScmRepositoryException |
| { |
| |
| List<String> validationMessages = new ArrayList<String>(); |
| |
| String[] tokens = StringUtils.split( scmSpecificUrl, Character.toString( delimiter ) ); |
| |
| // [[user][/pass]@host[:port]][:stream][:\project\dir] |
| |
| String basisStream = null; |
| String projectPath = null; |
| int port = AccuRev.DEFAULT_PORT; |
| String host = null; |
| String user = null; |
| String password = null; |
| Map<String, String> properties = new HashMap<String, String>(); |
| properties.put( TAG_FORMAT_PROPERTY, AccuRevScmProviderRepository.DEFAULT_TAG_FORMAT ); |
| properties.put( ACCUREV_EXECUTABLE_PROPERTY, AccuRev.DEFAULT_ACCUREV_EXECUTABLE ); |
| |
| fillSystemProperties( properties ); |
| |
| int i = 0; |
| while ( i < tokens.length ) |
| { |
| int at = tokens[i].indexOf( '@' ); |
| // prefer "/", better not have a "/" or a "\\" in your password. |
| int slash = tokens[i].indexOf( '/' ); |
| slash = slash < 0 ? tokens[i].indexOf( '\\' ) : slash; |
| |
| int qMark = tokens[i].indexOf( '?' ); |
| |
| if ( qMark == 0 ) |
| { |
| QuotedPropertyParser.parse( tokens[i].substring( 1 ), properties ); |
| } |
| else if ( slash == 0 ) |
| { |
| // this is the project path |
| projectPath = tokens[i].substring( 1 ); |
| break; |
| } |
| else if ( ( slash > 0 || ( at >= 0 ) ) && host == null && user == null ) |
| { |
| // user/pass@host |
| int len = tokens[i].length(); |
| if ( at >= 0 && len > at ) |
| { |
| // everything after the "@" |
| host = tokens[i].substring( at + 1 ); |
| } |
| |
| if ( slash > 0 ) |
| { |
| // user up to / |
| user = tokens[i].substring( 0, slash ); |
| // pass between / and @ |
| password = tokens[i].substring( slash + 1, at < 0 ? len : at ); |
| } |
| else |
| { |
| // no /, user from beginning to @ |
| user = tokens[i].substring( 0, at < 0 ? len : at ); |
| } |
| |
| } |
| else if ( host != null && tokens[i].matches( "^[0-9]+$" ) ) |
| { |
| // only valid entry with all digits is the port specification. |
| port = Integer.parseInt( tokens[i] ); |
| } |
| else |
| { |
| basisStream = tokens[i]; |
| } |
| |
| i++; |
| } |
| |
| if ( i < tokens.length ) |
| { |
| validationMessages.add( "Unknown tokens in URL " + scmSpecificUrl ); |
| } |
| |
| AccuRevScmProviderRepository repo = new AccuRevScmProviderRepository(); |
| repo.setLogger( getLogger() ); |
| if ( !StringUtils.isEmpty( user ) ) |
| { |
| repo.setUser( user ); |
| } |
| if ( !StringUtils.isEmpty( password ) ) |
| { |
| repo.setPassword( password ); |
| } |
| if ( !StringUtils.isEmpty( basisStream ) ) |
| { |
| repo.setStreamName( basisStream ); |
| } |
| if ( !StringUtils.isEmpty( projectPath ) ) |
| { |
| repo.setProjectPath( projectPath ); |
| } |
| if ( !StringUtils.isEmpty( host ) ) |
| { |
| repo.setHost( host ); |
| } |
| repo.setPort( port ); |
| repo.setTagFormat( properties.get( TAG_FORMAT_PROPERTY ) ); |
| |
| AccuRevCommandLine accuRev = new AccuRevCommandLine( host, port ); |
| accuRev.setLogger( getLogger() ); |
| accuRev.setExecutable( properties.get( ACCUREV_EXECUTABLE_PROPERTY ) ); |
| repo.setAccuRev( accuRev ); |
| |
| return repo; |
| |
| } |
| |
| private void fillSystemProperties( Map<String, String> properties ) |
| { |
| |
| Set<String> propertyKeys = properties.keySet(); |
| for ( String key : propertyKeys ) |
| { |
| String systemPropertyKey = SYSTEM_PROPERTY_PREFIX + key; |
| String systemProperty = System.getProperty( systemPropertyKey ); |
| if ( systemProperty != null ) |
| { |
| properties.put( key, systemProperty ); |
| } |
| } |
| |
| } |
| |
| @Override |
| protected LoginScmResult login( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters ) |
| throws ScmException |
| { |
| |
| if ( getLogger().isDebugEnabled() ) |
| { |
| getLogger().debug( repository.toString() ); |
| } |
| |
| AccuRevLoginCommand command = new AccuRevLoginCommand( getLogger() ); |
| return command.login( repository, fileSet, parameters ); |
| } |
| |
| @Override |
| protected CheckOutScmResult checkout( ScmProviderRepository repository, ScmFileSet fileSet, |
| CommandParameters parameters ) |
| throws ScmException |
| { |
| |
| // workaround deprecated behaviour |
| // TODO pull up to AbstractScmProvider |
| AccuRevScmProviderRepository accuRevRepo = (AccuRevScmProviderRepository) repository; |
| if ( !repository.isPersistCheckout() && accuRevRepo.shouldUseExportForNonPersistentCheckout() ) |
| { |
| |
| ExportScmResult result = export( repository, fileSet, parameters ); |
| if ( result.isSuccess() ) |
| { |
| return new CheckOutScmResult( result.getCommandLine(), result.getExportedFiles(), |
| accuRevRepo.getExportRelativePath() ); |
| } |
| else |
| { |
| return new CheckOutScmResult( result.getCommandLine(), result.getProviderMessage(), |
| result.getCommandOutput(), false ); |
| } |
| } |
| |
| AccuRevCheckOutCommand command = new AccuRevCheckOutCommand( getLogger() ); |
| |
| return command.checkout( repository, fileSet, parameters ); |
| |
| } |
| |
| @Override |
| protected CheckInScmResult checkin( ScmProviderRepository repository, ScmFileSet fileSet, |
| CommandParameters parameters ) |
| throws ScmException |
| { |
| |
| AccuRevCheckInCommand command = new AccuRevCheckInCommand( getLogger() ); |
| |
| return command.checkIn( repository, fileSet, parameters ); |
| } |
| |
| @Override |
| public ScmProviderRepository makeProviderScmRepository( File path ) |
| throws ScmRepositoryException, UnknownRepositoryStructure |
| { |
| |
| // TODO: accurev info with current dir = "path", find workspace. Find use-case for this. |
| return super.makeProviderScmRepository( path ); |
| } |
| |
| @Override |
| public AddScmResult add( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters ) |
| throws ScmException |
| { |
| AccuRevAddCommand command = new AccuRevAddCommand( getLogger() ); |
| return command.add( repository, fileSet, parameters ); |
| } |
| |
| @Override |
| protected TagScmResult tag( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters ) |
| throws ScmException |
| { |
| |
| AccuRevTagCommand command = new AccuRevTagCommand( getLogger() ); |
| return command.tag( repository, fileSet, parameters ); |
| |
| } |
| |
| @Override |
| protected StatusScmResult status( ScmProviderRepository repository, ScmFileSet fileSet, |
| CommandParameters parameters ) |
| throws ScmException |
| { |
| |
| AccuRevStatusCommand command = new AccuRevStatusCommand( getLogger() ); |
| return command.status( repository, fileSet, parameters ); |
| |
| } |
| |
| @Override |
| protected UpdateScmResult update( ScmProviderRepository repository, ScmFileSet fileSet, |
| CommandParameters parameters ) |
| throws ScmException |
| { |
| |
| AccuRevScmProviderRepository accurevRepo = (AccuRevScmProviderRepository) repository; |
| |
| AccuRevUpdateCommand command = new AccuRevUpdateCommand( getLogger() ); |
| |
| UpdateScmResult result = command.update( repository, fileSet, parameters ); |
| |
| if ( result.isSuccess() && parameters.getBoolean( CommandParameter.RUN_CHANGELOG_WITH_UPDATE ) ) |
| { |
| AccuRevUpdateScmResult accuRevResult = (AccuRevUpdateScmResult) result; |
| |
| ScmRevision fromRevision = new ScmRevision( accuRevResult.getFromRevision() ); |
| ScmRevision toRevision = new ScmRevision( accuRevResult.getToRevision() ); |
| |
| parameters.setScmVersion( CommandParameter.START_SCM_VERSION, fromRevision ); |
| parameters.setScmVersion( CommandParameter.END_SCM_VERSION, toRevision ); |
| |
| AccuRevVersion startVersion = accurevRepo.getAccuRevVersion( fromRevision ); |
| AccuRevVersion endVersion = accurevRepo.getAccuRevVersion( toRevision ); |
| if ( startVersion.getBasisStream().equals( endVersion.getBasisStream() ) ) |
| { |
| ChangeLogScmResult changeLogResult = changelog( repository, fileSet, parameters ); |
| |
| if ( changeLogResult.isSuccess() ) |
| { |
| result.setChanges( changeLogResult.getChangeLog().getChangeSets() ); |
| } |
| else |
| { |
| getLogger().warn( "Changelog from " + fromRevision + " to " + toRevision + " failed" ); |
| } |
| } |
| else |
| { |
| String comment = "Cross stream update result from " + startVersion + " to " + endVersion; |
| String author = ""; |
| List<ScmFile> files = result.getUpdatedFiles(); |
| List<ChangeFile> changeFiles = new ArrayList<ChangeFile>( files.size() ); |
| for ( ScmFile scmFile : files ) |
| { |
| changeFiles.add( new ChangeFile( scmFile.getPath() ) ); |
| } |
| ChangeSet dummyChangeSet = new ChangeSet( new Date(), comment, author, changeFiles ); |
| // different streams invalidates the change log, insert a dummy change instead. |
| List<ChangeSet> changeSets = Collections.singletonList( dummyChangeSet ); |
| result.setChanges( changeSets ); |
| } |
| |
| } |
| return result; |
| } |
| |
| @Override |
| protected ExportScmResult export( ScmProviderRepository repository, ScmFileSet fileSet, |
| CommandParameters parameters ) |
| throws ScmException |
| { |
| |
| AccuRevExportCommand command = new AccuRevExportCommand( getLogger() ); |
| return command.export( repository, fileSet, parameters ); |
| } |
| |
| @Override |
| protected ChangeLogScmResult changelog( ScmProviderRepository repository, ScmFileSet fileSet, |
| CommandParameters parameters ) |
| throws ScmException |
| { |
| |
| AccuRevChangeLogCommand command = new AccuRevChangeLogCommand( getLogger() ); |
| return command.changelog( repository, fileSet, parameters ); |
| } |
| |
| @Override |
| protected RemoveScmResult remove( ScmProviderRepository repository, ScmFileSet fileSet, |
| CommandParameters parameters ) |
| throws ScmException |
| { |
| |
| AccuRevRemoveCommand command = new AccuRevRemoveCommand( getLogger() ); |
| return command.remove( repository, fileSet, parameters ); |
| } |
| |
| /** {@inheritDoc} */ |
| @Override |
| protected BlameScmResult blame( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters ) |
| throws ScmException |
| { |
| |
| AccuRevBlameCommand blameCommand = new AccuRevBlameCommand( getLogger() ); |
| return blameCommand.blame( repository, fileSet, parameters ); |
| } |
| } |