View Javadoc
1   package org.apache.maven.scm.provider.perforce.command.blame;
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.ScmException;
23  import org.apache.maven.scm.ScmFileSet;
24  import org.apache.maven.scm.command.blame.AbstractBlameCommand;
25  import org.apache.maven.scm.command.blame.BlameLine;
26  import org.apache.maven.scm.command.blame.BlameScmResult;
27  import org.apache.maven.scm.provider.ScmProviderRepository;
28  import org.apache.maven.scm.provider.perforce.PerforceScmProvider;
29  import org.apache.maven.scm.provider.perforce.command.PerforceCommand;
30  import org.apache.maven.scm.provider.perforce.repository.PerforceScmProviderRepository;
31  import org.codehaus.plexus.util.cli.CommandLineException;
32  import org.codehaus.plexus.util.cli.CommandLineUtils;
33  import org.codehaus.plexus.util.cli.Commandline;
34  
35  import java.io.File;
36  import java.util.List;
37  
38  /**
39   * @author Evgeny Mandrikov
40   * @author Olivier Lamy
41   * @since 1.4
42   */
43  public class PerforceBlameCommand
44      extends AbstractBlameCommand
45      implements PerforceCommand
46  {
47      public BlameScmResult executeBlameCommand( ScmProviderRepository repo, ScmFileSet workingDirectory,
48                                                 String filename )
49          throws ScmException
50      {
51          // Call annotate command
52          PerforceScmProviderRepository p4repo = (PerforceScmProviderRepository) repo;
53          String clientspec = PerforceScmProvider.getClientspecName( getLogger(), p4repo, workingDirectory.getBasedir() );
54          Commandline cl =
55              createCommandLine( (PerforceScmProviderRepository) repo, workingDirectory.getBasedir(), filename,
56                                 clientspec );
57  
58          PerforceBlameConsumer blameConsumer = new PerforceBlameConsumer( getLogger() );
59  
60          CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer();
61  
62          int exitCode;
63  
64          try
65          {
66              exitCode = CommandLineUtils.executeCommandLine( cl, blameConsumer, stderr );
67          }
68          catch ( CommandLineException ex )
69          {
70              throw new ScmException( "Error while executing command.", ex );
71          }
72          if ( exitCode != 0 )
73          {
74              return new BlameScmResult( cl.toString(), "The perforce command failed.", stderr.getOutput(), false );
75          }
76  
77          // Call filelog command
78  
79          cl =
80              createFilelogCommandLine( (PerforceScmProviderRepository) repo, workingDirectory.getBasedir(), filename,
81                                        clientspec );
82  
83          PerforceFilelogConsumer filelogConsumer = new PerforceFilelogConsumer( getLogger() );
84  
85          try
86          {
87              exitCode = CommandLineUtils.executeCommandLine( cl, filelogConsumer, stderr );
88          }
89          catch ( CommandLineException ex )
90          {
91              throw new ScmException( "Error while executing command.", ex );
92          }
93          if ( exitCode != 0 )
94          {
95              return new BlameScmResult( cl.toString(), "The perforce command failed.", stderr.getOutput(), false );
96          }
97  
98          // Combine results
99  
100         List<BlameLine> lines = blameConsumer.getLines();
101         for ( int i = 0; i < lines.size(); i++ )
102         {
103             BlameLine line = lines.get( i );
104             String revision = line.getRevision();
105             line.setAuthor( filelogConsumer.getAuthor( revision ) );
106             line.setDate( filelogConsumer.getDate( revision ) );
107         }
108 
109         return new BlameScmResult( cl.toString(), lines );
110     }
111 
112     public static Commandline createCommandLine( PerforceScmProviderRepository repo, File workingDirectory,
113                                                  String filename, final String clientspec )
114     {
115         Commandline cl = PerforceScmProvider.createP4Command( repo, workingDirectory );
116         if ( clientspec != null )
117         {
118             cl.createArg().setValue( "-c" );
119             cl.createArg().setValue( clientspec );
120         }        
121         cl.createArg().setValue( "annotate" );
122         cl.createArg().setValue( "-q" ); // quiet
123         cl.createArg().setValue( filename );
124         return cl;
125     }
126 
127     public static Commandline createFilelogCommandLine( PerforceScmProviderRepository repo, File workingDirectory,
128                                                         String filename, final String clientspec )
129     {
130         Commandline cl = PerforceScmProvider.createP4Command( repo, workingDirectory );
131         if ( clientspec != null )
132         {
133             cl.createArg().setValue( "-c" );
134             cl.createArg().setValue( clientspec );
135         }
136         cl.createArg().setValue( "filelog" );
137         cl.createArg().setValue( filename );
138         return cl;
139     }
140 }