001package org.apache.maven.scm.provider.jazz.command.changelog;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 * http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import org.apache.maven.scm.ChangeSet;
023import org.apache.maven.scm.ScmBranch;
024import org.apache.maven.scm.ScmException;
025import org.apache.maven.scm.ScmFileSet;
026import org.apache.maven.scm.command.changelog.AbstractChangeLogCommand;
027import org.apache.maven.scm.command.changelog.ChangeLogScmResult;
028import org.apache.maven.scm.command.changelog.ChangeLogSet;
029import org.apache.maven.scm.provider.ScmProviderRepository;
030import org.apache.maven.scm.provider.jazz.command.JazzConstants;
031import org.apache.maven.scm.provider.jazz.command.JazzScmCommand;
032import org.apache.maven.scm.provider.jazz.command.consumer.ErrorConsumer;
033import org.apache.maven.scm.provider.jazz.repository.JazzScmProviderRepository;
034import org.codehaus.plexus.util.StringUtils;
035
036import java.util.ArrayList;
037import java.util.Date;
038import java.util.List;
039
040// To get a changelog, we need to get a list of changesets (scm history), and then for each changeset listed,
041// get the details of each changeset (scm list changesets X, Y, Z).
042// 
043// We do not appear to be able to get a list of changes between a range of dates, so all of them are returned.
044//
045// See the following links for additional information on the RTC "history" command:
046// RTC 2.0.0.2:
047// http://publib.boulder.ibm.com/infocenter/rtc/v2r0m0/topic/com.ibm.team.scm.doc/topics/r_scm_cli_history.html
048// RTC 3.0:
049// http://publib.boulder.ibm.com/infocenter/clmhelp/v3r0/topic/com.ibm.team.scm.doc/topics/r_scm_cli_history.html
050// RTC 3.0.1:
051// http://publib.boulder.ibm.com/infocenter/clmhelp/v3r0m1/topic/com.ibm.team.scm.doc/topics/r_scm_cli_history.html
052//
053//
054// See the following links for additional information on the RTC "list changesets" command:
055// RTC 2.0.0.2:
056// http://publib.boulder.ibm.com/infocenter/rtc/v2r0m0/topic/com.ibm.team.scm.doc/topics/r_scm_cli_list.html
057// RTC 3.0:
058// http://publib.boulder.ibm.com/infocenter/clmhelp/v3r0/topic/com.ibm.team.scm.doc/topics/r_scm_cli_list.html
059// RTC 3.0.1:
060// http://publib.boulder.ibm.com/infocenter/clmhelp/v3r0m1/topic/com.ibm.team.scm.doc/topics/r_scm_cli_list.html
061//
062
063/**
064 * @author <a href="mailto:ChrisGWarp@gmail.com">Chris Graham</a>
065 */
066public class JazzChangeLogCommand
067    extends AbstractChangeLogCommand
068{
069    /**
070     * {@inheritDoc}
071     */
072    protected ChangeLogScmResult executeChangeLogCommand( ScmProviderRepository repo, ScmFileSet fileSet,
073                                                          Date startDate, Date endDate, ScmBranch branch,
074                                                          String datePattern )
075        throws ScmException
076    {
077        if ( branch != null && StringUtils.isNotEmpty( branch.getName() ) )
078        {
079            throw new ScmException( "This SCM provider doesn't support branches." );
080        }
081
082        if ( getLogger().isDebugEnabled() )
083        {
084            getLogger().debug( "Executing changelog command..." );
085        }
086
087        // This acts as a two phase operation.
088        // The first pass is to call the "scm history" command to get a list
089        // of the changeSets from Jazz SCM. It is stored in the revision of the
090        // changeSets array.
091        List<ChangeSet> changeSets = new ArrayList<ChangeSet>();
092        JazzScmCommand historyCommand = createHistoryCommand( repo, fileSet );
093        JazzHistoryConsumer changeLogConsumer = new JazzHistoryConsumer( repo, getLogger(), changeSets );
094        ErrorConsumer errConsumer = new ErrorConsumer( getLogger() );
095        int status = historyCommand.execute( changeLogConsumer, errConsumer );
096        if ( status != 0 || errConsumer.hasBeenFed() )
097        {
098            return new ChangeLogScmResult( historyCommand.getCommandString(),
099                                           "Error code for Jazz SCM history command - " + status,
100                                           errConsumer.getOutput(), false );
101        }
102
103        // Now, call the "scm list changesets" command, passing in the list of changesets from the first pass.
104        JazzScmCommand listChangesetsCommand = createListChangesetCommand( repo, fileSet, changeSets );
105        JazzListChangesetConsumer listChangesetConsumer =
106            new JazzListChangesetConsumer( repo, getLogger(), changeSets, datePattern );
107        errConsumer = new ErrorConsumer( getLogger() );
108        status = listChangesetsCommand.execute( listChangesetConsumer, errConsumer );
109        if ( status != 0 || errConsumer.hasBeenFed() )
110        {
111            return new ChangeLogScmResult( listChangesetsCommand.getCommandString(),
112                                           "Error code for Jazz SCM list changesets command - " + status,
113                                           errConsumer.getOutput(), false );
114        }
115
116        // Build the result and return it.
117        ChangeLogSet changeLogSet = new ChangeLogSet( changeSets, startDate, endDate );
118
119        // Return the "main" command used, namely "scm history"
120        return new ChangeLogScmResult( historyCommand.getCommandString(), changeLogSet );
121    }
122
123    protected JazzScmCommand createHistoryCommand( ScmProviderRepository repo, ScmFileSet fileSet )
124    {
125        JazzScmCommand command = new JazzScmCommand( JazzConstants.CMD_HISTORY, repo, fileSet, getLogger() );
126        command.addArgument( JazzConstants.ARG_MAXIMUM );
127        command.addArgument( "10000000" );      // Beyond me as to why they didn't make 0 = all.
128        // And just to really annoy us, it defaults to 10.
129        // So we put something stupidly large in there instead.
130
131        return command;
132    }
133
134    protected JazzScmCommand createListChangesetCommand( ScmProviderRepository repo, ScmFileSet fileSet,
135                                                         List<ChangeSet> changeSets )
136    {
137        JazzScmProviderRepository jazzRepo = (JazzScmProviderRepository) repo;
138        JazzScmCommand command =
139            new JazzScmCommand( JazzConstants.CMD_LIST, JazzConstants.CMD_SUB_CHANGESETS, repo, fileSet, getLogger() );
140        command.addArgument( JazzConstants.ARG_WORKSPACE );
141        command.addArgument( jazzRepo.getWorkspace() );
142        for ( int i = 0; i < changeSets.size(); i++ )
143        {
144            command.addArgument( changeSets.get( i ).getRevision() );
145        }
146        return command;
147    }
148}