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: '"
77                               + line + "'." );
78              }
79  
80              return;
81          }
82  
83          String statusString = line.substring( 0, 1 );
84  
85          String file = line.substring( 7 ).trim();
86  
87          ScmFileStatus status;
88  
89          //  The first six columns in the output are each one character wide:
90          //    First column: Says if item was added, deleted, or otherwise changed
91          //      ' ' no modifications
92          //      'A' Added
93          //      'C' Conflicted
94          //      'D' Deleted
95          //      'I' Ignored
96          //      'M' Modified
97          //      'R' Replaced
98          //      'X' item is unversioned, but is used by an externals definition
99          //      '?' item is not under version control
100         //      '!' item is missing (removed by non-svn command) or incomplete
101         //      '~' versioned item obstructed by some item of a different kind
102         //    Second column: Modifications of a file's or directory's properties
103         //      ' ' no modifications
104         //      'C' Conflicted
105         //      'M' Modified
106         //    Third column: Whether the working copy directory is locked
107         //      ' ' not locked
108         //      'L' locked
109         //    Fourth column: Scheduled commit will contain addition-with-history
110         //      ' ' no history scheduled with commit
111         //      '+' history scheduled with commit
112         //    Fifth column: Whether the item is switched relative to its parent
113         //      ' ' normal
114         //      'S' switched
115         //    Sixth column: Repository lock token
116         //      (without -u)
117         //      ' ' no lock token
118         //      'K' lock token present
119         //      (with -u)
120         //      ' ' not locked in repository, no lock token
121         //      'K' locked in repository, lock toKen present
122         //      'O' locked in repository, lock token in some Other working copy
123         //      'T' locked in repository, lock token present but sTolen
124         //      'B' not locked in repository, lock token present but Broken
125         //
126         //  The out-of-date information appears in the eighth column (with -u):
127         //      '*' a newer revision exists on the server
128         //      ' ' the working copy is up to date
129         if ( statusString.equals( "A" ) )
130         {
131             status = ScmFileStatus.ADDED;
132         }
133         else if ( statusString.equals( "M" ) || statusString.equals( "R" ) || statusString.equals( "~" ) )
134         {
135             status = ScmFileStatus.MODIFIED;
136         }
137         else if ( statusString.equals( "D" ) )
138         {
139             status = ScmFileStatus.DELETED;
140         }
141         else if ( statusString.equals( "?" ) )
142         {
143             status = ScmFileStatus.UNKNOWN;
144         }
145         else if ( statusString.equals( "!" ) )
146         {
147             status = ScmFileStatus.MISSING;
148         }
149         else if ( statusString.equals( "C" ) )
150         {
151             status = ScmFileStatus.CONFLICT;
152         }
153         else if ( statusString.equals( "L" ) )
154         {
155             status = ScmFileStatus.LOCKED;
156         }
157         else if ( statusString.equals( "X" ) )
158         {
159             //skip svn:external entries
160             return;
161         }
162         else if ( statusString.equals( "I" ) )
163         {
164             //skip svn:external entries
165             return;
166         }
167         else
168         {
169             //Parse the second column
170             statusString = line.substring( 1, 1 );
171 
172             if ( statusString.equals( "M" ) )
173             {
174                 status = ScmFileStatus.MODIFIED;
175             }
176             else if ( statusString.equals( "C" ) )
177             {
178                 status = ScmFileStatus.CONFLICT;
179             }
180             else
181             {
182                 //The line isn't a status line, ie something like 'Performing status on external item at...'
183                 //or a status defined in next columns
184                 return;
185             }
186         }
187 
188         // If the file isn't a file; don't add it.
189         if ( !status.equals( ScmFileStatus.DELETED ) && !new File( workingDirectory, file ).isFile() )
190         {
191             return;
192         }
193 
194         changedFiles.add( new ScmFile( file, status ) );
195     }
196 
197     public List<ScmFile> getChangedFiles()
198     {
199         return changedFiles;
200     }
201 }