View Javadoc
1   package org.apache.maven.scm.provider.svn.svnexe.command.changelog;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   * http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.maven.scm.ScmBranch;
23  import org.apache.maven.scm.ScmException;
24  import org.apache.maven.scm.ScmFileSet;
25  import org.apache.maven.scm.ScmTag;
26  import org.apache.maven.scm.ScmVersion;
27  import org.apache.maven.scm.command.changelog.AbstractChangeLogCommand;
28  import org.apache.maven.scm.command.changelog.ChangeLogScmRequest;
29  import org.apache.maven.scm.command.changelog.ChangeLogScmResult;
30  import org.apache.maven.scm.command.changelog.ChangeLogSet;
31  import org.apache.maven.scm.provider.ScmProviderRepository;
32  import org.apache.maven.scm.provider.svn.SvnTagBranchUtils;
33  import org.apache.maven.scm.provider.svn.command.SvnCommand;
34  import org.apache.maven.scm.provider.svn.repository.SvnScmProviderRepository;
35  import org.apache.maven.scm.provider.svn.svnexe.command.SvnCommandLineUtils;
36  import org.codehaus.plexus.util.StringUtils;
37  import org.codehaus.plexus.util.cli.CommandLineException;
38  import org.codehaus.plexus.util.cli.CommandLineUtils;
39  import org.codehaus.plexus.util.cli.Commandline;
40  
41  import java.io.File;
42  import java.text.SimpleDateFormat;
43  import java.util.Date;
44  import java.util.TimeZone;
45  
46  /**
47   * @author <a href="mailto:evenisse@apache.org">Emmanuel Venisse</a>
48   * @author Olivier Lamy
49   *
50   */
51  public class SvnChangeLogCommand
52      extends AbstractChangeLogCommand
53      implements SvnCommand
54  {
55      private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss Z";
56  
57      /** {@inheritDoc} */
58      @Deprecated
59      protected ChangeLogScmResult executeChangeLogCommand( ScmProviderRepository repo, ScmFileSet fileSet,
60                                                            ScmVersion startVersion, ScmVersion endVersion,
61                                                            String datePattern )
62          throws ScmException
63      {
64          return executeChangeLogCommand( repo, fileSet, null, null, null, datePattern, startVersion, endVersion, null );
65      }
66  
67      /** {@inheritDoc} */
68      @Deprecated
69      protected ChangeLogScmResult executeChangeLogCommand( ScmProviderRepository repo, ScmFileSet fileSet,
70                                                            Date startDate, Date endDate, ScmBranch branch,
71                                                            String datePattern )
72          throws ScmException
73      {
74          return executeChangeLogCommand( repo, fileSet, startDate, endDate, branch, datePattern, null, null, null );
75      }
76  
77      @Override
78      protected ChangeLogScmResult executeChangeLogCommand( ChangeLogScmRequest request )
79          throws ScmException
80      {
81          final ScmVersion startVersion = request.getStartRevision();
82          final ScmVersion endVersion = request.getEndRevision();
83          final ScmFileSet fileSet = request.getScmFileSet();
84          final String datePattern = request.getDatePattern();
85          return executeChangeLogCommand( request.getScmRepository().getProviderRepository(), fileSet,
86              request.getStartDate(), request.getEndDate(), request.getScmBranch(), datePattern, startVersion,
87                  endVersion, request.getLimit() );
88      }
89  
90      private ChangeLogScmResult executeChangeLogCommand( ScmProviderRepository repo, ScmFileSet fileSet,
91                                                            Date startDate, Date endDate, ScmBranch branch,
92                                                            String datePattern, ScmVersion startVersion,
93                                                            ScmVersion endVersion, Integer limit )
94          throws ScmException
95      {
96          Commandline cl = createCommandLine( (SvnScmProviderRepository) repo, fileSet.getBasedir(), branch, startDate,
97                                              endDate, startVersion, endVersion, limit );
98  
99          SvnChangeLogConsumer consumer = new SvnChangeLogConsumer( getLogger(), datePattern );
100 
101         CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer();
102 
103         if ( getLogger().isInfoEnabled() )
104         {
105             getLogger().info( "Executing: " + SvnCommandLineUtils.cryptPassword( cl ) );
106             getLogger().info( "Working directory: " + cl.getWorkingDirectory().getAbsolutePath() );
107         }
108 
109         int exitCode;
110 
111         try
112         {
113             exitCode = SvnCommandLineUtils.execute( cl, consumer, stderr, getLogger() );
114         }
115         catch ( CommandLineException ex )
116         {
117             throw new ScmException( "Error while executing svn command.", ex );
118         }
119 
120         if ( exitCode != 0 )
121         {
122             return new ChangeLogScmResult( cl.toString(), "The svn command failed.", stderr.getOutput(), false );
123         }
124         ChangeLogSet changeLogSet = new ChangeLogSet( consumer.getModifications(), startDate, endDate );
125         changeLogSet.setStartVersion( startVersion );
126         changeLogSet.setEndVersion( endVersion );
127 
128         return new ChangeLogScmResult( cl.toString(), changeLogSet );
129     }
130 
131     // ----------------------------------------------------------------------
132     //
133     // ----------------------------------------------------------------------
134 
135     public static Commandline createCommandLine( SvnScmProviderRepository repository, File workingDirectory,
136                                                  ScmBranch branch, Date startDate, Date endDate,
137                                                  ScmVersion startVersion, ScmVersion endVersion )
138     {
139         return createCommandLine(repository, workingDirectory, branch,
140             startDate, endDate, startVersion, endVersion, null);
141     }
142 
143     public static Commandline createCommandLine( SvnScmProviderRepository repository, File workingDirectory,
144                                                  ScmBranch branch, Date startDate, Date endDate,
145                                                  ScmVersion startVersion, ScmVersion endVersion, Integer limit )
146     {
147         SimpleDateFormat dateFormat = new SimpleDateFormat( DATE_FORMAT );
148 
149         dateFormat.setTimeZone( TimeZone.getTimeZone( "GMT" ) );
150 
151         Commandline cl = SvnCommandLineUtils.getBaseSvnCommandLine( workingDirectory, repository );
152 
153         cl.createArg().setValue( "log" );
154 
155         cl.createArg().setValue( "-v" );
156 
157         // TODO: May want to add some kind of support for --stop-on-copy and --limit NUM
158 
159         if ( limit != null && limit > 0 )
160         {
161             cl.createArg().setValue( "--limit" );
162             cl.createArg().setValue( Integer.toString( limit ) );
163         }
164 
165         if ( startDate != null )
166         {
167             cl.createArg().setValue( "-r" );
168 
169             if ( endDate != null )
170             {
171                 cl.createArg().setValue(
172                     "{" + dateFormat.format( startDate ) + "}" + ":" + "{" + dateFormat.format( endDate ) + "}" );
173             }
174             else
175             {
176                 cl.createArg().setValue( "{" + dateFormat.format( startDate ) + "}:HEAD" );
177             }
178         }
179 
180         if ( startVersion != null )
181         {
182             cl.createArg().setValue( "-r" );
183 
184             if ( endVersion != null )
185             {
186                 if ( startVersion.getName().equals( endVersion.getName() ) )
187                 {
188                     cl.createArg().setValue( startVersion.getName() );
189                 }
190                 else
191                 {
192                     cl.createArg().setValue( startVersion.getName() + ":" + endVersion.getName() );
193                 }
194             }
195             else
196             {
197                 cl.createArg().setValue( startVersion.getName() + ":HEAD" );
198             }
199         }
200 
201         if ( branch != null && StringUtils.isNotEmpty( branch.getName() ) )
202         {
203             // By specifying a branch and this repository url below, subversion should show
204             // the changelog of that branch, but limit it to paths that also occur in this repository.
205             if ( branch instanceof ScmTag )
206             {
207                 cl.createArg().setValue( SvnTagBranchUtils.resolveTagUrl( repository, (ScmTag) branch ) );
208             }
209             else
210             {
211                 cl.createArg().setValue( SvnTagBranchUtils.resolveBranchUrl( repository, branch ) );
212             }
213         }
214 
215         if ( endVersion == null || !StringUtils.equals( "BASE", endVersion.getName() ) )
216         {
217             cl.createArg().setValue( repository.getUrl() );
218         }
219 
220         return cl;
221     }
222 }