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ø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 }