001package org.apache.maven.scm.provider.git.jgit.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.ScmVersion;
027import org.apache.maven.scm.command.changelog.AbstractChangeLogCommand;
028import org.apache.maven.scm.command.changelog.ChangeLogScmResult;
029import org.apache.maven.scm.command.changelog.ChangeLogSet;
030import org.apache.maven.scm.provider.ScmProviderRepository;
031import org.apache.maven.scm.provider.git.command.GitCommand;
032import org.apache.maven.scm.provider.git.jgit.command.JGitUtils;
033import org.eclipse.jgit.api.Git;
034import org.eclipse.jgit.errors.IncorrectObjectTypeException;
035import org.eclipse.jgit.errors.MissingObjectException;
036import org.eclipse.jgit.lib.Repository;
037import org.eclipse.jgit.revwalk.RevCommit;
038import org.eclipse.jgit.revwalk.RevSort;
039
040import java.io.File;
041import java.io.IOException;
042import java.util.ArrayList;
043import java.util.Date;
044import java.util.List;
045
046/**
047 * @author <a href="mailto:struberg@yahoo.de">Mark Struberg</a>
048 * @author Dominik Bartholdi (imod)
049 * @since 1.9
050 */
051public class JGitChangeLogCommand
052    extends AbstractChangeLogCommand
053    implements GitCommand
054{
055
056    /**
057     * {@inheritDoc}
058     */
059    protected ChangeLogScmResult executeChangeLogCommand( ScmProviderRepository repo, ScmFileSet fileSet,
060                                                          ScmVersion startVersion, ScmVersion endVersion,
061                                                          String datePattern )
062        throws ScmException
063    {
064        return executeChangeLogCommand( repo, fileSet, null, null, null, datePattern, startVersion, endVersion );
065    }
066
067    /**
068     * {@inheritDoc}
069     */
070    protected ChangeLogScmResult executeChangeLogCommand( ScmProviderRepository repo, ScmFileSet fileSet,
071                                                          Date startDate, Date endDate, ScmBranch branch,
072                                                          String datePattern )
073        throws ScmException
074    {
075        return executeChangeLogCommand( repo, fileSet, startDate, endDate, branch, datePattern, null, null );
076    }
077
078    protected ChangeLogScmResult executeChangeLogCommand( ScmProviderRepository repo, ScmFileSet fileSet,
079                                                          Date startDate, Date endDate, ScmBranch branch,
080                                                          String datePattern, ScmVersion startVersion,
081                                                          ScmVersion endVersion )
082        throws ScmException
083    {
084        Git git = null;
085        try
086        {
087            git = Git.open( fileSet.getBasedir() );
088
089            String startRev = startVersion != null ? startVersion.getName() : null;
090            String endRev = endVersion != null ? endVersion.getName() : null;
091
092            List<ChangeEntry> gitChanges =
093                this.whatchanged( git.getRepository(), null, startRev, endRev, startDate, endDate, -1 );
094
095            List<ChangeSet> modifications = new ArrayList<ChangeSet>( gitChanges.size() );
096
097            for ( ChangeEntry change : gitChanges )
098            {
099                ChangeSet scmChange = new ChangeSet();
100
101                scmChange.setAuthor( change.getAuthorName() );
102                scmChange.setComment( change.getBody() );
103                scmChange.setDate( change.getAuthorDate() );
104                scmChange.setRevision( change.getCommitHash() );
105                // X TODO scmChange.setFiles( change.get )
106
107                modifications.add( scmChange );
108            }
109
110            ChangeLogSet changeLogSet = new ChangeLogSet( modifications, startDate, endDate );
111            changeLogSet.setStartVersion( startVersion );
112            changeLogSet.setEndVersion( endVersion );
113
114            return new ChangeLogScmResult( "JGit changelog", changeLogSet );
115        }
116        catch ( Exception e )
117        {
118            throw new ScmException( "JGit changelog failure!", e );
119        }
120        finally
121        {
122            JGitUtils.closeRepo( git );
123        }
124    }
125
126    public List<ChangeEntry> whatchanged( Repository repo, RevSort[] sortings, String fromRev, String toRev,
127                                          Date fromDate, Date toDate, int maxLines )
128        throws MissingObjectException, IncorrectObjectTypeException, IOException
129    {
130        List<RevCommit> revs = JGitUtils.getRevCommits( repo, sortings, fromRev, toRev, fromDate, toDate, maxLines );
131        List<ChangeEntry> changes = new ArrayList<ChangeEntry>( revs.size() );
132
133        for ( RevCommit c : revs )
134        {
135            ChangeEntry ce = new ChangeEntry();
136
137            ce.setAuthorDate( c.getAuthorIdent().getWhen() );
138            ce.setAuthorEmail( c.getAuthorIdent().getEmailAddress() );
139            ce.setAuthorName( c.getAuthorIdent().getName() );
140            ce.setCommitterDate( c.getCommitterIdent().getWhen() );
141            ce.setCommitterEmail( c.getCommitterIdent().getEmailAddress() );
142            ce.setCommitterName( c.getCommitterIdent().getName() );
143
144            ce.setSubject( c.getShortMessage() );
145            ce.setBody( c.getFullMessage() );
146
147            ce.setCommitHash( c.getId().name() );
148            ce.setTreeHash( c.getTree().getId().name() );
149
150            // X TODO missing: file list
151
152            changes.add( ce );
153        }
154
155        return changes;
156    }
157
158    public static final class ChangeEntry
159    {
160        private String commitHash;
161
162        private String treeHash;
163
164        private String authorName;
165
166        private String authorEmail;
167
168        private Date authorDate;
169
170        private String committerName;
171
172        private String committerEmail;
173
174        private Date committerDate;
175
176        private String subject;
177
178        private String body;
179
180        private List<File> files;
181
182        public String getCommitHash()
183        {
184            return commitHash;
185        }
186
187        public void setCommitHash( String commitHash )
188        {
189            this.commitHash = commitHash;
190        }
191
192        public String getTreeHash()
193        {
194            return treeHash;
195        }
196
197        public void setTreeHash( String treeHash )
198        {
199            this.treeHash = treeHash;
200        }
201
202        public String getAuthorName()
203        {
204            return authorName;
205        }
206
207        public void setAuthorName( String authorName )
208        {
209            this.authorName = authorName;
210        }
211
212        public String getAuthorEmail()
213        {
214            return authorEmail;
215        }
216
217        public void setAuthorEmail( String authorEmail )
218        {
219            this.authorEmail = authorEmail;
220        }
221
222        public Date getAuthorDate()
223        {
224            return authorDate;
225        }
226
227        public void setAuthorDate( Date authorDate )
228        {
229            this.authorDate = authorDate;
230        }
231
232        public String getCommitterName()
233        {
234            return committerName;
235        }
236
237        public void setCommitterName( String committerName )
238        {
239            this.committerName = committerName;
240        }
241
242        public String getCommitterEmail()
243        {
244            return committerEmail;
245        }
246
247        public void setCommitterEmail( String committerEmail )
248        {
249            this.committerEmail = committerEmail;
250        }
251
252        public Date getCommitterDate()
253        {
254            return committerDate;
255        }
256
257        public void setCommitterDate( Date committerDate )
258        {
259            this.committerDate = committerDate;
260        }
261
262        public String getSubject()
263        {
264            return subject;
265        }
266
267        public void setSubject( String subject )
268        {
269            this.subject = subject;
270        }
271
272        public String getBody()
273        {
274            return body;
275        }
276
277        public void setBody( String body )
278        {
279            this.body = body;
280        }
281
282        public List<File> getFiles()
283        {
284            return files;
285        }
286
287        public void setFiles( List<File> files )
288        {
289            this.files = files;
290        }
291    }
292}