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, String filename )
48          throws ScmException
49      {
50          // Call annotate command
51  		PerforceScmProviderRepository p4repo = (PerforceScmProviderRepository) repo;
52  		String clientspec = PerforceScmProvider.getClientspecName( getLogger(), p4repo, workingDirectory.getBasedir() );
53          Commandline cl = createCommandLine( (PerforceScmProviderRepository) repo, workingDirectory.getBasedir(),
54                                              filename, clientspec);
55  
56          PerforceBlameConsumer blameConsumer = new PerforceBlameConsumer( getLogger() );
57  
58          CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer();
59  
60          int exitCode;
61  
62          try
63          {
64              exitCode = CommandLineUtils.executeCommandLine( cl, blameConsumer, stderr );
65          }
66          catch ( CommandLineException ex )
67          {
68              throw new ScmException( "Error while executing command.", ex );
69          }
70          if ( exitCode != 0 )
71          {
72              return new BlameScmResult( cl.toString(), "The perforce command failed.", stderr.getOutput(), false );
73          }
74  
75          // Call filelog command
76  
77          cl = createFilelogCommandLine( (PerforceScmProviderRepository) repo, workingDirectory.getBasedir(), filename, clientspec );
78  
79          PerforceFilelogConsumer filelogConsumer = new PerforceFilelogConsumer( getLogger() );
80  
81          try
82          {
83              exitCode = CommandLineUtils.executeCommandLine( cl, filelogConsumer, stderr );
84          }
85          catch ( CommandLineException ex )
86          {
87              throw new ScmException( "Error while executing command.", ex );
88          }
89          if ( exitCode != 0 )
90          {
91              return new BlameScmResult( cl.toString(), "The perforce command failed.", stderr.getOutput(), false );
92          }
93  
94          // Combine results
95  
96          List<BlameLine> lines = blameConsumer.getLines();
97          for ( int i = 0; i < lines.size(); i++ )
98          {
99              BlameLine line = lines.get( i );
100             String revision = line.getRevision();
101             line.setAuthor( filelogConsumer.getAuthor( revision ) );
102             line.setDate( filelogConsumer.getDate( revision ) );
103         }
104 
105         return new BlameScmResult( cl.toString(), lines );
106     }
107 
108     public static Commandline createCommandLine( PerforceScmProviderRepository repo, File workingDirectory,
109                                                  String filename, final String clientspec )
110     {
111         Commandline cl = PerforceScmProvider.createP4Command( repo, workingDirectory );
112 		if(clientspec != null)
113 		{
114 			cl.createArg().setValue( "-c" );
115 			cl.createArg().setValue( clientspec );
116 		}		
117         cl.createArg().setValue( "annotate" );
118         cl.createArg().setValue( "-q" ); // quiet
119         cl.createArg().setValue( filename );
120         return cl;
121     }
122 
123     public static Commandline createFilelogCommandLine( PerforceScmProviderRepository repo, File workingDirectory,
124                                                         String filename, final String clientspec )
125     {
126         Commandline cl = PerforceScmProvider.createP4Command( repo, workingDirectory );
127 		if(clientspec != null)
128 		{
129 			cl.createArg().setValue( "-c" );
130 			cl.createArg().setValue( clientspec );
131 		}
132 		cl.createArg().setValue( "filelog" );
133         cl.createArg().setValue( filename );
134         return cl;
135     }
136 }