View Javadoc
1   package org.apache.maven.scm.provider.svn.svnexe.command.status;
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.ScmFile;
23  import org.apache.maven.scm.ScmFileStatus;
24  import org.apache.maven.scm.log.ScmLogger;
25  import org.codehaus.plexus.util.StringUtils;
26  import org.codehaus.plexus.util.cli.StreamConsumer;
27  
28  import java.io.File;
29  import java.util.ArrayList;
30  import java.util.List;
31  
32  /**
33   * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
34   *
35   */
36  public class SvnStatusConsumer
37      implements StreamConsumer
38  {
39      private ScmLogger logger;
40  
41      private File workingDirectory;
42  
43      private List<ScmFile> changedFiles = new ArrayList<ScmFile>();
44  
45      // ----------------------------------------------------------------------
46      //
47      // ----------------------------------------------------------------------
48  
49      public SvnStatusConsumer( ScmLogger logger, File workingDirectory )
50      {
51          this.logger = logger;
52  
53          this.workingDirectory = workingDirectory;
54      }
55  
56      // ----------------------------------------------------------------------
57      // StreamConsumer Implementation
58      // ----------------------------------------------------------------------
59  
60      /** {@inheritDoc} */
61      public void consumeLine( String line )
62      {
63          if ( logger.isDebugEnabled() )
64          {
65              logger.debug( line );
66          }
67          if ( StringUtils.isEmpty( line.trim() ) )
68          {
69              return;
70          }
71  
72          if ( line.length() <= 7 )
73          {
74              if ( logger.isWarnEnabled() )
75              {
76                  logger.warn( "Unexpected input, the line must be at least seven characters long. Line: '" + line + "'." );
77              }
78  
79              return;
80          }
81  
82          String statusString = line.substring( 0, 1 );
83  
84          String file = line.substring( 7 ).trim();
85  
86          ScmFileStatus status;
87  
88          //  The first six columns in the output are each one character wide:
89          //    First column: Says if item was added, deleted, or otherwise changed
90          //      ' ' no modifications
91          //      'A' Added
92          //      'C' Conflicted
93          //      'D' Deleted
94          //      'I' Ignored
95          //      'M' Modified
96          //      'R' Replaced
97          //      'X' item is unversioned, but is used by an externals definition
98          //      '?' item is not under version control
99          //      '!' item is missing (removed by non-svn command) or incomplete
100         //      '~' versioned item obstructed by some item of a different kind
101         //    Second column: Modifications of a file's or directory's properties
102         //      ' ' no modifications
103         //      'C' Conflicted
104         //      'M' Modified
105         //    Third column: Whether the working copy directory is locked
106         //      ' ' not locked
107         //      'L' locked
108         //    Fourth column: Scheduled commit will contain addition-with-history
109         //      ' ' no history scheduled with commit
110         //      '+' history scheduled with commit
111         //    Fifth column: Whether the item is switched relative to its parent
112         //      ' ' normal
113         //      'S' switched
114         //    Sixth column: Repository lock token
115         //      (without -u)
116         //      ' ' no lock token
117         //      'K' lock token present
118         //      (with -u)
119         //      ' ' not locked in repository, no lock token
120         //      'K' locked in repository, lock toKen present
121         //      'O' locked in repository, lock token in some Other working copy
122         //      'T' locked in repository, lock token present but sTolen
123         //      'B' not locked in repository, lock token present but Broken
124         //
125         //  The out-of-date information appears in the eighth column (with -u):
126         //      '*' a newer revision exists on the server
127         //      ' ' the working copy is up to date
128         if ( statusString.equals( "A" ) )
129         {
130             status = ScmFileStatus.ADDED;
131         }
132         else if ( statusString.equals( "M" ) || statusString.equals( "R" ) || statusString.equals( "~" ) )
133         {
134             status = ScmFileStatus.MODIFIED;
135         }
136         else if ( statusString.equals( "D" ) )
137         {
138             status = ScmFileStatus.DELETED;
139         }
140         else if ( statusString.equals( "?" ) )
141         {
142             status = ScmFileStatus.UNKNOWN;
143         }
144         else if ( statusString.equals( "!" ) )
145         {
146             status = ScmFileStatus.MISSING;
147         }
148         else if ( statusString.equals( "C" ) )
149         {
150             status = ScmFileStatus.CONFLICT;
151         }
152         else if ( statusString.equals( "L" ) )
153         {
154             status = ScmFileStatus.LOCKED;
155         }
156         else if ( statusString.equals( "X" ) )
157         {
158             //skip svn:external entries
159             return;
160         }
161         else if ( statusString.equals( "I" ) )
162         {
163             //skip svn:external entries
164             return;
165         }
166         else
167         {
168             //Parse the second column
169             statusString = line.substring( 1, 1 );
170 
171             if ( statusString.equals( "M" ) )
172             {
173                 status = ScmFileStatus.MODIFIED;
174             }
175             else if ( statusString.equals( "C" ) )
176             {
177                 status = ScmFileStatus.CONFLICT;
178             }
179             else
180             {
181                 //The line isn't a status line, ie something like 'Performing status on external item at...'
182                 //or a status defined in next columns
183                 return;
184             }
185         }
186 
187         // If the file isn't a file; don't add it.
188         if ( !status.equals( ScmFileStatus.DELETED ) && !new File( workingDirectory, file ).isFile() )
189         {
190             return;
191         }
192 
193         changedFiles.add( new ScmFile( file, status ) );
194     }
195 
196     public List<ScmFile> getChangedFiles()
197     {
198         return changedFiles;
199     }
200 }