001    package 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    
022    import org.apache.maven.scm.ChangeSet;
023    import org.apache.maven.scm.ScmBranch;
024    import org.apache.maven.scm.ScmException;
025    import org.apache.maven.scm.ScmFileSet;
026    import org.apache.maven.scm.command.changelog.AbstractChangeLogCommand;
027    import org.apache.maven.scm.command.changelog.ChangeLogScmResult;
028    import org.apache.maven.scm.command.changelog.ChangeLogSet;
029    import org.apache.maven.scm.provider.ScmProviderRepository;
030    import org.apache.maven.scm.provider.jazz.command.JazzConstants;
031    import org.apache.maven.scm.provider.jazz.command.JazzScmCommand;
032    import org.apache.maven.scm.provider.jazz.command.consumer.ErrorConsumer;
033    import org.apache.maven.scm.provider.jazz.repository.JazzScmProviderRepository;
034    import org.codehaus.plexus.util.StringUtils;
035    
036    import java.util.ArrayList;
037    import java.util.Date;
038    import 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     */
066    public 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    }